nx 24.0.0-beta.0 → 24.0.0-beta.2
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/dist/nx-cloud-internals.d.ts +1 -0
- package/dist/nx-cloud-internals.js +7 -1
- package/dist/src/command-line/graph/graph.js +2 -1
- package/dist/src/command-line/migrate/agentic/close-agent-session.d.ts +1 -1
- package/dist/src/command-line/migrate/agentic/close-agent-session.js +4 -3
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +19 -23
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +16 -19
- package/dist/src/command-line/migrate/agentic/master/run-master-session.js +25 -13
- package/dist/src/command-line/migrate/agentic/master/spawn-master.js +82 -22
- package/dist/src/command-line/migrate/agentic/select.js +3 -3
- package/dist/src/command-line/migrate/agentic/types.js +1 -3
- package/dist/src/command-line/migrate/command-object.js +5 -9
- package/dist/src/command-line/migrate/execute-migration.d.ts +2 -2
- package/dist/src/command-line/migrate/execute-migration.js +18 -10
- package/dist/src/command-line/migrate/migrate-analytics.d.ts +6 -0
- package/dist/src/command-line/migrate/migrate-analytics.js +12 -0
- package/dist/src/command-line/migrate/migrate-commits.d.ts +4 -1
- package/dist/src/command-line/migrate/migrate-commits.js +10 -3
- package/dist/src/command-line/migrate/migrate-config.d.ts +6 -6
- package/dist/src/command-line/migrate/migrate-config.js +12 -6
- package/dist/src/command-line/migrate/migrate.d.ts +3 -30
- package/dist/src/command-line/migrate/migrate.js +206 -237
- package/dist/src/command-line/migrate/run/agent-output.d.ts +1 -0
- package/dist/src/command-line/migrate/run/agent-output.js +5 -0
- package/dist/src/command-line/migrate/run/broker.d.ts +14 -5
- package/dist/src/command-line/migrate/run/broker.js +68 -20
- package/dist/src/command-line/migrate/run/existing-run-report.d.ts +1 -1
- package/dist/src/command-line/migrate/run/existing-run-report.js +7 -5
- package/dist/src/command-line/migrate/run/index.d.ts +6 -5
- package/dist/src/command-line/migrate/run/index.js +12 -1
- package/dist/src/command-line/migrate/run/orchestrator.d.ts +21 -0
- package/dist/src/command-line/migrate/run/orchestrator.js +149 -32
- package/dist/src/command-line/migrate/run/run-state.d.ts +13 -0
- package/dist/src/command-line/migrate/run/run-state.js +21 -0
- package/dist/src/command-line/migrate/run/runbook.js +19 -0
- package/dist/src/command-line/migrate/run/state-machine.js +4 -1
- package/dist/src/command-line/migrate/run/util.d.ts +3 -0
- package/dist/src/command-line/migrate/run/util.js +7 -1
- package/dist/src/command-line/migrate/sort-migrations.d.ts +1 -7
- package/dist/src/command-line/migrate/sort-migrations.js +1 -12
- package/dist/src/command-line/show/show-target/info.js +1 -1
- package/dist/src/config/nx-json.d.ts +13 -4
- package/dist/src/config/task-graph.d.ts +1 -1
- package/dist/src/config/workspace-json-project-json.d.ts +72 -0
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/devkit-exports.d.ts +1 -1
- package/dist/src/hasher/check-task-files.js +4 -4
- package/dist/src/hasher/native-task-hasher-impl.js +3 -1
- package/dist/src/hasher/task-hasher.d.ts +2 -0
- package/dist/src/hasher/task-hasher.js +4 -1
- package/dist/src/native/index.d.ts +92 -14
- package/dist/src/native/native-bindings.js +3 -0
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/project-graph/utils/project-configuration/target-normalization.js +6 -1
- package/dist/src/project-graph/utils/retrieve-workspace-files.js +27 -6
- package/dist/src/tasks-runner/create-task-graph.d.ts +7 -16
- package/dist/src/tasks-runner/create-task-graph.js +43 -57
- package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
- package/dist/src/tasks-runner/init-tasks-runner.js +13 -0
- package/dist/src/tasks-runner/life-cycle.d.ts +4 -1
- package/dist/src/tasks-runner/life-cycle.js +7 -0
- package/dist/src/tasks-runner/life-cycles/performance-analysis.d.ts +5 -2
- package/dist/src/tasks-runner/life-cycles/performance-analysis.js +13 -7
- package/dist/src/tasks-runner/life-cycles/performance-life-cycle.d.ts +4 -3
- package/dist/src/tasks-runner/life-cycles/performance-life-cycle.js +9 -2
- package/dist/src/tasks-runner/readiness/probes.d.ts +9 -0
- package/dist/src/tasks-runner/readiness/probes.js +62 -0
- package/dist/src/tasks-runner/readiness/ready-when.d.ts +38 -0
- package/dist/src/tasks-runner/readiness/ready-when.js +190 -0
- package/dist/src/tasks-runner/run-command.js +7 -6
- package/dist/src/tasks-runner/running-tasks/batch-process.js +6 -0
- package/dist/src/tasks-runner/running-tasks/node-child-process.js +5 -4
- package/dist/src/tasks-runner/task-graph-utils.d.ts +9 -6
- package/dist/src/tasks-runner/task-graph-utils.js +17 -12
- package/dist/src/tasks-runner/task-orchestrator.d.ts +37 -10
- package/dist/src/tasks-runner/task-orchestrator.js +459 -79
- package/dist/src/tasks-runner/tasks-runner.d.ts +1 -1
- package/dist/src/tasks-runner/tasks-schedule.d.ts +18 -1
- package/dist/src/tasks-runner/tasks-schedule.js +64 -6
- package/dist/src/tasks-runner/utils.js +6 -22
- package/dist/src/utils/child-process.js +1 -0
- package/dist/src/utils/git-utils.d.ts +6 -1
- package/dist/src/utils/git-utils.js +26 -5
- package/dist/src/utils/plugins/core-plugins.js +4 -0
- package/dist/src/utils/spawn-without-terminal.d.ts +27 -0
- package/dist/src/utils/spawn-without-terminal.js +110 -0
- package/package.json +12 -11
- package/schemas/nx-schema.json +93 -4
- package/schemas/project-schema.json +84 -2
|
@@ -21,7 +21,7 @@ export { createNodesFromFiles } from './project-graph/plugins';
|
|
|
21
21
|
/**
|
|
22
22
|
* @category Tasks
|
|
23
23
|
*/
|
|
24
|
-
export type { Task, TaskGraph } from './config/task-graph';
|
|
24
|
+
export type { Task, TaskGraph, TaskGraphEdge } from './config/task-graph';
|
|
25
25
|
/**
|
|
26
26
|
* @category Tasks
|
|
27
27
|
*/
|
|
@@ -154,14 +154,14 @@ function getDepsOutputs(taskId, { projectGraph, nxJson }) {
|
|
|
154
154
|
function collectUpstreamTaskIds(taskGraph, rootTaskId, transitive) {
|
|
155
155
|
const direct = taskGraph.dependencies[rootTaskId] ?? [];
|
|
156
156
|
if (!transitive)
|
|
157
|
-
return
|
|
157
|
+
return direct.map((dep) => dep.id);
|
|
158
158
|
const collected = new Set();
|
|
159
159
|
const walk = (id) => {
|
|
160
160
|
for (const dep of taskGraph.dependencies[id] ?? []) {
|
|
161
|
-
if (collected.has(dep))
|
|
161
|
+
if (collected.has(dep.id))
|
|
162
162
|
continue;
|
|
163
|
-
collected.add(dep);
|
|
164
|
-
walk(dep);
|
|
163
|
+
collected.add(dep.id);
|
|
164
|
+
walk(dep.id);
|
|
165
165
|
}
|
|
166
166
|
};
|
|
167
167
|
walk(rootTaskId);
|
|
@@ -98,7 +98,9 @@ function taskGraphFingerprint(taskGraph, ultracacheConfigurations) {
|
|
|
98
98
|
];
|
|
99
99
|
for (const id of Object.keys(taskGraph.tasks).sort()) {
|
|
100
100
|
const task = taskGraph.tasks[id];
|
|
101
|
-
parts.push(id, task.target.project, task.target.target, task.target.configuration ?? '', (task.outputs ?? []).join(','), (taskGraph.dependencies[id] ?? []).
|
|
101
|
+
parts.push(id, task.target.project, task.target.target, task.target.configuration ?? '', (task.outputs ?? []).join(','), (taskGraph.dependencies[id] ?? []).map((edge) => edge.id).join(','), (taskGraph.continuousDependencies[id] ?? [])
|
|
102
|
+
.map((edge) => JSON.stringify([edge.id, edge.inputs === false]))
|
|
103
|
+
.join(','));
|
|
102
104
|
}
|
|
103
105
|
return (0, native_1.hashArray)(parts);
|
|
104
106
|
}
|
|
@@ -142,6 +142,7 @@ export declare function getInputs(task: Task, projectGraph: ProjectGraph, nxJson
|
|
|
142
142
|
projectInputs: {
|
|
143
143
|
input: string;
|
|
144
144
|
projects: string[];
|
|
145
|
+
dependencies?: true;
|
|
145
146
|
}[];
|
|
146
147
|
depsFilesets: {
|
|
147
148
|
fileset: string;
|
|
@@ -158,6 +159,7 @@ export declare function splitInputsIntoSelfAndDependencies(inputs: ReadonlyArray
|
|
|
158
159
|
projectInputs: {
|
|
159
160
|
input: string;
|
|
160
161
|
projects: string[];
|
|
162
|
+
dependencies?: true;
|
|
161
163
|
}[];
|
|
162
164
|
selfInputs: ExpandedSelfInput[];
|
|
163
165
|
depsOutputs: ExpandedDepsOutput[];
|
|
@@ -200,7 +200,7 @@ function splitInputsIntoSelfAndDependencies(inputs, namedInputs) {
|
|
|
200
200
|
}
|
|
201
201
|
else if ('input' in d &&
|
|
202
202
|
!('fileset' in d) &&
|
|
203
|
-
(('dependencies' in d && d.dependencies) ||
|
|
203
|
+
(('dependencies' in d && d.dependencies && !('projects' in d)) ||
|
|
204
204
|
// Todo(@AgentEnder): Remove check in v17
|
|
205
205
|
('projects' in d &&
|
|
206
206
|
typeof d.projects === 'string' &&
|
|
@@ -219,6 +219,9 @@ function splitInputsIntoSelfAndDependencies(inputs, namedInputs) {
|
|
|
219
219
|
projectInputs.push({
|
|
220
220
|
input: d.input,
|
|
221
221
|
projects: Array.isArray(d.projects) ? d.projects : [d.projects],
|
|
222
|
+
...('dependencies' in d && d.dependencies
|
|
223
|
+
? { dependencies: true }
|
|
224
|
+
: {}),
|
|
222
225
|
});
|
|
223
226
|
}
|
|
224
227
|
else {
|
|
@@ -32,7 +32,7 @@ export declare class ExternalObject<T> {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
export declare class AppLifeCycle {
|
|
35
|
-
constructor(tasks: Array<Task>, initiatingTasks: Array<string>, runMode: RunMode, pinnedTasks: Array<string>, tuiCliArgs: TuiCliArgs, tuiConfig: TuiConfig, titleText: string, workspaceRoot: string, taskGraph: TaskGraph, isCloudEnabled?: boolean | undefined | null)
|
|
35
|
+
constructor(tasks: Array<Task>, initiatingTasks: Array<string>, runMode: RunMode, pinnedTasks: Array<string>, tuiCliArgs: TuiCliArgs, tuiConfig: TuiConfig, titleText: string, workspaceRoot: string, taskGraph: TaskGraph, readyDependencies: Record<string, Array<string>>, isCloudEnabled?: boolean | undefined | null)
|
|
36
36
|
startCommand(threadCount?: number | undefined | null): void
|
|
37
37
|
scheduleTask(task: Task): void
|
|
38
38
|
startTasks(tasks: Array<Task>, metadata: object): void
|
|
@@ -44,6 +44,7 @@ export declare class AppLifeCycle {
|
|
|
44
44
|
registerRunningTaskWithEmptyParser(taskId: string): void
|
|
45
45
|
appendTaskOutput(taskId: string, output: string, isPtyOutput: boolean): void
|
|
46
46
|
setTaskStatus(taskId: string, status: TaskStatus): void
|
|
47
|
+
setTaskReadiness(taskId: string, readiness: TaskReadiness): void
|
|
47
48
|
setTaskTiming(taskId: string, startTime: number, endTime: number): void
|
|
48
49
|
registerForcedShutdownCallback(forcedShutdownCallback: (() => unknown)): void
|
|
49
50
|
__setCloudMessage(message: string): Promise<void>
|
|
@@ -98,7 +99,8 @@ export declare class HashPlanner {
|
|
|
98
99
|
constructor(nxJson: NxJson, projectGraph: ExternalObject<ProjectGraph>)
|
|
99
100
|
/**
|
|
100
101
|
* `configurations` is this run's Ultracache configurations; a task with an
|
|
101
|
-
* eligible entry hashes its observed reads instead of its declared
|
|
102
|
+
* eligible entry hashes its observed reads instead of its declared
|
|
103
|
+
* filesets, except `always` ones.
|
|
102
104
|
* `options` carries the task ids decided in JS, where executors and
|
|
103
105
|
* target configuration are resolved.
|
|
104
106
|
*/
|
|
@@ -127,6 +129,15 @@ export declare class ImportResult {
|
|
|
127
129
|
staticImportExpressions: Array<string>
|
|
128
130
|
}
|
|
129
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Done once every pattern has appeared in the fed output, in any order, even
|
|
134
|
+
* split across chunks or interleaved with terminal control sequences.
|
|
135
|
+
*/
|
|
136
|
+
export declare class LogMatcher {
|
|
137
|
+
constructor(patterns: Array<string>)
|
|
138
|
+
feed(chunk: string): boolean
|
|
139
|
+
}
|
|
140
|
+
|
|
130
141
|
export declare class NxCache {
|
|
131
142
|
cacheDirectory: string
|
|
132
143
|
constructor(workspaceRoot: string, cachePath: string, dbConnection: ExternalObject<NxDbConnection>, linkTaskDetails?: boolean | undefined | null, maxCacheSize?: number | undefined | null)
|
|
@@ -232,15 +243,33 @@ export declare class ProcessMetricsCollector {
|
|
|
232
243
|
subscribe(callback: (err: Error | null, event: MetricsUpdate) => void): void
|
|
233
244
|
}
|
|
234
245
|
|
|
246
|
+
/**
|
|
247
|
+
* Retries a probe until it passes, the timeout elapses or `cancel` is called.
|
|
248
|
+
* A failing attempt is never an error.
|
|
249
|
+
*/
|
|
250
|
+
export declare class ReadinessProbe {
|
|
251
|
+
constructor(config: ReadinessProbeConfig, cwd: string)
|
|
252
|
+
/** False once the timeout elapses or `cancel` is called. */
|
|
253
|
+
wait(): Promise<boolean>
|
|
254
|
+
cancel(): void
|
|
255
|
+
}
|
|
256
|
+
|
|
235
257
|
export declare class RunningTasksService {
|
|
236
258
|
constructor(db: ExternalObject<NxDbConnection>)
|
|
237
259
|
getRunningTasks(ids: Array<string>): Array<string>
|
|
238
260
|
addRunningTask(taskId: string): void
|
|
239
261
|
/**
|
|
240
|
-
* Release this process's claim on a task. A row another
|
|
241
|
-
* taken over is left in place.
|
|
262
|
+
* Release this process's claim on a task and its readiness. A row another
|
|
263
|
+
* process has since taken over is left in place.
|
|
242
264
|
*/
|
|
243
265
|
removeRunningTask(taskId: string): void
|
|
266
|
+
/**
|
|
267
|
+
* No-op unless this process holds the task's claim, so a late or displaced
|
|
268
|
+
* probe result cannot overwrite the current owner's verdict.
|
|
269
|
+
*/
|
|
270
|
+
setTaskReadiness(taskId: string, status: TaskReadiness): void
|
|
271
|
+
/** `None` when the task is not running. */
|
|
272
|
+
getTaskReadiness(taskId: string): TaskReadiness | null
|
|
244
273
|
}
|
|
245
274
|
|
|
246
275
|
export declare class RustPseudoTerminal {
|
|
@@ -704,8 +733,12 @@ export declare const enum EventType {
|
|
|
704
733
|
rescan = 'rescan'
|
|
705
734
|
}
|
|
706
735
|
|
|
707
|
-
/**
|
|
708
|
-
|
|
736
|
+
/**
|
|
737
|
+
* The files an `includeIgnored` fileset group matches on disk, sorted.
|
|
738
|
+
* Given the workspace's project roots, an entry skips projects nested below
|
|
739
|
+
* the one it reads from, as hashing does.
|
|
740
|
+
*/
|
|
741
|
+
export declare function expandFilesInput(workspaceRoot: string, globs: Array<string>, projectRoots?: Array<string> | undefined | null): Array<string>
|
|
709
742
|
|
|
710
743
|
export declare function expandOutputs(directory: string, entries: Array<string>): Array<string>
|
|
711
744
|
|
|
@@ -751,6 +784,11 @@ export interface FileSetInput {
|
|
|
751
784
|
* instead of the workspace file map.
|
|
752
785
|
*/
|
|
753
786
|
includeIgnored?: boolean
|
|
787
|
+
/**
|
|
788
|
+
* Keep the matched files in the hash even when the task is hashed from
|
|
789
|
+
* its ultracache recording.
|
|
790
|
+
*/
|
|
791
|
+
always?: boolean
|
|
754
792
|
}
|
|
755
793
|
|
|
756
794
|
export declare function findImports(projectFileMap: Record<string, Array<string>>): Array<ImportResult>
|
|
@@ -909,8 +947,17 @@ export interface InputMatch {
|
|
|
909
947
|
|
|
910
948
|
export interface InputsInput {
|
|
911
949
|
input: string
|
|
950
|
+
/**
|
|
951
|
+
* With `projects`: the selected projects' dependencies' `input`, as `^input`
|
|
952
|
+
* resolves for each, instead of the projects' own files.
|
|
953
|
+
*/
|
|
912
954
|
dependencies?: boolean
|
|
913
955
|
projects?: string | Array<string>
|
|
956
|
+
/**
|
|
957
|
+
* Keep the files this input resolves to in the hash even when the task
|
|
958
|
+
* is hashed from its ultracache recording.
|
|
959
|
+
*/
|
|
960
|
+
always?: boolean
|
|
914
961
|
}
|
|
915
962
|
|
|
916
963
|
export declare function installNxConsole(): Promise<boolean>
|
|
@@ -950,6 +997,11 @@ export interface JsonInput {
|
|
|
950
997
|
json: string
|
|
951
998
|
fields?: Array<string>
|
|
952
999
|
excludeFields?: Array<string>
|
|
1000
|
+
/**
|
|
1001
|
+
* Keep the file in the hash even when the task is hashed from its
|
|
1002
|
+
* ultracache recording.
|
|
1003
|
+
*/
|
|
1004
|
+
always?: boolean
|
|
953
1005
|
}
|
|
954
1006
|
|
|
955
1007
|
/**
|
|
@@ -1116,6 +1168,16 @@ export interface ProjectGraph {
|
|
|
1116
1168
|
externalNodes: Record<string, ExternalNode>
|
|
1117
1169
|
}
|
|
1118
1170
|
|
|
1171
|
+
/** Exactly one of `url`, `port` or `command` is set. `interval` absent means backoff. */
|
|
1172
|
+
export interface ReadinessProbeConfig {
|
|
1173
|
+
url?: string
|
|
1174
|
+
port?: number
|
|
1175
|
+
host?: string
|
|
1176
|
+
command?: string
|
|
1177
|
+
timeout: number
|
|
1178
|
+
interval?: number
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1119
1181
|
export declare function remove(src: string): void
|
|
1120
1182
|
|
|
1121
1183
|
/**
|
|
@@ -1287,14 +1349,19 @@ export interface TaskGraph {
|
|
|
1287
1349
|
roots: Array<string>
|
|
1288
1350
|
/** Map of Task IDs to Tasks */
|
|
1289
1351
|
tasks: Record<string, Task>
|
|
1290
|
-
/** Map of Task IDs to
|
|
1291
|
-
dependencies: Record<string, Array<
|
|
1292
|
-
continuousDependencies: Record<string, Array<
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1352
|
+
/** Map of Task IDs to the edges to tasks which the task depends on */
|
|
1353
|
+
dependencies: Record<string, Array<TaskGraphEdge>>
|
|
1354
|
+
continuousDependencies: Record<string, Array<TaskGraphEdge>>
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
/** An edge from a task to one of the tasks it depends on */
|
|
1358
|
+
export interface TaskGraphEdge {
|
|
1359
|
+
/** ID of the task depended on */
|
|
1360
|
+
id: string
|
|
1361
|
+
/** What the dependent waits for on a continuous dependency. Defaults to `started`. */
|
|
1362
|
+
waitFor?: 'started' | 'ready'
|
|
1363
|
+
/** `false` on a continuous dependency whose inputs the dependent does not hash */
|
|
1364
|
+
inputs?: false
|
|
1298
1365
|
}
|
|
1299
1366
|
|
|
1300
1367
|
/** Details about the composition of a task's hash */
|
|
@@ -1339,6 +1406,12 @@ export interface TaskOutputs {
|
|
|
1339
1406
|
files?: Array<OutputFile>
|
|
1340
1407
|
}
|
|
1341
1408
|
|
|
1409
|
+
export declare const enum TaskReadiness {
|
|
1410
|
+
Pending = 0,
|
|
1411
|
+
Ready = 1,
|
|
1412
|
+
Failed = 2
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1342
1415
|
/**
|
|
1343
1416
|
* The result of a completed Task.
|
|
1344
1417
|
*
|
|
@@ -1386,6 +1459,11 @@ export interface TaskTarget {
|
|
|
1386
1459
|
export interface TaskUltracacheSettings {
|
|
1387
1460
|
/** How this target's tasks participate. Defaults to `on`. */
|
|
1388
1461
|
mode?: 'on' | 'warn' | 'error' | 'off'
|
|
1462
|
+
/**
|
|
1463
|
+
* Collect successful stat metadata accesses as inputs. Defaults to `false`.
|
|
1464
|
+
* Missing-path probes are tracked independently of this setting.
|
|
1465
|
+
*/
|
|
1466
|
+
collectStats?: boolean
|
|
1389
1467
|
/**
|
|
1390
1468
|
* Workspace-relative glob patterns for reads that should be excluded
|
|
1391
1469
|
* from ultracache reports. The first path segment cannot contain `*`,
|
|
@@ -584,11 +584,13 @@ module.exports.HashPlanner = nativeBinding.HashPlanner
|
|
|
584
584
|
module.exports.HttpRemoteCache = nativeBinding.HttpRemoteCache
|
|
585
585
|
module.exports.IgnoredIndexReader = nativeBinding.IgnoredIndexReader
|
|
586
586
|
module.exports.ImportResult = nativeBinding.ImportResult
|
|
587
|
+
module.exports.LogMatcher = nativeBinding.LogMatcher
|
|
587
588
|
module.exports.NxCache = nativeBinding.NxCache
|
|
588
589
|
module.exports.NxConsolePreferences = nativeBinding.NxConsolePreferences
|
|
589
590
|
module.exports.NxPluginCapabilities = nativeBinding.NxPluginCapabilities
|
|
590
591
|
module.exports.NxTaskHistory = nativeBinding.NxTaskHistory
|
|
591
592
|
module.exports.ProcessMetricsCollector = nativeBinding.ProcessMetricsCollector
|
|
593
|
+
module.exports.ReadinessProbe = nativeBinding.ReadinessProbe
|
|
592
594
|
module.exports.RunningTasksService = nativeBinding.RunningTasksService
|
|
593
595
|
module.exports.RustPseudoTerminal = nativeBinding.RustPseudoTerminal
|
|
594
596
|
module.exports.TaskDetails = nativeBinding.TaskDetails
|
|
@@ -649,6 +651,7 @@ module.exports.restoreTerminal = nativeBinding.restoreTerminal
|
|
|
649
651
|
module.exports.RunMode = nativeBinding.RunMode
|
|
650
652
|
module.exports.SupportedEditor = nativeBinding.SupportedEditor
|
|
651
653
|
module.exports.sweepBatchOutputs = nativeBinding.sweepBatchOutputs
|
|
654
|
+
module.exports.TaskReadiness = nativeBinding.TaskReadiness
|
|
652
655
|
module.exports.TaskStatus = nativeBinding.TaskStatus
|
|
653
656
|
module.exports.testOnlyTransferFileMap = nativeBinding.testOnlyTransferFileMap
|
|
654
657
|
module.exports.trackEvent = nativeBinding.trackEvent
|
|
Binary file
|
|
Binary file
|
|
@@ -186,6 +186,7 @@ function warnAboutLegacyCachedTargets(legacyCacheReads) {
|
|
|
186
186
|
*/
|
|
187
187
|
const KNOWN_ULTRACACHE_KEYS = new Set([
|
|
188
188
|
'mode',
|
|
189
|
+
'collectStats',
|
|
189
190
|
'ignoredReads',
|
|
190
191
|
'ignoredWrites',
|
|
191
192
|
utils_1.NX_SPREAD_TOKEN,
|
|
@@ -233,7 +234,7 @@ function validateTargetUltracache(ultracache, projectName, projectRoot, targetNa
|
|
|
233
234
|
const errors = [];
|
|
234
235
|
for (const key of Object.keys(ultracache)) {
|
|
235
236
|
if (!KNOWN_ULTRACACHE_KEYS.has(key)) {
|
|
236
|
-
errors.push(`"ultracache.${key}" for target ${where} is not an ultracache option. Supported options are "mode", "ignoredReads" and "ignoredWrites".`);
|
|
237
|
+
errors.push(`"ultracache.${key}" for target ${where} is not an ultracache option. Supported options are "mode", "collectStats", "ignoredReads" and "ignoredWrites".`);
|
|
237
238
|
}
|
|
238
239
|
}
|
|
239
240
|
if (ultracache.mode !== undefined &&
|
|
@@ -243,6 +244,10 @@ function validateTargetUltracache(ultracache, projectName, projectRoot, targetNa
|
|
|
243
244
|
? `"${ultracache.mode}"`
|
|
244
245
|
: describeUltracacheValue(ultracache.mode)}.`);
|
|
245
246
|
}
|
|
247
|
+
if (ultracache.collectStats !== undefined &&
|
|
248
|
+
typeof ultracache.collectStats !== 'boolean') {
|
|
249
|
+
errors.push(`"ultracache.collectStats" for target ${where} must be a boolean, but it is ${describeUltracacheValue(ultracache.collectStats)}.`);
|
|
250
|
+
}
|
|
246
251
|
for (const key of ['ignoredReads', 'ignoredWrites']) {
|
|
247
252
|
const value = ultracache[key];
|
|
248
253
|
if (value === undefined)
|
|
@@ -12,6 +12,7 @@ const angular_json_1 = require("../../adapter/angular-json");
|
|
|
12
12
|
const nx_json_1 = require("../../config/nx-json");
|
|
13
13
|
const project_configuration_utils_1 = require("./project-configuration-utils");
|
|
14
14
|
const workspace_context_1 = require("../../utils/workspace-context");
|
|
15
|
+
const minimatch_1 = require("minimatch");
|
|
15
16
|
const path_1 = require("path");
|
|
16
17
|
const get_plugins_1 = require("../plugins/get-plugins");
|
|
17
18
|
/**
|
|
@@ -45,11 +46,9 @@ async function retrieveWorkspaceFiles(workspaceRoot, projectRootMap) {
|
|
|
45
46
|
async function retrieveProjectConfigurations(separatedPlugins, workspaceRoot, nxJson) {
|
|
46
47
|
const specifiedWithCreateNodes = separatedPlugins.specifiedPlugins.filter((p) => !!p.createNodes);
|
|
47
48
|
const defaultWithCreateNodes = separatedPlugins.defaultPlugins.filter((p) => !!p.createNodes);
|
|
48
|
-
const specifiedGlobPatterns = getGlobPatternsOfPlugins(specifiedWithCreateNodes);
|
|
49
|
-
const defaultGlobPatterns = getGlobPatternsOfPlugins(defaultWithCreateNodes);
|
|
50
49
|
const [specifiedPluginFiles, defaultPluginFiles] = await Promise.all([
|
|
51
|
-
(
|
|
52
|
-
(
|
|
50
|
+
globPluginFiles(workspaceRoot, specifiedWithCreateNodes),
|
|
51
|
+
globPluginFiles(workspaceRoot, defaultWithCreateNodes),
|
|
53
52
|
]);
|
|
54
53
|
return (0, project_configuration_utils_1.createProjectConfigurationsWithPlugins)(workspaceRoot, nxJson, {
|
|
55
54
|
specifiedPluginFiles: specifiedPluginFiles ?? [],
|
|
@@ -71,8 +70,7 @@ async function retrieveProjectConfigurationsWithAngularProjects(workspaceRoot, n
|
|
|
71
70
|
return res;
|
|
72
71
|
}
|
|
73
72
|
async function retrieveProjectConfigurationPaths(root, plugins) {
|
|
74
|
-
const
|
|
75
|
-
const pluginConfigFiles = await (0, workspace_context_1.multiGlobWithWorkspaceContext)(root, projectGlobPatterns);
|
|
73
|
+
const pluginConfigFiles = await globPluginFiles(root, plugins);
|
|
76
74
|
return pluginConfigFiles.flat();
|
|
77
75
|
}
|
|
78
76
|
const projectsWithoutPluginCache = new Map();
|
|
@@ -105,6 +103,29 @@ async function retrieveProjectConfigurationsWithoutPluginInference(root) {
|
|
|
105
103
|
function clearProjectsWithoutPluginInferenceCache() {
|
|
106
104
|
projectsWithoutPluginCache.clear();
|
|
107
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Files each plugin's createNodes pattern matches, in plugin order. A plugin
|
|
108
|
+
* scoped by `include` globs only those patterns natively, so a broad pattern
|
|
109
|
+
* (every `.ts` file, say) is never matched against the whole workspace in JS.
|
|
110
|
+
*/
|
|
111
|
+
async function globPluginFiles(root, plugins) {
|
|
112
|
+
const unscoped = plugins.filter((p) => !canGlobInclude(p));
|
|
113
|
+
const unscopedFiles = (await (0, workspace_context_1.multiGlobWithWorkspaceContext)(root, unscoped.map((p) => p.createNodes[0]))) ?? [];
|
|
114
|
+
return Promise.all(plugins.map(async (plugin) => {
|
|
115
|
+
if (!canGlobInclude(plugin)) {
|
|
116
|
+
return unscopedFiles[unscoped.indexOf(plugin)] ?? [];
|
|
117
|
+
}
|
|
118
|
+
const pattern = new minimatch_1.Minimatch(plugin.createNodes[0], { dot: true });
|
|
119
|
+
const included = await (0, workspace_context_1.globWithWorkspaceContext)(root, plugin.include);
|
|
120
|
+
return included.filter((file) => pattern.match(file));
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
// Only narrow includes: a `**` scope can return more files than the plugin
|
|
124
|
+
// pattern does. Negations and extglobs keep the JS matcher's semantics.
|
|
125
|
+
function canGlobInclude(plugin) {
|
|
126
|
+
return (plugin.include?.length > 0 &&
|
|
127
|
+
plugin.include.every((pattern) => !pattern.includes('**') && !/[!()]/.test(pattern)));
|
|
128
|
+
}
|
|
108
129
|
function getGlobPatternsOfPlugins(plugins) {
|
|
109
130
|
return plugins.map((p) => p.createNodes[0]);
|
|
110
131
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph';
|
|
2
|
-
import { Task, TaskGraph } from '../config/task-graph';
|
|
2
|
+
import { Task, TaskGraph, TaskGraphEdge } from '../config/task-graph';
|
|
3
3
|
import { TargetDependencies } from '../config/nx-json';
|
|
4
4
|
/**
|
|
5
5
|
* For each task, the overrides every `dependsOn` edge into it would give it,
|
|
@@ -20,13 +20,11 @@ export declare class ProcessTasks {
|
|
|
20
20
|
[id: string]: Task;
|
|
21
21
|
};
|
|
22
22
|
readonly dependencies: {
|
|
23
|
-
[k: string]:
|
|
23
|
+
[k: string]: TaskGraphEdge[];
|
|
24
24
|
};
|
|
25
25
|
readonly continuousDependencies: {
|
|
26
|
-
[k: string]:
|
|
26
|
+
[k: string]: TaskGraphEdge[];
|
|
27
27
|
};
|
|
28
|
-
private readonly continuousEdgesWithoutInputs;
|
|
29
|
-
private readonly continuousEdgesWithInputs;
|
|
30
28
|
readonly dependencyOverrides: DependencyOverrides;
|
|
31
29
|
private readonly allTargetNames;
|
|
32
30
|
constructor(extraTargetDependencies: TargetDependencies, projectGraph: ProjectGraph, recordDependencyOverrides?: boolean);
|
|
@@ -36,13 +34,6 @@ export declare class ProcessTasks {
|
|
|
36
34
|
private processTasksForSingleProject;
|
|
37
35
|
private processTasksForDependencies;
|
|
38
36
|
private addContinuousEdge;
|
|
39
|
-
/**
|
|
40
|
-
* Continuous edges every `dependsOn` path into which has `inputs: false`.
|
|
41
|
-
* Undefined when there are none, so graphs without the option are unchanged.
|
|
42
|
-
*/
|
|
43
|
-
continuousDependenciesWithoutInputs(): {
|
|
44
|
-
[k: string]: string[];
|
|
45
|
-
} | undefined;
|
|
46
37
|
private recordEdge;
|
|
47
38
|
private createDummyTask;
|
|
48
39
|
createTask(id: string, project: ProjectGraphProjectNode, target: string, resolvedConfiguration: string | undefined, overrides: Record<string, unknown>): Task;
|
|
@@ -64,11 +55,11 @@ export declare function filterTaskGraphToSelection(projectGraph: ProjectGraph, t
|
|
|
64
55
|
* It will manipulate the dependencies object in place
|
|
65
56
|
*/
|
|
66
57
|
export declare function filterDummyTasks(dependencies: {
|
|
67
|
-
[k: string]:
|
|
58
|
+
[k: string]: TaskGraphEdge[];
|
|
68
59
|
}): void;
|
|
69
60
|
/**
|
|
70
61
|
* this function is used to get the non dummy dependencies of a task recursively
|
|
71
62
|
*/
|
|
72
|
-
export declare function getNonDummyDeps(
|
|
73
|
-
[k: string]:
|
|
74
|
-
}, cycles?: Set<string>, seen?: Set<string>):
|
|
63
|
+
export declare function getNonDummyDeps(currentEdge: TaskGraphEdge, dependencies: {
|
|
64
|
+
[k: string]: TaskGraphEdge[];
|
|
65
|
+
}, cycles?: Set<string>, seen?: Set<string>): TaskGraphEdge[];
|
|
@@ -20,11 +20,6 @@ class ProcessTasks {
|
|
|
20
20
|
this.tasks = {};
|
|
21
21
|
this.dependencies = {};
|
|
22
22
|
this.continuousDependencies = {};
|
|
23
|
-
// `from\0to` continuous edges by whether their `dependsOn` entry has
|
|
24
|
-
// `inputs: false`. Keyed from the creator's target, like `recordEdge`, so
|
|
25
|
-
// an edge through a dummy task names the real task.
|
|
26
|
-
this.continuousEdgesWithoutInputs = new Set();
|
|
27
|
-
this.continuousEdgesWithInputs = new Set();
|
|
28
23
|
this.dependencyOverrides = {};
|
|
29
24
|
const allTargetNames = new Set();
|
|
30
25
|
for (const projectName in projectGraph.nodes) {
|
|
@@ -64,28 +59,14 @@ class ProcessTasks {
|
|
|
64
59
|
}
|
|
65
60
|
}
|
|
66
61
|
for (let d of Object.keys(this.dependencies)) {
|
|
67
|
-
this.dependencies[d] = this.dependencies[d].filter((dd) => !!initialTasks[dd]);
|
|
62
|
+
this.dependencies[d] = this.dependencies[d].filter((dd) => !!initialTasks[dd.id]);
|
|
68
63
|
}
|
|
69
64
|
for (let d of Object.keys(this.continuousDependencies)) {
|
|
70
|
-
this.continuousDependencies[d] = this.continuousDependencies[d].filter((dd) => !!initialTasks[dd]);
|
|
65
|
+
this.continuousDependencies[d] = this.continuousDependencies[d].filter((dd) => !!initialTasks[dd.id]);
|
|
71
66
|
}
|
|
72
67
|
}
|
|
73
68
|
filterDummyTasks(this.dependencies);
|
|
74
|
-
for (const taskId of Object.keys(this.dependencies)) {
|
|
75
|
-
if (this.dependencies[taskId].length > 0) {
|
|
76
|
-
this.dependencies[taskId] = [
|
|
77
|
-
...new Set(this.dependencies[taskId].filter((d) => d !== taskId)).values(),
|
|
78
|
-
];
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
69
|
filterDummyTasks(this.continuousDependencies);
|
|
82
|
-
for (const taskId of Object.keys(this.continuousDependencies)) {
|
|
83
|
-
if (this.continuousDependencies[taskId].length > 0) {
|
|
84
|
-
this.continuousDependencies[taskId] = [
|
|
85
|
-
...new Set(this.continuousDependencies[taskId].filter((d) => d !== taskId)).values(),
|
|
86
|
-
];
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
70
|
return Object.keys(this.tasks).filter((d) => this.dependencies[d].length === 0 &&
|
|
90
71
|
this.continuousDependencies[d].length === 0);
|
|
91
72
|
}
|
|
@@ -140,7 +121,7 @@ class ProcessTasks {
|
|
|
140
121
|
this.addContinuousEdge(task, selfTaskId, dependencyConfig);
|
|
141
122
|
}
|
|
142
123
|
else {
|
|
143
|
-
this.dependencies[task.id].push(selfTaskId);
|
|
124
|
+
this.dependencies[task.id].push({ id: selfTaskId });
|
|
144
125
|
}
|
|
145
126
|
}
|
|
146
127
|
}
|
|
@@ -164,7 +145,7 @@ class ProcessTasks {
|
|
|
164
145
|
this.addContinuousEdge(task, depTargetId, dependencyConfig);
|
|
165
146
|
}
|
|
166
147
|
else {
|
|
167
|
-
this.dependencies[task.id].push(depTargetId);
|
|
148
|
+
this.dependencies[task.id].push({ id: depTargetId });
|
|
168
149
|
}
|
|
169
150
|
}
|
|
170
151
|
if (!this.tasks[depTargetId]) {
|
|
@@ -182,8 +163,8 @@ class ProcessTasks {
|
|
|
182
163
|
'__' +
|
|
183
164
|
dependencyConfig.target +
|
|
184
165
|
DUMMY_TASK_TARGET, undefined);
|
|
185
|
-
this.dependencies[task.id].push(dummyId);
|
|
186
|
-
this.continuousDependencies[task.id].push(dummyId);
|
|
166
|
+
this.dependencies[task.id].push({ id: dummyId });
|
|
167
|
+
this.continuousDependencies[task.id].push({ id: dummyId });
|
|
187
168
|
this.dependencies[dummyId] ??= [];
|
|
188
169
|
this.continuousDependencies[dummyId] ??= [];
|
|
189
170
|
const noopTask = this.createDummyTask(dummyId, task);
|
|
@@ -192,30 +173,7 @@ class ProcessTasks {
|
|
|
192
173
|
}
|
|
193
174
|
}
|
|
194
175
|
addContinuousEdge(task, dependencyId, dependencyConfig) {
|
|
195
|
-
this.continuousDependencies[task.id].push(dependencyId);
|
|
196
|
-
const { project, target, configuration } = task.target;
|
|
197
|
-
const edge = `${(0, utils_1.createTaskId)(project, target, configuration)}\0${dependencyId}`;
|
|
198
|
-
(dependencyConfig.inputs === false
|
|
199
|
-
? this.continuousEdgesWithoutInputs
|
|
200
|
-
: this.continuousEdgesWithInputs).add(edge);
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Continuous edges every `dependsOn` path into which has `inputs: false`.
|
|
204
|
-
* Undefined when there are none, so graphs without the option are unchanged.
|
|
205
|
-
*/
|
|
206
|
-
continuousDependenciesWithoutInputs() {
|
|
207
|
-
let without;
|
|
208
|
-
for (const [taskId, deps] of Object.entries(this.continuousDependencies)) {
|
|
209
|
-
const excluded = deps.filter((dep) => {
|
|
210
|
-
const edge = `${taskId}\0${dep}`;
|
|
211
|
-
return (this.continuousEdgesWithoutInputs.has(edge) &&
|
|
212
|
-
!this.continuousEdgesWithInputs.has(edge));
|
|
213
|
-
});
|
|
214
|
-
if (excluded.length > 0) {
|
|
215
|
-
(without ??= {})[taskId] = excluded;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
return without;
|
|
176
|
+
this.continuousDependencies[task.id].push(continuousEdge(dependencyId, dependencyConfig));
|
|
219
177
|
}
|
|
220
178
|
recordEdge(task, dependencyId, overrides) {
|
|
221
179
|
if (!this.recordDependencyOverrides) {
|
|
@@ -307,15 +265,11 @@ function filterTaskGraphToSelection(projectGraph, taskGraph, dependencyOverrides
|
|
|
307
265
|
}
|
|
308
266
|
function buildTaskGraph(p, projectNames, targets, configuration, overrides, excludeTaskDependencies) {
|
|
309
267
|
const roots = p.processTasks(projectNames, targets, configuration, overrides, excludeTaskDependencies);
|
|
310
|
-
const continuousDependenciesWithoutInputs = p.continuousDependenciesWithoutInputs();
|
|
311
268
|
return {
|
|
312
269
|
roots,
|
|
313
270
|
tasks: p.tasks,
|
|
314
271
|
dependencies: p.dependencies,
|
|
315
272
|
continuousDependencies: p.continuousDependencies,
|
|
316
|
-
...(continuousDependenciesWithoutInputs
|
|
317
|
-
? { continuousDependenciesWithoutInputs }
|
|
318
|
-
: {}),
|
|
319
273
|
};
|
|
320
274
|
}
|
|
321
275
|
function interpolateOverrides(args, projectName, project) {
|
|
@@ -333,6 +287,37 @@ function interpolateOverrides(args, projectName, project) {
|
|
|
333
287
|
});
|
|
334
288
|
return interpolatedArgs;
|
|
335
289
|
}
|
|
290
|
+
function continuousEdge(id, dependencyConfig) {
|
|
291
|
+
const edge = { id };
|
|
292
|
+
if (dependencyConfig.waitFor === 'ready') {
|
|
293
|
+
edge.waitFor = 'ready';
|
|
294
|
+
}
|
|
295
|
+
if (dependencyConfig.inputs === false) {
|
|
296
|
+
edge.inputs = false;
|
|
297
|
+
}
|
|
298
|
+
return edge;
|
|
299
|
+
}
|
|
300
|
+
// A task reached by several edges waits for ready when any of them does, and
|
|
301
|
+
// keeps its inputs unless all of them opt out
|
|
302
|
+
function mergeEdges(edges) {
|
|
303
|
+
const byId = new Map();
|
|
304
|
+
for (const edge of edges) {
|
|
305
|
+
const seen = byId.get(edge.id);
|
|
306
|
+
if (!seen) {
|
|
307
|
+
byId.set(edge.id, edge);
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
const merged = { id: edge.id };
|
|
311
|
+
if (seen.waitFor === 'ready' || edge.waitFor === 'ready') {
|
|
312
|
+
merged.waitFor = 'ready';
|
|
313
|
+
}
|
|
314
|
+
if (seen.inputs === false && edge.inputs === false) {
|
|
315
|
+
merged.inputs = false;
|
|
316
|
+
}
|
|
317
|
+
byId.set(edge.id, merged);
|
|
318
|
+
}
|
|
319
|
+
return [...byId.values()];
|
|
320
|
+
}
|
|
336
321
|
/**
|
|
337
322
|
* This function is used to filter out the dummy tasks from the dependencies
|
|
338
323
|
* It will manipulate the dependencies object in place
|
|
@@ -345,7 +330,7 @@ function filterDummyTasks(dependencies) {
|
|
|
345
330
|
for (const dep of deps) {
|
|
346
331
|
normalizedDeps.push(...getNonDummyDeps(dep, dependencies, cycles, new Set([key])));
|
|
347
332
|
}
|
|
348
|
-
dependencies[key] = normalizedDeps;
|
|
333
|
+
dependencies[key] = mergeEdges(normalizedDeps);
|
|
349
334
|
}
|
|
350
335
|
}
|
|
351
336
|
for (const key of Object.keys(dependencies)) {
|
|
@@ -357,12 +342,13 @@ function filterDummyTasks(dependencies) {
|
|
|
357
342
|
/**
|
|
358
343
|
* this function is used to get the non dummy dependencies of a task recursively
|
|
359
344
|
*/
|
|
360
|
-
function getNonDummyDeps(
|
|
345
|
+
function getNonDummyDeps(currentEdge, dependencies, cycles, seen = new Set()) {
|
|
346
|
+
const currentTask = currentEdge.id;
|
|
361
347
|
if (seen.has(currentTask)) {
|
|
362
348
|
return [];
|
|
363
349
|
}
|
|
364
|
-
seen.add(currentTask);
|
|
365
350
|
if (currentTask.endsWith(DUMMY_TASK_TARGET)) {
|
|
351
|
+
seen.add(currentTask);
|
|
366
352
|
if (cycles?.has(currentTask)) {
|
|
367
353
|
return [];
|
|
368
354
|
}
|
|
@@ -374,7 +360,7 @@ function getNonDummyDeps(currentTask, dependencies, cycles, seen = new Set()) {
|
|
|
374
360
|
return deps.flatMap((dep) => getNonDummyDeps(dep, dependencies, cycles, seen));
|
|
375
361
|
}
|
|
376
362
|
else {
|
|
377
|
-
return [
|
|
363
|
+
return [currentEdge];
|
|
378
364
|
}
|
|
379
365
|
}
|
|
380
366
|
function createTaskOverrides(dependencyConfig, cliOverrides, sourceTask, projectGraph) {
|
|
@@ -68,7 +68,7 @@ const defaultTasksRunner = async (tasks, options, context) => {
|
|
|
68
68
|
};
|
|
69
69
|
exports.defaultTasksRunner = defaultTasksRunner;
|
|
70
70
|
async function runAllTasks(options, context) {
|
|
71
|
-
const orchestrator = new task_orchestrator_1.TaskOrchestrator(context.hasher, context.initiatingProject, context.initiatingTasks, context.projectGraph, context.taskGraph, context.nxJson, options, context.nxArgs?.nxBail, context.daemon, context.nxArgs?.specifiedOutputStyle, context.nxArgs?.resolvedOutputStyle ?? 'static-failures-only', context.taskGraph, context.
|
|
71
|
+
const orchestrator = new task_orchestrator_1.TaskOrchestrator(context.hasher, context.initiatingProject, context.initiatingTasks, context.projectGraph, context.taskGraph, context.nxJson, options, context.nxArgs?.nxBail, context.daemon, context.nxArgs?.specifiedOutputStyle, context.nxArgs?.resolvedOutputStyle ?? 'static-failures-only', context.taskGraph, context.hashingDeferredTaskIds);
|
|
72
72
|
return orchestrator.run();
|
|
73
73
|
}
|
|
74
74
|
exports.default = exports.defaultTasksRunner;
|