Skip to content
This repository has been archived by the owner on Mar 11, 2024. It is now read-only.

New solidity project types has added: empty, sample and unbox a truffle project #222

Merged
merged 2 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,11 +482,19 @@ export class Constants {
public static typeOfSolidityProject = {
action: {
emptyProject: 'createEmptyProject',
sampleProject: 'createSampleProject',
projectFromTruffleBox: 'createProjectFromTruffleBox',
},
text: {
emptyProject: 'Create basic project',
projectFromTruffleBox: 'Create Project from Truffle box',
emptyProject: 'Create empty project',
sampleProject: 'Create sample project',
projectFromTruffleBox: 'Create project from Truffle box',
},
description: {
emptyProject: 'Empty project equivalent of truffle init',
sampleProject: 'Sample project (current vscode-starter-box) with some enhancements)',
projectFromTruffleBox:
'Project from Truffle Box (which will launch another dropdown with the full list of all boxes)',
},
};

Expand Down
124 changes: 95 additions & 29 deletions src/commands/ProjectCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,85 @@ import fs from 'fs-extra';
import {Uri, window, workspace} from 'vscode';
import {gitHelper, outputCommandHelper} from '../helpers';

/**
* Represents the project type for creating a new project.
*/
enum ProjectType {
empty = 'empty',
sample = 'sample',
box = 'box',
}

/**
* Represents the command for creating the new project (destinations).
*/
interface IProjectDestination {
cmd: (projectPath: string) => Promise<void>;
cmd: (projectPath: string, projectType: ProjectType) => Promise<void>;
label: string;
detail?: string;
projectType: ProjectType;
}

export namespace ProjectCommands {
/**
* This role is a public role responsible for allowing the user to start
* creating the project.
*/
export async function newSolidityProject(): Promise<void> {
Telemetry.sendEvent('ProjectCommands.newSolidityProject.started');

// Checks if required applications are installed
if (!(await required.checkRequiredApps())) {
return;
}

// Chooses the directory path where the new project will be created
const projectPath = await chooseNewProjectDir();

// Sets the QuickPick items
const typeOfSolidityProjectDestination: IProjectDestination[] = [
{
cmd: createNewEmptyProject,
cmd: createProject,
label: Constants.typeOfSolidityProject.text.emptyProject,
detail: Constants.typeOfSolidityProject.description.emptyProject,
projectType: ProjectType.empty,
},
{
cmd: createProjectFromTruffleBox,
cmd: createProject,
label: Constants.typeOfSolidityProject.text.sampleProject,
detail: Constants.typeOfSolidityProject.description.sampleProject,
projectType: ProjectType.sample,
},
{
cmd: createProject,
label: Constants.typeOfSolidityProject.text.projectFromTruffleBox,
detail: Constants.typeOfSolidityProject.description.projectFromTruffleBox,
projectType: ProjectType.box,
},
];

const command = await showQuickPick(typeOfSolidityProjectDestination, {
// Displays the QuickPick with the possibilities to choose between project types
const command = (await showQuickPick(typeOfSolidityProjectDestination, {
placeHolder: Constants.placeholders.selectTypeOfSolidityProject,
ignoreFocusOut: true,
});
})) as IProjectDestination;

const projectPath = await chooseNewProjectDir();
// Creates the project
await command.cmd(projectPath, command.projectType);

Telemetry.sendEvent('ProjectCommands.newSolidityProject.initialization');
await command.cmd(projectPath);
// Starts the git
await gitHelper.gitInit(projectPath);

Telemetry.sendEvent('ProjectCommands.newSolidityProject.finished');
}
}

/**
* This function is responsible for allowing the user to choose in which directory
* the new project will be created.
*
* @returns the project path
*/
async function chooseNewProjectDir(): Promise<string> {
const projectPath = await showOpenFolderDialog();

Expand All @@ -72,34 +115,51 @@ async function chooseNewProjectDir(): Promise<string> {
return projectPath;
}

async function createNewEmptyProject(projectPath: string): Promise<void> {
Telemetry.sendEvent('ProjectCommands.createNewEmptyProject.started');

await createProject(projectPath, Constants.defaultTruffleBox);

Telemetry.sendEvent('ProjectCommands.createNewEmptyProject.finished');
}

async function createProjectFromTruffleBox(projectPath: string): Promise<void> {
const truffleBoxName = await getTruffleBoxName();

Telemetry.sendEvent('ProjectCommands.createProjectFromTruffleBox.started', {truffleBoxName});

await createProject(projectPath, truffleBoxName);

Telemetry.sendEvent('ProjectCommands.createProjectFromTruffleBox.finished', {truffleBoxName});
}

async function createProject(projectPath: string, truffleBoxName: string): Promise<void> {
/**
* This function is responsible for creating the project according to the chosen project type.
*
* @param projectPath the directory path where the project will be created
* @param projectType the type of project the user wants to create: empty, default, or unbox a truffle project
*/
async function createProject(projectPath: string, projectType: ProjectType): Promise<void> {
await showIgnorableNotification(Constants.statusBarMessages.creatingProject, async () => {
try {
Telemetry.sendEvent('ProjectCommands.createProject.unbox', {truffleBoxName});
await outputCommandHelper.executeCommand(projectPath, 'npx', RequiredApps.truffle, 'unbox', truffleBoxName);
Telemetry.sendEvent(`ProjectCommands.createProject.${projectType}.started`);

// Checks the project type
switch (projectType) {
case ProjectType.empty:
// Starts a empty project
await outputCommandHelper.executeCommand(projectPath, 'npx', RequiredApps.truffle, 'init');
break;
case ProjectType.sample:
// Starts a default project
await outputCommandHelper.executeCommand(
xhulz marked this conversation as resolved.
Show resolved Hide resolved
projectPath,
'npx',
RequiredApps.truffle,
'unbox',
Constants.defaultTruffleBox
);
break;
case ProjectType.box: {
// Gets the name of truffle box
const truffleBoxName = await getTruffleBoxName();
// Unboxs the truffle project
await outputCommandHelper.executeCommand(projectPath, 'npx', RequiredApps.truffle, 'unbox', truffleBoxName);
break;
}
}

// Looking for truffle config named in old style and rename it to truffle-config.js
checkTruffleConfigNaming(projectPath);

// Updates the workspace folders with the new workspace
workspace.updateWorkspaceFolders(0, workspace.workspaceFolders ? workspace.workspaceFolders.length : null, {
uri: Uri.file(projectPath),
});

Telemetry.sendEvent(`ProjectCommands.createProject.${projectType}.finished`);
} catch (error) {
fs.emptyDirSync(projectPath);
Telemetry.sendException(new Error(Constants.errorMessageStrings.NewProjectCreationFailed));
Expand All @@ -108,6 +168,12 @@ async function createProject(projectPath: string, truffleBoxName: string): Promi
});
}

/**
* This function is responsible for allowing the user to type the name of a
* truffle box so that the unbox is performed.
*
* @returns the truffle box name
*/
async function getTruffleBoxName(): Promise<string> {
return await showInputBox({
ignoreFocusOut: true,
Expand Down
Loading