Skip to content

Commit 76ff072

Browse files
authored
Merge pull request #3870 from NativeScript/sis0k0/generate-2
feat: add generate command
2 parents e34d148 + 188bdb1 commit 76ff072

File tree

7 files changed

+127
-2
lines changed

7 files changed

+127
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<% if (isJekyll) { %>---
2+
title: tns generate
3+
position: 9
4+
---<% } %>
5+
# tns generate
6+
7+
8+
Usage | Synopsis
9+
------|-------
10+
General | `$ tns generate <Schematic Name> [--collection <Collection>] [option=value]`
11+
12+
Modifies the project by executing a specified schematic to it.
13+
14+
### Options
15+
* `--collection` - specifies the node package to be used as schematics collection. If it's not specified, `@nativescript/schematics` will be used.
16+
17+
### Attributes
18+
* `<Schematic Name>` - name of the schematic to be executed. The schematic should be specified in the used collection.
19+
* `<option=value>` - options for executed schematic.
20+
21+
<% if(isHtml) { %>
22+
### Related Commands
23+
24+
Command | Description
25+
----------|----------
26+
[update](update.md) | Updates a NativeScript project to the latest (or specified) version.
27+
[resources generate icons](resources-generate-icons.md) | Generates icons for Android and iOS.
28+
[resources generate splashes](resources-generate-splashes.md) | Generates splashscreens for Android and iOS.
29+
<% } %>

lib/bootstrap.ts

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ $injector.require("emulatorSettingsService", "./services/emulator-settings-servi
4242

4343
$injector.require("platformCommandParameter", "./platform-command-param");
4444
$injector.requireCommand("create", "./commands/create-project");
45+
$injector.requireCommand("generate", "./commands/generate");
4546
$injector.requireCommand("platform|*list", "./commands/list-platforms");
4647
$injector.requireCommand("platform|add", "./commands/add-platform");
4748
$injector.requireCommand("platform|remove", "./commands/remove-platform");

lib/commands/generate.ts

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { run, ExecutionOptions } from '@nativescript/schematics-executor';
2+
3+
export class GenerateCommand implements ICommand {
4+
public allowedParameters: ICommandParameter[] = [];
5+
private executionOptions: ExecutionOptions;
6+
7+
constructor(private $logger: ILogger,
8+
private $options: IOptions,
9+
private $errors: IErrors) { }
10+
11+
public async execute(_rawArgs: string[]): Promise<void> {
12+
try {
13+
await run(this.executionOptions);
14+
} catch (error) {
15+
this.$errors.failWithoutHelp(error.message);
16+
}
17+
}
18+
19+
public async canExecute(rawArgs: string[]): Promise<boolean> {
20+
this.setExecutionOptions(rawArgs);
21+
this.validateExecutionOptions();
22+
23+
return true;
24+
}
25+
26+
private validateExecutionOptions() {
27+
if (!this.executionOptions.schematic) {
28+
this.$errors.fail(`The generate command requires a schematic name to be specified.`);
29+
}
30+
}
31+
32+
private setExecutionOptions(rawArgs: string[]) {
33+
const options = this.parseRawArgs(rawArgs);
34+
35+
this.executionOptions = {
36+
...options,
37+
logger: this.$logger,
38+
directory: process.cwd(),
39+
};
40+
}
41+
42+
private parseRawArgs(rawArgs: string[]) {
43+
const collection = this.$options.collection;
44+
const schematic = rawArgs.shift();
45+
const { options, args } = parseSchematicSettings(rawArgs);
46+
47+
return {
48+
collection,
49+
schematic,
50+
schematicOptions: options,
51+
schematicArgs: args,
52+
};
53+
}
54+
}
55+
56+
/**
57+
* Converts an array of command line arguments to options for the executed schematic.
58+
* @param rawArgs The command line arguments. They should be in the format 'key=value' for strings or 'key' for booleans.
59+
*/
60+
function parseSchematicSettings(rawArgs: string[]) {
61+
const [optionStrings, args] = partition<string>(rawArgs, item => item.includes('='));
62+
const options = optionStrings
63+
.map(o => o.split("=")) // split to key and value pairs
64+
.map(([key, ...value]) => [key, value.join("=")]) // concat the value arrays if there are multiple = signs
65+
.reduce((obj, [key, value]) => {
66+
return { ...obj, [key]: value };
67+
}, {});
68+
69+
return { options, args };
70+
}
71+
/**
72+
* Splits an array into two groups based on a predicate.
73+
* @param array The array to split.
74+
* @param predicate The condition to be used for splitting.
75+
*/
76+
function partition<T>(array: T[], predicate: (item: T) => boolean): T[][] {
77+
return array.reduce(([pass, fail], item) => {
78+
return predicate(item) ?
79+
[[...pass, item], fail] :
80+
[pass, [...fail, item]];
81+
}, [[], []]);
82+
}
83+
84+
$injector.registerCommand("generate", GenerateCommand);

lib/declarations.d.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,10 @@ interface ICreateProjectOptions extends INpmInstallConfigurationOptionsBase {
440440
pathToTemplate?: string;
441441
}
442442

443+
interface IGenerateOptions {
444+
collection?: string;
445+
}
446+
443447
interface IDebugInformation extends IPort, Mobile.IDeviceIdentifier {
444448
url: string;
445449
}
@@ -453,7 +457,7 @@ interface IPluginSeedOptions {
453457
pluginName: string;
454458
}
455459

456-
interface IOptions extends ICommonOptions, IBundleString, IPlatformTemplate, IHasEmulatorOption, IClean, IProvision, ITeamIdentifier, IAndroidReleaseOptions, INpmInstallConfigurationOptions, IPort, IEnvOptions, IPluginSeedOptions {
460+
interface IOptions extends ICommonOptions, IBundleString, IPlatformTemplate, IHasEmulatorOption, IClean, IProvision, ITeamIdentifier, IAndroidReleaseOptions, INpmInstallConfigurationOptions, IPort, IEnvOptions, IPluginSeedOptions, IGenerateOptions {
457461
all: boolean;
458462
client: boolean;
459463
compileSdk: number;

lib/options.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ export class Options extends commonOptionsLibPath.OptionsBase {
4141
background: { type: OptionType.String },
4242
username: { type: OptionType.String },
4343
pluginName: { type: OptionType.String },
44-
hmr: {type: OptionType.Boolean}
44+
hmr: { type: OptionType.Boolean },
45+
collection: { type: OptionType.String, alias: "c" },
4546
},
4647
$errors, $staticConfig, $settingsService);
4748

npm-shrinkwrap.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"mobile"
3131
],
3232
"dependencies": {
33+
"@nativescript/schematics-executor": "0.0.2",
3334
"byline": "4.2.1",
3435
"chalk": "1.1.0",
3536
"chokidar": "1.7.0",

0 commit comments

Comments
 (0)