Skip to content

Commit 2dca6f2

Browse files
iclantonCopilot
andauthored
[rush][rush-published-versions-json-plugin] Add plugin-native global commands; add published versions JSON plugin. (#5701)
* Add functions to better support commands provided by global commands. * Introduce rush-published-versions-json-plugin. * fixup! Introduce rush-published-versions-json-plugin. * fixup! Introduce rush-published-versions-json-plugin. * fixup! Introduce rush-published-versions-json-plugin. * fixup! Introduce rush-published-versions-json-plugin. * Add "globalPlugin" command kind for plugin-native global commands Introduces a new "globalPlugin" commandKind for command-line.json that can only be used in Rush plugin command-line.json files. Unlike "global" commands, it has no shellCommand — the implementation must be provided entirely by the plugin via the runGlobalCustomCommand hook with setHandled(). - Added globalPluginCommandKind constant to RushConstants - Added globalPluginCommand to JSON schema (no shellCommand/autoinstallerName) - Added IGlobalPluginCommandJson type; at runtime, normalized to IGlobalCommandConfig with shellCommand="" and isPluginOnly=true (similar to bulk→phased conversion) - Rejected globalPlugin in repo command-line.json (loadFromFileOrDefault) - Updated plugin command-line.json to use the new kind - Fixed plugin .npmignore to include command-line.json Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add changefile for globalPlugin command kind Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR feedback: rename isPluginOnly to providedByPlugin Rename isPluginOnly → providedByPlugin for clarity per review feedback. Also update the first changefile comment to reflect the globalPlugin design. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Split changefiles: API additions vs globalPlugin command kind Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 646541e commit 2dca6f2

26 files changed

Lines changed: 582 additions & 44 deletions

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ These GitHub repositories provide supplementary resources for Rush Stack:
117117
| [/rush-plugins/rush-buildxl-graph-plugin](./rush-plugins/rush-buildxl-graph-plugin/) | [![npm version](https://badge.fury.io/js/%40rushstack%2Frush-buildxl-graph-plugin.svg)](https://badge.fury.io/js/%40rushstack%2Frush-buildxl-graph-plugin) | | [@rushstack/rush-buildxl-graph-plugin](https://www.npmjs.com/package/@rushstack/rush-buildxl-graph-plugin) |
118118
| [/rush-plugins/rush-http-build-cache-plugin](./rush-plugins/rush-http-build-cache-plugin/) | [![npm version](https://badge.fury.io/js/%40rushstack%2Frush-http-build-cache-plugin.svg)](https://badge.fury.io/js/%40rushstack%2Frush-http-build-cache-plugin) | | [@rushstack/rush-http-build-cache-plugin](https://www.npmjs.com/package/@rushstack/rush-http-build-cache-plugin) |
119119
| [/rush-plugins/rush-mcp-docs-plugin](./rush-plugins/rush-mcp-docs-plugin/) | [![npm version](https://badge.fury.io/js/%40rushstack%2Frush-mcp-docs-plugin.svg)](https://badge.fury.io/js/%40rushstack%2Frush-mcp-docs-plugin) | [changelog](./rush-plugins/rush-mcp-docs-plugin/CHANGELOG.md) | [@rushstack/rush-mcp-docs-plugin](https://www.npmjs.com/package/@rushstack/rush-mcp-docs-plugin) |
120+
| [/rush-plugins/rush-published-versions-json-plugin](./rush-plugins/rush-published-versions-json-plugin/) | [![npm version](https://badge.fury.io/js/%40rushstack%2Frush-published-versions-json-plugin.svg)](https://badge.fury.io/js/%40rushstack%2Frush-published-versions-json-plugin) | [changelog](./rush-plugins/rush-published-versions-json-plugin/CHANGELOG.md) | [@rushstack/rush-published-versions-json-plugin](https://www.npmjs.com/package/@rushstack/rush-published-versions-json-plugin) |
120121
| [/rush-plugins/rush-redis-cobuild-plugin](./rush-plugins/rush-redis-cobuild-plugin/) | [![npm version](https://badge.fury.io/js/%40rushstack%2Frush-redis-cobuild-plugin.svg)](https://badge.fury.io/js/%40rushstack%2Frush-redis-cobuild-plugin) | | [@rushstack/rush-redis-cobuild-plugin](https://www.npmjs.com/package/@rushstack/rush-redis-cobuild-plugin) |
121122
| [/rush-plugins/rush-resolver-cache-plugin](./rush-plugins/rush-resolver-cache-plugin/) | [![npm version](https://badge.fury.io/js/%40rushstack%2Frush-resolver-cache-plugin.svg)](https://badge.fury.io/js/%40rushstack%2Frush-resolver-cache-plugin) | | [@rushstack/rush-resolver-cache-plugin](https://www.npmjs.com/package/@rushstack/rush-resolver-cache-plugin) |
122123
| [/rush-plugins/rush-serve-plugin](./rush-plugins/rush-serve-plugin/) | [![npm version](https://badge.fury.io/js/%40rushstack%2Frush-serve-plugin.svg)](https://badge.fury.io/js/%40rushstack%2Frush-serve-plugin) | | [@rushstack/rush-serve-plugin](https://www.npmjs.com/package/@rushstack/rush-serve-plugin) |
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@microsoft/rush",
5+
"comment": "Add `getCustomParametersByLongName()` and `setHandled()` to `IGlobalCommand`, enabling Rush plugins to handle global command execution and access parsed command-line parameter values.",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@microsoft/rush"
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@microsoft/rush",
5+
"comment": "Add a new \"globalPlugin\" command kind for command-line.json that allows Rush plugins to define global commands without a shellCommand. This command kind can only be used in plugin-provided command-line.json files.",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@microsoft/rush"
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@rushstack/rush-published-versions-json-plugin",
5+
"comment": "Initial release.",
6+
"type": "minor"
7+
}
8+
],
9+
"packageName": "@rushstack/rush-published-versions-json-plugin"
10+
}

common/config/subspaces/default/pnpm-lock.yaml

Lines changed: 42 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush.
22
{
3-
"pnpmShrinkwrapHash": "54470e7caa94b190d86dbd4f9cc43e0d58456972",
3+
"pnpmShrinkwrapHash": "c482c23c40b202ed750549c796c24b3550d0ba6e",
44
"preferredVersionsHash": "029c99bd6e65c5e1f25e2848340509811ff9753c"
55
}

common/reviews/api/rush-lib.api.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ export interface IGetChangedProjectsOptions {
514514

515515
// @beta
516516
export interface IGlobalCommand extends IRushCommand {
517+
getCustomParametersByLongName<TParameter extends CommandLineParameter>(longName: string): TParameter;
518+
setHandled(): void;
517519
}
518520

519521
// @public
@@ -1434,6 +1436,7 @@ export class RushConstants {
14341436
static readonly defaultWatchDebounceMs: 1000;
14351437
static readonly experimentsFilename: 'experiments.json';
14361438
static readonly globalCommandKind: 'global';
1439+
static readonly globalPluginCommandKind: 'globalPlugin';
14371440
static readonly hashDelimiter: '|';
14381441
static readonly lastLinkFlagFilename: 'last-link';
14391442
static readonly mergeQueueIgnoreFileName: '.mergequeueignore';
@@ -1502,7 +1505,7 @@ export class RushLifecycleHooks {
15021505
variant: string | undefined
15031506
]>;
15041507
readonly beforeInstall: AsyncSeriesHook<[
1505-
command: IGlobalCommand,
1508+
command: IRushCommand,
15061509
subspace: Subspace,
15071510
variant: string | undefined
15081511
]>;

libraries/rush-lib/src/api/CommandLineConfiguration.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,14 @@ export interface IPhasedCommandConfig extends IPhasedCommandWithoutPhasesJson, I
127127
alwaysInstall: boolean | undefined;
128128
}
129129

130-
export interface IGlobalCommandConfig extends IGlobalCommandJson, ICommandWithParameters {}
130+
export interface IGlobalCommandConfig extends IGlobalCommandJson, ICommandWithParameters {
131+
/**
132+
* If true, this command was declared with commandKind "globalPlugin" and its implementation
133+
* is provided by a Rush plugin via the `runGlobalCustomCommand` hook. There is no shell
134+
* command to execute.
135+
*/
136+
providedByPlugin: boolean;
137+
}
131138

132139
export type Command = IGlobalCommandConfig | IPhasedCommandConfig;
133140

@@ -408,6 +415,20 @@ export class CommandLineConfiguration {
408415
case RushConstants.globalCommandKind: {
409416
normalizedCommand = {
410417
...command,
418+
providedByPlugin: false,
419+
associatedParameters: new Set<IParameterJson>()
420+
};
421+
break;
422+
}
423+
424+
case RushConstants.globalPluginCommandKind: {
425+
// Normalize globalPlugin commands to global commands with an empty shellCommand,
426+
// similar to how bulk commands are converted to phased commands.
427+
normalizedCommand = {
428+
...command,
429+
commandKind: RushConstants.globalCommandKind,
430+
shellCommand: '',
431+
providedByPlugin: true,
411432
associatedParameters: new Set<IParameterJson>()
412433
};
413434
break;
@@ -694,6 +715,17 @@ export class CommandLineConfiguration {
694715
this._applyBuildCommandDefaults(commandLineJson);
695716

696717
CommandLineConfiguration._jsonSchema.validateObject(commandLineJson, jsonFilePath);
718+
719+
// Validate that globalPlugin commands are not used in the repo's command-line.json
720+
for (const { commandKind, name } of commandLineJson.commands) {
721+
if (commandKind === RushConstants.globalPluginCommandKind) {
722+
throw new Error(
723+
`${RushConstants.commandLineFilename} defines a command "${name}" using ` +
724+
`the command kind "${RushConstants.globalPluginCommandKind}". This command kind can only ` +
725+
`be used in command-line.json files provided by Rush plugins.`
726+
);
727+
}
728+
}
697729
}
698730
}
699731

libraries/rush-lib/src/api/CommandLineJson.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* "baseCommand" from command-line.schema.json
66
*/
77
export interface IBaseCommandJson {
8-
commandKind: 'bulk' | 'global' | 'phased';
8+
commandKind: 'bulk' | 'global' | 'globalPlugin' | 'phased';
99
name: string;
1010
summary: string;
1111
/**
@@ -66,7 +66,20 @@ export interface IGlobalCommandJson extends IBaseCommandJson {
6666
shellCommand: string;
6767
}
6868

69-
export type CommandJson = IBulkCommandJson | IGlobalCommandJson | IPhasedCommandJson;
69+
/**
70+
* "globalPluginCommand" from command-line.schema.json.
71+
* A global command whose implementation is provided entirely by a Rush plugin.
72+
* This command kind can only be used in command-line.json files provided by Rush plugins.
73+
*/
74+
export interface IGlobalPluginCommandJson extends IBaseCommandJson {
75+
commandKind: 'globalPlugin';
76+
}
77+
78+
export type CommandJson =
79+
| IBulkCommandJson
80+
| IGlobalCommandJson
81+
| IGlobalPluginCommandJson
82+
| IPhasedCommandJson;
7083

7184
/**
7285
* The dependencies of a phase.

0 commit comments

Comments
 (0)