-
-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathcreate-plugin.ts
114 lines (95 loc) · 4.35 KB
/
create-plugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import * as path from "path";
import { isInteractive } from "../../common/helpers";
export class CreatePluginCommand implements ICommand {
public allowedParameters: ICommandParameter[] = [];
public userMessage = "What is your GitHub username?\n(will be used to update the Github URLs in the plugin's package.json)";
public nameMessage = "What will be the name of your plugin?\n(use lowercase characters and dashes only)";
constructor(private $options: IOptions,
private $errors: IErrors,
private $terminalSpinnerService: ITerminalSpinnerService,
private $logger: ILogger,
private $pacoteService: IPacoteService,
private $fs: IFileSystem,
private $childProcess: IChildProcess,
private $prompter: IPrompter,
private $npm: INodePackageManager) { }
public async execute(args: string[]): Promise<void> {
const pluginRepoName = args[0];
const pathToProject = this.$options.path;
const selectedPath = path.resolve(pathToProject || ".");
const projectDir = path.join(selectedPath, pluginRepoName);
this.$logger.printMarkdown("Downloading the latest version of NativeScript Plugin Seed...");
await this.downloadPackage(projectDir);
this.$logger.printMarkdown("Executing initial plugin configuration script...");
await this.setupSeed(projectDir, pluginRepoName);
this.$logger.printMarkdown("Solution for `%s` was successfully created.", pluginRepoName);
}
public async canExecute(args: string[]): Promise<boolean> {
if (!args[0]) {
this.$errors.fail("You must specify the plugin repository name.");
}
return true;
}
private async setupSeed(projectDir: string, pluginRepoName: string): Promise<void> {
const config = this.$options;
const spinner = this.$terminalSpinnerService.createSpinner();
const cwd = path.join(projectDir, "src");
try {
spinner.start();
const npmOptions: any = { silent: true };
await this.$npm.install(cwd, cwd, npmOptions);
} finally {
spinner.stop();
}
const gitHubUsername = await this.getGitHubUsername(config.username);
const pluginNameSource = await this.getPluginNameSource(config.pluginName, pluginRepoName);
if (!isInteractive() && (!config.username || !config.pluginName)) {
this.$logger.printMarkdown("Using default values for Github user and/or plugin name since your shell is not interactive.");
}
// run postclone script manually and kill it if it takes more than 10 sec
const pathToPostCloneScript = path.join("scripts", "postclone");
const params = [pathToPostCloneScript, `gitHubUsername=${gitHubUsername}`, `pluginName=${pluginNameSource}`, "initGit=y"];
const outputScript = (await this.$childProcess.spawnFromEvent(process.execPath, params, "close", { cwd, timeout: 10000 }));
if (outputScript && outputScript.stdout) {
this.$logger.printMarkdown(outputScript.stdout);
}
}
private async downloadPackage(projectDir: string): Promise<void> {
this.$fs.createDirectory(projectDir);
if (this.$fs.exists(projectDir) && !this.$fs.isEmptyDir(projectDir)) {
this.$errors.fail("Path already exists and is not empty %s", projectDir);
}
const spinner = this.$terminalSpinnerService.createSpinner();
const packageToInstall = "https://github.com/NativeScript/nativescript-plugin-seed/archive/master.tar.gz";
try {
spinner.start();
await this.$pacoteService.extractPackage(packageToInstall, projectDir);
} catch (err) {
this.$fs.deleteDirectory(projectDir);
throw err;
} finally {
spinner.stop();
}
}
private async getGitHubUsername(gitHubUsername: string) {
if (!gitHubUsername) {
gitHubUsername = "NativeScriptDeveloper";
if (isInteractive()) {
gitHubUsername = await this.$prompter.getString(this.userMessage, { allowEmpty: false, defaultAction: () => { return gitHubUsername; } });
}
}
return gitHubUsername;
}
private async getPluginNameSource(pluginNameSource: string, pluginRepoName: string) {
if (!pluginNameSource) {
// remove nativescript- prefix for naming plugin files
const prefix = 'nativescript-';
pluginNameSource = pluginRepoName.toLowerCase().startsWith(prefix) ? pluginRepoName.slice(prefix.length, pluginRepoName.length) : pluginRepoName;
if (isInteractive()) {
pluginNameSource = await this.$prompter.getString(this.nameMessage, { allowEmpty: false, defaultAction: () => { return pluginNameSource; } });
}
}
return pluginNameSource;
}
}
$injector.registerCommand(["plugin|create"], CreatePluginCommand);