Skip to content

Commit 43407b4

Browse files
committed
Init command
1 parent 572acff commit 43407b4

File tree

7 files changed

+147
-4
lines changed

7 files changed

+147
-4
lines changed

docs/man_pages/project/creation/create.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,12 @@ Creates a new project for native development with NativeScript from the default
1616
* `<App Name>` is the name of project. The specified name must meet the requirements of all platforms that you want to target. <% if(isConsole) { %>For more information about the `<App Name>` requirements, run `$ tns help create`<% } %><% if(isHtml) { %>For projects that target Android, you can use uppercase or lowercase letters, numbers, and underscores. The name must start with a letter.
1717
For projects that target iOS, you can use uppercase or lowercase letters, numbers, and hyphens.<% } %>
1818
* `<App ID>` is the application identifier for your project. It must be a domain name in reverse and must meet the requirements of all platforms that you want to target. If not specified, the application identifier is set to `org.nativescript.<App name>` <% if(isConsole) { %>For more information about the `<App ID>` requirements, run `$ tns help create`<% } %><% if(isHtml) { %>For projects that target Android, you can use uppercase or lowercase letters, numbers, and underscores in the strings of the reversed domain name, separated by a dot. Strings must be separated by a dot and must start with a letter. For example: `com.nativescript.My_Andro1d_App`
19-
For projects that target iOS, you can use uppercase or lowercase letters, numbers, and hyphens in the strings of the reversed domain name. Strings must be separated by a dot. For example: `com.nativescript.My-i0s-App`.<% } %>
19+
For projects that target iOS, you can use uppercase or lowercase letters, numbers, and hyphens in the strings of the reversed domain name. Strings must be separated by a dot. For example: `com.nativescript.My-i0s-App`.<% } %>
20+
21+
<% if(isHtml) { %>
22+
### Related Commands
23+
24+
Command | Description
25+
----------|----------
26+
[init](init.html) | Initializes a project for development. It will ask you interactively to configure the project and will write a package.json for you.
27+
<% } %>
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
init
2+
==========
3+
4+
Usage | Synopsis
5+
---|---
6+
General | `$ tns init [--path <Directory>] [--force]`
7+
8+
Initializes a project for development. It will ask you interactively to configure the project and will write a package.json for you.
9+
10+
### Options
11+
* `--path` - Specifies the directory where you want to initialize the project, if different from the current directory. The directory must be empty.
12+
* `--force` - Will use only defaults and not prompt you for any options.
13+
14+
<% if(isHtml) { %>
15+
### Related Commands
16+
17+
Command | Description
18+
----------|----------
19+
[create](create.html) | Creates a new project for native development with NativeScript from the default template or from an existing NativeScript project.
20+
<% } %>

lib/bootstrap.ts

+1
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,6 @@ $injector.require("pluginsService", "./services/plugins-service");
6060
$injector.requireCommand("plugin|add", "./commands/plugin/add-plugin");
6161
$injector.requireCommand("plugin|remove", "./commands/plugin/remove-plugin");
6262
$injector.requireCommand("install", "./commands/install");
63+
$injector.requireCommand("init", "./commands/init");
6364

6465
$injector.require("projectFilesManager", "./services/project-files-manager");

