@rushstack/rush-buildxl-graph-plugin 5.170.1-pr5378.0 → 5.171.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/DropBuildGraphPlugin.js +1 -1
- package/lib-commonjs/DropBuildGraphPlugin.js.map +1 -1
- package/lib-commonjs/GraphProcessor.js +1 -1
- package/lib-commonjs/GraphProcessor.js.map +1 -1
- package/lib-commonjs/debugGraphFiltering.js +1 -0
- package/lib-commonjs/debugGraphFiltering.js.map +1 -1
- package/lib-dts/GraphProcessor.d.ts.map +1 -1
- package/lib-dts/debugGraphFiltering.d.ts +2 -2
- package/lib-dts/debugGraphFiltering.d.ts.map +1 -1
- package/lib-esm/DropBuildGraphPlugin.js +1 -1
- package/lib-esm/DropBuildGraphPlugin.js.map +1 -1
- package/lib-esm/GraphProcessor.js +1 -1
- package/lib-esm/GraphProcessor.js.map +1 -1
- package/lib-esm/debugGraphFiltering.js +1 -0
- package/lib-esm/debugGraphFiltering.js.map +1 -1
- package/package.json +4 -4
|
@@ -87,7 +87,7 @@ class DropBuildGraphPlugin {
|
|
|
87
87
|
}
|
|
88
88
|
for (const buildXLCommandName of this._buildXLCommandNames) {
|
|
89
89
|
session.hooks.runPhasedCommand.for(buildXLCommandName).tap(PLUGIN_NAME, (command) => {
|
|
90
|
-
command.hooks.
|
|
90
|
+
command.hooks.createOperations.tapPromise({
|
|
91
91
|
name: PLUGIN_NAME,
|
|
92
92
|
stage: Number.MAX_SAFE_INTEGER // Run this after other plugins have created all operations
|
|
93
93
|
}, async (operations, context) => await handleCreateOperationsForCommandAsync(command.actionName, operations, context));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropBuildGraphPlugin.js","sourceRoot":"","sources":["../src/DropBuildGraphPlugin.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE3D,kDAQ6B;AAC7B,gEAAuG;AAIvG,MAAM,WAAW,GAA2B,sBAAsB,CAAC;AAuBnE,MAAM,8BAA8B,GAAmB,cAAc,CAAC;AAEtE;;;GAGG;AACH,MAAa,oBAAoB;IAI/B,YAAmB,OAAgC;QAHnC,eAAU,GAAW,WAAW,CAAC;QAI/C,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAC1D,CAAC;IAEM,KAAK,CAAC,OAAoB,EAAE,iBAAoC;QACrE,KAAK,UAAU,qCAAqC,CAClD,WAAmB,EACnB,UAA0B,EAC1B,OAAiC;YAEjC,4GAA4G;YAC5G,YAAY;YACZ,MAAM,kBAAkB,GAA2C,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAC7F,8BAA8B,CACD,CAAC;YAChC,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,4GAA4G;gBAC5G,YAAY;gBACZ,MAAM,IAAI,KAAK,CACb,OAAO,8BAA8B,sCAAsC,wBAAa,CAAC,mBAAmB,IAAI;oBAC9G,mCAAmC,WAAW,GAAG,CACpD,CAAC;YACJ,CAAC;iBAAM,IAAI,kBAAkB,CAAC,IAAI,KAAK,0CAAwB,CAAC,MAAM,EAAE,CAAC;gBACvE,MAAM,IAAI,KAAK,CAAC,OAAO,8BAA8B,uCAAuC,CAAC,CAAC;YAChG,CAAC;YAED,MAAM,aAAa,GAAuB,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,KAAK,CAAC;YACpE,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,EAAE,cAAc,EAAE,GAAG,wDAAa,aAAa,GAAC,CAAC;gBACvD,MAAM,OAAO,GAAY,MAAM,cAAc,CAAC;oBAC5C,UAAU;oBACV,OAAO;oBACP,aAAa;oBACb,iBAAiB;oBACjB,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC;iBACvC,CAAC,CAAC;gBAEH,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;gBAClD,CAAC;qBAAM,CAAC;oBACN,4FAA4F;oBAC5F,OAAO,IAAI,GAAG,EAAE,CAAC;gBACnB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;QAED,KAAK,MAAM,kBAAkB,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC3D,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,OAAuB,EAAE,EAAE;gBAClG,OAAO,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"DropBuildGraphPlugin.js","sourceRoot":"","sources":["../src/DropBuildGraphPlugin.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE3D,kDAQ6B;AAC7B,gEAAuG;AAIvG,MAAM,WAAW,GAA2B,sBAAsB,CAAC;AAuBnE,MAAM,8BAA8B,GAAmB,cAAc,CAAC;AAEtE;;;GAGG;AACH,MAAa,oBAAoB;IAI/B,YAAmB,OAAgC;QAHnC,eAAU,GAAW,WAAW,CAAC;QAI/C,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAC1D,CAAC;IAEM,KAAK,CAAC,OAAoB,EAAE,iBAAoC;QACrE,KAAK,UAAU,qCAAqC,CAClD,WAAmB,EACnB,UAA0B,EAC1B,OAAiC;YAEjC,4GAA4G;YAC5G,YAAY;YACZ,MAAM,kBAAkB,GAA2C,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAC7F,8BAA8B,CACD,CAAC;YAChC,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,4GAA4G;gBAC5G,YAAY;gBACZ,MAAM,IAAI,KAAK,CACb,OAAO,8BAA8B,sCAAsC,wBAAa,CAAC,mBAAmB,IAAI;oBAC9G,mCAAmC,WAAW,GAAG,CACpD,CAAC;YACJ,CAAC;iBAAM,IAAI,kBAAkB,CAAC,IAAI,KAAK,0CAAwB,CAAC,MAAM,EAAE,CAAC;gBACvE,MAAM,IAAI,KAAK,CAAC,OAAO,8BAA8B,uCAAuC,CAAC,CAAC;YAChG,CAAC;YAED,MAAM,aAAa,GAAuB,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,KAAK,CAAC;YACpE,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,EAAE,cAAc,EAAE,GAAG,wDAAa,aAAa,GAAC,CAAC;gBACvD,MAAM,OAAO,GAAY,MAAM,cAAc,CAAC;oBAC5C,UAAU;oBACV,OAAO;oBACP,aAAa;oBACb,iBAAiB;oBACjB,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC;iBACvC,CAAC,CAAC;gBAEH,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;gBAClD,CAAC;qBAAM,CAAC;oBACN,4FAA4F;oBAC5F,OAAO,IAAI,GAAG,EAAE,CAAC;gBACnB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;QAED,KAAK,MAAM,kBAAkB,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC3D,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,OAAuB,EAAE,EAAE;gBAClG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,UAAU,CACvC;oBACE,IAAI,EAAE,WAAW;oBACjB,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,2DAA2D;iBAC3F,EACD,KAAK,EAAE,UAA0B,EAAE,OAAiC,EAAE,EAAE,CACtE,MAAM,qCAAqC,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CACvF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF;AAjED,oDAiEC","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 {\n RushConstants,\n type ICreateOperationsContext,\n type IPhasedCommand,\n type IRushPlugin,\n type Operation,\n type RushConfiguration,\n type RushSession\n} from '@rushstack/rush-sdk';\nimport { CommandLineParameterKind, type CommandLineStringParameter } from '@rushstack/ts-command-line';\n\nimport type { IGraphNode } from './GraphProcessor';\n\nconst PLUGIN_NAME: 'DropBuildGraphPlugin' = 'DropBuildGraphPlugin';\n\n/**\n * This is the type that represents the schema of the drop file\n * @public\n */\nexport interface IBuildXLRushGraph {\n nodes: IGraphNode[];\n repoSettings: {\n commonTempFolder: string;\n };\n}\n\n/**\n * @public\n */\nexport interface IDropGraphPluginOptions {\n /**\n * The names of the commands that will be used to run BuildXL\n */\n buildXLCommandNames: string[];\n}\n\nconst DROP_GRAPH_PARAMETER_LONG_NAME: '--drop-graph' = '--drop-graph';\n\n/**\n * This plugin is used to drop the build graph to a file for BuildXL to consume.\n * @public\n */\nexport class DropBuildGraphPlugin implements IRushPlugin {\n public readonly pluginName: string = PLUGIN_NAME;\n private readonly _buildXLCommandNames: string[];\n\n public constructor(options: IDropGraphPluginOptions) {\n this._buildXLCommandNames = options.buildXLCommandNames;\n }\n\n public apply(session: RushSession, rushConfiguration: RushConfiguration): void {\n async function handleCreateOperationsForCommandAsync(\n commandName: string,\n operations: Set<Operation>,\n context: ICreateOperationsContext\n ): Promise<Set<Operation>> {\n // TODO: Introduce an API to allow plugins to register command line options for arbitrary, existing commands\n // in a repo\n const dropGraphParameter: CommandLineStringParameter | undefined = context.customParameters.get(\n DROP_GRAPH_PARAMETER_LONG_NAME\n ) as CommandLineStringParameter;\n if (!dropGraphParameter) {\n // TODO: Introduce an API to allow plugins to register command line options for arbitrary, existing commands\n // in a repo\n throw new Error(\n `The ${DROP_GRAPH_PARAMETER_LONG_NAME} parameter needs to be defined in \"${RushConstants.commandLineFilename}\" ` +\n `and associated with the action \"${commandName}\"`\n );\n } else if (dropGraphParameter.kind !== CommandLineParameterKind.String) {\n throw new Error(`The ${DROP_GRAPH_PARAMETER_LONG_NAME} parameter must be a string parameter`);\n }\n\n const dropGraphPath: string | undefined = dropGraphParameter?.value;\n if (dropGraphPath) {\n const { dropGraphAsync } = await import('./dropGraph');\n const isValid: boolean = await dropGraphAsync({\n operations,\n context,\n dropGraphPath,\n rushConfiguration,\n logger: session.getLogger(PLUGIN_NAME)\n });\n\n if (!isValid) {\n throw new Error('Failed to validate the graph');\n } else {\n // If the --drop-graph flag is present, we want to exit the process after dropping the graph\n return new Set();\n }\n } else {\n return operations;\n }\n }\n\n for (const buildXLCommandName of this._buildXLCommandNames) {\n session.hooks.runPhasedCommand.for(buildXLCommandName).tap(PLUGIN_NAME, (command: IPhasedCommand) => {\n command.hooks.createOperations.tapPromise(\n {\n name: PLUGIN_NAME,\n stage: Number.MAX_SAFE_INTEGER // Run this after other plugins have created all operations\n },\n async (operations: Set<Operation>, context: ICreateOperationsContext) =>\n await handleCreateOperationsForCommandAsync(command.actionName, operations, context)\n );\n });\n }\n }\n}\n"]}
|
|
@@ -121,7 +121,7 @@ class GraphProcessor {
|
|
|
121
121
|
package: packageName,
|
|
122
122
|
dependencies,
|
|
123
123
|
workingDirectory,
|
|
124
|
-
command: runner === null || runner === void 0 ? void 0 : runner.
|
|
124
|
+
command: runner === null || runner === void 0 ? void 0 : runner.commandToRun
|
|
125
125
|
};
|
|
126
126
|
if (settings === null || settings === void 0 ? void 0 : settings.disableBuildCacheForOperation) {
|
|
127
127
|
node.cacheable = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphProcessor.js","sourceRoot":"","sources":["../src/GraphProcessor.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 type { Operation, ILogger } from '@rushstack/rush-sdk';\nimport { Colorize } from '@rushstack/terminal';\n\n/**\n * @example\n * ```\n * {\n * \"id\": \"@rushstack/node-core-library#_phase:build\",\n * \"task\": \"_phase:build\",\n * \"package\": \"@rushstack/node-core-library\",\n * \"dependencies\": [\n * \"@rushstack/eslint-patch#_phase:build\",\n * \"@rushstack/eslint-plugin#_phase:build\",\n * \"@rushstack/eslint-plugin-packlets#_phase:build\",\n * \"@rushstack/eslint-plugin-security#_phase:build\"\n * ],\n * \"workingDirectory\": \"/repo/libraries/node-core-library\",\n * \"command\": \"heft run --only build -- --clean --production --drop-graph ./src/examples/graph.json\"\n * }\n * ```\n *\n * See https://github.com/microsoft/BuildXL/blob/adf025c1b96b8106984928df3e9c30c8331bc8d6/Public/Src/Tools/JavaScript/Tool.RushGraphBuilder/src/RushBuildPluginGraph.ts\n *\n * @public\n */\nexport interface IGraphNode {\n /**\n * The unique id of the Pip\n *\n * @example\n * `@rushstack/node-core-library#_phase:build`\n */\n id: string;\n\n /**\n * The command to run during the Pip\n */\n command: string;\n\n /**\n * The working directory of the Pip\n */\n workingDirectory: string;\n\n /**\n * The project name associated with the Pip\n *\n * @example\n * `@rushstack/node-core-library`\n */\n package: string;\n\n /**\n * The task name of the Pip\n *\n * @example\n * `_phase:build`\n */\n task: string;\n\n /**\n * The IDs of the dependencies of the Pip. These are the {@link IGraphNode.id} properties of other Pips.\n */\n dependencies: string[];\n\n /**\n * If false, the Pip is uncacheable\n */\n cacheable?: false;\n}\n\ninterface IGraphNodeInternal extends Omit<IGraphNode, 'dependencies' | 'command'> {\n dependencies: ReadonlySet<string>;\n command: string | undefined;\n}\n\ntype NodeMap = ReadonlyMap<string, IGraphNodeInternal>;\n\nconst REQUIRED_FIELDS: Array<keyof IGraphNodeInternal> = [\n // command is absent because it is not required\n 'id',\n 'task',\n 'package',\n 'dependencies',\n 'workingDirectory'\n];\n\n/*\n * Get the operation id\n */\nexport function getOperationId(operation: Operation): string {\n const {\n associatedPhase: { name: task },\n associatedProject: { packageName }\n } = operation;\n return `${packageName}#${task}`;\n}\n\nexport class GraphProcessor {\n private readonly _logger: ILogger;\n\n public constructor(logger: ILogger) {\n this._logger = logger;\n }\n\n /*\n * Convert the operationMap into an array of graph nodes with empty commands pruned\n */\n public processOperations(operations: Set<Operation>): IGraphNode[] {\n const nodeMap: Map<string, IGraphNodeInternal> = new Map();\n for (const operation of operations) {\n const entry: IGraphNodeInternal = this._operationAsHashedEntry(operation);\n nodeMap.set(entry.id, entry);\n }\n\n return this._pruneNoOps(nodeMap);\n }\n\n /*\n * Validate that all dependencies exist\n * Validate that all nodes have a non-empty command\n * Print a message to the logger, and return true if the graph is valid\n */\n public validateGraph(entries: readonly Readonly<IGraphNode>[]): boolean {\n const entryIDs: Set<string> = new Set(entries.map((entry) => entry.id));\n let isValid: boolean = true;\n for (const entry of entries) {\n for (const depId of entry.dependencies) {\n if (!entryIDs.has(depId)) {\n this._logger.emitError(new Error(`${entry.id} has a dependency on ${depId} which does not exist`));\n isValid = false;\n }\n }\n\n if (!entry.command) {\n this._logger.emitError(new Error(`There is an empty command in ${entry.id}`));\n isValid = false;\n }\n }\n\n if (isValid) {\n this._logger.terminal.writeLine(\n Colorize.green('All nodes have non-empty commands and dependencies which exist')\n );\n }\n\n const totalEdges: number = entries.reduce((acc, entry) => acc + entry.dependencies.length, 0);\n this._logger.terminal.writeLine(`Graph has ${entries.length} nodes, ${totalEdges} edges`);\n return isValid;\n }\n\n /*\n * remove all entries with empty commands\n * if an entry has a dependency with an empty command, it should inherit the dependencies of the empty command\n */\n private _pruneNoOps(inputNodeMap: NodeMap): IGraphNode[] {\n // Cache for the non-empty upstream dependencies of each operation\n const nonEmptyDependenciesByOperation: Map<IGraphNodeInternal, Set<string>> = new Map();\n function getNonEmptyDependencies(node: IGraphNodeInternal): ReadonlySet<string> {\n // If we've already computed this, return the cached result\n let nonEmptyDependencies: Set<string> | undefined = nonEmptyDependenciesByOperation.get(node);\n if (!nonEmptyDependencies) {\n nonEmptyDependencies = new Set();\n nonEmptyDependenciesByOperation.set(node, nonEmptyDependencies);\n for (const dependencyID of node.dependencies) {\n if (!inputNodeMap.get(dependencyID)!.command) {\n // If the dependency is empty, recursively inherit its non-empty dependencies\n for (const deepDependency of getNonEmptyDependencies(inputNodeMap.get(dependencyID)!)) {\n nonEmptyDependencies.add(deepDependency);\n }\n } else {\n nonEmptyDependencies.add(dependencyID);\n }\n }\n }\n\n return nonEmptyDependencies;\n }\n\n const result: IGraphNode[] = [];\n for (const node of inputNodeMap.values()) {\n const command: string | undefined = node.command;\n if (command) {\n const nonEmptyDependencySet: ReadonlySet<string> = getNonEmptyDependencies(node);\n result.push({\n ...node,\n dependencies: Array.from(nonEmptyDependencySet),\n command: command\n });\n }\n }\n\n return result;\n }\n\n /*\n * Convert an operation into a graph node\n */\n private _operationAsHashedEntry(operation: Operation): IGraphNodeInternal {\n const {\n runner,\n associatedPhase: { name: task },\n associatedProject: {\n // \"package\" is a reserved word\n packageName,\n projectFolder: workingDirectory\n },\n settings,\n dependencies: operationDependencies\n } = operation;\n\n const dependencies: Set<string> = new Set();\n for (const dependency of operationDependencies.values()) {\n const id: string = getOperationId(dependency);\n dependencies.add(id);\n }\n\n const node: Partial<IGraphNodeInternal> = {\n id: getOperationId(operation),\n task,\n package: packageName,\n dependencies,\n workingDirectory,\n command: runner?.getConfigHash()\n };\n\n if (settings?.disableBuildCacheForOperation) {\n node.cacheable = false;\n }\n\n const missingFields: (keyof IGraphNodeInternal)[] = [];\n for (const requiredField of REQUIRED_FIELDS) {\n if (!node[requiredField]) {\n missingFields.push(requiredField);\n }\n }\n\n if (missingFields.length > 0) {\n this._logger.emitError(\n new Error(`Operation is missing required fields ${missingFields.join(', ')}: ${JSON.stringify(node)}`)\n );\n }\n\n // the runner is a no-op if and only if the command is empty\n if (!!runner?.isNoOp !== !node.command) {\n this._logger.emitError(\n new Error(`${node.id}: Operation runner isNoOp does not match commandToRun existence`)\n );\n }\n\n return node as IGraphNodeInternal;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"GraphProcessor.js","sourceRoot":"","sources":["../src/GraphProcessor.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 type { Operation, ILogger } from '@rushstack/rush-sdk';\nimport type { ShellOperationRunner } from '@rushstack/rush-sdk/lib/logic/operations/ShellOperationRunner';\nimport { Colorize } from '@rushstack/terminal';\n\n/**\n * @example\n * ```\n * {\n * \"id\": \"@rushstack/node-core-library#_phase:build\",\n * \"task\": \"_phase:build\",\n * \"package\": \"@rushstack/node-core-library\",\n * \"dependencies\": [\n * \"@rushstack/eslint-patch#_phase:build\",\n * \"@rushstack/eslint-plugin#_phase:build\",\n * \"@rushstack/eslint-plugin-packlets#_phase:build\",\n * \"@rushstack/eslint-plugin-security#_phase:build\"\n * ],\n * \"workingDirectory\": \"/repo/libraries/node-core-library\",\n * \"command\": \"heft run --only build -- --clean --production --drop-graph ./src/examples/graph.json\"\n * }\n * ```\n *\n * See https://github.com/microsoft/BuildXL/blob/adf025c1b96b8106984928df3e9c30c8331bc8d6/Public/Src/Tools/JavaScript/Tool.RushGraphBuilder/src/RushBuildPluginGraph.ts\n *\n * @public\n */\nexport interface IGraphNode {\n /**\n * The unique id of the Pip\n *\n * @example\n * `@rushstack/node-core-library#_phase:build`\n */\n id: string;\n\n /**\n * The command to run during the Pip\n */\n command: string;\n\n /**\n * The working directory of the Pip\n */\n workingDirectory: string;\n\n /**\n * The project name associated with the Pip\n *\n * @example\n * `@rushstack/node-core-library`\n */\n package: string;\n\n /**\n * The task name of the Pip\n *\n * @example\n * `_phase:build`\n */\n task: string;\n\n /**\n * The IDs of the dependencies of the Pip. These are the {@link IGraphNode.id} properties of other Pips.\n */\n dependencies: string[];\n\n /**\n * If false, the Pip is uncacheable\n */\n cacheable?: false;\n}\n\ninterface IGraphNodeInternal extends Omit<IGraphNode, 'dependencies' | 'command'> {\n dependencies: ReadonlySet<string>;\n command: string | undefined;\n}\n\ntype NodeMap = ReadonlyMap<string, IGraphNodeInternal>;\n\nconst REQUIRED_FIELDS: Array<keyof IGraphNodeInternal> = [\n // command is absent because it is not required\n 'id',\n 'task',\n 'package',\n 'dependencies',\n 'workingDirectory'\n];\n\n/*\n * Get the operation id\n */\nexport function getOperationId(operation: Operation): string {\n const {\n associatedPhase: { name: task },\n associatedProject: { packageName }\n } = operation;\n return `${packageName}#${task}`;\n}\n\nexport class GraphProcessor {\n private readonly _logger: ILogger;\n\n public constructor(logger: ILogger) {\n this._logger = logger;\n }\n\n /*\n * Convert the operationMap into an array of graph nodes with empty commands pruned\n */\n public processOperations(operations: Set<Operation>): IGraphNode[] {\n const nodeMap: Map<string, IGraphNodeInternal> = new Map();\n for (const operation of operations) {\n const entry: IGraphNodeInternal = this._operationAsHashedEntry(operation);\n nodeMap.set(entry.id, entry);\n }\n\n return this._pruneNoOps(nodeMap);\n }\n\n /*\n * Validate that all dependencies exist\n * Validate that all nodes have a non-empty command\n * Print a message to the logger, and return true if the graph is valid\n */\n public validateGraph(entries: readonly Readonly<IGraphNode>[]): boolean {\n const entryIDs: Set<string> = new Set(entries.map((entry) => entry.id));\n let isValid: boolean = true;\n for (const entry of entries) {\n for (const depId of entry.dependencies) {\n if (!entryIDs.has(depId)) {\n this._logger.emitError(new Error(`${entry.id} has a dependency on ${depId} which does not exist`));\n isValid = false;\n }\n }\n\n if (!entry.command) {\n this._logger.emitError(new Error(`There is an empty command in ${entry.id}`));\n isValid = false;\n }\n }\n\n if (isValid) {\n this._logger.terminal.writeLine(\n Colorize.green('All nodes have non-empty commands and dependencies which exist')\n );\n }\n\n const totalEdges: number = entries.reduce((acc, entry) => acc + entry.dependencies.length, 0);\n this._logger.terminal.writeLine(`Graph has ${entries.length} nodes, ${totalEdges} edges`);\n return isValid;\n }\n\n /*\n * remove all entries with empty commands\n * if an entry has a dependency with an empty command, it should inherit the dependencies of the empty command\n */\n private _pruneNoOps(inputNodeMap: NodeMap): IGraphNode[] {\n // Cache for the non-empty upstream dependencies of each operation\n const nonEmptyDependenciesByOperation: Map<IGraphNodeInternal, Set<string>> = new Map();\n function getNonEmptyDependencies(node: IGraphNodeInternal): ReadonlySet<string> {\n // If we've already computed this, return the cached result\n let nonEmptyDependencies: Set<string> | undefined = nonEmptyDependenciesByOperation.get(node);\n if (!nonEmptyDependencies) {\n nonEmptyDependencies = new Set();\n nonEmptyDependenciesByOperation.set(node, nonEmptyDependencies);\n for (const dependencyID of node.dependencies) {\n if (!inputNodeMap.get(dependencyID)!.command) {\n // If the dependency is empty, recursively inherit its non-empty dependencies\n for (const deepDependency of getNonEmptyDependencies(inputNodeMap.get(dependencyID)!)) {\n nonEmptyDependencies.add(deepDependency);\n }\n } else {\n nonEmptyDependencies.add(dependencyID);\n }\n }\n }\n\n return nonEmptyDependencies;\n }\n\n const result: IGraphNode[] = [];\n for (const node of inputNodeMap.values()) {\n const command: string | undefined = node.command;\n if (command) {\n const nonEmptyDependencySet: ReadonlySet<string> = getNonEmptyDependencies(node);\n result.push({\n ...node,\n dependencies: Array.from(nonEmptyDependencySet),\n command: command\n });\n }\n }\n\n return result;\n }\n\n /*\n * Convert an operation into a graph node\n */\n private _operationAsHashedEntry(operation: Operation): IGraphNodeInternal {\n const {\n runner,\n associatedPhase: { name: task },\n associatedProject: {\n // \"package\" is a reserved word\n packageName,\n projectFolder: workingDirectory\n },\n settings,\n dependencies: operationDependencies\n } = operation;\n\n const dependencies: Set<string> = new Set();\n for (const dependency of operationDependencies.values()) {\n const id: string = getOperationId(dependency);\n dependencies.add(id);\n }\n\n const node: Partial<IGraphNodeInternal> = {\n id: getOperationId(operation),\n task,\n package: packageName,\n dependencies,\n workingDirectory,\n command: (runner as Partial<Pick<ShellOperationRunner, 'commandToRun'>>)?.commandToRun\n };\n\n if (settings?.disableBuildCacheForOperation) {\n node.cacheable = false;\n }\n\n const missingFields: (keyof IGraphNodeInternal)[] = [];\n for (const requiredField of REQUIRED_FIELDS) {\n if (!node[requiredField]) {\n missingFields.push(requiredField);\n }\n }\n\n if (missingFields.length > 0) {\n this._logger.emitError(\n new Error(`Operation is missing required fields ${missingFields.join(', ')}: ${JSON.stringify(node)}`)\n );\n }\n\n // the runner is a no-op if and only if the command is empty\n if (!!runner?.isNoOp !== !node.command) {\n this._logger.emitError(\n new Error(`${node.id}: Operation runner isNoOp does not match commandToRun existence`)\n );\n }\n\n return node as IGraphNodeInternal;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debugGraphFiltering.js","sourceRoot":"","sources":["../src/debugGraphFiltering.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;
|
|
1
|
+
{"version":3,"file":"debugGraphFiltering.js","sourceRoot":"","sources":["../src/debugGraphFiltering.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 { getOperationId } from './GraphProcessor';\n\nconst BANNED_KEYS: ReadonlySet<string> = new Set([\n 'packageJsonEditor',\n '_packageJson',\n '_subspaces',\n 'subspace',\n 'rushConfiguration',\n '_rushConfiguration',\n 'associatedParameters',\n '_dependencyProjects'\n]);\n\nconst ALLOWED_KEYS: ReadonlySet<string> = new Set([\n 'associatedPhase',\n 'name',\n 'associatedProject',\n 'packageName',\n 'projectFolder',\n 'dependencies',\n 'runner',\n 'commandToRun',\n 'isNoOp'\n]);\n\n/*\n * Filter Rush's build graph to remove repetitive and unimportant information. Useful if the schema ever changes, or needs to.\n * Due to the fact that it includes all properties that are not banned, it is not guaranteed to be stable across versions.\n * Should not be part of the critical path.\n * @param obj - the object to filter\n * @param depth - the maximum depth to recurse\n * @param simplify - if true, will replace embedded operations with their operation id\n */\nexport function filterObjectForDebug(obj: object, depth: number = 10, simplify: boolean = false): object {\n const output: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (BANNED_KEYS.has(key)) {\n output[key] = `${key} truncated`;\n continue;\n } else if (typeof value === 'function') {\n output[key] = `${key}()`;\n continue;\n } else if (value instanceof Set) {\n output[key] = filterObjectForDebug(Array.from(value), Math.min(depth - 1, 5), true);\n continue;\n } else if (value instanceof Object) {\n if (depth <= 0) {\n output[key] = `${key} too deep`;\n continue;\n }\n\n if (simplify) {\n const operationId: string | undefined = getOperationId(value);\n if (operationId) {\n output[key] = operationId;\n continue;\n }\n }\n\n output[key] = filterObjectForDebug(value, depth - 1);\n continue;\n }\n\n output[key] = value;\n }\n\n return output;\n}\n\nexport function filterObjectForTesting(obj: object, depth: number = 10, ignoreSets: boolean = false): object {\n const output: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (!ALLOWED_KEYS.has(key) && !key.match(/^\\d+$/)) {\n continue;\n } else if (value instanceof Set) {\n if (!ignoreSets) {\n // Don't need sets inside sets\n output[key] = Array.from(value).map((subValue) =>\n filterObjectForTesting(subValue, Math.min(depth - 1, 5), true)\n );\n }\n\n continue;\n } else if (value instanceof Object) {\n if (depth <= 0) {\n output[key] = `${key} too deep`;\n continue;\n }\n\n output[key] = filterObjectForTesting(value, depth - 1, ignoreSets);\n continue;\n }\n\n output[key] = value;\n }\n\n return output;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphProcessor.d.ts","sourceRoot":"","sources":["../src/GraphProcessor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"GraphProcessor.d.ts","sourceRoot":"","sources":["../src/GraphProcessor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAI9D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB;AAqBD,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAM3D;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEf,MAAM,EAAE,OAAO;IAO3B,iBAAiB,CAAC,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,UAAU,EAAE;IAe3D,aAAa,CAAC,OAAO,EAAE,SAAS,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,OAAO;IAgCvE,OAAO,CAAC,WAAW;IA2CnB,OAAO,CAAC,uBAAuB;CAsDhC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare function filterObjectForDebug(obj: object, depth?: number, simplify?: boolean):
|
|
2
|
-
export declare function filterObjectForTesting(obj: object, depth?: number, ignoreSets?: boolean):
|
|
1
|
+
export declare function filterObjectForDebug(obj: object, depth?: number, simplify?: boolean): object;
|
|
2
|
+
export declare function filterObjectForTesting(obj: object, depth?: number, ignoreSets?: boolean): object;
|
|
3
3
|
//# sourceMappingURL=debugGraphFiltering.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debugGraphFiltering.d.ts","sourceRoot":"","sources":["../src/debugGraphFiltering.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"debugGraphFiltering.d.ts","sourceRoot":"","sources":["../src/debugGraphFiltering.ts"],"names":[],"mappings":"AAoCA,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,EAAE,QAAQ,GAAE,OAAe,GAAG,MAAM,CAkCvG;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,EAAE,UAAU,GAAE,OAAe,GAAG,MAAM,CA4B3G"}
|
|
@@ -51,7 +51,7 @@ export class DropBuildGraphPlugin {
|
|
|
51
51
|
}
|
|
52
52
|
for (const buildXLCommandName of this._buildXLCommandNames) {
|
|
53
53
|
session.hooks.runPhasedCommand.for(buildXLCommandName).tap(PLUGIN_NAME, (command) => {
|
|
54
|
-
command.hooks.
|
|
54
|
+
command.hooks.createOperations.tapPromise({
|
|
55
55
|
name: PLUGIN_NAME,
|
|
56
56
|
stage: Number.MAX_SAFE_INTEGER // Run this after other plugins have created all operations
|
|
57
57
|
}, async (operations, context) => await handleCreateOperationsForCommandAsync(command.actionName, operations, context));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropBuildGraphPlugin.js","sourceRoot":"","sources":["../src/DropBuildGraphPlugin.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EACL,aAAa,EAOd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,wBAAwB,EAAmC,MAAM,4BAA4B,CAAC;AAIvG,MAAM,WAAW,GAA2B,sBAAsB,CAAC;AAuBnE,MAAM,8BAA8B,GAAmB,cAAc,CAAC;AAEtE;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IAI/B,YAAmB,OAAgC;QAHnC,eAAU,GAAW,WAAW,CAAC;QAI/C,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAC1D,CAAC;IAEM,KAAK,CAAC,OAAoB,EAAE,iBAAoC;QACrE,KAAK,UAAU,qCAAqC,CAClD,WAAmB,EACnB,UAA0B,EAC1B,OAAiC;YAEjC,4GAA4G;YAC5G,YAAY;YACZ,MAAM,kBAAkB,GAA2C,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAC7F,8BAA8B,CACD,CAAC;YAChC,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,4GAA4G;gBAC5G,YAAY;gBACZ,MAAM,IAAI,KAAK,CACb,OAAO,8BAA8B,sCAAsC,aAAa,CAAC,mBAAmB,IAAI;oBAC9G,mCAAmC,WAAW,GAAG,CACpD,CAAC;YACJ,CAAC;iBAAM,IAAI,kBAAkB,CAAC,IAAI,KAAK,wBAAwB,CAAC,MAAM,EAAE,CAAC;gBACvE,MAAM,IAAI,KAAK,CAAC,OAAO,8BAA8B,uCAAuC,CAAC,CAAC;YAChG,CAAC;YAED,MAAM,aAAa,GAAuB,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,KAAK,CAAC;YACpE,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;gBACvD,MAAM,OAAO,GAAY,MAAM,cAAc,CAAC;oBAC5C,UAAU;oBACV,OAAO;oBACP,aAAa;oBACb,iBAAiB;oBACjB,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC;iBACvC,CAAC,CAAC;gBAEH,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;gBAClD,CAAC;qBAAM,CAAC;oBACN,4FAA4F;oBAC5F,OAAO,IAAI,GAAG,EAAE,CAAC;gBACnB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;QAED,KAAK,MAAM,kBAAkB,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC3D,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,OAAuB,EAAE,EAAE;gBAClG,OAAO,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"DropBuildGraphPlugin.js","sourceRoot":"","sources":["../src/DropBuildGraphPlugin.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EACL,aAAa,EAOd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,wBAAwB,EAAmC,MAAM,4BAA4B,CAAC;AAIvG,MAAM,WAAW,GAA2B,sBAAsB,CAAC;AAuBnE,MAAM,8BAA8B,GAAmB,cAAc,CAAC;AAEtE;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IAI/B,YAAmB,OAAgC;QAHnC,eAAU,GAAW,WAAW,CAAC;QAI/C,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAC1D,CAAC;IAEM,KAAK,CAAC,OAAoB,EAAE,iBAAoC;QACrE,KAAK,UAAU,qCAAqC,CAClD,WAAmB,EACnB,UAA0B,EAC1B,OAAiC;YAEjC,4GAA4G;YAC5G,YAAY;YACZ,MAAM,kBAAkB,GAA2C,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAC7F,8BAA8B,CACD,CAAC;YAChC,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,4GAA4G;gBAC5G,YAAY;gBACZ,MAAM,IAAI,KAAK,CACb,OAAO,8BAA8B,sCAAsC,aAAa,CAAC,mBAAmB,IAAI;oBAC9G,mCAAmC,WAAW,GAAG,CACpD,CAAC;YACJ,CAAC;iBAAM,IAAI,kBAAkB,CAAC,IAAI,KAAK,wBAAwB,CAAC,MAAM,EAAE,CAAC;gBACvE,MAAM,IAAI,KAAK,CAAC,OAAO,8BAA8B,uCAAuC,CAAC,CAAC;YAChG,CAAC;YAED,MAAM,aAAa,GAAuB,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,KAAK,CAAC;YACpE,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;gBACvD,MAAM,OAAO,GAAY,MAAM,cAAc,CAAC;oBAC5C,UAAU;oBACV,OAAO;oBACP,aAAa;oBACb,iBAAiB;oBACjB,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC;iBACvC,CAAC,CAAC;gBAEH,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;gBAClD,CAAC;qBAAM,CAAC;oBACN,4FAA4F;oBAC5F,OAAO,IAAI,GAAG,EAAE,CAAC;gBACnB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;QAED,KAAK,MAAM,kBAAkB,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC3D,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,OAAuB,EAAE,EAAE;gBAClG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,UAAU,CACvC;oBACE,IAAI,EAAE,WAAW;oBACjB,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,2DAA2D;iBAC3F,EACD,KAAK,EAAE,UAA0B,EAAE,OAAiC,EAAE,EAAE,CACtE,MAAM,qCAAqC,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CACvF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;IACH,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 {\n RushConstants,\n type ICreateOperationsContext,\n type IPhasedCommand,\n type IRushPlugin,\n type Operation,\n type RushConfiguration,\n type RushSession\n} from '@rushstack/rush-sdk';\nimport { CommandLineParameterKind, type CommandLineStringParameter } from '@rushstack/ts-command-line';\n\nimport type { IGraphNode } from './GraphProcessor';\n\nconst PLUGIN_NAME: 'DropBuildGraphPlugin' = 'DropBuildGraphPlugin';\n\n/**\n * This is the type that represents the schema of the drop file\n * @public\n */\nexport interface IBuildXLRushGraph {\n nodes: IGraphNode[];\n repoSettings: {\n commonTempFolder: string;\n };\n}\n\n/**\n * @public\n */\nexport interface IDropGraphPluginOptions {\n /**\n * The names of the commands that will be used to run BuildXL\n */\n buildXLCommandNames: string[];\n}\n\nconst DROP_GRAPH_PARAMETER_LONG_NAME: '--drop-graph' = '--drop-graph';\n\n/**\n * This plugin is used to drop the build graph to a file for BuildXL to consume.\n * @public\n */\nexport class DropBuildGraphPlugin implements IRushPlugin {\n public readonly pluginName: string = PLUGIN_NAME;\n private readonly _buildXLCommandNames: string[];\n\n public constructor(options: IDropGraphPluginOptions) {\n this._buildXLCommandNames = options.buildXLCommandNames;\n }\n\n public apply(session: RushSession, rushConfiguration: RushConfiguration): void {\n async function handleCreateOperationsForCommandAsync(\n commandName: string,\n operations: Set<Operation>,\n context: ICreateOperationsContext\n ): Promise<Set<Operation>> {\n // TODO: Introduce an API to allow plugins to register command line options for arbitrary, existing commands\n // in a repo\n const dropGraphParameter: CommandLineStringParameter | undefined = context.customParameters.get(\n DROP_GRAPH_PARAMETER_LONG_NAME\n ) as CommandLineStringParameter;\n if (!dropGraphParameter) {\n // TODO: Introduce an API to allow plugins to register command line options for arbitrary, existing commands\n // in a repo\n throw new Error(\n `The ${DROP_GRAPH_PARAMETER_LONG_NAME} parameter needs to be defined in \"${RushConstants.commandLineFilename}\" ` +\n `and associated with the action \"${commandName}\"`\n );\n } else if (dropGraphParameter.kind !== CommandLineParameterKind.String) {\n throw new Error(`The ${DROP_GRAPH_PARAMETER_LONG_NAME} parameter must be a string parameter`);\n }\n\n const dropGraphPath: string | undefined = dropGraphParameter?.value;\n if (dropGraphPath) {\n const { dropGraphAsync } = await import('./dropGraph');\n const isValid: boolean = await dropGraphAsync({\n operations,\n context,\n dropGraphPath,\n rushConfiguration,\n logger: session.getLogger(PLUGIN_NAME)\n });\n\n if (!isValid) {\n throw new Error('Failed to validate the graph');\n } else {\n // If the --drop-graph flag is present, we want to exit the process after dropping the graph\n return new Set();\n }\n } else {\n return operations;\n }\n }\n\n for (const buildXLCommandName of this._buildXLCommandNames) {\n session.hooks.runPhasedCommand.for(buildXLCommandName).tap(PLUGIN_NAME, (command: IPhasedCommand) => {\n command.hooks.createOperations.tapPromise(\n {\n name: PLUGIN_NAME,\n stage: Number.MAX_SAFE_INTEGER // Run this after other plugins have created all operations\n },\n async (operations: Set<Operation>, context: ICreateOperationsContext) =>\n await handleCreateOperationsForCommandAsync(command.actionName, operations, context)\n );\n });\n }\n }\n}\n"]}
|
|
@@ -117,7 +117,7 @@ export class GraphProcessor {
|
|
|
117
117
|
package: packageName,
|
|
118
118
|
dependencies,
|
|
119
119
|
workingDirectory,
|
|
120
|
-
command: runner === null || runner === void 0 ? void 0 : runner.
|
|
120
|
+
command: runner === null || runner === void 0 ? void 0 : runner.commandToRun
|
|
121
121
|
};
|
|
122
122
|
if (settings === null || settings === void 0 ? void 0 : settings.disableBuildCacheForOperation) {
|
|
123
123
|
node.cacheable = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphProcessor.js","sourceRoot":"","sources":["../src/GraphProcessor.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAG3D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AA6E/C,MAAM,eAAe,GAAoC;IACvD,+CAA+C;IAC/C,IAAI;IACJ,MAAM;IACN,SAAS;IACT,cAAc;IACd,kBAAkB;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,SAAoB;IACjD,MAAM,EACJ,eAAe,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAC/B,iBAAiB,EAAE,EAAE,WAAW,EAAE,EACnC,GAAG,SAAS,CAAC;IACd,OAAO,GAAG,WAAW,IAAI,IAAI,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,OAAO,cAAc;IAGzB,YAAmB,MAAe;QAChC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED;;OAEG;IACI,iBAAiB,CAAC,UAA0B;QACjD,MAAM,OAAO,GAAoC,IAAI,GAAG,EAAE,CAAC;QAC3D,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,KAAK,GAAuB,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;YAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC;QAED,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACI,aAAa,CAAC,OAAwC;QAC3D,MAAM,QAAQ,GAAgB,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACxE,IAAI,OAAO,GAAY,IAAI,CAAC;QAC5B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBACvC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBACzB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,EAAE,wBAAwB,KAAK,uBAAuB,CAAC,CAAC,CAAC;oBACnG,OAAO,GAAG,KAAK,CAAC;gBAClB,CAAC;YACH,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBACnB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;gBAC9E,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC;QACH,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAC7B,QAAQ,CAAC,KAAK,CAAC,gEAAgE,CAAC,CACjF,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAW,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC9F,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,aAAa,OAAO,CAAC,MAAM,WAAW,UAAU,QAAQ,CAAC,CAAC;QAC1F,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACK,WAAW,CAAC,YAAqB;QACvC,kEAAkE;QAClE,MAAM,+BAA+B,GAAyC,IAAI,GAAG,EAAE,CAAC;QACxF,SAAS,uBAAuB,CAAC,IAAwB;YACvD,2DAA2D;YAC3D,IAAI,oBAAoB,GAA4B,+BAA+B,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9F,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBAC1B,oBAAoB,GAAG,IAAI,GAAG,EAAE,CAAC;gBACjC,+BAA+B,CAAC,GAAG,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;gBAChE,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;oBAC7C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAE,CAAC,OAAO,EAAE,CAAC;wBAC7C,6EAA6E;wBAC7E,KAAK,MAAM,cAAc,IAAI,uBAAuB,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAE,CAAC,EAAE,CAAC;4BACtF,oBAAoB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;wBAC3C,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;oBACzC,CAAC;gBACH,CAAC;YACH,CAAC;YAED,OAAO,oBAAoB,CAAC;QAC9B,CAAC;QAED,MAAM,MAAM,GAAiB,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,MAAM,OAAO,GAAuB,IAAI,CAAC,OAAO,CAAC;YACjD,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,qBAAqB,GAAwB,uBAAuB,CAAC,IAAI,CAAC,CAAC;gBACjF,MAAM,CAAC,IAAI,CAAC;oBACV,GAAG,IAAI;oBACP,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC;oBAC/C,OAAO,EAAE,OAAO;iBACjB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,uBAAuB,CAAC,SAAoB;QAClD,MAAM,EACJ,MAAM,EACN,eAAe,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAC/B,iBAAiB,EAAE;QACjB,+BAA+B;QAC/B,WAAW,EACX,aAAa,EAAE,gBAAgB,EAChC,EACD,QAAQ,EACR,YAAY,EAAE,qBAAqB,EACpC,GAAG,SAAS,CAAC;QAEd,MAAM,YAAY,GAAgB,IAAI,GAAG,EAAE,CAAC;QAC5C,KAAK,MAAM,UAAU,IAAI,qBAAqB,CAAC,MAAM,EAAE,EAAE,CAAC;YACxD,MAAM,EAAE,GAAW,cAAc,CAAC,UAAU,CAAC,CAAC;YAC9C,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvB,CAAC;QAED,MAAM,IAAI,GAAgC;YACxC,EAAE,EAAE,cAAc,CAAC,SAAS,CAAC;YAC7B,IAAI;YACJ,OAAO,EAAE,WAAW;YACpB,YAAY;YACZ,gBAAgB;YAChB,OAAO,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,aAAa,EAAE;SACjC,CAAC;QAEF,IAAI,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,6BAA6B,EAAE,CAAC;YAC5C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACzB,CAAC;QAED,MAAM,aAAa,GAAiC,EAAE,CAAC;QACvD,KAAK,MAAM,aAAa,IAAI,eAAe,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;gBACzB,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,CAAC,SAAS,CACpB,IAAI,KAAK,CAAC,wCAAwC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CACvG,CAAC;QACJ,CAAC;QAED,4DAA4D;QAC5D,IAAI,CAAC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,SAAS,CACpB,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,EAAE,iEAAiE,CAAC,CACvF,CAAC;QACJ,CAAC;QAED,OAAO,IAA0B,CAAC;IACpC,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 type { Operation, ILogger } from '@rushstack/rush-sdk';\nimport { Colorize } from '@rushstack/terminal';\n\n/**\n * @example\n * ```\n * {\n * \"id\": \"@rushstack/node-core-library#_phase:build\",\n * \"task\": \"_phase:build\",\n * \"package\": \"@rushstack/node-core-library\",\n * \"dependencies\": [\n * \"@rushstack/eslint-patch#_phase:build\",\n * \"@rushstack/eslint-plugin#_phase:build\",\n * \"@rushstack/eslint-plugin-packlets#_phase:build\",\n * \"@rushstack/eslint-plugin-security#_phase:build\"\n * ],\n * \"workingDirectory\": \"/repo/libraries/node-core-library\",\n * \"command\": \"heft run --only build -- --clean --production --drop-graph ./src/examples/graph.json\"\n * }\n * ```\n *\n * See https://github.com/microsoft/BuildXL/blob/adf025c1b96b8106984928df3e9c30c8331bc8d6/Public/Src/Tools/JavaScript/Tool.RushGraphBuilder/src/RushBuildPluginGraph.ts\n *\n * @public\n */\nexport interface IGraphNode {\n /**\n * The unique id of the Pip\n *\n * @example\n * `@rushstack/node-core-library#_phase:build`\n */\n id: string;\n\n /**\n * The command to run during the Pip\n */\n command: string;\n\n /**\n * The working directory of the Pip\n */\n workingDirectory: string;\n\n /**\n * The project name associated with the Pip\n *\n * @example\n * `@rushstack/node-core-library`\n */\n package: string;\n\n /**\n * The task name of the Pip\n *\n * @example\n * `_phase:build`\n */\n task: string;\n\n /**\n * The IDs of the dependencies of the Pip. These are the {@link IGraphNode.id} properties of other Pips.\n */\n dependencies: string[];\n\n /**\n * If false, the Pip is uncacheable\n */\n cacheable?: false;\n}\n\ninterface IGraphNodeInternal extends Omit<IGraphNode, 'dependencies' | 'command'> {\n dependencies: ReadonlySet<string>;\n command: string | undefined;\n}\n\ntype NodeMap = ReadonlyMap<string, IGraphNodeInternal>;\n\nconst REQUIRED_FIELDS: Array<keyof IGraphNodeInternal> = [\n // command is absent because it is not required\n 'id',\n 'task',\n 'package',\n 'dependencies',\n 'workingDirectory'\n];\n\n/*\n * Get the operation id\n */\nexport function getOperationId(operation: Operation): string {\n const {\n associatedPhase: { name: task },\n associatedProject: { packageName }\n } = operation;\n return `${packageName}#${task}`;\n}\n\nexport class GraphProcessor {\n private readonly _logger: ILogger;\n\n public constructor(logger: ILogger) {\n this._logger = logger;\n }\n\n /*\n * Convert the operationMap into an array of graph nodes with empty commands pruned\n */\n public processOperations(operations: Set<Operation>): IGraphNode[] {\n const nodeMap: Map<string, IGraphNodeInternal> = new Map();\n for (const operation of operations) {\n const entry: IGraphNodeInternal = this._operationAsHashedEntry(operation);\n nodeMap.set(entry.id, entry);\n }\n\n return this._pruneNoOps(nodeMap);\n }\n\n /*\n * Validate that all dependencies exist\n * Validate that all nodes have a non-empty command\n * Print a message to the logger, and return true if the graph is valid\n */\n public validateGraph(entries: readonly Readonly<IGraphNode>[]): boolean {\n const entryIDs: Set<string> = new Set(entries.map((entry) => entry.id));\n let isValid: boolean = true;\n for (const entry of entries) {\n for (const depId of entry.dependencies) {\n if (!entryIDs.has(depId)) {\n this._logger.emitError(new Error(`${entry.id} has a dependency on ${depId} which does not exist`));\n isValid = false;\n }\n }\n\n if (!entry.command) {\n this._logger.emitError(new Error(`There is an empty command in ${entry.id}`));\n isValid = false;\n }\n }\n\n if (isValid) {\n this._logger.terminal.writeLine(\n Colorize.green('All nodes have non-empty commands and dependencies which exist')\n );\n }\n\n const totalEdges: number = entries.reduce((acc, entry) => acc + entry.dependencies.length, 0);\n this._logger.terminal.writeLine(`Graph has ${entries.length} nodes, ${totalEdges} edges`);\n return isValid;\n }\n\n /*\n * remove all entries with empty commands\n * if an entry has a dependency with an empty command, it should inherit the dependencies of the empty command\n */\n private _pruneNoOps(inputNodeMap: NodeMap): IGraphNode[] {\n // Cache for the non-empty upstream dependencies of each operation\n const nonEmptyDependenciesByOperation: Map<IGraphNodeInternal, Set<string>> = new Map();\n function getNonEmptyDependencies(node: IGraphNodeInternal): ReadonlySet<string> {\n // If we've already computed this, return the cached result\n let nonEmptyDependencies: Set<string> | undefined = nonEmptyDependenciesByOperation.get(node);\n if (!nonEmptyDependencies) {\n nonEmptyDependencies = new Set();\n nonEmptyDependenciesByOperation.set(node, nonEmptyDependencies);\n for (const dependencyID of node.dependencies) {\n if (!inputNodeMap.get(dependencyID)!.command) {\n // If the dependency is empty, recursively inherit its non-empty dependencies\n for (const deepDependency of getNonEmptyDependencies(inputNodeMap.get(dependencyID)!)) {\n nonEmptyDependencies.add(deepDependency);\n }\n } else {\n nonEmptyDependencies.add(dependencyID);\n }\n }\n }\n\n return nonEmptyDependencies;\n }\n\n const result: IGraphNode[] = [];\n for (const node of inputNodeMap.values()) {\n const command: string | undefined = node.command;\n if (command) {\n const nonEmptyDependencySet: ReadonlySet<string> = getNonEmptyDependencies(node);\n result.push({\n ...node,\n dependencies: Array.from(nonEmptyDependencySet),\n command: command\n });\n }\n }\n\n return result;\n }\n\n /*\n * Convert an operation into a graph node\n */\n private _operationAsHashedEntry(operation: Operation): IGraphNodeInternal {\n const {\n runner,\n associatedPhase: { name: task },\n associatedProject: {\n // \"package\" is a reserved word\n packageName,\n projectFolder: workingDirectory\n },\n settings,\n dependencies: operationDependencies\n } = operation;\n\n const dependencies: Set<string> = new Set();\n for (const dependency of operationDependencies.values()) {\n const id: string = getOperationId(dependency);\n dependencies.add(id);\n }\n\n const node: Partial<IGraphNodeInternal> = {\n id: getOperationId(operation),\n task,\n package: packageName,\n dependencies,\n workingDirectory,\n command: runner?.getConfigHash()\n };\n\n if (settings?.disableBuildCacheForOperation) {\n node.cacheable = false;\n }\n\n const missingFields: (keyof IGraphNodeInternal)[] = [];\n for (const requiredField of REQUIRED_FIELDS) {\n if (!node[requiredField]) {\n missingFields.push(requiredField);\n }\n }\n\n if (missingFields.length > 0) {\n this._logger.emitError(\n new Error(`Operation is missing required fields ${missingFields.join(', ')}: ${JSON.stringify(node)}`)\n );\n }\n\n // the runner is a no-op if and only if the command is empty\n if (!!runner?.isNoOp !== !node.command) {\n this._logger.emitError(\n new Error(`${node.id}: Operation runner isNoOp does not match commandToRun existence`)\n );\n }\n\n return node as IGraphNodeInternal;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"GraphProcessor.js","sourceRoot":"","sources":["../src/GraphProcessor.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 type { Operation, ILogger } from '@rushstack/rush-sdk';\nimport type { ShellOperationRunner } from '@rushstack/rush-sdk/lib/logic/operations/ShellOperationRunner';\nimport { Colorize } from '@rushstack/terminal';\n\n/**\n * @example\n * ```\n * {\n * \"id\": \"@rushstack/node-core-library#_phase:build\",\n * \"task\": \"_phase:build\",\n * \"package\": \"@rushstack/node-core-library\",\n * \"dependencies\": [\n * \"@rushstack/eslint-patch#_phase:build\",\n * \"@rushstack/eslint-plugin#_phase:build\",\n * \"@rushstack/eslint-plugin-packlets#_phase:build\",\n * \"@rushstack/eslint-plugin-security#_phase:build\"\n * ],\n * \"workingDirectory\": \"/repo/libraries/node-core-library\",\n * \"command\": \"heft run --only build -- --clean --production --drop-graph ./src/examples/graph.json\"\n * }\n * ```\n *\n * See https://github.com/microsoft/BuildXL/blob/adf025c1b96b8106984928df3e9c30c8331bc8d6/Public/Src/Tools/JavaScript/Tool.RushGraphBuilder/src/RushBuildPluginGraph.ts\n *\n * @public\n */\nexport interface IGraphNode {\n /**\n * The unique id of the Pip\n *\n * @example\n * `@rushstack/node-core-library#_phase:build`\n */\n id: string;\n\n /**\n * The command to run during the Pip\n */\n command: string;\n\n /**\n * The working directory of the Pip\n */\n workingDirectory: string;\n\n /**\n * The project name associated with the Pip\n *\n * @example\n * `@rushstack/node-core-library`\n */\n package: string;\n\n /**\n * The task name of the Pip\n *\n * @example\n * `_phase:build`\n */\n task: string;\n\n /**\n * The IDs of the dependencies of the Pip. These are the {@link IGraphNode.id} properties of other Pips.\n */\n dependencies: string[];\n\n /**\n * If false, the Pip is uncacheable\n */\n cacheable?: false;\n}\n\ninterface IGraphNodeInternal extends Omit<IGraphNode, 'dependencies' | 'command'> {\n dependencies: ReadonlySet<string>;\n command: string | undefined;\n}\n\ntype NodeMap = ReadonlyMap<string, IGraphNodeInternal>;\n\nconst REQUIRED_FIELDS: Array<keyof IGraphNodeInternal> = [\n // command is absent because it is not required\n 'id',\n 'task',\n 'package',\n 'dependencies',\n 'workingDirectory'\n];\n\n/*\n * Get the operation id\n */\nexport function getOperationId(operation: Operation): string {\n const {\n associatedPhase: { name: task },\n associatedProject: { packageName }\n } = operation;\n return `${packageName}#${task}`;\n}\n\nexport class GraphProcessor {\n private readonly _logger: ILogger;\n\n public constructor(logger: ILogger) {\n this._logger = logger;\n }\n\n /*\n * Convert the operationMap into an array of graph nodes with empty commands pruned\n */\n public processOperations(operations: Set<Operation>): IGraphNode[] {\n const nodeMap: Map<string, IGraphNodeInternal> = new Map();\n for (const operation of operations) {\n const entry: IGraphNodeInternal = this._operationAsHashedEntry(operation);\n nodeMap.set(entry.id, entry);\n }\n\n return this._pruneNoOps(nodeMap);\n }\n\n /*\n * Validate that all dependencies exist\n * Validate that all nodes have a non-empty command\n * Print a message to the logger, and return true if the graph is valid\n */\n public validateGraph(entries: readonly Readonly<IGraphNode>[]): boolean {\n const entryIDs: Set<string> = new Set(entries.map((entry) => entry.id));\n let isValid: boolean = true;\n for (const entry of entries) {\n for (const depId of entry.dependencies) {\n if (!entryIDs.has(depId)) {\n this._logger.emitError(new Error(`${entry.id} has a dependency on ${depId} which does not exist`));\n isValid = false;\n }\n }\n\n if (!entry.command) {\n this._logger.emitError(new Error(`There is an empty command in ${entry.id}`));\n isValid = false;\n }\n }\n\n if (isValid) {\n this._logger.terminal.writeLine(\n Colorize.green('All nodes have non-empty commands and dependencies which exist')\n );\n }\n\n const totalEdges: number = entries.reduce((acc, entry) => acc + entry.dependencies.length, 0);\n this._logger.terminal.writeLine(`Graph has ${entries.length} nodes, ${totalEdges} edges`);\n return isValid;\n }\n\n /*\n * remove all entries with empty commands\n * if an entry has a dependency with an empty command, it should inherit the dependencies of the empty command\n */\n private _pruneNoOps(inputNodeMap: NodeMap): IGraphNode[] {\n // Cache for the non-empty upstream dependencies of each operation\n const nonEmptyDependenciesByOperation: Map<IGraphNodeInternal, Set<string>> = new Map();\n function getNonEmptyDependencies(node: IGraphNodeInternal): ReadonlySet<string> {\n // If we've already computed this, return the cached result\n let nonEmptyDependencies: Set<string> | undefined = nonEmptyDependenciesByOperation.get(node);\n if (!nonEmptyDependencies) {\n nonEmptyDependencies = new Set();\n nonEmptyDependenciesByOperation.set(node, nonEmptyDependencies);\n for (const dependencyID of node.dependencies) {\n if (!inputNodeMap.get(dependencyID)!.command) {\n // If the dependency is empty, recursively inherit its non-empty dependencies\n for (const deepDependency of getNonEmptyDependencies(inputNodeMap.get(dependencyID)!)) {\n nonEmptyDependencies.add(deepDependency);\n }\n } else {\n nonEmptyDependencies.add(dependencyID);\n }\n }\n }\n\n return nonEmptyDependencies;\n }\n\n const result: IGraphNode[] = [];\n for (const node of inputNodeMap.values()) {\n const command: string | undefined = node.command;\n if (command) {\n const nonEmptyDependencySet: ReadonlySet<string> = getNonEmptyDependencies(node);\n result.push({\n ...node,\n dependencies: Array.from(nonEmptyDependencySet),\n command: command\n });\n }\n }\n\n return result;\n }\n\n /*\n * Convert an operation into a graph node\n */\n private _operationAsHashedEntry(operation: Operation): IGraphNodeInternal {\n const {\n runner,\n associatedPhase: { name: task },\n associatedProject: {\n // \"package\" is a reserved word\n packageName,\n projectFolder: workingDirectory\n },\n settings,\n dependencies: operationDependencies\n } = operation;\n\n const dependencies: Set<string> = new Set();\n for (const dependency of operationDependencies.values()) {\n const id: string = getOperationId(dependency);\n dependencies.add(id);\n }\n\n const node: Partial<IGraphNodeInternal> = {\n id: getOperationId(operation),\n task,\n package: packageName,\n dependencies,\n workingDirectory,\n command: (runner as Partial<Pick<ShellOperationRunner, 'commandToRun'>>)?.commandToRun\n };\n\n if (settings?.disableBuildCacheForOperation) {\n node.cacheable = false;\n }\n\n const missingFields: (keyof IGraphNodeInternal)[] = [];\n for (const requiredField of REQUIRED_FIELDS) {\n if (!node[requiredField]) {\n missingFields.push(requiredField);\n }\n }\n\n if (missingFields.length > 0) {\n this._logger.emitError(\n new Error(`Operation is missing required fields ${missingFields.join(', ')}: ${JSON.stringify(node)}`)\n );\n }\n\n // the runner is a no-op if and only if the command is empty\n if (!!runner?.isNoOp !== !node.command) {\n this._logger.emitError(\n new Error(`${node.id}: Operation runner isNoOp does not match commandToRun existence`)\n );\n }\n\n return node as IGraphNodeInternal;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debugGraphFiltering.js","sourceRoot":"","sources":["../src/debugGraphFiltering.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC;IAC/C,mBAAmB;IACnB,cAAc;IACd,YAAY;IACZ,UAAU;IACV,mBAAmB;IACnB,oBAAoB;IACpB,sBAAsB;IACtB,qBAAqB;CACtB,CAAC,CAAC;AAEH,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC;IAChD,iBAAiB;IACjB,MAAM;IACN,mBAAmB;IACnB,aAAa;IACb,eAAe;IACf,cAAc;IACd,QAAQ;IACR,QAAQ;CACT,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,
|
|
1
|
+
{"version":3,"file":"debugGraphFiltering.js","sourceRoot":"","sources":["../src/debugGraphFiltering.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 { getOperationId } from './GraphProcessor';\n\nconst BANNED_KEYS: ReadonlySet<string> = new Set([\n 'packageJsonEditor',\n '_packageJson',\n '_subspaces',\n 'subspace',\n 'rushConfiguration',\n '_rushConfiguration',\n 'associatedParameters',\n '_dependencyProjects'\n]);\n\nconst ALLOWED_KEYS: ReadonlySet<string> = new Set([\n 'associatedPhase',\n 'name',\n 'associatedProject',\n 'packageName',\n 'projectFolder',\n 'dependencies',\n 'runner',\n 'commandToRun',\n 'isNoOp'\n]);\n\n/*\n * Filter Rush's build graph to remove repetitive and unimportant information. Useful if the schema ever changes, or needs to.\n * Due to the fact that it includes all properties that are not banned, it is not guaranteed to be stable across versions.\n * Should not be part of the critical path.\n * @param obj - the object to filter\n * @param depth - the maximum depth to recurse\n * @param simplify - if true, will replace embedded operations with their operation id\n */\nexport function filterObjectForDebug(obj: object, depth: number = 10, simplify: boolean = false): object {\n const output: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (BANNED_KEYS.has(key)) {\n output[key] = `${key} truncated`;\n continue;\n } else if (typeof value === 'function') {\n output[key] = `${key}()`;\n continue;\n } else if (value instanceof Set) {\n output[key] = filterObjectForDebug(Array.from(value), Math.min(depth - 1, 5), true);\n continue;\n } else if (value instanceof Object) {\n if (depth <= 0) {\n output[key] = `${key} too deep`;\n continue;\n }\n\n if (simplify) {\n const operationId: string | undefined = getOperationId(value);\n if (operationId) {\n output[key] = operationId;\n continue;\n }\n }\n\n output[key] = filterObjectForDebug(value, depth - 1);\n continue;\n }\n\n output[key] = value;\n }\n\n return output;\n}\n\nexport function filterObjectForTesting(obj: object, depth: number = 10, ignoreSets: boolean = false): object {\n const output: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (!ALLOWED_KEYS.has(key) && !key.match(/^\\d+$/)) {\n continue;\n } else if (value instanceof Set) {\n if (!ignoreSets) {\n // Don't need sets inside sets\n output[key] = Array.from(value).map((subValue) =>\n filterObjectForTesting(subValue, Math.min(depth - 1, 5), true)\n );\n }\n\n continue;\n } else if (value instanceof Object) {\n if (depth <= 0) {\n output[key] = `${key} too deep`;\n continue;\n }\n\n output[key] = filterObjectForTesting(value, depth - 1, ignoreSets);\n continue;\n }\n\n output[key] = value;\n }\n\n return output;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rushstack/rush-buildxl-graph-plugin",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.171.0",
|
|
4
4
|
"description": "Rush plugin for generating a BuildXL graph.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
"license": "MIT",
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@rushstack/node-core-library": "5.20.3",
|
|
41
|
-
"@rushstack/
|
|
41
|
+
"@rushstack/rush-sdk": "5.171.0",
|
|
42
42
|
"@rushstack/ts-command-line": "5.3.3",
|
|
43
|
-
"@rushstack/
|
|
43
|
+
"@rushstack/terminal": "0.22.3"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"eslint": "~9.37.0",
|
|
47
|
-
"@microsoft/rush-lib": "5.
|
|
47
|
+
"@microsoft/rush-lib": "5.171.0",
|
|
48
48
|
"@rushstack/heft": "1.2.7",
|
|
49
49
|
"local-node-rig": "1.0.0"
|
|
50
50
|
},
|