Skip to content

Commit 77b23b7

Browse files
committed
feat(generate): parse CLI arguments to execution settings
1 parent 7de1a5b commit 77b23b7

File tree

1 file changed

+74
-12
lines changed

1 file changed

+74
-12
lines changed

lib/commands/generate.ts

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,87 @@
1-
import { run } from '@nativescript/schematics-engine';
1+
import { run, ExecutionOptions } from '@nativescript/schematics-engine';
22

33
export class GenerateCommand implements ICommand {
44
public allowedParameters: ICommandParameter[] = [];
5+
private executionOptions: ExecutionOptions;
56

6-
constructor(private $logger: ILogger, private $errors: IErrors) {}
7+
constructor(private $logger: ILogger,
8+
private $options: IOptions,
9+
private $errors: IErrors) { }
710

8-
public async execute(args: string[]): Promise<void> {
11+
public async execute(_rawArgs: string[]): Promise<void> {
912
try {
10-
await run({
11-
logger: this.$logger,
12-
schematic: 'component',
13-
schematicOptions: {
14-
name: 'random',
15-
// project: 'web-mobile-project'
16-
},
17-
directory: process.cwd(),
18-
});
13+
await run(this.executionOptions);
1914
} catch (error) {
2015
this.$errors.failWithoutHelp(error.message);
2116
}
2217
}
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 {
46+
options: schematicOptions,
47+
args: schematicArgs,
48+
} = parseSchematicSettings(rawArgs);
49+
50+
return {
51+
collection,
52+
schematic,
53+
schematicOptions,
54+
schematicArgs,
55+
};
56+
}
57+
}
58+
59+
/**
60+
* Converts an array of command line arguments to options for the executed schematic.
61+
* @param rawArgs The command line arguments. They should be in the format 'key=value' for strings or 'key' for booleans.
62+
*/
63+
function parseSchematicSettings(rawArgs: string[]) {
64+
const [optionStrings, args] = partition<string>(rawArgs, item => item.includes('='));
65+
const options = optionStrings
66+
.map(o => o.split("=")) // split to key and value pairs
67+
.map(([key, ...value]) => [key, value.join("=")]) // concat the value arrays if there are multiple = signs
68+
.reduce((obj, [key, value]) => {
69+
return { ...obj, [key]: value };
70+
}, {});
71+
72+
return { options, args };
73+
}
74+
/**
75+
* Splits an array into two groups based on a predicate.
76+
* @param array The array to split.
77+
* @param predicate The condition to be used for splitting.
78+
*/
79+
function partition<T>(array: T[], predicate: (item: T) => boolean): T[][] {
80+
return array.reduce(([pass, fail], item) => {
81+
return predicate(item) ?
82+
[[...pass, item], fail] :
83+
[pass, [...fail, item]];
84+
}, [[], []]);
2385
}
2486

2587
$injector.registerCommand("generate", GenerateCommand);

0 commit comments

Comments
 (0)