From f9ef10be0ac9487dfa0ecf69c743723948e19e22 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Tue, 27 Mar 2018 01:12:06 +0300 Subject: [PATCH] feat(commands) Introduce postCommandAction Introduce postCommandAction that is executed when the command succeeds. Use the action to print additional information to user how to continue after command is finished. Show some information on successful postinstall - instruct the users how to use local builds, cloud builds and playground. --- lib/commands/create-project.ts | 13 ++++++++++++- lib/commands/post-install.ts | 21 +++++++++++++++++++++ lib/common | 2 +- lib/definitions/project.d.ts | 13 ++++++++++--- lib/services/project-service.ts | 3 ++- test/project-commands.ts | 3 ++- test/project-service.ts | 2 +- 7 files changed, 49 insertions(+), 8 deletions(-) diff --git a/lib/commands/create-project.ts b/lib/commands/create-project.ts index 802f829f44..bc024dc6f5 100644 --- a/lib/commands/create-project.ts +++ b/lib/commands/create-project.ts @@ -1,10 +1,14 @@ import * as constants from "../constants"; +import * as path from "path"; export class CreateProjectCommand implements ICommand { public enableHooks = false; public allowedParameters: ICommandParameter[] = [this.$stringParameterBuilder.createMandatoryParameter("Project name cannot be empty.")]; + private createdProjecData: ICreateProjectData; + constructor(private $projectService: IProjectService, + private $logger: ILogger, private $errors: IErrors, private $options: IOptions, private $stringParameterBuilder: IStringParameterBuilder) { } @@ -23,7 +27,7 @@ export class CreateProjectCommand implements ICommand { selectedTemplate = this.$options.template; } - await this.$projectService.createProject({ + this.createdProjecData = await this.$projectService.createProject({ projectName: args[0], template: selectedTemplate, appId: this.$options.appid, @@ -32,6 +36,13 @@ export class CreateProjectCommand implements ICommand { ignoreScripts: this.$options.ignoreScripts }); } + + public async postCommandAction(args: string[]): Promise { + const { projectDir } = this.createdProjecData; + const relativePath = path.relative(process.cwd(), projectDir); + this.$logger.printMarkdown(`Now you can navigate to your project with \`$ cd ${relativePath}\``); + this.$logger.printMarkdown(`After that you can run it on device/emulator by executing \`$ tns run \``); + } } $injector.registerCommand("create", CreateProjectCommand); diff --git a/lib/commands/post-install.ts b/lib/commands/post-install.ts index 80db0dfc9b..75c600e6a5 100644 --- a/lib/commands/post-install.ts +++ b/lib/commands/post-install.ts @@ -18,6 +18,27 @@ export class PostInstallCliCommand extends PostInstallCommand { await this.$subscriptionService.subscribeForNewsletter(); } + + public async postCommandAction(args: string[]): Promise { + this.$logger.info("You have successfully installed NativeScript CLI."); + this.$logger.info("In order to create a new project, you can use:".green); + this.$logger.printMarkdown("`tns create `"); + this.$logger.info("To build your project locally you can use:".green); + this.$logger.printMarkdown("`tns build `"); + this.$logger.printMarkdown("NOTE: Local builds require additional setup of your environment. You can find more information here: `https://docs.nativescript.org/start/quick-setup`"); + + // Add a new line just to ensure separation between local builds and cloud builds info. + this.$logger.info(""); + this.$logger.info("To build your project in the cloud you can use:".green); + this.$logger.printMarkdown("`tns cloud build `"); + this.$logger.printMarkdown("NOTE: Cloud builds require Telerik account. You can find more information here: `https://docs.nativescript.org/sidekick/intro/requirements`"); + + this.$logger.info(""); + this.$logger.printMarkdown("In case you want to experiment quickly with NativeScript, you can try the Playground: `https://play.nativescript.org`"); + + this.$logger.info(""); + this.$logger.printMarkdown("In case you have any questions, you can check our forum: `https://forum.nativescript.org` and our public Slack channel: `https://nativescriptcommunity.slack.com/`"); + } } $injector.registerCommand("post-install-cli", PostInstallCliCommand); diff --git a/lib/common b/lib/common index 2b4ee454a1..d5b8319094 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit 2b4ee454a17575d3a1bb028fa8df42d78677b823 +Subproject commit d5b83190946bae0cbb2aae5d90d89128aeb63d15 diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts index 01132e0d95..2e99a72bfd 100644 --- a/lib/definitions/project.d.ts +++ b/lib/definitions/project.d.ts @@ -37,13 +37,21 @@ interface IProjectSettings { ignoreScripts?: boolean; } +interface IProjectName { + projectName: string; +} + +interface ICreateProjectData extends IProjectDir, IProjectName { + +} + interface IProjectService { /** * Creates new NativeScript application. * @param {any} projectSettings Options describing new project - its name, appId, path and template from which to be created. * @returns {Promise} */ - createProject(projectSettings: IProjectSettings): Promise; + createProject(projectSettings: IProjectSettings): Promise; /** * Checks if the specified project is valid NativeScript project. @@ -58,8 +66,7 @@ interface INsConfig { appResourcesPath?: string; } -interface IProjectData extends IProjectDir { - projectName: string; +interface IProjectData extends ICreateProjectData { platformsDir: string; projectFilePath: string; projectId?: string; diff --git a/lib/services/project-service.ts b/lib/services/project-service.ts index ecabbc9b5e..2a92ea0a0c 100644 --- a/lib/services/project-service.ts +++ b/lib/services/project-service.ts @@ -18,7 +18,7 @@ export class ProjectService implements IProjectService { private $npmInstallationManager: INpmInstallationManager) { } @exported("projectService") - public async createProject(projectOptions: IProjectSettings): Promise { + public async createProject(projectOptions: IProjectSettings): Promise { let projectName = projectOptions.projectName; let selectedTemplate = projectOptions.template; @@ -74,6 +74,7 @@ export class ProjectService implements IProjectService { } this.$logger.printMarkdown("Project `%s` was successfully created.", projectName); + return { projectName, projectDir }; } @exported("projectService") diff --git a/test/project-commands.ts b/test/project-commands.ts index d5ddccaa41..20722bceb8 100644 --- a/test/project-commands.ts +++ b/test/project-commands.ts @@ -10,9 +10,10 @@ let isProjectCreated: boolean; const dummyArgs = ["dummyArgsString"]; class ProjectServiceMock implements IProjectService { - async createProject(projectOptions: IProjectSettings): Promise { + async createProject(projectOptions: IProjectSettings): Promise { selectedTemplateName = projectOptions.template; isProjectCreated = true; + return null; } isValidNativeScriptProject(pathToProject?: string): boolean { diff --git a/test/project-service.ts b/test/project-service.ts index 027598df2d..3b54318e80 100644 --- a/test/project-service.ts +++ b/test/project-service.ts @@ -59,7 +59,7 @@ class ProjectIntegrationTest { this.createTestInjector(); } - public async createProject(projectOptions: IProjectSettings): Promise { + public async createProject(projectOptions: IProjectSettings): Promise { const projectService: IProjectService = this.testInjector.resolve("projectService"); if (!projectOptions.template) { projectOptions.template = constants.RESERVED_TEMPLATE_NAMES["default"];