@rushstack/rush-bridge-cache-plugin 5.169.3 → 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.
- package/lib-commonjs/BridgeCachePlugin.js +66 -79
- package/lib-commonjs/BridgeCachePlugin.js.map +1 -1
- package/lib-dts/BridgeCachePlugin.d.ts +1 -1
- package/lib-dts/BridgeCachePlugin.d.ts.map +1 -1
- package/lib-esm/BridgeCachePlugin.js +67 -80
- package/lib-esm/BridgeCachePlugin.js.map +1 -1
- package/package.json +7 -7
|
@@ -20,92 +20,79 @@ class BridgeCachePlugin {
|
|
|
20
20
|
}
|
|
21
21
|
apply(session) {
|
|
22
22
|
session.hooks.runAnyPhasedCommand.tapPromise(PLUGIN_NAME, async (command) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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 (!(
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
requireOutputFolders = this._isRequireOutputFoldersFlagSet(customParameters);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
75
|
-
|
|
41
|
+
if (!filteredOperations.length) {
|
|
42
|
+
return; // nothing to do, continue normal execution
|
|
76
43
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
|
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":"
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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 (!(
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
requireOutputFolders = this._isRequireOutputFoldersFlagSet(customParameters);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
72
|
-
|
|
38
|
+
if (!filteredOperations.length) {
|
|
39
|
+
return; // nothing to do, continue normal execution
|
|
73
40
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,oBAAoB,IAAI,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAWlF,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAGtE,MAAM,WAAW,GAA4B,uBAAuB,CAAC;AAErE,MAAM,iBAAiB,GAAW,MAAM,CAAC;AACzC,MAAM,kBAAkB,GAAY,OAAO,CAAC;AAS5C,MAAM,OAAO,iBAAiB;IAK5B,YAAmB,OAAkC;QAJrC,eAAU,GAAW,WAAW,CAAC;QAK/C,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;QACxD,IAAI,CAAC,kCAAkC,GAAG,OAAO,CAAC,iCAAiC,CAAC;QAEpF,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,wHAAwH,CACzH,CAAC;QACJ,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,OAAoB;QAC/B,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,UAAU,CAAC,WAAW,EAAE,KAAK,EAAE,OAAuB,EAAE,EAAE;YAC1F,MAAM,MAAM,GAAY,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAEvD,IAAI,WAAoC,CAAC;YACzC,IAAI,oBAAoB,GAAY,KAAK,CAAC;YAE1C,wGAAwG;YACxG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAChC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,gBAAgB,EAAE,EACrD,CAAC,UAA0B,EAAE,OAAiC,EAAkB,EAAE;;gBAChF,MAAM,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC;gBACrC,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC;gBAErD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC9B,IAAI,CAAC,CAAA,MAAA,OAAO,CAAC,uBAAuB,0CAAE,iBAAiB,CAAA,EAAE,CAAC;wBACxD,MAAM,IAAI,KAAK,CACb,+CAA+C,IAAI,CAAC,oBAAoB,cAAc,CACvF,CAAC;oBACJ,CAAC;oBAED,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;wBACnC,SAAS,CAAC,OAAO,GAAG,KAAK,CAAC;oBAC5B,CAAC;oBAED,oBAAoB,GAAG,IAAI,CAAC,8BAA8B,CAAC,gBAAgB,CAAC,CAAC;gBAC/E,CAAC;gBAED,OAAO,UAAU,CAAC;YACpB,CAAC,CACF,CAAC;YACF,wCAAwC;YACxC,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,UAAU,CAC9C,WAAW,EACX,KAAK,EACH,iBAA4D,EAC5D,OAAkC,EACnB,EAAE;gBACjB,MAAM,EACJ,uBAAuB,EACvB,iBAAiB,EAAE,EACjB,wBAAwB,EAAE,EACxB,aAAa,EAAE,EAAE,kCAAkC,EAAE,EACtD,EACF,EACF,GAAG,OAAO,CAAC;gBACZ,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;gBAE5B,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC9B,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC,CAAA,uBAAuB,aAAvB,uBAAuB,uBAAvB,uBAAuB,CAAE,iBAAiB,CAAA,EAAE,CAAC;oBAChD,MAAM,IAAI,KAAK,CACb,+CAA+C,IAAI,CAAC,oBAAoB,cAAc,CACvF,CAAC;gBACJ,CAAC;gBAED,MAAM,kBAAkB,GAAmC,IAAI,GAAG,EAAE,CAAC;gBACrE,KAAK,MAAM,wBAAwB,IAAI,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC;oBAClE,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;wBAC/C,kBAAkB,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;oBACnD,CAAC;gBACH,CAAC;gBAED,IAAI,YAAY,GAAW,CAAC,CAAC;gBAE7B,MAAM,KAAK,CAAC,YAAY,CACtB,kBAAkB,EAClB,KAAK,EAAE,wBAAmD,EAAE,EAAE;;oBAC5D,MAAM,iBAAiB,GAAwB,mBAAmB,CAAC,YAAY,CAC7E,wBAAwB,EACxB;wBACE,uBAAuB;wBACvB,QAAQ;wBACR,uBAAuB,EAAE,CAAC,CAAC,kCAAkC;qBAC9D,CACF,CAAC;oBAEF,MAAM,EAAE,SAAS,EAAE,GAAG,wBAAwB,CAAC;oBAE/C,IAAI,WAAW,KAAK,iBAAiB,EAAE,CAAC;wBACtC,MAAM,OAAO,GAAY,MAAM,iBAAiB,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAC;wBACpF,IAAI,OAAO,EAAE,CAAC;4BACZ,EAAE,YAAY,CAAC;4BACf,QAAQ,CAAC,SAAS,CAChB,cAAc,SAAS,CAAC,IAAI,sDAAsD,CACnF,CAAC;4BACF,QAAQ,CAAC,SAAS,CAAC,cAAc,iBAAiB,CAAC,OAAO,EAAE,CAAC,CAAC;wBAChE,CAAC;6BAAM,CAAC;4BACN,QAAQ,CAAC,gBAAgB,CACvB,cAAc,SAAS,CAAC,IAAI,wDAAwD,CACrF,CAAC;wBACJ,CAAC;oBACH,CAAC;yBAAM,IAAI,WAAW,KAAK,kBAAkB,EAAE,CAAC;wBAC9C,qIAAqI;wBACrI,IACE,oBAAoB;6BACpB,MAAA,SAAS,CAAC,QAAQ,0CAAE,iBAAiB,CAAA;4BACrC,CAAA,MAAA,MAAA,SAAS,CAAC,QAAQ,0CAAE,iBAAiB,0CAAE,MAAM,IAAG,CAAC,EACjD,CAAC;4BACD,MAAM,aAAa,GAAW,MAAA,SAAS,CAAC,iBAAiB,0CAAE,aAAa,CAAC;4BACzE,MAAM,cAAc,GAAa,EAAE,CAAC;4BACpC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,gBAAwB,EAAE,EAAE;gCACxE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,aAAa,IAAI,gBAAgB,EAAE,CAAC,EAAE,CAAC;oCAC/D,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;gCACxC,CAAC;4BACH,CAAC,CAAC,CAAC;4BACH,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCAC9B,QAAQ,CAAC,gBAAgB,CACvB,cAAc,SAAS,CAAC,IAAI,kDAAkD,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,+BAA+B,CACzI,CAAC;gCACF,OAAO;4BACT,CAAC;wBACH,CAAC;wBAED,MAAM,OAAO,GAAY,MAAM,iBAAiB,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;wBACjF,IAAI,OAAO,EAAE,CAAC;4BACZ,EAAE,YAAY,CAAC;4BACf,QAAQ,CAAC,SAAS,CAChB,cAAc,SAAS,CAAC,IAAI,yEAAyE,CACtG,CAAC;4BACF,QAAQ,CAAC,SAAS,CAAC,cAAc,iBAAiB,CAAC,OAAO,EAAE,CAAC,CAAC;wBAChE,CAAC;6BAAM,CAAC;4BACN,QAAQ,CAAC,cAAc,CACrB,cAAc,SAAS,CAAC,IAAI,yEAAyE,CACtG,CAAC;wBACJ,CAAC;oBACH,CAAC;gBACH,CAAC,EACD;oBACE,WAAW,EAAE,OAAO,CAAC,WAAW;iBACjC,CACF,CAAC;gBAEF,QAAQ,CAAC,SAAS,CAChB,oBAAoB,WAAW,gCAAgC,YAAY,WAAW,kBAAkB,CAAC,IAAI,cAAc,CAC5H,CAAC;YACJ,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,eAAe,CACrB,gBAA2D;QAE3D,MAAM,oBAAoB,GAAqC,gBAAgB,CAAC,GAAG,CACjF,IAAI,CAAC,oBAAoB,CAC1B,CAAC;QAEF,IAAI,oBAAoB,EAAE,CAAC;YACzB,IAAI,oBAAoB,CAAC,IAAI,KAAK,wBAAwB,CAAC,MAAM,EAAE,CAAC;gBAClE,MAAM,IAAI,KAAK,CACb,kBAAkB,IAAI,CAAC,oBAAoB,4DAA4D,CACxG,CAAC;YACJ,CAAC;YAED,IACE,oBAAoB,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC;gBAC5C,CAAC,oBAAoB,CAAC,YAAY,CAAC,GAAG,CAAC,iBAAiB,CAAC;gBACzD,CAAC,oBAAoB,CAAC,YAAY,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAC1D,CAAC;gBACD,MAAM,IAAI,KAAK,CACb,kBAAkB,IAAI,CAAC,oBAAoB,qCAAqC,iBAAiB,UAAU,kBAAkB,2CAA2C,CACzK,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAuB,oBAAoB,CAAC,KAAK,CAAC;YAC7D,QAAQ,KAAK,EAAE,CAAC;gBACd,KAAK,iBAAiB,CAAC;gBACvB,KAAK,kBAAkB;oBACrB,OAAO,KAAK,CAAC;gBACf,KAAK,SAAS;oBACZ,OAAO,SAAS,CAAC;gBACnB;oBACE,MAAM,IAAI,KAAK,CACb,kBAAkB,IAAI,CAAC,oBAAoB,sBAAsB,iBAAiB,SAAS,kBAAkB,iBAAiB,KAAK,2CAA2C,CAC/K,CAAC;YACN,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,8BAA8B,CACpC,gBAA2D;QAE3D,IAAI,CAAC,IAAI,CAAC,kCAAkC,EAAE,CAAC;YAC7C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,yBAAyB,GAAqC,gBAAgB,CAAC,GAAG,CACtF,IAAI,CAAC,kCAAkC,CACxC,CAAC;QAEF,IAAI,CAAC,yBAAyB,EAAE,CAAC;YAC/B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,yBAAyB,CAAC,IAAI,KAAK,wBAAwB,CAAC,IAAI,EAAE,CAAC;YACrE,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAC,kCAAkC,mBAAmB,CAAC,CAAC;QAChG,CAAC;QAED,OAAO,yBAAyB,CAAC,KAAK,CAAC;IACzC,CAAC;CACF","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.
|
|
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",
|
|
@@ -37,15 +37,15 @@
|
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@rushstack/ts-command-line": "5.3.
|
|
41
|
-
"@rushstack/rush-sdk": "5.
|
|
42
|
-
"@rushstack/node-core-library": "5.20.
|
|
43
|
-
"@rushstack/terminal": "0.22.
|
|
40
|
+
"@rushstack/ts-command-line": "5.3.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",
|
|
47
|
-
"
|
|
48
|
-
"
|
|
47
|
+
"@rushstack/heft": "1.2.7",
|
|
48
|
+
"local-node-rig": "1.0.0"
|
|
49
49
|
},
|
|
50
50
|
"sideEffects": false,
|
|
51
51
|
"scripts": {
|