@rushstack/rush-bridge-cache-plugin 5.170.1-pr5378.0 → 5.170.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,79 +20,92 @@ class BridgeCachePlugin {
20
20
  }
21
21
  apply(session) {
22
22
  session.hooks.runAnyPhasedCommand.tapPromise(PLUGIN_NAME, async (command) => {
23
- command.hooks.onGraphCreatedAsync.tap(PLUGIN_NAME, async (graph, context) => {
24
- const { customParameters, buildCacheConfiguration } = context;
25
- const cacheAction = this._getCacheAction(customParameters);
23
+ const logger = session.getLogger(PLUGIN_NAME);
24
+ let cacheAction;
25
+ let requireOutputFolders = false;
26
+ // cancel the actual operations. We don't want to run the command, just cache the output folders on disk
27
+ command.hooks.createOperations.tap({ name: PLUGIN_NAME, stage: Number.MAX_SAFE_INTEGER }, (operations, context) => {
28
+ var _a;
29
+ const { customParameters } = context;
30
+ cacheAction = this._getCacheAction(customParameters);
26
31
  if (cacheAction !== undefined) {
27
- if (!(buildCacheConfiguration === null || buildCacheConfiguration === void 0 ? void 0 : buildCacheConfiguration.buildCacheEnabled)) {
32
+ if (!((_a = context.buildCacheConfiguration) === null || _a === void 0 ? void 0 : _a.buildCacheEnabled)) {
28
33
  throw new Error(`The build cache must be enabled to use the "${this._actionParameterName}" parameter.`);
29
34
  }
30
- const { rushConfiguration: { experimentsConfiguration: { configuration: { omitAppleDoubleFilesFromBuildCache } } } } = context;
31
- const logger = session.getLogger(PLUGIN_NAME);
32
- const { terminal } = logger;
33
- const requireOutputFolders = this._isRequireOutputFoldersFlagSet(customParameters);
34
- graph.hooks.beforeExecuteIterationAsync.tapPromise(PLUGIN_NAME, async (operationRecords, iterationOptions) => {
35
- const filteredOperations = [];
36
- for (const record of operationRecords.values()) {
37
- if (!record.operation.isNoOp) {
38
- filteredOperations.push(record);
39
- }
35
+ for (const operation of operations) {
36
+ operation.enabled = false;
37
+ }
38
+ requireOutputFolders = this._isRequireOutputFoldersFlagSet(customParameters);
39
+ }
40
+ return operations;
41
+ });
42
+ // populate the cache for each operation
43
+ command.hooks.beforeExecuteOperations.tapPromise(PLUGIN_NAME, async (recordByOperation, context) => {
44
+ const { buildCacheConfiguration, rushConfiguration: { experimentsConfiguration: { configuration: { omitAppleDoubleFilesFromBuildCache } } } } = context;
45
+ const { terminal } = logger;
46
+ if (cacheAction === undefined) {
47
+ return;
48
+ }
49
+ if (!(buildCacheConfiguration === null || buildCacheConfiguration === void 0 ? void 0 : buildCacheConfiguration.buildCacheEnabled)) {
50
+ throw new Error(`The build cache must be enabled to use the "${this._actionParameterName}" parameter.`);
51
+ }
52
+ const filteredOperations = new Set();
53
+ for (const operationExecutionResult of recordByOperation.values()) {
54
+ if (!operationExecutionResult.operation.isNoOp) {
55
+ filteredOperations.add(operationExecutionResult);
56
+ }
57
+ }
58
+ let successCount = 0;
59
+ await node_core_library_1.Async.forEachAsync(filteredOperations, async (operationExecutionResult) => {
60
+ var _a, _b, _c, _d;
61
+ const projectBuildCache = rush_sdk_1._OperationBuildCache.forOperation(operationExecutionResult, {
62
+ buildCacheConfiguration,
63
+ terminal,
64
+ excludeAppleDoubleFiles: !!omitAppleDoubleFilesFromBuildCache
65
+ });
66
+ const { operation } = operationExecutionResult;
67
+ if (cacheAction === CACHE_ACTION_READ) {
68
+ const success = await projectBuildCache.tryRestoreFromCacheAsync(terminal);
69
+ if (success) {
70
+ ++successCount;
71
+ terminal.writeLine(`Operation "${operation.name}": Outputs have been restored from the build cache."`);
72
+ terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);
40
73
  }
41
- if (!filteredOperations.length) {
42
- return; // nothing to do, continue normal execution
74
+ else {
75
+ terminal.writeWarningLine(`Operation "${operation.name}": Outputs could not be restored from the build cache.`);
43
76
  }
44
- let successCount = 0;
45
- await node_core_library_1.Async.forEachAsync(filteredOperations, async (operationExecutionResult) => {
46
- var _a, _b, _c, _d;
47
- const projectBuildCache = rush_sdk_1._OperationBuildCache.forOperation(operationExecutionResult, {
48
- buildCacheConfiguration,
49
- terminal,
50
- excludeAppleDoubleFiles: !!omitAppleDoubleFilesFromBuildCache
51
- });
52
- const { operation } = operationExecutionResult;
53
- if (cacheAction === CACHE_ACTION_READ) {
54
- const success = await projectBuildCache.tryRestoreFromCacheAsync(terminal);
55
- if (success) {
56
- ++successCount;
57
- terminal.writeLine(`Operation "${operation.name}": Outputs have been restored from the build cache."`);
58
- terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);
59
- }
60
- else {
61
- terminal.writeWarningLine(`Operation "${operation.name}": Outputs could not be restored from the build cache.`);
62
- }
63
- }
64
- else if (cacheAction === CACHE_ACTION_WRITE) {
65
- if (requireOutputFolders &&
66
- ((_a = operation.settings) === null || _a === void 0 ? void 0 : _a.outputFolderNames) &&
67
- ((_c = (_b = operation.settings) === null || _b === void 0 ? void 0 : _b.outputFolderNames) === null || _c === void 0 ? void 0 : _c.length) > 0) {
68
- const projectFolder = (_d = operation.associatedProject) === null || _d === void 0 ? void 0 : _d.projectFolder;
69
- const missingFolders = [];
70
- operation.settings.outputFolderNames.forEach((outputFolderName) => {
71
- if (!node_core_library_1.FileSystem.exists(`${projectFolder}/${outputFolderName}`)) {
72
- missingFolders.push(outputFolderName);
73
- }
74
- });
75
- if (missingFolders.length > 0) {
76
- terminal.writeWarningLine(`Operation "${operation.name}": The following output folders do not exist: "${missingFolders.join('", "')}". Skipping cache population.`);
77
- return;
78
- }
79
- }
80
- const success = await projectBuildCache.trySetCacheEntryAsync(terminal);
81
- if (success) {
82
- ++successCount;
83
- terminal.writeLine(`Operation "${operation.name}": Existing outputs have been successfully written to the build cache."`);
84
- terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);
85
- }
86
- else {
87
- terminal.writeErrorLine(`Operation "${operation.name}": An error occurred while writing existing outputs to the build cache.`);
77
+ }
78
+ else if (cacheAction === CACHE_ACTION_WRITE) {
79
+ // if the require output folders flag has been passed, skip populating the cache if any of the expected output folders does not exist
80
+ if (requireOutputFolders &&
81
+ ((_a = operation.settings) === null || _a === void 0 ? void 0 : _a.outputFolderNames) &&
82
+ ((_c = (_b = operation.settings) === null || _b === void 0 ? void 0 : _b.outputFolderNames) === null || _c === void 0 ? void 0 : _c.length) > 0) {
83
+ const projectFolder = (_d = operation.associatedProject) === null || _d === void 0 ? void 0 : _d.projectFolder;
84
+ const missingFolders = [];
85
+ operation.settings.outputFolderNames.forEach((outputFolderName) => {
86
+ if (!node_core_library_1.FileSystem.exists(`${projectFolder}/${outputFolderName}`)) {
87
+ missingFolders.push(outputFolderName);
88
88
  }
89
+ });
90
+ if (missingFolders.length > 0) {
91
+ terminal.writeWarningLine(`Operation "${operation.name}": The following output folders do not exist: "${missingFolders.join('", "')}". Skipping cache population.`);
92
+ return;
89
93
  }
90
- }, { concurrency: graph.parallelism });
91
- terminal.writeLine(`Cache operation "${cacheAction}" completed successfully for ${successCount} out of ${filteredOperations.length} operations.`);
92
- // Bail out with a status indicating success; treat cache read as FromCache.
93
- return cacheAction === CACHE_ACTION_READ ? rush_sdk_1.OperationStatus.FromCache : rush_sdk_1.OperationStatus.Success;
94
- });
95
- }
94
+ }
95
+ const success = await projectBuildCache.trySetCacheEntryAsync(terminal);
96
+ if (success) {
97
+ ++successCount;
98
+ terminal.writeLine(`Operation "${operation.name}": Existing outputs have been successfully written to the build cache."`);
99
+ terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);
100
+ }
101
+ else {
102
+ terminal.writeErrorLine(`Operation "${operation.name}": An error occurred while writing existing outputs to the build cache.`);
103
+ }
104
+ }
105
+ }, {
106
+ concurrency: context.parallelism
107
+ });
108
+ terminal.writeLine(`Cache operation "${cacheAction}" completed successfully for ${successCount} out of ${filteredOperations.size} operations.`);
96
109
  });
97
110
  });
98
111
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BridgeCachePlugin.js","sourceRoot":"","sources":["../src/BridgeCachePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { Async, FileSystem } from '@rushstack/node-core-library';\nimport {\n _OperationBuildCache as OperationBuildCache,\n OperationStatus,\n type Operation,\n type IOperationExecutionResult,\n type IOperationGraphIterationOptions,\n type ILogger,\n type IBaseOperationExecutionResult,\n type IPhasedCommand,\n type IRushPlugin,\n type RushSession\n} from '@rushstack/rush-sdk';\nimport { CommandLineParameterKind, type CommandLineParameter } from '@rushstack/ts-command-line';\n\nconst PLUGIN_NAME: 'RushBridgeCachePlugin' = 'RushBridgeCachePlugin';\n\nconst CACHE_ACTION_READ: 'read' = 'read';\nconst CACHE_ACTION_WRITE: 'write' = 'write';\n\ntype CacheAction = typeof CACHE_ACTION_READ | typeof CACHE_ACTION_WRITE;\n\nexport interface IBridgeCachePluginOptions {\n readonly actionParameterName: string;\n readonly requireOutputFoldersParameterName: string | undefined;\n}\n\nexport class BridgeCachePlugin implements IRushPlugin {\n public readonly pluginName: string = PLUGIN_NAME;\n private readonly _actionParameterName: string;\n private readonly _requireOutputFoldersParameterName: string | undefined;\n\n public constructor(options: IBridgeCachePluginOptions) {\n this._actionParameterName = options.actionParameterName;\n this._requireOutputFoldersParameterName = options.requireOutputFoldersParameterName;\n\n if (!this._actionParameterName) {\n throw new Error(\n 'The \"actionParameterName\" option must be provided for the BridgeCachePlugin. Please see the plugin README for details.'\n );\n }\n }\n\n public apply(session: RushSession): void {\n session.hooks.runAnyPhasedCommand.tapPromise(PLUGIN_NAME, async (command: IPhasedCommand) => {\n command.hooks.onGraphCreatedAsync.tap(PLUGIN_NAME, async (graph, context) => {\n const { customParameters, buildCacheConfiguration } = context;\n const cacheAction: CacheAction | undefined = this._getCacheAction(customParameters);\n\n if (cacheAction !== undefined) {\n if (!buildCacheConfiguration?.buildCacheEnabled) {\n throw new Error(\n `The build cache must be enabled to use the \"${this._actionParameterName}\" parameter.`\n );\n }\n\n const {\n rushConfiguration: {\n experimentsConfiguration: {\n configuration: { omitAppleDoubleFilesFromBuildCache }\n }\n }\n } = context;\n\n const logger: ILogger = session.getLogger(PLUGIN_NAME);\n const { terminal } = logger;\n const requireOutputFolders: boolean = this._isRequireOutputFoldersFlagSet(customParameters);\n\n graph.hooks.beforeExecuteIterationAsync.tapPromise(\n PLUGIN_NAME,\n async (\n operationRecords: ReadonlyMap<Operation, IOperationExecutionResult>,\n iterationOptions: IOperationGraphIterationOptions\n ): Promise<OperationStatus | undefined> => {\n const filteredOperations: IBaseOperationExecutionResult[] = [];\n for (const record of operationRecords.values()) {\n if (!record.operation.isNoOp) {\n filteredOperations.push(record);\n }\n }\n\n if (!filteredOperations.length) {\n return; // nothing to do, continue normal execution\n }\n\n let successCount: number = 0;\n await Async.forEachAsync(\n filteredOperations,\n async (operationExecutionResult: IBaseOperationExecutionResult) => {\n const projectBuildCache: OperationBuildCache = OperationBuildCache.forOperation(\n operationExecutionResult,\n {\n buildCacheConfiguration,\n terminal,\n excludeAppleDoubleFiles: !!omitAppleDoubleFilesFromBuildCache\n }\n );\n\n const { operation } = operationExecutionResult;\n\n if (cacheAction === CACHE_ACTION_READ) {\n const success: boolean = await projectBuildCache.tryRestoreFromCacheAsync(terminal);\n if (success) {\n ++successCount;\n terminal.writeLine(\n `Operation \"${operation.name}\": Outputs have been restored from the build cache.\"`\n );\n terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);\n } else {\n terminal.writeWarningLine(\n `Operation \"${operation.name}\": Outputs could not be restored from the build cache.`\n );\n }\n } else if (cacheAction === CACHE_ACTION_WRITE) {\n if (\n requireOutputFolders &&\n operation.settings?.outputFolderNames &&\n operation.settings?.outputFolderNames?.length > 0\n ) {\n const projectFolder: string = operation.associatedProject?.projectFolder;\n const missingFolders: string[] = [];\n operation.settings.outputFolderNames.forEach((outputFolderName: string) => {\n if (!FileSystem.exists(`${projectFolder}/${outputFolderName}`)) {\n missingFolders.push(outputFolderName);\n }\n });\n if (missingFolders.length > 0) {\n terminal.writeWarningLine(\n `Operation \"${operation.name}\": The following output folders do not exist: \"${missingFolders.join('\", \"')}\". Skipping cache population.`\n );\n return;\n }\n }\n\n const success: boolean = await projectBuildCache.trySetCacheEntryAsync(terminal);\n if (success) {\n ++successCount;\n terminal.writeLine(\n `Operation \"${operation.name}\": Existing outputs have been successfully written to the build cache.\"`\n );\n terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);\n } else {\n terminal.writeErrorLine(\n `Operation \"${operation.name}\": An error occurred while writing existing outputs to the build cache.`\n );\n }\n }\n },\n { concurrency: graph.parallelism }\n );\n\n terminal.writeLine(\n `Cache operation \"${cacheAction}\" completed successfully for ${successCount} out of ${filteredOperations.length} operations.`\n );\n\n // Bail out with a status indicating success; treat cache read as FromCache.\n return cacheAction === CACHE_ACTION_READ ? OperationStatus.FromCache : OperationStatus.Success;\n }\n );\n }\n });\n });\n }\n\n private _getCacheAction(\n customParameters: ReadonlyMap<string, CommandLineParameter>\n ): CacheAction | undefined {\n const cacheActionParameter: CommandLineParameter | undefined = customParameters.get(\n this._actionParameterName\n );\n\n if (cacheActionParameter) {\n if (cacheActionParameter.kind !== CommandLineParameterKind.Choice) {\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must be a choice. Please check the plugin configuration.`\n );\n }\n\n if (\n cacheActionParameter.alternatives.size !== 2 ||\n !cacheActionParameter.alternatives.has(CACHE_ACTION_READ) ||\n !cacheActionParameter.alternatives.has(CACHE_ACTION_WRITE)\n ) {\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must have exactly two choices: \"${CACHE_ACTION_READ}\" and \"${CACHE_ACTION_WRITE}\". Please check the plugin configuration.`\n );\n }\n\n const value: string | undefined = cacheActionParameter.value;\n switch (value) {\n case CACHE_ACTION_READ:\n case CACHE_ACTION_WRITE:\n return value;\n case undefined:\n return undefined;\n default:\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must be one of: \"${CACHE_ACTION_READ}\" or \"${CACHE_ACTION_WRITE}\". Received: \"${value}\". Please check the plugin configuration.`\n );\n }\n }\n\n return undefined;\n }\n\n private _isRequireOutputFoldersFlagSet(\n customParameters: ReadonlyMap<string, CommandLineParameter>\n ): boolean {\n if (!this._requireOutputFoldersParameterName) {\n return false;\n }\n\n const requireOutputFoldersParam: CommandLineParameter | undefined = customParameters.get(\n this._requireOutputFoldersParameterName\n );\n\n if (!requireOutputFoldersParam) {\n return false;\n }\n\n if (requireOutputFoldersParam.kind !== CommandLineParameterKind.Flag) {\n throw new Error(`The parameter \"${this._requireOutputFoldersParameterName}\" must be a flag.`);\n }\n\n return requireOutputFoldersParam.value;\n }\n}\n"]}
1
+ {"version":3,"file":"BridgeCachePlugin.js","sourceRoot":"","sources":["../src/BridgeCachePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { Async, FileSystem } from '@rushstack/node-core-library';\nimport { _OperationBuildCache as OperationBuildCache } from '@rushstack/rush-sdk';\nimport type {\n ICreateOperationsContext,\n IExecuteOperationsContext,\n ILogger,\n IOperationExecutionResult,\n IPhasedCommand,\n IRushPlugin,\n Operation,\n RushSession\n} from '@rushstack/rush-sdk';\nimport { CommandLineParameterKind } from '@rushstack/ts-command-line';\nimport type { CommandLineParameter } from '@rushstack/ts-command-line';\n\nconst PLUGIN_NAME: 'RushBridgeCachePlugin' = 'RushBridgeCachePlugin';\n\nconst CACHE_ACTION_READ: 'read' = 'read';\nconst CACHE_ACTION_WRITE: 'write' = 'write';\n\ntype CacheAction = typeof CACHE_ACTION_READ | typeof CACHE_ACTION_WRITE;\n\nexport interface IBridgeCachePluginOptions {\n readonly actionParameterName: string;\n readonly requireOutputFoldersParameterName: string | undefined;\n}\n\nexport class BridgeCachePlugin implements IRushPlugin {\n public readonly pluginName: string = PLUGIN_NAME;\n private readonly _actionParameterName: string;\n private readonly _requireOutputFoldersParameterName: string | undefined;\n\n public constructor(options: IBridgeCachePluginOptions) {\n this._actionParameterName = options.actionParameterName;\n this._requireOutputFoldersParameterName = options.requireOutputFoldersParameterName;\n\n if (!this._actionParameterName) {\n throw new Error(\n 'The \"actionParameterName\" option must be provided for the BridgeCachePlugin. Please see the plugin README for details.'\n );\n }\n }\n\n public apply(session: RushSession): void {\n session.hooks.runAnyPhasedCommand.tapPromise(PLUGIN_NAME, async (command: IPhasedCommand) => {\n const logger: ILogger = session.getLogger(PLUGIN_NAME);\n\n let cacheAction: CacheAction | undefined;\n let requireOutputFolders: boolean = false;\n\n // cancel the actual operations. We don't want to run the command, just cache the output folders on disk\n command.hooks.createOperations.tap(\n { name: PLUGIN_NAME, stage: Number.MAX_SAFE_INTEGER },\n (operations: Set<Operation>, context: ICreateOperationsContext): Set<Operation> => {\n const { customParameters } = context;\n cacheAction = this._getCacheAction(customParameters);\n\n if (cacheAction !== undefined) {\n if (!context.buildCacheConfiguration?.buildCacheEnabled) {\n throw new Error(\n `The build cache must be enabled to use the \"${this._actionParameterName}\" parameter.`\n );\n }\n\n for (const operation of operations) {\n operation.enabled = false;\n }\n\n requireOutputFolders = this._isRequireOutputFoldersFlagSet(customParameters);\n }\n\n return operations;\n }\n );\n // populate the cache for each operation\n command.hooks.beforeExecuteOperations.tapPromise(\n PLUGIN_NAME,\n async (\n recordByOperation: Map<Operation, IOperationExecutionResult>,\n context: IExecuteOperationsContext\n ): Promise<void> => {\n const {\n buildCacheConfiguration,\n rushConfiguration: {\n experimentsConfiguration: {\n configuration: { omitAppleDoubleFilesFromBuildCache }\n }\n }\n } = context;\n const { terminal } = logger;\n\n if (cacheAction === undefined) {\n return;\n }\n\n if (!buildCacheConfiguration?.buildCacheEnabled) {\n throw new Error(\n `The build cache must be enabled to use the \"${this._actionParameterName}\" parameter.`\n );\n }\n\n const filteredOperations: Set<IOperationExecutionResult> = new Set();\n for (const operationExecutionResult of recordByOperation.values()) {\n if (!operationExecutionResult.operation.isNoOp) {\n filteredOperations.add(operationExecutionResult);\n }\n }\n\n let successCount: number = 0;\n\n await Async.forEachAsync(\n filteredOperations,\n async (operationExecutionResult: IOperationExecutionResult) => {\n const projectBuildCache: OperationBuildCache = OperationBuildCache.forOperation(\n operationExecutionResult,\n {\n buildCacheConfiguration,\n terminal,\n excludeAppleDoubleFiles: !!omitAppleDoubleFilesFromBuildCache\n }\n );\n\n const { operation } = operationExecutionResult;\n\n if (cacheAction === CACHE_ACTION_READ) {\n const success: boolean = await projectBuildCache.tryRestoreFromCacheAsync(terminal);\n if (success) {\n ++successCount;\n terminal.writeLine(\n `Operation \"${operation.name}\": Outputs have been restored from the build cache.\"`\n );\n terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);\n } else {\n terminal.writeWarningLine(\n `Operation \"${operation.name}\": Outputs could not be restored from the build cache.`\n );\n }\n } else if (cacheAction === CACHE_ACTION_WRITE) {\n // if the require output folders flag has been passed, skip populating the cache if any of the expected output folders does not exist\n if (\n requireOutputFolders &&\n operation.settings?.outputFolderNames &&\n operation.settings?.outputFolderNames?.length > 0\n ) {\n const projectFolder: string = operation.associatedProject?.projectFolder;\n const missingFolders: string[] = [];\n operation.settings.outputFolderNames.forEach((outputFolderName: string) => {\n if (!FileSystem.exists(`${projectFolder}/${outputFolderName}`)) {\n missingFolders.push(outputFolderName);\n }\n });\n if (missingFolders.length > 0) {\n terminal.writeWarningLine(\n `Operation \"${operation.name}\": The following output folders do not exist: \"${missingFolders.join('\", \"')}\". Skipping cache population.`\n );\n return;\n }\n }\n\n const success: boolean = await projectBuildCache.trySetCacheEntryAsync(terminal);\n if (success) {\n ++successCount;\n terminal.writeLine(\n `Operation \"${operation.name}\": Existing outputs have been successfully written to the build cache.\"`\n );\n terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);\n } else {\n terminal.writeErrorLine(\n `Operation \"${operation.name}\": An error occurred while writing existing outputs to the build cache.`\n );\n }\n }\n },\n {\n concurrency: context.parallelism\n }\n );\n\n terminal.writeLine(\n `Cache operation \"${cacheAction}\" completed successfully for ${successCount} out of ${filteredOperations.size} operations.`\n );\n }\n );\n });\n }\n\n private _getCacheAction(\n customParameters: ReadonlyMap<string, CommandLineParameter>\n ): CacheAction | undefined {\n const cacheActionParameter: CommandLineParameter | undefined = customParameters.get(\n this._actionParameterName\n );\n\n if (cacheActionParameter) {\n if (cacheActionParameter.kind !== CommandLineParameterKind.Choice) {\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must be a choice. Please check the plugin configuration.`\n );\n }\n\n if (\n cacheActionParameter.alternatives.size !== 2 ||\n !cacheActionParameter.alternatives.has(CACHE_ACTION_READ) ||\n !cacheActionParameter.alternatives.has(CACHE_ACTION_WRITE)\n ) {\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must have exactly two choices: \"${CACHE_ACTION_READ}\" and \"${CACHE_ACTION_WRITE}\". Please check the plugin configuration.`\n );\n }\n\n const value: string | undefined = cacheActionParameter.value;\n switch (value) {\n case CACHE_ACTION_READ:\n case CACHE_ACTION_WRITE:\n return value;\n case undefined:\n return undefined;\n default:\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must be one of: \"${CACHE_ACTION_READ}\" or \"${CACHE_ACTION_WRITE}\". Received: \"${value}\". Please check the plugin configuration.`\n );\n }\n }\n\n return undefined;\n }\n\n private _isRequireOutputFoldersFlagSet(\n customParameters: ReadonlyMap<string, CommandLineParameter>\n ): boolean {\n if (!this._requireOutputFoldersParameterName) {\n return false;\n }\n\n const requireOutputFoldersParam: CommandLineParameter | undefined = customParameters.get(\n this._requireOutputFoldersParameterName\n );\n\n if (!requireOutputFoldersParam) {\n return false;\n }\n\n if (requireOutputFoldersParam.kind !== CommandLineParameterKind.Flag) {\n throw new Error(`The parameter \"${this._requireOutputFoldersParameterName}\" must be a flag.`);\n }\n\n return requireOutputFoldersParam.value;\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { type IRushPlugin, type RushSession } from '@rushstack/rush-sdk';
1
+ import type { IRushPlugin, RushSession } from '@rushstack/rush-sdk';
2
2
  export interface IBridgeCachePluginOptions {
3
3
  readonly actionParameterName: string;
4
4
  readonly requireOutputFoldersParameterName: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"BridgeCachePlugin.d.ts","sourceRoot":"","sources":["../src/BridgeCachePlugin.ts"],"names":[],"mappings":"AAIA,OAAO,EASL,KAAK,WAAW,EAChB,KAAK,WAAW,EACjB,MAAM,qBAAqB,CAAC;AAU7B,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,iCAAiC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChE;AAED,qBAAa,iBAAkB,YAAW,WAAW;IACnD,SAAgB,UAAU,EAAE,MAAM,CAAe;IACjD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,kCAAkC,CAAqB;gBAErD,OAAO,EAAE,yBAAyB;IAW9C,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAyHxC,OAAO,CAAC,eAAe;IAyCvB,OAAO,CAAC,8BAA8B;CAqBvC"}
1
+ {"version":3,"file":"BridgeCachePlugin.d.ts","sourceRoot":"","sources":["../src/BridgeCachePlugin.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAMV,WAAW,EAEX,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAW7B,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,iCAAiC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChE;AAED,qBAAa,iBAAkB,YAAW,WAAW;IACnD,SAAgB,UAAU,EAAE,MAAM,CAAe;IACjD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,kCAAkC,CAAqB;gBAErD,OAAO,EAAE,yBAAyB;IAW9C,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IA+IxC,OAAO,CAAC,eAAe;IAyCvB,OAAO,CAAC,8BAA8B;CAqBvC"}
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
2
  // See LICENSE in the project root for license information.
3
3
  import { Async, FileSystem } from '@rushstack/node-core-library';
4
- import { _OperationBuildCache as OperationBuildCache, OperationStatus } from '@rushstack/rush-sdk';
4
+ import { _OperationBuildCache as OperationBuildCache } from '@rushstack/rush-sdk';
5
5
  import { CommandLineParameterKind } from '@rushstack/ts-command-line';
6
6
  const PLUGIN_NAME = 'RushBridgeCachePlugin';
7
7
  const CACHE_ACTION_READ = 'read';
@@ -17,79 +17,92 @@ export class BridgeCachePlugin {
17
17
  }
18
18
  apply(session) {
19
19
  session.hooks.runAnyPhasedCommand.tapPromise(PLUGIN_NAME, async (command) => {
20
- command.hooks.onGraphCreatedAsync.tap(PLUGIN_NAME, async (graph, context) => {
21
- const { customParameters, buildCacheConfiguration } = context;
22
- const cacheAction = this._getCacheAction(customParameters);
20
+ const logger = session.getLogger(PLUGIN_NAME);
21
+ let cacheAction;
22
+ let requireOutputFolders = false;
23
+ // cancel the actual operations. We don't want to run the command, just cache the output folders on disk
24
+ command.hooks.createOperations.tap({ name: PLUGIN_NAME, stage: Number.MAX_SAFE_INTEGER }, (operations, context) => {
25
+ var _a;
26
+ const { customParameters } = context;
27
+ cacheAction = this._getCacheAction(customParameters);
23
28
  if (cacheAction !== undefined) {
24
- if (!(buildCacheConfiguration === null || buildCacheConfiguration === void 0 ? void 0 : buildCacheConfiguration.buildCacheEnabled)) {
29
+ if (!((_a = context.buildCacheConfiguration) === null || _a === void 0 ? void 0 : _a.buildCacheEnabled)) {
25
30
  throw new Error(`The build cache must be enabled to use the "${this._actionParameterName}" parameter.`);
26
31
  }
27
- const { rushConfiguration: { experimentsConfiguration: { configuration: { omitAppleDoubleFilesFromBuildCache } } } } = context;
28
- const logger = session.getLogger(PLUGIN_NAME);
29
- const { terminal } = logger;
30
- const requireOutputFolders = this._isRequireOutputFoldersFlagSet(customParameters);
31
- graph.hooks.beforeExecuteIterationAsync.tapPromise(PLUGIN_NAME, async (operationRecords, iterationOptions) => {
32
- const filteredOperations = [];
33
- for (const record of operationRecords.values()) {
34
- if (!record.operation.isNoOp) {
35
- filteredOperations.push(record);
36
- }
32
+ for (const operation of operations) {
33
+ operation.enabled = false;
34
+ }
35
+ requireOutputFolders = this._isRequireOutputFoldersFlagSet(customParameters);
36
+ }
37
+ return operations;
38
+ });
39
+ // populate the cache for each operation
40
+ command.hooks.beforeExecuteOperations.tapPromise(PLUGIN_NAME, async (recordByOperation, context) => {
41
+ const { buildCacheConfiguration, rushConfiguration: { experimentsConfiguration: { configuration: { omitAppleDoubleFilesFromBuildCache } } } } = context;
42
+ const { terminal } = logger;
43
+ if (cacheAction === undefined) {
44
+ return;
45
+ }
46
+ if (!(buildCacheConfiguration === null || buildCacheConfiguration === void 0 ? void 0 : buildCacheConfiguration.buildCacheEnabled)) {
47
+ throw new Error(`The build cache must be enabled to use the "${this._actionParameterName}" parameter.`);
48
+ }
49
+ const filteredOperations = new Set();
50
+ for (const operationExecutionResult of recordByOperation.values()) {
51
+ if (!operationExecutionResult.operation.isNoOp) {
52
+ filteredOperations.add(operationExecutionResult);
53
+ }
54
+ }
55
+ let successCount = 0;
56
+ await Async.forEachAsync(filteredOperations, async (operationExecutionResult) => {
57
+ var _a, _b, _c, _d;
58
+ const projectBuildCache = OperationBuildCache.forOperation(operationExecutionResult, {
59
+ buildCacheConfiguration,
60
+ terminal,
61
+ excludeAppleDoubleFiles: !!omitAppleDoubleFilesFromBuildCache
62
+ });
63
+ const { operation } = operationExecutionResult;
64
+ if (cacheAction === CACHE_ACTION_READ) {
65
+ const success = await projectBuildCache.tryRestoreFromCacheAsync(terminal);
66
+ if (success) {
67
+ ++successCount;
68
+ terminal.writeLine(`Operation "${operation.name}": Outputs have been restored from the build cache."`);
69
+ terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);
37
70
  }
38
- if (!filteredOperations.length) {
39
- return; // nothing to do, continue normal execution
71
+ else {
72
+ terminal.writeWarningLine(`Operation "${operation.name}": Outputs could not be restored from the build cache.`);
40
73
  }
41
- let successCount = 0;
42
- await Async.forEachAsync(filteredOperations, async (operationExecutionResult) => {
43
- var _a, _b, _c, _d;
44
- const projectBuildCache = OperationBuildCache.forOperation(operationExecutionResult, {
45
- buildCacheConfiguration,
46
- terminal,
47
- excludeAppleDoubleFiles: !!omitAppleDoubleFilesFromBuildCache
48
- });
49
- const { operation } = operationExecutionResult;
50
- if (cacheAction === CACHE_ACTION_READ) {
51
- const success = await projectBuildCache.tryRestoreFromCacheAsync(terminal);
52
- if (success) {
53
- ++successCount;
54
- terminal.writeLine(`Operation "${operation.name}": Outputs have been restored from the build cache."`);
55
- terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);
56
- }
57
- else {
58
- terminal.writeWarningLine(`Operation "${operation.name}": Outputs could not be restored from the build cache.`);
59
- }
60
- }
61
- else if (cacheAction === CACHE_ACTION_WRITE) {
62
- if (requireOutputFolders &&
63
- ((_a = operation.settings) === null || _a === void 0 ? void 0 : _a.outputFolderNames) &&
64
- ((_c = (_b = operation.settings) === null || _b === void 0 ? void 0 : _b.outputFolderNames) === null || _c === void 0 ? void 0 : _c.length) > 0) {
65
- const projectFolder = (_d = operation.associatedProject) === null || _d === void 0 ? void 0 : _d.projectFolder;
66
- const missingFolders = [];
67
- operation.settings.outputFolderNames.forEach((outputFolderName) => {
68
- if (!FileSystem.exists(`${projectFolder}/${outputFolderName}`)) {
69
- missingFolders.push(outputFolderName);
70
- }
71
- });
72
- if (missingFolders.length > 0) {
73
- terminal.writeWarningLine(`Operation "${operation.name}": The following output folders do not exist: "${missingFolders.join('", "')}". Skipping cache population.`);
74
- return;
75
- }
76
- }
77
- const success = await projectBuildCache.trySetCacheEntryAsync(terminal);
78
- if (success) {
79
- ++successCount;
80
- terminal.writeLine(`Operation "${operation.name}": Existing outputs have been successfully written to the build cache."`);
81
- terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);
82
- }
83
- else {
84
- terminal.writeErrorLine(`Operation "${operation.name}": An error occurred while writing existing outputs to the build cache.`);
74
+ }
75
+ else if (cacheAction === CACHE_ACTION_WRITE) {
76
+ // if the require output folders flag has been passed, skip populating the cache if any of the expected output folders does not exist
77
+ if (requireOutputFolders &&
78
+ ((_a = operation.settings) === null || _a === void 0 ? void 0 : _a.outputFolderNames) &&
79
+ ((_c = (_b = operation.settings) === null || _b === void 0 ? void 0 : _b.outputFolderNames) === null || _c === void 0 ? void 0 : _c.length) > 0) {
80
+ const projectFolder = (_d = operation.associatedProject) === null || _d === void 0 ? void 0 : _d.projectFolder;
81
+ const missingFolders = [];
82
+ operation.settings.outputFolderNames.forEach((outputFolderName) => {
83
+ if (!FileSystem.exists(`${projectFolder}/${outputFolderName}`)) {
84
+ missingFolders.push(outputFolderName);
85
85
  }
86
+ });
87
+ if (missingFolders.length > 0) {
88
+ terminal.writeWarningLine(`Operation "${operation.name}": The following output folders do not exist: "${missingFolders.join('", "')}". Skipping cache population.`);
89
+ return;
86
90
  }
87
- }, { concurrency: graph.parallelism });
88
- terminal.writeLine(`Cache operation "${cacheAction}" completed successfully for ${successCount} out of ${filteredOperations.length} operations.`);
89
- // Bail out with a status indicating success; treat cache read as FromCache.
90
- return cacheAction === CACHE_ACTION_READ ? OperationStatus.FromCache : OperationStatus.Success;
91
- });
92
- }
91
+ }
92
+ const success = await projectBuildCache.trySetCacheEntryAsync(terminal);
93
+ if (success) {
94
+ ++successCount;
95
+ terminal.writeLine(`Operation "${operation.name}": Existing outputs have been successfully written to the build cache."`);
96
+ terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);
97
+ }
98
+ else {
99
+ terminal.writeErrorLine(`Operation "${operation.name}": An error occurred while writing existing outputs to the build cache.`);
100
+ }
101
+ }
102
+ }, {
103
+ concurrency: context.parallelism
104
+ });
105
+ terminal.writeLine(`Cache operation "${cacheAction}" completed successfully for ${successCount} out of ${filteredOperations.size} operations.`);
93
106
  });
94
107
  });
95
108
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BridgeCachePlugin.js","sourceRoot":"","sources":["../src/BridgeCachePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { Async, FileSystem } from '@rushstack/node-core-library';\nimport {\n _OperationBuildCache as OperationBuildCache,\n OperationStatus,\n type Operation,\n type IOperationExecutionResult,\n type IOperationGraphIterationOptions,\n type ILogger,\n type IBaseOperationExecutionResult,\n type IPhasedCommand,\n type IRushPlugin,\n type RushSession\n} from '@rushstack/rush-sdk';\nimport { CommandLineParameterKind, type CommandLineParameter } from '@rushstack/ts-command-line';\n\nconst PLUGIN_NAME: 'RushBridgeCachePlugin' = 'RushBridgeCachePlugin';\n\nconst CACHE_ACTION_READ: 'read' = 'read';\nconst CACHE_ACTION_WRITE: 'write' = 'write';\n\ntype CacheAction = typeof CACHE_ACTION_READ | typeof CACHE_ACTION_WRITE;\n\nexport interface IBridgeCachePluginOptions {\n readonly actionParameterName: string;\n readonly requireOutputFoldersParameterName: string | undefined;\n}\n\nexport class BridgeCachePlugin implements IRushPlugin {\n public readonly pluginName: string = PLUGIN_NAME;\n private readonly _actionParameterName: string;\n private readonly _requireOutputFoldersParameterName: string | undefined;\n\n public constructor(options: IBridgeCachePluginOptions) {\n this._actionParameterName = options.actionParameterName;\n this._requireOutputFoldersParameterName = options.requireOutputFoldersParameterName;\n\n if (!this._actionParameterName) {\n throw new Error(\n 'The \"actionParameterName\" option must be provided for the BridgeCachePlugin. Please see the plugin README for details.'\n );\n }\n }\n\n public apply(session: RushSession): void {\n session.hooks.runAnyPhasedCommand.tapPromise(PLUGIN_NAME, async (command: IPhasedCommand) => {\n command.hooks.onGraphCreatedAsync.tap(PLUGIN_NAME, async (graph, context) => {\n const { customParameters, buildCacheConfiguration } = context;\n const cacheAction: CacheAction | undefined = this._getCacheAction(customParameters);\n\n if (cacheAction !== undefined) {\n if (!buildCacheConfiguration?.buildCacheEnabled) {\n throw new Error(\n `The build cache must be enabled to use the \"${this._actionParameterName}\" parameter.`\n );\n }\n\n const {\n rushConfiguration: {\n experimentsConfiguration: {\n configuration: { omitAppleDoubleFilesFromBuildCache }\n }\n }\n } = context;\n\n const logger: ILogger = session.getLogger(PLUGIN_NAME);\n const { terminal } = logger;\n const requireOutputFolders: boolean = this._isRequireOutputFoldersFlagSet(customParameters);\n\n graph.hooks.beforeExecuteIterationAsync.tapPromise(\n PLUGIN_NAME,\n async (\n operationRecords: ReadonlyMap<Operation, IOperationExecutionResult>,\n iterationOptions: IOperationGraphIterationOptions\n ): Promise<OperationStatus | undefined> => {\n const filteredOperations: IBaseOperationExecutionResult[] = [];\n for (const record of operationRecords.values()) {\n if (!record.operation.isNoOp) {\n filteredOperations.push(record);\n }\n }\n\n if (!filteredOperations.length) {\n return; // nothing to do, continue normal execution\n }\n\n let successCount: number = 0;\n await Async.forEachAsync(\n filteredOperations,\n async (operationExecutionResult: IBaseOperationExecutionResult) => {\n const projectBuildCache: OperationBuildCache = OperationBuildCache.forOperation(\n operationExecutionResult,\n {\n buildCacheConfiguration,\n terminal,\n excludeAppleDoubleFiles: !!omitAppleDoubleFilesFromBuildCache\n }\n );\n\n const { operation } = operationExecutionResult;\n\n if (cacheAction === CACHE_ACTION_READ) {\n const success: boolean = await projectBuildCache.tryRestoreFromCacheAsync(terminal);\n if (success) {\n ++successCount;\n terminal.writeLine(\n `Operation \"${operation.name}\": Outputs have been restored from the build cache.\"`\n );\n terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);\n } else {\n terminal.writeWarningLine(\n `Operation \"${operation.name}\": Outputs could not be restored from the build cache.`\n );\n }\n } else if (cacheAction === CACHE_ACTION_WRITE) {\n if (\n requireOutputFolders &&\n operation.settings?.outputFolderNames &&\n operation.settings?.outputFolderNames?.length > 0\n ) {\n const projectFolder: string = operation.associatedProject?.projectFolder;\n const missingFolders: string[] = [];\n operation.settings.outputFolderNames.forEach((outputFolderName: string) => {\n if (!FileSystem.exists(`${projectFolder}/${outputFolderName}`)) {\n missingFolders.push(outputFolderName);\n }\n });\n if (missingFolders.length > 0) {\n terminal.writeWarningLine(\n `Operation \"${operation.name}\": The following output folders do not exist: \"${missingFolders.join('\", \"')}\". Skipping cache population.`\n );\n return;\n }\n }\n\n const success: boolean = await projectBuildCache.trySetCacheEntryAsync(terminal);\n if (success) {\n ++successCount;\n terminal.writeLine(\n `Operation \"${operation.name}\": Existing outputs have been successfully written to the build cache.\"`\n );\n terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);\n } else {\n terminal.writeErrorLine(\n `Operation \"${operation.name}\": An error occurred while writing existing outputs to the build cache.`\n );\n }\n }\n },\n { concurrency: graph.parallelism }\n );\n\n terminal.writeLine(\n `Cache operation \"${cacheAction}\" completed successfully for ${successCount} out of ${filteredOperations.length} operations.`\n );\n\n // Bail out with a status indicating success; treat cache read as FromCache.\n return cacheAction === CACHE_ACTION_READ ? OperationStatus.FromCache : OperationStatus.Success;\n }\n );\n }\n });\n });\n }\n\n private _getCacheAction(\n customParameters: ReadonlyMap<string, CommandLineParameter>\n ): CacheAction | undefined {\n const cacheActionParameter: CommandLineParameter | undefined = customParameters.get(\n this._actionParameterName\n );\n\n if (cacheActionParameter) {\n if (cacheActionParameter.kind !== CommandLineParameterKind.Choice) {\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must be a choice. Please check the plugin configuration.`\n );\n }\n\n if (\n cacheActionParameter.alternatives.size !== 2 ||\n !cacheActionParameter.alternatives.has(CACHE_ACTION_READ) ||\n !cacheActionParameter.alternatives.has(CACHE_ACTION_WRITE)\n ) {\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must have exactly two choices: \"${CACHE_ACTION_READ}\" and \"${CACHE_ACTION_WRITE}\". Please check the plugin configuration.`\n );\n }\n\n const value: string | undefined = cacheActionParameter.value;\n switch (value) {\n case CACHE_ACTION_READ:\n case CACHE_ACTION_WRITE:\n return value;\n case undefined:\n return undefined;\n default:\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must be one of: \"${CACHE_ACTION_READ}\" or \"${CACHE_ACTION_WRITE}\". Received: \"${value}\". Please check the plugin configuration.`\n );\n }\n }\n\n return undefined;\n }\n\n private _isRequireOutputFoldersFlagSet(\n customParameters: ReadonlyMap<string, CommandLineParameter>\n ): boolean {\n if (!this._requireOutputFoldersParameterName) {\n return false;\n }\n\n const requireOutputFoldersParam: CommandLineParameter | undefined = customParameters.get(\n this._requireOutputFoldersParameterName\n );\n\n if (!requireOutputFoldersParam) {\n return false;\n }\n\n if (requireOutputFoldersParam.kind !== CommandLineParameterKind.Flag) {\n throw new Error(`The parameter \"${this._requireOutputFoldersParameterName}\" must be a flag.`);\n }\n\n return requireOutputFoldersParam.value;\n }\n}\n"]}
1
+ {"version":3,"file":"BridgeCachePlugin.js","sourceRoot":"","sources":["../src/BridgeCachePlugin.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { Async, FileSystem } from '@rushstack/node-core-library';\nimport { _OperationBuildCache as OperationBuildCache } from '@rushstack/rush-sdk';\nimport type {\n ICreateOperationsContext,\n IExecuteOperationsContext,\n ILogger,\n IOperationExecutionResult,\n IPhasedCommand,\n IRushPlugin,\n Operation,\n RushSession\n} from '@rushstack/rush-sdk';\nimport { CommandLineParameterKind } from '@rushstack/ts-command-line';\nimport type { CommandLineParameter } from '@rushstack/ts-command-line';\n\nconst PLUGIN_NAME: 'RushBridgeCachePlugin' = 'RushBridgeCachePlugin';\n\nconst CACHE_ACTION_READ: 'read' = 'read';\nconst CACHE_ACTION_WRITE: 'write' = 'write';\n\ntype CacheAction = typeof CACHE_ACTION_READ | typeof CACHE_ACTION_WRITE;\n\nexport interface IBridgeCachePluginOptions {\n readonly actionParameterName: string;\n readonly requireOutputFoldersParameterName: string | undefined;\n}\n\nexport class BridgeCachePlugin implements IRushPlugin {\n public readonly pluginName: string = PLUGIN_NAME;\n private readonly _actionParameterName: string;\n private readonly _requireOutputFoldersParameterName: string | undefined;\n\n public constructor(options: IBridgeCachePluginOptions) {\n this._actionParameterName = options.actionParameterName;\n this._requireOutputFoldersParameterName = options.requireOutputFoldersParameterName;\n\n if (!this._actionParameterName) {\n throw new Error(\n 'The \"actionParameterName\" option must be provided for the BridgeCachePlugin. Please see the plugin README for details.'\n );\n }\n }\n\n public apply(session: RushSession): void {\n session.hooks.runAnyPhasedCommand.tapPromise(PLUGIN_NAME, async (command: IPhasedCommand) => {\n const logger: ILogger = session.getLogger(PLUGIN_NAME);\n\n let cacheAction: CacheAction | undefined;\n let requireOutputFolders: boolean = false;\n\n // cancel the actual operations. We don't want to run the command, just cache the output folders on disk\n command.hooks.createOperations.tap(\n { name: PLUGIN_NAME, stage: Number.MAX_SAFE_INTEGER },\n (operations: Set<Operation>, context: ICreateOperationsContext): Set<Operation> => {\n const { customParameters } = context;\n cacheAction = this._getCacheAction(customParameters);\n\n if (cacheAction !== undefined) {\n if (!context.buildCacheConfiguration?.buildCacheEnabled) {\n throw new Error(\n `The build cache must be enabled to use the \"${this._actionParameterName}\" parameter.`\n );\n }\n\n for (const operation of operations) {\n operation.enabled = false;\n }\n\n requireOutputFolders = this._isRequireOutputFoldersFlagSet(customParameters);\n }\n\n return operations;\n }\n );\n // populate the cache for each operation\n command.hooks.beforeExecuteOperations.tapPromise(\n PLUGIN_NAME,\n async (\n recordByOperation: Map<Operation, IOperationExecutionResult>,\n context: IExecuteOperationsContext\n ): Promise<void> => {\n const {\n buildCacheConfiguration,\n rushConfiguration: {\n experimentsConfiguration: {\n configuration: { omitAppleDoubleFilesFromBuildCache }\n }\n }\n } = context;\n const { terminal } = logger;\n\n if (cacheAction === undefined) {\n return;\n }\n\n if (!buildCacheConfiguration?.buildCacheEnabled) {\n throw new Error(\n `The build cache must be enabled to use the \"${this._actionParameterName}\" parameter.`\n );\n }\n\n const filteredOperations: Set<IOperationExecutionResult> = new Set();\n for (const operationExecutionResult of recordByOperation.values()) {\n if (!operationExecutionResult.operation.isNoOp) {\n filteredOperations.add(operationExecutionResult);\n }\n }\n\n let successCount: number = 0;\n\n await Async.forEachAsync(\n filteredOperations,\n async (operationExecutionResult: IOperationExecutionResult) => {\n const projectBuildCache: OperationBuildCache = OperationBuildCache.forOperation(\n operationExecutionResult,\n {\n buildCacheConfiguration,\n terminal,\n excludeAppleDoubleFiles: !!omitAppleDoubleFilesFromBuildCache\n }\n );\n\n const { operation } = operationExecutionResult;\n\n if (cacheAction === CACHE_ACTION_READ) {\n const success: boolean = await projectBuildCache.tryRestoreFromCacheAsync(terminal);\n if (success) {\n ++successCount;\n terminal.writeLine(\n `Operation \"${operation.name}\": Outputs have been restored from the build cache.\"`\n );\n terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);\n } else {\n terminal.writeWarningLine(\n `Operation \"${operation.name}\": Outputs could not be restored from the build cache.`\n );\n }\n } else if (cacheAction === CACHE_ACTION_WRITE) {\n // if the require output folders flag has been passed, skip populating the cache if any of the expected output folders does not exist\n if (\n requireOutputFolders &&\n operation.settings?.outputFolderNames &&\n operation.settings?.outputFolderNames?.length > 0\n ) {\n const projectFolder: string = operation.associatedProject?.projectFolder;\n const missingFolders: string[] = [];\n operation.settings.outputFolderNames.forEach((outputFolderName: string) => {\n if (!FileSystem.exists(`${projectFolder}/${outputFolderName}`)) {\n missingFolders.push(outputFolderName);\n }\n });\n if (missingFolders.length > 0) {\n terminal.writeWarningLine(\n `Operation \"${operation.name}\": The following output folders do not exist: \"${missingFolders.join('\", \"')}\". Skipping cache population.`\n );\n return;\n }\n }\n\n const success: boolean = await projectBuildCache.trySetCacheEntryAsync(terminal);\n if (success) {\n ++successCount;\n terminal.writeLine(\n `Operation \"${operation.name}\": Existing outputs have been successfully written to the build cache.\"`\n );\n terminal.writeLine(`Cache key: ${projectBuildCache.cacheId}`);\n } else {\n terminal.writeErrorLine(\n `Operation \"${operation.name}\": An error occurred while writing existing outputs to the build cache.`\n );\n }\n }\n },\n {\n concurrency: context.parallelism\n }\n );\n\n terminal.writeLine(\n `Cache operation \"${cacheAction}\" completed successfully for ${successCount} out of ${filteredOperations.size} operations.`\n );\n }\n );\n });\n }\n\n private _getCacheAction(\n customParameters: ReadonlyMap<string, CommandLineParameter>\n ): CacheAction | undefined {\n const cacheActionParameter: CommandLineParameter | undefined = customParameters.get(\n this._actionParameterName\n );\n\n if (cacheActionParameter) {\n if (cacheActionParameter.kind !== CommandLineParameterKind.Choice) {\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must be a choice. Please check the plugin configuration.`\n );\n }\n\n if (\n cacheActionParameter.alternatives.size !== 2 ||\n !cacheActionParameter.alternatives.has(CACHE_ACTION_READ) ||\n !cacheActionParameter.alternatives.has(CACHE_ACTION_WRITE)\n ) {\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must have exactly two choices: \"${CACHE_ACTION_READ}\" and \"${CACHE_ACTION_WRITE}\". Please check the plugin configuration.`\n );\n }\n\n const value: string | undefined = cacheActionParameter.value;\n switch (value) {\n case CACHE_ACTION_READ:\n case CACHE_ACTION_WRITE:\n return value;\n case undefined:\n return undefined;\n default:\n throw new Error(\n `The parameter \"${this._actionParameterName}\" must be one of: \"${CACHE_ACTION_READ}\" or \"${CACHE_ACTION_WRITE}\". Received: \"${value}\". Please check the plugin configuration.`\n );\n }\n }\n\n return undefined;\n }\n\n private _isRequireOutputFoldersFlagSet(\n customParameters: ReadonlyMap<string, CommandLineParameter>\n ): boolean {\n if (!this._requireOutputFoldersParameterName) {\n return false;\n }\n\n const requireOutputFoldersParam: CommandLineParameter | undefined = customParameters.get(\n this._requireOutputFoldersParameterName\n );\n\n if (!requireOutputFoldersParam) {\n return false;\n }\n\n if (requireOutputFoldersParam.kind !== CommandLineParameterKind.Flag) {\n throw new Error(`The parameter \"${this._requireOutputFoldersParameterName}\" must be a flag.`);\n }\n\n return requireOutputFoldersParam.value;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rushstack/rush-bridge-cache-plugin",
3
- "version": "5.170.1-pr5378.0",
3
+ "version": "5.170.1",
4
4
  "description": "Rush plugin that provides a --set-cache-only command flag to populate the cache from content on disk.",
5
5
  "license": "MIT",
6
6
  "main": "./lib-commonjs/index.js",
@@ -38,14 +38,14 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@rushstack/ts-command-line": "5.3.3",
41
- "@rushstack/rush-sdk": "5.170.1-pr5378.0",
41
+ "@rushstack/terminal": "0.22.3",
42
42
  "@rushstack/node-core-library": "5.20.3",
43
- "@rushstack/terminal": "0.22.3"
43
+ "@rushstack/rush-sdk": "5.170.1"
44
44
  },
45
45
  "devDependencies": {
46
46
  "eslint": "~9.37.0",
47
- "@rushstack/heft": "1.2.7",
48
- "local-node-rig": "1.0.0"
47
+ "local-node-rig": "1.0.0",
48
+ "@rushstack/heft": "1.2.7"
49
49
  },
50
50
  "sideEffects": false,
51
51
  "scripts": {