Skip to content

Commit c40ef93

Browse files
authored
Merge pull request microsoft#681 from Microsoft/pgonzal/rush-global-commands
[rush] Redesign command-line.json to support multiple command types
2 parents ba78121 + 9645e17 commit c40ef93

22 files changed

Lines changed: 876 additions & 504 deletions

apps/rush-lib/etc/examples/legacy-command-line.json

Lines changed: 0 additions & 47 deletions
This file was deleted.

apps/rush-lib/etc/examples/sample-command-line.json

Lines changed: 0 additions & 60 deletions
This file was deleted.
Lines changed: 70 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
1-
import {
2-
CommandLineConfiguration,
3-
ICustomCommand,
4-
CustomOption
5-
} from '../../data/CommandLineConfiguration';
1+
import * as path from 'path';
2+
3+
import { CommandLineConfiguration } from '../../data/CommandLineConfiguration';
4+
import { CommandJson } from '../../data/CommandLineJson';
65

76
import { RushCommandLineParser } from './RushCommandLineParser';
87
import { CustomRushAction } from './CustomRushAction';
8+
import { RushConstants } from '../../RushConstants';
99

1010
/**
1111
* Using the custom command line configuration, generates a set of
1212
* rush actions that are then registered to the command line.
1313
*/
1414
export class CustomCommandFactory {
15-
public static createCommands(
16-
parser: RushCommandLineParser,
17-
commandLineConfig: CommandLineConfiguration | undefined
18-
): Map<string, CustomRushAction> {
19-
const customActions: Map<string, CustomRushAction> = new Map<string, CustomRushAction>();
15+
public static addActions(parser: RushCommandLineParser): void {
16+
if (!parser.rushConfiguration) {
17+
return;
18+
}
19+
20+
const commandLineConfigFile: string = path.join(
21+
parser.rushConfiguration.commonRushConfigFolder, RushConstants.commandLineFilename
22+
);
23+
const commandLineConfiguration: CommandLineConfiguration
24+
= CommandLineConfiguration.loadFromFileOrDefault(commandLineConfigFile);
2025

2126
const documentationForBuild: string = 'The Rush build command assumes that the package.json file for each'
2227
+ ' project contains a "scripts" entry for "npm run build". It invokes'
@@ -26,49 +31,69 @@ export class CustomCommandFactory {
2631
+ ' unless overridden by the --parallelism flag.';
2732

2833
// always create a build and a rebuild command
29-
customActions.set('build', new CustomRushAction(parser, {
34+
parser.addAction(new CustomRushAction({
3035
actionName: 'build',
3136
summary: '(EXPERIMENTAL) Build all projects that haven\'t been built, or have changed since they were last '
3237
+ 'built.',
33-
documentation: documentationForBuild
34-
}, true));
38+
documentation: documentationForBuild,
39+
40+
parser: parser,
41+
commandLineConfiguration: commandLineConfiguration,
3542

36-
customActions.set('rebuild', new CustomRushAction(parser, {
43+
enableParallelism: true,
44+
ignoreMissingScript: false
45+
}));
46+
47+
parser.addAction(new CustomRushAction({
3748
actionName: 'rebuild',
3849
summary: 'Clean and rebuild the entire set of projects',
39-
documentation: documentationForBuild
40-
}, true));
41-
42-
if (commandLineConfig) {
43-
// Register each custom command
44-
commandLineConfig.commands.forEach((command: ICustomCommand) => {
45-
if (customActions.get(command.name)) {
46-
throw new Error(`Cannot define two custom actions with the same name: "${command.name}"`);
47-
}
48-
customActions.set(command.name, new CustomRushAction(parser, {
50+
documentation: documentationForBuild,
51+
52+
parser: parser,
53+
commandLineConfiguration: commandLineConfiguration,
54+
55+
enableParallelism: true,
56+
ignoreMissingScript: false
57+
}));
58+
59+
// Register each custom command
60+
for (const command of commandLineConfiguration.commands) {
61+
if (parser.tryGetAction(command.name)) {
62+
throw new Error(`${RushConstants.commandLineFilename} defines a command "${command.name}"`
63+
+ ` using a name that already exists`);
64+
}
65+
66+
switch (command.commandKind) {
67+
case 'bulk':
68+
parser.addAction(new CustomRushAction({
4969
actionName: command.name,
5070
summary: command.summary,
51-
documentation: command.documentation || command.summary
52-
},
53-
command.parallelized,
54-
command.ignoreMissingScript
55-
));
56-
});
57-
58-
// Associate each custom option to a command
59-
commandLineConfig.options.forEach((customOption: CustomOption, longName: string) => {
60-
customOption.associatedCommands.forEach((associatedCommand: string) => {
61-
const customAction: CustomRushAction | undefined = customActions.get(associatedCommand);
62-
if (customAction) {
63-
customAction.addCustomOption(longName, customOption);
64-
} else {
65-
throw new Error(`Cannot find custom command "${associatedCommand}" associated with`
66-
+ ` custom option "${longName}".`);
67-
}
68-
});
69-
});
71+
documentation: command.description || command.summary,
72+
73+
parser: parser,
74+
commandLineConfiguration: commandLineConfiguration,
75+
76+
enableParallelism: command.enableParallelism,
77+
ignoreMissingScript: command.ignoreMissingScript || false
78+
}));
79+
break;
80+
case 'global':
81+
// todo
82+
break;
83+
default:
84+
throw new Error(`${RushConstants.commandLineFilename} defines a command "${command!.name}"`
85+
+ ` using an unsupported command kind "${command!.commandKind}"`);
86+
}
7087
}
7188

72-
return customActions;
89+
// Check for any invalid associations
90+
for (const parameter of commandLineConfiguration.parameters) {
91+
for (const associatedCommand of parameter.associatedCommands) {
92+
if (!parser.tryGetAction(associatedCommand)) {
93+
throw new Error(`${RushConstants.commandLineFilename} defines a parameter "${parameter.longName}"`
94+
+ ` that is associated with a nonexistent command "${associatedCommand}"`);
95+
}
96+
}
97+
}
7398
}
74-
}
99+
}

0 commit comments

Comments
 (0)