diff --git a/bin/nativescript.cmd b/bin/tns.cmd similarity index 100% rename from bin/nativescript.cmd rename to bin/tns.cmd diff --git a/lib/commands/list-platforms.ts b/lib/commands/list-platforms.ts index 855d384f13..e625fac248 100644 --- a/lib/commands/list-platforms.ts +++ b/lib/commands/list-platforms.ts @@ -11,7 +11,8 @@ export class ListPlatformsCommand implements ICommand { this.$logger.out("Available platforms: %s", helpers.formatListOfNames(availablePlatforms)); var installedPlatforms = this.$platformService.getInstalledPlatforms().wait(); - this.$logger.out("Installed platforms %s", helpers.formatListOfNames(installedPlatforms)); + var message = installedPlatforms.length > 0 ? helpers.formatListOfNames(installedPlatforms) : "No installed platforms found"; + this.$logger.out("Installed platforms: %s", message); }).future()(); } } diff --git a/lib/common b/lib/common index 789a82292b..fb4c0eeb66 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit 789a82292b66159981e7e02791f4ba89a32c74a1 +Subproject commit fb4c0eeb668eb988e69a62b91ab989e336d06dbc diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts index 7b6b80be7d..01c5c3ebed 100644 --- a/lib/definitions/project.d.ts +++ b/lib/definitions/project.d.ts @@ -1,6 +1,5 @@ interface IProjectService { createProject(projectName: string, projectId: string): IFuture; - ensureProject(): void; } interface IProjectData { diff --git a/lib/nativescript-cli.ts b/lib/nativescript-cli.ts index 2c58c2c502..cb3b98e6e0 100644 --- a/lib/nativescript-cli.ts +++ b/lib/nativescript-cli.ts @@ -10,7 +10,13 @@ require("./options"); import errors = require("./common/errors"); errors.installUncaughtExceptionListener(); -$injector.register("config", {"CI_LOGGER": false, PROJECT_FILE_NAME: ".tnsproject", "DEBUG": process.env.NATIVESCRIPT_DEBUG}); +$injector.register("config", { + CI_LOGGER: false, + PROJECT_FILE_NAME: ".tnsproject", + DEBUG: process.env.NATIVESCRIPT_DEBUG, + version: require("../package.json").version, + client: "tns" +}); var dispatcher = $injector.resolve("dispatcher"); dispatcher.runMainFiber(); \ No newline at end of file diff --git a/lib/options.ts b/lib/options.ts index 20f58e75e7..77dfaff124 100644 --- a/lib/options.ts +++ b/lib/options.ts @@ -8,6 +8,7 @@ var knownOpts:any = { "log" : String, "verbose" : Boolean, "path" : String, + "appid" : String, "copy-from": String, "link-to": String, "release": String, diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index 7740396b7c..c48772db38 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -49,8 +49,6 @@ export class PlatformService implements IPlatformService { this.$errors.fail("No platform specified. Please specify a platform to add"); } - this.$projectService.ensureProject(); - var platformsDir = this.$projectData.platformsDir; this.$fs.ensureDirectoryExists(platformsDir).wait(); @@ -65,7 +63,7 @@ export class PlatformService implements IPlatformService { return(() => { platform = platform.split("@")[0]; - this.validatePlatform(platform); + this.validatePlatform(platform, true); var platformPath = path.join(this.$projectData.platformsDir, platform); @@ -110,7 +108,9 @@ export class PlatformService implements IPlatformService { public preparePlatform(platform: string): IFuture { return (() => { platform = platform.toLowerCase(); + this.validatePlatform(platform); + var normalizedPlatformName = this.normalizePlatformName(platform); this.$platformProjectService.prepareProject(normalizedPlatformName, this.$platformsData.platformsNames).wait(); @@ -119,14 +119,14 @@ export class PlatformService implements IPlatformService { public buildPlatform(platform: string): IFuture { return (() => { - platform = platform.toLocaleLowerCase(); + platform = platform.toLowerCase(); this.validatePlatform(platform); this.$platformProjectService.buildProject(platform).wait(); }).future()(); } - private validatePlatform(platform: string): void { + private validatePlatform(platform: string, skipIsPlatformInstalledCheck?: boolean): void { if (!this.isValidPlatform(platform)) { this.$errors.fail("Invalid platform %s. Valid platforms are %s.", platform, helpers.formatListOfNames(this.$platformsData.platformsNames)); } @@ -134,6 +134,12 @@ export class PlatformService implements IPlatformService { if (!this.isPlatformSupportedForOS(platform)) { this.$errors.fail("Applications for platform %s can not be built on this OS - %s", platform, process.platform); } + + if(!skipIsPlatformInstalledCheck) { + if (!this.isPlatformInstalled(platform).wait()) { + this.$errors.fail("The platform %s is not added to this project. Please use 'tns platform add '", platform); + } + } } private isValidPlatform(platform: string) { @@ -150,6 +156,12 @@ export class PlatformService implements IPlatformService { return false; } + private isPlatformInstalled(platform: string): IFuture { + return (() => { + return this.$fs.exists(path.join(this.$projectData.platformsDir, platform)).wait(); + }).future()(); + } + private normalizePlatformName(platform: string): string { switch(platform) { case "android": diff --git a/lib/services/project-service.ts b/lib/services/project-service.ts index 764e624518..7929cc3037 100644 --- a/lib/services/project-service.ts +++ b/lib/services/project-service.ts @@ -15,6 +15,7 @@ class ProjectData implements IProjectData { public projectName: string; constructor(private $fs: IFileSystem, + private $errors: IErrors, private $projectHelper: IProjectHelper, private $config) { this.initializeProjectData().wait(); @@ -23,7 +24,7 @@ class ProjectData implements IProjectData { private initializeProjectData(): IFuture { return(() => { var projectDir = this.$projectHelper.projectDir; - + // If no project found, projectDir should be null if(projectDir) { this.projectDir = projectDir; this.projectName = path.basename(projectDir); @@ -34,15 +35,15 @@ class ProjectData implements IProjectData { var fileContent = this.$fs.readJson(this.projectFilePath).wait(); this.projectId = fileContent.id; } + } else { + this.$errors.fail("No project found at or above '%s' and neither was a --path specified.", process.cwd()); } - }).future()(); } } $injector.register("projectData", ProjectData); export class ProjectService implements IProjectService { - private static DEFAULT_PROJECT_ID = "com.telerik.tns.HelloWorld"; private static DEFAULT_PROJECT_NAME = "HelloNativescript"; public static APP_FOLDER_NAME = "app"; @@ -50,15 +51,15 @@ export class ProjectService implements IProjectService { private $errors: IErrors, private $fs: IFileSystem, private $projectTemplatesService: IProjectTemplatesService, - private $projectData: IProjectData, + private $projectHelper: IProjectHelper, private $config) { } public createProject(projectName: string, projectId: string): IFuture { return(() => { var projectDir = path.resolve(options.path || "."); - projectId = projectId || ProjectService.DEFAULT_PROJECT_ID; projectName = projectName || ProjectService.DEFAULT_PROJECT_NAME; + projectId = options.appid || this.$projectHelper.generateDefaultAppId(projectName); projectDir = path.join(projectDir, projectName); this.$fs.createDirectory(projectDir).wait(); @@ -82,9 +83,13 @@ export class ProjectService implements IProjectService { // Make sure that the source app/ is not a direct ancestor of a target app/ var relativePathFromSourceToTarget = path.relative(customAppPath, appDirectory); - var doesRelativePathGoUpAtLeastOneDir = relativePathFromSourceToTarget.split(path.sep)[0] == ".."; - if(!doesRelativePathGoUpAtLeastOneDir) { - this.$errors.fail("Project dir %s must not be created at/inside the template used to create the project %s.", projectDir, customAppPath); + // path.relative returns second argument if the paths are located on different disks + // so in this case we don't need to make the check for direct ancestor + if(relativePathFromSourceToTarget !== appDirectory) { + var doesRelativePathGoUpAtLeastOneDir = relativePathFromSourceToTarget.split(path.sep)[0] === ".."; + if (!doesRelativePathGoUpAtLeastOneDir) { + this.$errors.fail("Project dir %s must not be created at/inside the template used to create the project %s.", projectDir, customAppPath); + } } this.$logger.trace("Copying custom app into %s", appDirectory); appPath = customAppPath; @@ -97,6 +102,8 @@ export class ProjectService implements IProjectService { } this.createProjectCore(projectDir, appPath, projectId, false).wait(); + + this.$logger.out("Project %s was successfully created", projectName); }).future()(); } @@ -141,12 +148,6 @@ export class ProjectService implements IProjectService { return customAppPath; } - - public ensureProject() { - if (this.$projectData.projectDir === "" || !this.$fs.exists(this.$projectData.projectFilePath).wait()) { - this.$errors.fail("No project found at or above '%s' and neither was a --path specified.", process.cwd()); - } - } } $injector.register("projectService", ProjectService); diff --git a/resources/help.txt b/resources/help.txt new file mode 100644 index 0000000000..a05c2d6b11 --- /dev/null +++ b/resources/help.txt @@ -0,0 +1,111 @@ +--[]-- + +Usage: + $ tns [command parameters] [--command ] + +General commands: + help Shows additional information about the commands in this list. + + create Creates a new NativeScript project with given project name and application identifier. + platform add Creates a new platform specific project. + platform list Lists all available and all installed platforms. + prepare Copies files for specified platform, so that the project is ready to build in platform specific SDK. + build Builds the project for the selected target platform and produces an application package. + run This is shorthand for prepare and build. + +General options: + --help Prints help about the selected command. + --path Specifies the directory that contains the project. If not set, the project is searched for + in the current directory and all directories above it. + --version Prints the client version. +--[/]-- + +--[help]-- + +Usage: + $ tns help [] +Lists the available commands or shows information about the selected command. + is any of the available commands as listed by $ tns help. + +--[/]-- + +--[create]-- + +Usage: + $ tns create [--path ] [--appid ] [--copy-from ] + +Creates a new NativeScript project. + is the name of project. It should conform to platform package type limitations. For example classes in Java +don't begin with numbers. + +Options: + --path - Specifies the directory where you want to create the project, if different from the current directory. + The directory must be empty. + --appid - Sets the application identifier for your project. The application identifier must consist of at least three + alphanumeric strings, separated by a dot (.). Each string must start with a letter. + The application identifier corresponds to the Bundle ID for iOS apps and to the package identifier for Android apps. + If not specified, the application identifier is set to com.telerik.. + --copy-from - Specifies the directory where your javascript files are located. If not set, + the default hello world template is used. + +--[/]-- + +--[platform]-- + +Usage: + $ tns platform + + is a related command that extends the platform command. You can run the following related commands: + list - Lists all available and installed platforms. + add - Creates a new platform specific project + +--[/]-- + +--[platform|list]-- + +Usage: + $ tns platform + +Lists all available and currently installed platforms. + +--[/]-- + +--[platform|add]-- + +Usage: + $ tns platform add + +Platform-specific usage: + $ tns platform add android + $ tns platform add ios + +Creates a new platform specific project. In this version of Telerik NativeScript you can create only ios and android projects. +You can create Android projects on windows and Mac machine. You can create ios projects only on Mac machine. +--[/]-- + +--[prepare]-- + +Usage: + $ tns prepare [] + +Platform-specific usage: + $ tns prepare android + $ tns prepare ios + +Copies files for specified platform, so that the project is ready to build in each SDK. + +--[/]-- + +--[build]-- + +Usage: + $ tns build [] + +Platform-specific usage: + $ tns build android + $ tns build ios + +Builds the project for specified platform. This generates platform-specific code within the project's platforms subdirectory. + +--[/]-- +