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

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,92 +20,79 @@ class BridgeCachePlugin {
20
20
  }
21
21
  apply(session) {
22
22
  session.hooks.runAnyPhasedCommand.tapPromise(PLUGIN_NAME, async (command) => {
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);
23
+ command.hooks.onGraphCreatedAsync.tap(PLUGIN_NAME, async (graph, context) => {
24
+ const { customParameters, buildCacheConfiguration } = context;
25
+ const cacheAction = this._getCacheAction(customParameters);
31
26
  if (cacheAction !== undefined) {
32
- if (!((_a = context.buildCacheConfiguration) === null || _a === void 0 ? void 0 : _a.buildCacheEnabled)) {
27
+ if (!(buildCacheConfiguration === null || buildCacheConfiguration === void 0 ? void 0 : buildCacheConfiguration.buildCacheEnabled)) {
33
28
  throw new Error(`The build cache must be enabled to use the "${this._actionParameterName}" parameter.`);
34
29
  }
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}`);
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
+ }
73
40
  }
74
- else {
75
- terminal.writeWarningLine(`Operation "${operation.name}": Outputs could not be restored from the build cache.`);
41
+ if (!filteredOperations.length) {
42
+ return; // nothing to do, continue normal execution
76
43
  }
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
- }
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
89
51
  });
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;
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
+ }
93
63
  }
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.`);
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.`);
88
+ }
89
+ }
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
+ }
109
96
  });
110
97
  });
111
98
  }
@@ -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 { _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
+ {"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,4 +1,4 @@
1
- import type { IRushPlugin, RushSession } from '@rushstack/rush-sdk';
1
+ import { type IRushPlugin, type 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":"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
+ {"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,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 } from '@rushstack/rush-sdk';
4
+ import { _OperationBuildCache as OperationBuildCache, OperationStatus } 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,92 +17,79 @@ export class BridgeCachePlugin {
17
17
  }
18
18
  apply(session) {
19
19
  session.hooks.runAnyPhasedCommand.tapPromise(PLUGIN_NAME, async (command) => {
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);
20
+ command.hooks.onGraphCreatedAsync.tap(PLUGIN_NAME, async (graph, context) => {
21
+ const { customParameters, buildCacheConfiguration } = context;
22
+ const cacheAction = this._getCacheAction(customParameters);
28
23
  if (cacheAction !== undefined) {
29
- if (!((_a = context.buildCacheConfiguration) === null || _a === void 0 ? void 0 : _a.buildCacheEnabled)) {
24
+ if (!(buildCacheConfiguration === null || buildCacheConfiguration === void 0 ? void 0 : buildCacheConfiguration.buildCacheEnabled)) {
30
25
  throw new Error(`The build cache must be enabled to use the "${this._actionParameterName}" parameter.`);
31
26
  }
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}`);
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
+ }
70
37
  }
71
- else {
72
- terminal.writeWarningLine(`Operation "${operation.name}": Outputs could not be restored from the build cache.`);
38
+ if (!filteredOperations.length) {
39
+ return; // nothing to do, continue normal execution
73
40
  }
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
- }
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
86
48
  });
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;
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
+ }
90
60
  }
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.`);
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.`);
85
+ }
86
+ }
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
+ }
106
93
  });
107
94
  });
108
95
  }
@@ -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 { _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
+ {"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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rushstack/rush-bridge-cache-plugin",
3
- "version": "5.170.0",
3
+ "version": "5.170.1-pr5378.0",
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,9 +38,9 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@rushstack/ts-command-line": "5.3.3",
41
- "@rushstack/rush-sdk": "5.170.0",
42
- "@rushstack/terminal": "0.22.3",
43
- "@rushstack/node-core-library": "5.20.3"
41
+ "@rushstack/rush-sdk": "5.170.1-pr5378.0",
42
+ "@rushstack/node-core-library": "5.20.3",
43
+ "@rushstack/terminal": "0.22.3"
44
44
  },
45
45
  "devDependencies": {
46
46
  "eslint": "~9.37.0",