nx 21.0.0-beta.10 → 21.0.0-beta.11
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/migrations.json +10 -0
- package/package.json +11 -11
- package/schemas/nx-schema.json +5 -0
- package/src/adapter/angular-json.js +11 -0
- package/src/command-line/migrate/migrate-ui-api.js +1 -1
- package/src/command-line/migrate/migrate.d.ts +12 -6
- package/src/command-line/migrate/migrate.js +31 -9
- package/src/command-line/repair/repair.js +8 -2
- package/src/command-line/report/report.js +1 -1
- package/src/config/misc-interfaces.d.ts +9 -1
- package/src/config/nx-json.d.ts +0 -4
- package/src/core/graph/main.js +1 -1
- package/src/devkit-exports.d.ts +1 -1
- package/src/migrations/update-21-0-0/remove-custom-tasks-runner.d.ts +2 -0
- package/src/migrations/update-21-0-0/remove-custom-tasks-runner.js +38 -0
- package/src/migrations/update-21-0-0/remove-legacy-cache.d.ts +2 -0
- package/src/migrations/update-21-0-0/remove-legacy-cache.js +17 -0
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/plugins/js/index.d.ts +2 -1
- package/src/plugins/js/index.js +8 -1
- package/src/project-graph/plugins/loaded-nx-plugin.js +1 -5
- package/src/tasks-runner/batch/run-batch.js +1 -1
- package/src/tasks-runner/cache.d.ts +1 -2
- package/src/tasks-runner/cache.js +2 -18
- package/src/tasks-runner/life-cycles/tui-summary-life-cycle.js +8 -7
- package/src/tasks-runner/pseudo-terminal.d.ts +1 -0
- package/src/tasks-runner/pseudo-terminal.js +11 -1
- package/src/tasks-runner/run-command.js +2 -24
- package/src/tasks-runner/task-graph-utils.d.ts +3 -0
- package/src/tasks-runner/task-graph-utils.js +31 -2
- package/src/tasks-runner/task-orchestrator.js +10 -1
package/src/devkit-exports.d.ts
CHANGED
@@ -13,7 +13,7 @@ export type { WorkspaceJsonConfiguration, ProjectsConfigurations, TargetDependen
|
|
13
13
|
/**
|
14
14
|
* @category Workspace
|
15
15
|
*/
|
16
|
-
export type { Generator, GeneratorCallback, PromiseExecutor, AsyncIteratorExecutor, Executor, ExecutorContext, TaskGraphExecutor, GeneratorsJson, ExecutorsJson, MigrationsJson, CustomHasher, HasherContext, } from './config/misc-interfaces';
|
16
|
+
export type { Generator, Migration, GeneratorCallback, PromiseExecutor, AsyncIteratorExecutor, Executor, ExecutorContext, TaskGraphExecutor, GeneratorsJson, ExecutorsJson, MigrationsJson, CustomHasher, HasherContext, } from './config/misc-interfaces';
|
17
17
|
export { workspaceLayout } from './config/configuration';
|
18
18
|
export type { NxPlugin, NxPluginV2, CreateNodes, CreateNodesFunction, CreateNodesResult, CreateNodesContext, CreateNodesContextV2, CreateNodesFunctionV2, CreateNodesResultV2, CreateNodesV2, CreateDependencies, CreateDependenciesContext, CreateMetadata, CreateMetadataContext, ProjectsMetadata, PreTasksExecution, PreTasksExecutionContext, PostTasksExecution, PostTasksExecutionContext, } from './project-graph/plugins';
|
19
19
|
export { AggregateCreateNodesError, StaleProjectGraphCacheError, } from './project-graph/error-types';
|
@@ -0,0 +1,38 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.default = update;
|
4
|
+
const format_changed_files_with_prettier_if_available_1 = require("../../generators/internal-utils/format-changed-files-with-prettier-if-available");
|
5
|
+
const nx_json_1 = require("../../generators/utils/nx-json");
|
6
|
+
function isCustomRunnerPath(modulePath) {
|
7
|
+
return !['nx-cloud', '@nrwl/nx-cloud', 'nx/tasks-runners/default'].includes(modulePath);
|
8
|
+
}
|
9
|
+
async function update(tree) {
|
10
|
+
const nxJson = (0, nx_json_1.readNxJson)(tree);
|
11
|
+
if (!nxJson?.tasksRunnerOptions) {
|
12
|
+
return;
|
13
|
+
}
|
14
|
+
const nextSteps = [];
|
15
|
+
for (const key in nxJson.tasksRunnerOptions) {
|
16
|
+
const runner = nxJson.tasksRunnerOptions[key].runner;
|
17
|
+
if (runner && isCustomRunnerPath(runner)) {
|
18
|
+
let nextStepText = 'Nx 21 removed support for custom task runners. For more information, please check: ';
|
19
|
+
if (runner === '@nx-aws-cache/nx-aws-cache') {
|
20
|
+
nextStepText +=
|
21
|
+
'https://nx.dev/deprecated/custom-tasks-runner#migrating-from-nxawsplugin';
|
22
|
+
}
|
23
|
+
else {
|
24
|
+
nextStepText += 'https://nx.dev/deprecated/custom-tasks-runner';
|
25
|
+
}
|
26
|
+
if (nextSteps.length === 0) {
|
27
|
+
nextSteps.push(nextStepText);
|
28
|
+
}
|
29
|
+
delete nxJson.tasksRunnerOptions[key];
|
30
|
+
}
|
31
|
+
}
|
32
|
+
if (Object.keys(nxJson.tasksRunnerOptions).length === 0) {
|
33
|
+
delete nxJson.tasksRunnerOptions;
|
34
|
+
}
|
35
|
+
(0, nx_json_1.updateNxJson)(tree, nxJson);
|
36
|
+
await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree);
|
37
|
+
return nextSteps;
|
38
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.default = update;
|
4
|
+
const format_changed_files_with_prettier_if_available_1 = require("../../generators/internal-utils/format-changed-files-with-prettier-if-available");
|
5
|
+
const nx_json_1 = require("../../generators/utils/nx-json");
|
6
|
+
async function update(tree) {
|
7
|
+
const nxJson = (0, nx_json_1.readNxJson)(tree);
|
8
|
+
if (!nxJson) {
|
9
|
+
return;
|
10
|
+
}
|
11
|
+
// If workspaces had `useLegacyCache` we can just delete the property as the property is not functional in nx v21
|
12
|
+
if (nxJson.useLegacyCache) {
|
13
|
+
delete nxJson.useLegacyCache;
|
14
|
+
}
|
15
|
+
(0, nx_json_1.updateNxJson)(tree, nxJson);
|
16
|
+
await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree);
|
17
|
+
}
|
Binary file
|
@@ -1,4 +1,5 @@
|
|
1
|
-
import { CreateDependencies, CreateNodes } from '../../project-graph/plugins';
|
1
|
+
import { CreateDependencies, CreateNodes, CreateNodesV2 } from '../../project-graph/plugins';
|
2
2
|
export declare const name = "nx/js/dependencies-and-lockfile";
|
3
|
+
export declare const createNodesV2: CreateNodesV2;
|
3
4
|
export declare const createNodes: CreateNodes;
|
4
5
|
export declare const createDependencies: CreateDependencies;
|
package/src/plugins/js/index.js
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.createDependencies = exports.createNodes = exports.name = void 0;
|
3
|
+
exports.createDependencies = exports.createNodes = exports.createNodesV2 = exports.name = void 0;
|
4
4
|
const fs_1 = require("fs");
|
5
5
|
const path_1 = require("path");
|
6
6
|
const perf_hooks_1 = require("perf_hooks");
|
7
7
|
const cache_directory_1 = require("../../utils/cache-directory");
|
8
8
|
const globs_1 = require("../../utils/globs");
|
9
|
+
const plugins_1 = require("../../project-graph/plugins");
|
9
10
|
const lock_file_1 = require("./lock-file/lock-file");
|
10
11
|
const build_dependencies_1 = require("./project-graph/build-dependencies/build-dependencies");
|
11
12
|
const config_1 = require("./utils/config");
|
@@ -16,6 +17,12 @@ const versions_1 = require("../../utils/versions");
|
|
16
17
|
const child_process_1 = require("child_process");
|
17
18
|
exports.name = 'nx/js/dependencies-and-lockfile';
|
18
19
|
let parsedLockFile = {};
|
20
|
+
exports.createNodesV2 = [
|
21
|
+
(0, globs_1.combineGlobPatterns)(lock_file_1.LOCKFILES),
|
22
|
+
(files, _, context) => {
|
23
|
+
return (0, plugins_1.createNodesFromFiles)(exports.createNodes[1], files, _, context);
|
24
|
+
},
|
25
|
+
];
|
19
26
|
exports.createNodes = [
|
20
27
|
// Look for all lockfiles
|
21
28
|
(0, globs_1.combineGlobPatterns)(lock_file_1.LOCKFILES),
|
@@ -2,7 +2,6 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.LoadedNxPlugin = void 0;
|
4
4
|
const error_types_1 = require("../error-types");
|
5
|
-
const utils_1 = require("./utils");
|
6
5
|
const enabled_1 = require("./isolation/enabled");
|
7
6
|
const client_1 = require("../../daemon/client/client");
|
8
7
|
class LoadedNxPlugin {
|
@@ -14,10 +13,7 @@ class LoadedNxPlugin {
|
|
14
13
|
this.exclude = pluginDefinition.exclude;
|
15
14
|
}
|
16
15
|
if (plugin.createNodes && !plugin.createNodesV2) {
|
17
|
-
|
18
|
-
plugin.createNodes[0],
|
19
|
-
(configFiles, context) => (0, utils_1.createNodesFromFiles)(plugin.createNodes[1], configFiles, this.options, context).then((results) => results.map((r) => [this.name, r[0], r[1]])),
|
20
|
-
];
|
16
|
+
throw new Error(`Plugin ${plugin.name} only provides \`createNodes\` which was removed in Nx 21, it should provide a \`createNodesV2\` implementation.`);
|
21
17
|
}
|
22
18
|
if (plugin.createNodesV2) {
|
23
19
|
this.createNodes = [
|
@@ -32,7 +32,7 @@ async function runTasks(executorName, projectGraph, batchTaskGraph, fullTaskGrap
|
|
32
32
|
input[task.id] = (0, params_1.combineOptionsForExecutor)(task.overrides, task.target.configuration, targetConfiguration, batchExecutor.schema, null, process.cwd());
|
33
33
|
}
|
34
34
|
try {
|
35
|
-
const results = await batchExecutor.batchImplementationFactory()(batchTaskGraph, input, tasks[
|
35
|
+
const results = await batchExecutor.batchImplementationFactory()(batchTaskGraph, input, tasks[tasks.length - 1].overrides, context);
|
36
36
|
if (typeof results !== 'object') {
|
37
37
|
throw new Error(`"${executorName} returned invalid results: ${results}`);
|
38
38
|
}
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import { DefaultTasksRunnerOptions, RemoteCache } from './default-tasks-runner';
|
2
2
|
import { Task } from '../config/task-graph';
|
3
|
-
import { NxJsonConfiguration } from '../config/nx-json';
|
4
3
|
export type CachedResult = {
|
5
4
|
terminalOutput: string;
|
6
5
|
outputsPath: string;
|
@@ -11,7 +10,7 @@ export type TaskWithCachedResult = {
|
|
11
10
|
task: Task;
|
12
11
|
cachedResult: CachedResult;
|
13
12
|
};
|
14
|
-
export declare function dbCacheEnabled(
|
13
|
+
export declare function dbCacheEnabled(): boolean;
|
15
14
|
export declare function getCache(options: DefaultTasksRunnerOptions): DbCache | Cache;
|
16
15
|
export declare class DbCache {
|
17
16
|
private readonly options;
|
@@ -24,23 +24,7 @@ const is_ci_1 = require("../utils/is-ci");
|
|
24
24
|
const output_1 = require("../utils/output");
|
25
25
|
const logger_1 = require("../utils/logger");
|
26
26
|
// This function is called once during tasks runner initialization. It checks if the db cache is enabled and logs a warning if it is not.
|
27
|
-
function dbCacheEnabled(
|
28
|
-
// If the user has explicitly disabled the db cache, we can warn...
|
29
|
-
if (nxJson.useLegacyCache ||
|
30
|
-
process.env.NX_DISABLE_DB === 'true' ||
|
31
|
-
process.env.NX_DB_CACHE === 'false') {
|
32
|
-
let readMoreLink = 'https://nx.dev/deprecated/legacy-cache';
|
33
|
-
if (nxJson.tasksRunnerOptions?.default?.runner &&
|
34
|
-
!['nx-cloud', 'nx/tasks-runners/default', '@nrwl/nx-cloud'].includes(nxJson.tasksRunnerOptions.default.runner)) {
|
35
|
-
readMoreLink += '#tasksrunneroptions';
|
36
|
-
}
|
37
|
-
else if (process.env.NX_REJECT_UNKNOWN_LOCAL_CACHE === '0' ||
|
38
|
-
process.env.NX_REJECT_UNKNOWN_LOCAL_CACHE === 'false') {
|
39
|
-
readMoreLink += '#nxrejectunknownlocalcache';
|
40
|
-
}
|
41
|
-
logger_1.logger.warn(`Nx is configured to use the legacy cache. This cache will be removed in Nx 21. Read more at ${readMoreLink}.`);
|
42
|
-
return false;
|
43
|
-
}
|
27
|
+
function dbCacheEnabled() {
|
44
28
|
// ...but if on wasm and the the db cache isnt supported we shouldn't warn
|
45
29
|
if (native_1.IS_WASM) {
|
46
30
|
return false;
|
@@ -59,7 +43,7 @@ function dbCacheEnabled(nxJson = (0, nx_json_1.readNxJson)()) {
|
|
59
43
|
// Do not change the order of these arguments as this function is used by nx cloud
|
60
44
|
function getCache(options) {
|
61
45
|
const nxJson = (0, nx_json_1.readNxJson)();
|
62
|
-
return dbCacheEnabled(
|
46
|
+
return dbCacheEnabled()
|
63
47
|
? new DbCache({
|
64
48
|
// Remove this in Nx 21
|
65
49
|
nxCloudRemoteCache: (0, nx_cloud_utils_1.isNxCloudUsed)(nxJson) ? options.remoteCache : null,
|
@@ -20,10 +20,10 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
20
20
|
let totalSuccessfulTasks = 0;
|
21
21
|
let totalFailedTasks = 0;
|
22
22
|
let totalCompletedTasks = 0;
|
23
|
-
let totalStoppedTasks = 0;
|
24
23
|
let timeTakenText;
|
25
24
|
const failedTasks = new Set();
|
26
25
|
const inProgressTasks = new Set();
|
26
|
+
const stoppedTasks = new Set();
|
27
27
|
const tasksToTerminalOutputs = {};
|
28
28
|
const taskIdsInOrderOfCompletion = [];
|
29
29
|
lifeCycle.startTasks = (tasks) => {
|
@@ -37,7 +37,8 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
37
37
|
};
|
38
38
|
lifeCycle.setTaskStatus = (taskId, taskStatus) => {
|
39
39
|
if (taskStatus === 9 /* NativeTaskStatus.Stopped */) {
|
40
|
-
|
40
|
+
stoppedTasks.add(taskId);
|
41
|
+
inProgressTasks.delete(taskId);
|
41
42
|
}
|
42
43
|
};
|
43
44
|
lifeCycle.endTasks = (taskResults) => {
|
@@ -83,7 +84,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
83
84
|
};
|
84
85
|
const printRunOneSummary = () => {
|
85
86
|
let lines = [];
|
86
|
-
const failure = totalSuccessfulTasks +
|
87
|
+
const failure = totalSuccessfulTasks + stoppedTasks.size !== totalTasks;
|
87
88
|
// Prints task outputs in the order they were completed
|
88
89
|
// above the summary, since run-one should print all task results.
|
89
90
|
for (const taskId of taskIdsInOrderOfCompletion) {
|
@@ -107,7 +108,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
107
108
|
}
|
108
109
|
lines = [output_1.output.colors.green(lines.join(node_os_1.EOL))];
|
109
110
|
}
|
110
|
-
else if (totalCompletedTasks +
|
111
|
+
else if (totalCompletedTasks + stoppedTasks.size === totalTasks) {
|
111
112
|
let text = `Ran target ${output_1.output.bold(targets[0])} for project ${output_1.output.bold(initiatingProject)}`;
|
112
113
|
if (tasks.length > 1) {
|
113
114
|
text += ` and ${output_1.output.bold(tasks.length - 1)} task(s) they depend on`;
|
@@ -129,7 +130,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
129
130
|
`${LEFT_PAD}${output_1.output.colors.red(figures.cross)}${SPACER}${totalFailedTasks}${`/${totalCompletedTasks}`} failed`,
|
130
131
|
`${LEFT_PAD}${output_1.output.dim(figures.tick)}${SPACER}${totalSuccessfulTasks}${`/${totalCompletedTasks}`} succeeded ${output_1.output.dim(`[${totalCachedTasks} read from cache]`)}`,
|
131
132
|
...viewLogs,
|
132
|
-
]),
|
133
|
+
].join(node_os_1.EOL)),
|
133
134
|
];
|
134
135
|
}
|
135
136
|
else {
|
@@ -145,7 +146,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
145
146
|
const printRunManySummary = () => {
|
146
147
|
console.log('');
|
147
148
|
const lines = [];
|
148
|
-
const failure = totalSuccessfulTasks +
|
149
|
+
const failure = totalSuccessfulTasks + stoppedTasks.size !== totalTasks;
|
149
150
|
for (const taskId of taskIdsInOrderOfCompletion) {
|
150
151
|
const { terminalOutput, taskStatus } = tasksToTerminalOutputs[taskId];
|
151
152
|
if (taskStatus === 'failure') {
|
@@ -157,7 +158,7 @@ function getTuiTerminalSummaryLifeCycle({ projectNames, tasks, args, overrides,
|
|
157
158
|
}
|
158
159
|
}
|
159
160
|
lines.push(...output_1.output.getVerticalSeparatorLines(failure ? 'red' : 'green'));
|
160
|
-
if (totalSuccessfulTasks +
|
161
|
+
if (totalSuccessfulTasks + stoppedTasks.size === totalTasks) {
|
161
162
|
const successSummaryRows = [];
|
162
163
|
const text = `Successfully ran ${(0, formatting_utils_1.formatTargetsAndProjects)(projectNames, targets, tasks)}`;
|
163
164
|
const taskOverridesRows = [];
|
@@ -38,6 +38,7 @@ class PseudoTerminal {
|
|
38
38
|
this.pseudoIPCPath = (0, socket_utils_1.getForkedProcessOsSocketPath)(process.pid.toString() + '-' + id++);
|
39
39
|
this.pseudoIPC = new pseudo_ipc_1.PseudoIPCServer(this.pseudoIPCPath);
|
40
40
|
this.initialized = false;
|
41
|
+
this.childProcesses = new Set();
|
41
42
|
}
|
42
43
|
async init() {
|
43
44
|
if (this.initialized) {
|
@@ -47,18 +48,27 @@ class PseudoTerminal {
|
|
47
48
|
this.initialized = true;
|
48
49
|
}
|
49
50
|
shutdown() {
|
51
|
+
for (const cp of this.childProcesses) {
|
52
|
+
try {
|
53
|
+
cp.kill();
|
54
|
+
}
|
55
|
+
catch { }
|
56
|
+
}
|
50
57
|
if (this.initialized) {
|
51
58
|
this.pseudoIPC.close();
|
52
59
|
}
|
53
60
|
}
|
54
61
|
runCommand(command, { cwd, execArgv, jsEnv, quiet, tty, } = {}) {
|
55
|
-
|
62
|
+
const cp = new PseudoTtyProcess(this.rustPseudoTerminal, this.rustPseudoTerminal.runCommand(command, cwd, jsEnv, execArgv, quiet, tty));
|
63
|
+
this.childProcesses.add(cp);
|
64
|
+
return cp;
|
56
65
|
}
|
57
66
|
async fork(id, script, { cwd, execArgv, jsEnv, quiet, }) {
|
58
67
|
if (!this.initialized) {
|
59
68
|
throw new Error('Call init() before forking processes');
|
60
69
|
}
|
61
70
|
const cp = new PseudoTtyProcessWithSend(this.rustPseudoTerminal, this.rustPseudoTerminal.fork(id, script, this.pseudoIPCPath, cwd, jsEnv, execArgv, quiet), id, this.pseudoIPC);
|
71
|
+
this.childProcesses.add(cp);
|
62
72
|
await this.pseudoIPC.waitForChildReady(id);
|
63
73
|
return cp;
|
64
74
|
}
|
@@ -17,7 +17,6 @@ const create_task_hasher_1 = require("../hasher/create-task-hasher");
|
|
17
17
|
const hash_task_1 = require("../hasher/hash-task");
|
18
18
|
const tasks_execution_hooks_1 = require("../project-graph/plugins/tasks-execution-hooks");
|
19
19
|
const project_graph_1 = require("../project-graph/project-graph");
|
20
|
-
const fileutils_1 = require("../utils/fileutils");
|
21
20
|
const handle_errors_1 = require("../utils/handle-errors");
|
22
21
|
const is_ci_1 = require("../utils/is-ci");
|
23
22
|
const nx_cloud_utils_1 = require("../utils/nx-cloud-utils");
|
@@ -241,6 +240,7 @@ async function getTerminalOutputLifeCycle(initiatingProject, initiatingTasks, pr
|
|
241
240
|
}
|
242
241
|
function createTaskGraphAndRunValidations(projectGraph, extraTargetDependencies, projectNames, nxArgs, overrides, extraOptions) {
|
243
242
|
const taskGraph = (0, create_task_graph_1.createTaskGraph)(projectGraph, extraTargetDependencies, projectNames, nxArgs.targets, nxArgs.configuration, overrides, extraOptions.excludeTaskDependencies);
|
243
|
+
(0, task_graph_utils_1.assertTaskGraphDoesNotContainInvalidTargets)(taskGraph);
|
244
244
|
const cycle = (0, task_graph_utils_1.findCycle)(taskGraph);
|
245
245
|
if (cycle) {
|
246
246
|
if (process.env.NX_IGNORE_CYCLES === 'true' || nxArgs.nxIgnoreCycles) {
|
@@ -712,14 +712,6 @@ function getRunner(nxArgs, nxJson) {
|
|
712
712
|
}
|
713
713
|
const modulePath = getTasksRunnerPath(runner, nxJson);
|
714
714
|
try {
|
715
|
-
if (isCustomRunnerPath(modulePath)) {
|
716
|
-
output_1.output.warn({
|
717
|
-
title: `Custom task runners will be replaced by a new API starting with Nx 21.`,
|
718
|
-
bodyLines: [
|
719
|
-
`For more information, see https://nx.dev/deprecated/custom-tasks-runner`,
|
720
|
-
],
|
721
|
-
});
|
722
|
-
}
|
723
715
|
const tasksRunner = loadTasksRunner(modulePath);
|
724
716
|
return {
|
725
717
|
tasksRunner,
|
@@ -732,18 +724,12 @@ function getRunner(nxArgs, nxJson) {
|
|
732
724
|
}
|
733
725
|
const defaultTasksRunnerPath = require.resolve('./default-tasks-runner');
|
734
726
|
function getTasksRunnerPath(runner, nxJson) {
|
735
|
-
let modulePath = nxJson.tasksRunnerOptions?.[runner]?.runner;
|
736
|
-
if (modulePath) {
|
737
|
-
if ((0, fileutils_1.isRelativePath)(modulePath)) {
|
738
|
-
return (0, node_path_1.join)(workspace_root_1.workspaceRoot, modulePath);
|
739
|
-
}
|
740
|
-
return modulePath;
|
741
|
-
}
|
742
727
|
const isCloudRunner =
|
743
728
|
// No tasksRunnerOptions for given --runner
|
744
729
|
nxJson.nxCloudAccessToken ||
|
745
730
|
// No runner prop in tasks runner options, check if access token is set.
|
746
731
|
nxJson.tasksRunnerOptions?.[runner]?.options?.accessToken ||
|
732
|
+
['nx-cloud', '@nrwl/nx-cloud'].includes(nxJson.tasksRunnerOptions?.[runner]?.runner) ||
|
747
733
|
// Cloud access token specified in env var.
|
748
734
|
process.env.NX_CLOUD_ACCESS_TOKEN ||
|
749
735
|
// Nx Cloud ID specified in nxJson
|
@@ -792,11 +778,3 @@ function getRunnerOptions(runner, nxJson, nxArgs, isCloudDefault) {
|
|
792
778
|
}
|
793
779
|
return result;
|
794
780
|
}
|
795
|
-
function isCustomRunnerPath(modulePath) {
|
796
|
-
return ![
|
797
|
-
'nx-cloud',
|
798
|
-
'@nrwl/nx-cloud',
|
799
|
-
'nx/tasks-runners/default',
|
800
|
-
defaultTasksRunnerPath,
|
801
|
-
].includes(modulePath);
|
802
|
-
}
|
@@ -6,6 +6,7 @@ import { TaskGraph } from '../config/task-graph';
|
|
6
6
|
*/
|
7
7
|
export declare function findCycle(graph: {
|
8
8
|
dependencies: Record<string, string[]>;
|
9
|
+
continuousDependencies?: Record<string, string[]>;
|
9
10
|
}): string[] | null;
|
10
11
|
/**
|
11
12
|
* This function finds all cycles in the graph.
|
@@ -13,9 +14,11 @@ export declare function findCycle(graph: {
|
|
13
14
|
*/
|
14
15
|
export declare function findCycles(graph: {
|
15
16
|
dependencies: Record<string, string[]>;
|
17
|
+
continuousDependencies?: Record<string, string[]>;
|
16
18
|
}): Set<string> | null;
|
17
19
|
export declare function makeAcyclic(graph: {
|
18
20
|
roots: string[];
|
19
21
|
dependencies: Record<string, string[]>;
|
20
22
|
}): void;
|
21
23
|
export declare function validateNoAtomizedTasks(taskGraph: TaskGraph, projectGraph: ProjectGraph): void;
|
24
|
+
export declare function assertTaskGraphDoesNotContainInvalidTargets(taskGraph: TaskGraph): void;
|
@@ -4,12 +4,16 @@ exports.findCycle = findCycle;
|
|
4
4
|
exports.findCycles = findCycles;
|
5
5
|
exports.makeAcyclic = makeAcyclic;
|
6
6
|
exports.validateNoAtomizedTasks = validateNoAtomizedTasks;
|
7
|
+
exports.assertTaskGraphDoesNotContainInvalidTargets = assertTaskGraphDoesNotContainInvalidTargets;
|
7
8
|
const output_1 = require("../utils/output");
|
8
9
|
function _findCycle(graph, id, visited, path) {
|
9
10
|
if (visited[id])
|
10
11
|
return null;
|
11
12
|
visited[id] = true;
|
12
|
-
for (const d of
|
13
|
+
for (const d of [
|
14
|
+
...graph.dependencies[id],
|
15
|
+
...(graph.continuousDependencies?.[id] ?? []),
|
16
|
+
]) {
|
13
17
|
if (path.includes(d))
|
14
18
|
return [...path, d];
|
15
19
|
const cycle = _findCycle(graph, d, visited, [...path, d]);
|
@@ -57,9 +61,11 @@ function _makeAcyclic(graph, id, visited, path) {
|
|
57
61
|
return;
|
58
62
|
visited[id] = true;
|
59
63
|
const deps = graph.dependencies[id];
|
60
|
-
|
64
|
+
const continuousDeps = graph.continuousDependencies?.[id] ?? [];
|
65
|
+
for (const d of [...deps, ...continuousDeps]) {
|
61
66
|
if (path.includes(d)) {
|
62
67
|
deps.splice(deps.indexOf(d), 1);
|
68
|
+
continuousDeps.splice(continuousDeps.indexOf(d), 1);
|
63
69
|
}
|
64
70
|
else {
|
65
71
|
_makeAcyclic(graph, d, visited, [...path, d]);
|
@@ -109,3 +115,26 @@ function validateNoAtomizedTasks(taskGraph, projectGraph) {
|
|
109
115
|
}
|
110
116
|
process.exit(1);
|
111
117
|
}
|
118
|
+
function assertTaskGraphDoesNotContainInvalidTargets(taskGraph) {
|
119
|
+
const invalidTasks = [];
|
120
|
+
for (const task of Object.values(taskGraph.tasks)) {
|
121
|
+
if (task.parallelism === false &&
|
122
|
+
taskGraph.continuousDependencies[task.id].length > 0) {
|
123
|
+
invalidTasks.push(task);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
if (invalidTasks.length > 0) {
|
127
|
+
throw new NonParallelTaskDependsOnContinuousTasksError(invalidTasks, taskGraph);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
class NonParallelTaskDependsOnContinuousTasksError extends Error {
|
131
|
+
constructor(invalidTasks, taskGraph) {
|
132
|
+
let message = 'The following tasks do not support parallelism but depend on continuous tasks:';
|
133
|
+
for (const task of invalidTasks) {
|
134
|
+
message += `\n - ${task.id} -> ${taskGraph.continuousDependencies[task.id].join(', ')}`;
|
135
|
+
}
|
136
|
+
super(message);
|
137
|
+
this.invalidTasks = invalidTasks;
|
138
|
+
this.name = 'NonParallelTaskDependsOnContinuousTasksError';
|
139
|
+
}
|
140
|
+
}
|
@@ -173,7 +173,7 @@ class TaskOrchestrator {
|
|
173
173
|
// No output files to restore
|
174
174
|
!!outputs.length &&
|
175
175
|
// Remote caches are restored to output dirs when applied and using db cache
|
176
|
-
(!cachedResult.remote || !(0, cache_1.dbCacheEnabled)(
|
176
|
+
(!cachedResult.remote || !(0, cache_1.dbCacheEnabled)()) &&
|
177
177
|
// Output files have not been touched since last run
|
178
178
|
(await this.shouldCopyOutputsFromCache(outputs, task.hash));
|
179
179
|
if (shouldCopyOutputsFromCache) {
|
@@ -194,6 +194,7 @@ class TaskOrchestrator {
|
|
194
194
|
// endregion Applying Cache
|
195
195
|
// region Batch
|
196
196
|
async applyFromCacheOrRunBatch(doNotSkipCache, batch, groupId) {
|
197
|
+
const applyFromCacheOrRunBatchStart = perf_hooks_1.performance.mark('TaskOrchestrator-apply-from-cache-or-run-batch:start');
|
197
198
|
const taskEntries = Object.entries(batch.taskGraph.tasks);
|
198
199
|
const tasks = taskEntries.map(([, task]) => task);
|
199
200
|
// Wait for batch to be processed
|
@@ -219,8 +220,12 @@ class TaskOrchestrator {
|
|
219
220
|
taskGraph: (0, utils_1.removeTasksFromTaskGraph)(batch.taskGraph, tasksCompleted.map(([taskId]) => taskId)),
|
220
221
|
}, groupId);
|
221
222
|
}
|
223
|
+
// Batch is done, mark it as completed
|
224
|
+
const applyFromCacheOrRunBatchEnd = perf_hooks_1.performance.mark('TaskOrchestrator-apply-from-cache-or-run-batch:end');
|
225
|
+
perf_hooks_1.performance.measure('TaskOrchestrator-apply-from-cache-or-run-batch', applyFromCacheOrRunBatchStart.name, applyFromCacheOrRunBatchEnd.name);
|
222
226
|
}
|
223
227
|
async runBatch(batch, env) {
|
228
|
+
const runBatchStart = perf_hooks_1.performance.mark('TaskOrchestrator-run-batch:start');
|
224
229
|
try {
|
225
230
|
const batchProcess = await this.forkedProcessTaskRunner.forkProcessForBatch(batch, this.projectGraph, this.taskGraph, env);
|
226
231
|
const results = await batchProcess.getResults();
|
@@ -242,6 +247,10 @@ class TaskOrchestrator {
|
|
242
247
|
status: 'failure',
|
243
248
|
}));
|
244
249
|
}
|
250
|
+
finally {
|
251
|
+
const runBatchEnd = perf_hooks_1.performance.mark('TaskOrchestrator-run-batch:end');
|
252
|
+
perf_hooks_1.performance.measure('TaskOrchestrator-run-batch', runBatchStart.name, runBatchEnd.name);
|
253
|
+
}
|
245
254
|
}
|
246
255
|
// endregion Batch
|
247
256
|
// region Single Task
|