lib/commands/init.ts

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
///<reference path="../.d.ts"/>
2+
"use strict";
3+
4+
import constants = require("./../constants");
5+
import helpers = require("./../common/helpers");
6+
import Future = require("fibers/future");
7+
import path = require("path");
8+
9+
export class InitCommand implements ICommand {
10+
private _projectFilePath: string;
11+
12+
constructor(private $fs: IFileSystem,
13+
private $errors: IErrors,
14+
private $logger: ILogger,
15+
private $options: IOptions,
16+
private $injector: IInjector,
17+
private $staticConfig: IStaticConfig,
18+
private $projectHelper: IProjectHelper,
19+
private $prompter: IPrompter,
20+
private $npm: INodePackageManager,
21+
private $npmInstallationManager: INpmInstallationManager) { }
22+
23+
public allowedParameters: ICommandParameter[] = [];
24+
public enableHooks = false;
25+
26+
public execute(args: string[]): IFuture<void> {
27+
return (() => {
28+
let projectData: any = { };
29+
30+
if(this.$fs.exists(this.projectFilePath).wait()) {
31+
projectData = this.$fs.readJson(this.projectFilePath).wait();
32+
}
33+
34+
if(!projectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE]) {
35+
projectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE] = { };
36+
}
37+
38+
let projectDataBackup = _.extend({}, projectData);
39+
40+
try {
41+
this.$fs.writeJson(this.projectFilePath, projectData).wait(); // We need to create package.json file here in order to prevent "No project found at or above and neither was a --path specified." when resolving platformsData
42+
43+
projectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE]["id"] = this.getProjectId().wait();
44+
45+
let $platformsData = this.$injector.resolve("platformsData");
46+
_.each($platformsData.platformsNames, platform => {
47+
let platformData: IPlatformData = $platformsData.getPlatformData(platform);
48+
if(!platformData.targetedOS || (platformData.targetedOS && _.contains(platformData.targetedOS, process.platform))) {
49+
projectData[this.$staticConfig.CLIENT_NAME_KEY_IN_PROJECT_FILE][platformData.frameworkPackageName] = this.getVersionData(platformData.frameworkPackageName).wait();
50+
}
51+
});
52+
53+
this.$fs.writeJson(this.projectFilePath, projectData).wait();
54+
} catch(err) {
55+
this.$fs.writeJson(this.projectFilePath, projectDataBackup).wait();
56+
throw err;
57+
}
58+
59+
this.$logger.out("Project successfully initialized.");
60+
}).future<void>()();
61+
}
62+
63+
public canExecute(args: string[]): IFuture<boolean> {
64+
return Future.fromResult(true);
65+
}
66+
67+
private get projectFilePath(): string {
68+
if(!this._projectFilePath) {
69+
let projectPath = path.resolve(this.$options.path || ".");
70+
this._projectFilePath = path.join(projectPath, constants.PACKAGE_JSON_FILE_NAME);
71+
}
72+
73+
return this._projectFilePath;
74+
}
75+
76+
private set projectFilePath(newProjectFilePath: string) {
77+
this._projectFilePath = newProjectFilePath;
78+
}
79+
80+
private getProjectId(): IFuture<string> {
81+
return (() => {
82+
let defaultAppId = this.$projectHelper.generateDefaultAppId(path.basename(path.dirname(this.projectFilePath)), constants.DEFAULT_APP_IDENTIFIER_PREFIX);
83+
if(this.canUseDefaultValue) {
84+
return defaultAppId;
85+
}
86+
87+
return this.$prompter.getString("Id:", () => defaultAppId).wait();
88+
}).future<string>()();
89+
}
90+
91+
private getVersionData(packageName: string): IFuture<IStringDictionary> {
92+
return (() => {
93+
let latestVersion = this.$npmInstallationManager.getLatestVersion(packageName).wait();
94+
if(this.canUseDefaultValue) {
95+
return this.buildVersionData(latestVersion);
96+
}
97+
98+
let data = this.$npm.view(packageName, "versions").wait();
99+
let versions = data[latestVersion].versions;
100+
let sortedVersions = versions.sort(helpers.versionCompare).reverse();
101+
let version = this.$prompter.promptForChoice(`${packageName} version:`, sortedVersions).wait();
102+
return this.buildVersionData(version);
103+
}).future<IStringDictionary>()();
104+
}
105+
106+
private buildVersionData(version: string) {
107+
return { "version": version };
108+
}
109+
110+
private get canUseDefaultValue(): boolean {
111+
return !helpers.isInteractive() || this.$options.force;
112+
}
113+
}
114+
$injector.registerCommand("init", InitCommand);

lib/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export var NATIVESCRIPT_KEY_NAME = "nativescript";
77
export var NODE_MODULES_FOLDER_NAME = "node_modules";
88
export var PACKAGE_JSON_FILE_NAME = "package.json";
99
export var NODE_MODULE_CACHE_PATH_KEY_NAME = "node-modules-cache-path";
10+
export var DEFAULT_APP_IDENTIFIER_PREFIX = "org.nativescript";
1011

1112
export class ReleaseType {
1213
static MAJOR = "major";

lib/services/project-service.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import shell = require("shelljs");
99
import util = require("util");
1010

1111
export class ProjectService implements IProjectService {
12-
private static DEFAULT_APP_IDENTIFIER_PREFIX = "org.nativescript";
1312

1413
constructor(private $errors: IErrors,
1514
private $fs: IFileSystem,
@@ -27,7 +26,7 @@ export class ProjectService implements IProjectService {
2726
}
2827
this.$projectNameValidator.validate(projectName);
2928

30-
var projectId = this.$options.appid || this.$projectHelper.generateDefaultAppId(projectName, ProjectService.DEFAULT_APP_IDENTIFIER_PREFIX);
29+
var projectId = this.$options.appid || this.$projectHelper.generateDefaultAppId(projectName, constants.DEFAULT_APP_IDENTIFIER_PREFIX);
3130

3231
var projectDir = path.join(path.resolve(this.$options.path || "."), projectName);
3332
this.$fs.createDirectory(projectDir).wait();

0 commit comments

Comments
 (0)