nx 20.5.0-canary.20250204-bc4ded0 → 21.0.0-beta.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/package.json +12 -11
- package/src/command-line/graph/graph.js +2 -0
- package/src/commands-runner/get-command-projects.js +17 -2
- package/src/config/task-graph.d.ts +5 -0
- package/src/config/workspace-json-project-json.d.ts +4 -0
- package/src/executors/run-commands/run-commands.impl.d.ts +16 -13
- package/src/executors/run-commands/run-commands.impl.js +24 -263
- package/src/executors/run-commands/running-tasks.d.ts +38 -0
- package/src/executors/run-commands/running-tasks.js +349 -0
- package/src/native/index.d.ts +1 -0
- package/src/native/nx.wasm32-wasi.wasm +0 -0
- package/src/tasks-runner/create-task-graph.d.ts +3 -0
- package/src/tasks-runner/create-task-graph.js +36 -5
- package/src/tasks-runner/forked-process-task-runner.d.ts +6 -12
- package/src/tasks-runner/forked-process-task-runner.js +110 -263
- package/src/tasks-runner/init-tasks-runner.js +4 -0
- package/src/tasks-runner/pseudo-terminal.d.ts +7 -1
- package/src/tasks-runner/pseudo-terminal.js +26 -12
- package/src/tasks-runner/running-tasks/batch-process.d.ts +14 -0
- package/src/tasks-runner/running-tasks/batch-process.js +70 -0
- package/src/tasks-runner/running-tasks/node-child-process.d.ts +36 -0
- package/src/tasks-runner/running-tasks/node-child-process.js +184 -0
- package/src/tasks-runner/running-tasks/noop-child-process.d.ts +15 -0
- package/src/tasks-runner/running-tasks/noop-child-process.js +19 -0
- package/src/tasks-runner/running-tasks/running-task.d.ts +8 -0
- package/src/tasks-runner/running-tasks/running-task.js +6 -0
- package/src/tasks-runner/task-orchestrator.d.ts +7 -1
- package/src/tasks-runner/task-orchestrator.js +137 -82
- package/src/tasks-runner/tasks-schedule.js +5 -1
- package/src/tasks-runner/utils.d.ts +0 -8
- package/src/tasks-runner/utils.js +12 -4
@@ -0,0 +1,349 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.SeriallyRunningTasks = exports.ParallelRunningTasks = void 0;
|
4
|
+
const child_process_1 = require("child_process");
|
5
|
+
const run_commands_impl_1 = require("./run-commands.impl");
|
6
|
+
const path_1 = require("path");
|
7
|
+
const chalk = require("chalk");
|
8
|
+
const npm_run_path_1 = require("npm-run-path");
|
9
|
+
const task_env_1 = require("../../tasks-runner/task-env");
|
10
|
+
const treeKill = require("tree-kill");
|
11
|
+
class ParallelRunningTasks {
|
12
|
+
constructor(options, context) {
|
13
|
+
this.exitCallbacks = [];
|
14
|
+
this.childProcesses = options.commands.map((commandConfig) => new RunningNodeProcess(commandConfig, options.color, calculateCwd(options.cwd, context), options.env ?? {}, options.readyWhenStatus, options.streamOutput, options.envFile));
|
15
|
+
this.readyWhenStatus = options.readyWhenStatus;
|
16
|
+
this.streamOutput = options.streamOutput;
|
17
|
+
this.run();
|
18
|
+
}
|
19
|
+
async getResults() {
|
20
|
+
return new Promise((res) => {
|
21
|
+
this.onExit((code, terminalOutput) => {
|
22
|
+
res({ code, terminalOutput });
|
23
|
+
});
|
24
|
+
});
|
25
|
+
}
|
26
|
+
onExit(cb) {
|
27
|
+
this.exitCallbacks.push(cb);
|
28
|
+
}
|
29
|
+
send(message) {
|
30
|
+
for (const childProcess of this.childProcesses) {
|
31
|
+
childProcess.send(message);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
async kill(signal) {
|
35
|
+
await Promise.all(this.childProcesses.map(async (p) => {
|
36
|
+
try {
|
37
|
+
return p.kill();
|
38
|
+
}
|
39
|
+
catch (e) {
|
40
|
+
console.error(`Unable to terminate "${p.command}"\nError:`, e);
|
41
|
+
}
|
42
|
+
}));
|
43
|
+
}
|
44
|
+
async run() {
|
45
|
+
if (this.readyWhenStatus.length) {
|
46
|
+
let { childProcess, result: { code, terminalOutput }, } = await Promise.race(this.childProcesses.map((childProcess) => new Promise((res) => {
|
47
|
+
childProcess.onExit((code, terminalOutput) => {
|
48
|
+
res({
|
49
|
+
childProcess,
|
50
|
+
result: { code, terminalOutput },
|
51
|
+
});
|
52
|
+
});
|
53
|
+
})));
|
54
|
+
if (code !== 0) {
|
55
|
+
const output = `Warning: command "${childProcess.command}" exited with non-zero status code`;
|
56
|
+
terminalOutput += output;
|
57
|
+
if (this.streamOutput) {
|
58
|
+
process.stderr.write(output);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
for (const cb of this.exitCallbacks) {
|
62
|
+
cb(code, terminalOutput);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
else {
|
66
|
+
const results = await Promise.all(this.childProcesses.map((childProcess) => childProcess.getResults().then((result) => ({
|
67
|
+
childProcess,
|
68
|
+
result,
|
69
|
+
}))));
|
70
|
+
let terminalOutput = results
|
71
|
+
.map((r) => r.result.terminalOutput)
|
72
|
+
.join('\r\n');
|
73
|
+
const failed = results.filter((result) => result.result.code !== 0);
|
74
|
+
if (failed.length > 0) {
|
75
|
+
const output = failed
|
76
|
+
.map((failedResult) => `Warning: command "${failedResult.childProcess.command}" exited with non-zero status code`)
|
77
|
+
.join('\r\n');
|
78
|
+
terminalOutput += output;
|
79
|
+
if (this.streamOutput) {
|
80
|
+
process.stderr.write(output);
|
81
|
+
}
|
82
|
+
for (const cb of this.exitCallbacks) {
|
83
|
+
cb(1, terminalOutput);
|
84
|
+
}
|
85
|
+
}
|
86
|
+
else {
|
87
|
+
for (const cb of this.exitCallbacks) {
|
88
|
+
cb(0, terminalOutput);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
exports.ParallelRunningTasks = ParallelRunningTasks;
|
95
|
+
class SeriallyRunningTasks {
|
96
|
+
constructor(options, context, pseudoTerminal) {
|
97
|
+
this.pseudoTerminal = pseudoTerminal;
|
98
|
+
this.terminalOutput = '';
|
99
|
+
this.currentProcess = null;
|
100
|
+
this.exitCallbacks = [];
|
101
|
+
this.code = 0;
|
102
|
+
this.run(options, context)
|
103
|
+
.catch((e) => {
|
104
|
+
this.error = e;
|
105
|
+
})
|
106
|
+
.finally(() => {
|
107
|
+
for (const cb of this.exitCallbacks) {
|
108
|
+
cb(this.code, this.terminalOutput);
|
109
|
+
}
|
110
|
+
});
|
111
|
+
}
|
112
|
+
getResults() {
|
113
|
+
return new Promise((res, rej) => {
|
114
|
+
this.onExit((code) => {
|
115
|
+
if (this.error) {
|
116
|
+
rej(this.error);
|
117
|
+
}
|
118
|
+
else {
|
119
|
+
res({ code, terminalOutput: this.terminalOutput });
|
120
|
+
}
|
121
|
+
});
|
122
|
+
});
|
123
|
+
}
|
124
|
+
onExit(cb) {
|
125
|
+
this.exitCallbacks.push(cb);
|
126
|
+
}
|
127
|
+
send(message) {
|
128
|
+
throw new Error('Not implemented');
|
129
|
+
}
|
130
|
+
kill(signal) {
|
131
|
+
return this.currentProcess.kill(signal);
|
132
|
+
}
|
133
|
+
async run(options, context) {
|
134
|
+
for (const c of options.commands) {
|
135
|
+
const childProcess = await this.createProcess(c, [], options.color, calculateCwd(options.cwd, context), options.processEnv ?? options.env ?? {}, false, options.usePty, options.streamOutput, options.tty, options.envFile);
|
136
|
+
this.currentProcess = childProcess;
|
137
|
+
let { code, terminalOutput } = await childProcess.getResults();
|
138
|
+
this.terminalOutput += terminalOutput;
|
139
|
+
this.code = code;
|
140
|
+
if (code !== 0) {
|
141
|
+
const output = `Warning: command "${c.command}" exited with non-zero status code`;
|
142
|
+
terminalOutput += output;
|
143
|
+
if (options.streamOutput) {
|
144
|
+
process.stderr.write(output);
|
145
|
+
}
|
146
|
+
this.terminalOutput += terminalOutput;
|
147
|
+
// Stop running commands
|
148
|
+
break;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
}
|
152
|
+
async createProcess(commandConfig, readyWhenStatus = [], color, cwd, env, isParallel, usePty = true, streamOutput = true, tty, envFile) {
|
153
|
+
// The rust runCommand is always a tty, so it will not look nice in parallel and if we need prefixes
|
154
|
+
// currently does not work properly in windows
|
155
|
+
if (this.pseudoTerminal &&
|
156
|
+
process.env.NX_NATIVE_COMMAND_RUNNER !== 'false' &&
|
157
|
+
!commandConfig.prefix &&
|
158
|
+
readyWhenStatus.length === 0 &&
|
159
|
+
!isParallel &&
|
160
|
+
usePty) {
|
161
|
+
return createProcessWithPseudoTty(this.pseudoTerminal, commandConfig, color, cwd, env, streamOutput, tty, envFile);
|
162
|
+
}
|
163
|
+
return new RunningNodeProcess(commandConfig, color, cwd, env, readyWhenStatus, streamOutput, envFile);
|
164
|
+
}
|
165
|
+
}
|
166
|
+
exports.SeriallyRunningTasks = SeriallyRunningTasks;
|
167
|
+
class RunningNodeProcess {
|
168
|
+
constructor(commandConfig, color, cwd, env, readyWhenStatus, streamOutput = true, envFile) {
|
169
|
+
this.readyWhenStatus = readyWhenStatus;
|
170
|
+
this.terminalOutput = '';
|
171
|
+
this.exitCallbacks = [];
|
172
|
+
env = processEnv(color, cwd, env, envFile);
|
173
|
+
this.command = commandConfig.command;
|
174
|
+
this.terminalOutput = chalk.dim('> ') + commandConfig.command + '\r\n\r\n';
|
175
|
+
if (streamOutput) {
|
176
|
+
process.stdout.write(this.terminalOutput);
|
177
|
+
}
|
178
|
+
this.childProcess = (0, child_process_1.exec)(commandConfig.command, {
|
179
|
+
maxBuffer: run_commands_impl_1.LARGE_BUFFER,
|
180
|
+
env,
|
181
|
+
cwd,
|
182
|
+
windowsHide: false,
|
183
|
+
});
|
184
|
+
this.addListeners(commandConfig, streamOutput);
|
185
|
+
}
|
186
|
+
getResults() {
|
187
|
+
return new Promise((res) => {
|
188
|
+
this.onExit((code, terminalOutput) => {
|
189
|
+
res({ code, terminalOutput });
|
190
|
+
});
|
191
|
+
});
|
192
|
+
}
|
193
|
+
onExit(cb) {
|
194
|
+
this.exitCallbacks.push(cb);
|
195
|
+
}
|
196
|
+
send(message) {
|
197
|
+
this.childProcess.send(message);
|
198
|
+
}
|
199
|
+
kill(signal) {
|
200
|
+
return new Promise((res, rej) => {
|
201
|
+
treeKill(this.childProcess.pid, signal, (err) => {
|
202
|
+
if (err) {
|
203
|
+
rej(err);
|
204
|
+
}
|
205
|
+
else {
|
206
|
+
res();
|
207
|
+
}
|
208
|
+
});
|
209
|
+
});
|
210
|
+
}
|
211
|
+
addListeners(commandConfig, streamOutput) {
|
212
|
+
this.childProcess.stdout.on('data', (data) => {
|
213
|
+
const output = addColorAndPrefix(data, commandConfig);
|
214
|
+
this.terminalOutput += output;
|
215
|
+
if (streamOutput) {
|
216
|
+
process.stdout.write(output);
|
217
|
+
}
|
218
|
+
if (this.readyWhenStatus.length &&
|
219
|
+
isReady(this.readyWhenStatus, data.toString())) {
|
220
|
+
for (const cb of this.exitCallbacks) {
|
221
|
+
cb(0, this.terminalOutput);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
});
|
225
|
+
this.childProcess.stderr.on('data', (err) => {
|
226
|
+
const output = addColorAndPrefix(err, commandConfig);
|
227
|
+
this.terminalOutput += output;
|
228
|
+
if (streamOutput) {
|
229
|
+
process.stderr.write(output);
|
230
|
+
}
|
231
|
+
if (this.readyWhenStatus.length &&
|
232
|
+
isReady(this.readyWhenStatus, err.toString())) {
|
233
|
+
for (const cb of this.exitCallbacks) {
|
234
|
+
cb(1, this.terminalOutput);
|
235
|
+
}
|
236
|
+
}
|
237
|
+
});
|
238
|
+
this.childProcess.on('error', (err) => {
|
239
|
+
const output = addColorAndPrefix(err.toString(), commandConfig);
|
240
|
+
this.terminalOutput += output;
|
241
|
+
if (streamOutput) {
|
242
|
+
process.stderr.write(output);
|
243
|
+
}
|
244
|
+
for (const cb of this.exitCallbacks) {
|
245
|
+
cb(1, this.terminalOutput);
|
246
|
+
}
|
247
|
+
});
|
248
|
+
this.childProcess.on('exit', (code) => {
|
249
|
+
if (!this.readyWhenStatus.length || isReady(this.readyWhenStatus)) {
|
250
|
+
for (const cb of this.exitCallbacks) {
|
251
|
+
cb(code, this.terminalOutput);
|
252
|
+
}
|
253
|
+
}
|
254
|
+
});
|
255
|
+
}
|
256
|
+
}
|
257
|
+
async function createProcessWithPseudoTty(pseudoTerminal, commandConfig, color, cwd, env, streamOutput = true, tty, envFile) {
|
258
|
+
let terminalOutput = chalk.dim('> ') + commandConfig.command + '\r\n\r\n';
|
259
|
+
if (streamOutput) {
|
260
|
+
process.stdout.write(terminalOutput);
|
261
|
+
}
|
262
|
+
env = processEnv(color, cwd, env, envFile);
|
263
|
+
const childProcess = pseudoTerminal.runCommand(commandConfig.command, {
|
264
|
+
cwd,
|
265
|
+
jsEnv: env,
|
266
|
+
quiet: !streamOutput,
|
267
|
+
tty,
|
268
|
+
});
|
269
|
+
childProcess.onOutput((output) => {
|
270
|
+
terminalOutput += output;
|
271
|
+
});
|
272
|
+
return childProcess;
|
273
|
+
}
|
274
|
+
function addColorAndPrefix(out, config) {
|
275
|
+
if (config.prefix) {
|
276
|
+
out = out
|
277
|
+
.split('\n')
|
278
|
+
.map((l) => {
|
279
|
+
let prefixText = config.prefix;
|
280
|
+
if (config.prefixColor && chalk[config.prefixColor]) {
|
281
|
+
prefixText = chalk[config.prefixColor](prefixText);
|
282
|
+
}
|
283
|
+
prefixText = chalk.bold(prefixText);
|
284
|
+
return l.trim().length > 0 ? `${prefixText} ${l}` : l;
|
285
|
+
})
|
286
|
+
.join('\n');
|
287
|
+
}
|
288
|
+
if (config.color && chalk[config.color]) {
|
289
|
+
out = chalk[config.color](out);
|
290
|
+
}
|
291
|
+
if (config.bgColor && chalk[config.bgColor]) {
|
292
|
+
out = chalk[config.bgColor](out);
|
293
|
+
}
|
294
|
+
return out;
|
295
|
+
}
|
296
|
+
function calculateCwd(cwd, context) {
|
297
|
+
if (!cwd)
|
298
|
+
return context.root;
|
299
|
+
if ((0, path_1.isAbsolute)(cwd))
|
300
|
+
return cwd;
|
301
|
+
return (0, path_1.join)(context.root, cwd);
|
302
|
+
}
|
303
|
+
/**
|
304
|
+
* Env variables are processed in the following order:
|
305
|
+
* - env option from executor options
|
306
|
+
* - env file from envFile option if provided
|
307
|
+
* - local env variables
|
308
|
+
*/
|
309
|
+
function processEnv(color, cwd, envOptionFromExecutor, envFile) {
|
310
|
+
let localEnv = (0, npm_run_path_1.env)({ cwd: cwd ?? process.cwd() });
|
311
|
+
localEnv = {
|
312
|
+
...process.env,
|
313
|
+
...localEnv,
|
314
|
+
};
|
315
|
+
if (process.env.NX_LOAD_DOT_ENV_FILES !== 'false' && envFile) {
|
316
|
+
loadEnvVarsFile(envFile, localEnv);
|
317
|
+
}
|
318
|
+
let res = {
|
319
|
+
...localEnv,
|
320
|
+
...envOptionFromExecutor,
|
321
|
+
};
|
322
|
+
// need to override PATH to make sure we are using the local node_modules
|
323
|
+
if (localEnv.PATH)
|
324
|
+
res.PATH = localEnv.PATH; // UNIX-like
|
325
|
+
if (localEnv.Path)
|
326
|
+
res.Path = localEnv.Path; // Windows
|
327
|
+
if (color) {
|
328
|
+
res.FORCE_COLOR = `${color}`;
|
329
|
+
}
|
330
|
+
return res;
|
331
|
+
}
|
332
|
+
function isReady(readyWhenStatus = [], data) {
|
333
|
+
if (data) {
|
334
|
+
for (const readyWhenElement of readyWhenStatus) {
|
335
|
+
if (data.toString().indexOf(readyWhenElement.stringToMatch) > -1) {
|
336
|
+
readyWhenElement.found = true;
|
337
|
+
break;
|
338
|
+
}
|
339
|
+
}
|
340
|
+
}
|
341
|
+
return readyWhenStatus.every((readyWhenElement) => readyWhenElement.found);
|
342
|
+
}
|
343
|
+
function loadEnvVarsFile(path, env = {}) {
|
344
|
+
(0, task_env_1.unloadDotEnvFile)(path, env);
|
345
|
+
const result = (0, task_env_1.loadAndExpandDotEnvFile)(path, env);
|
346
|
+
if (result.error) {
|
347
|
+
throw result.error;
|
348
|
+
}
|
349
|
+
}
|
package/src/native/index.d.ts
CHANGED
Binary file
|
@@ -11,6 +11,9 @@ export declare class ProcessTasks {
|
|
11
11
|
readonly dependencies: {
|
12
12
|
[k: string]: string[];
|
13
13
|
};
|
14
|
+
readonly continuousDependencies: {
|
15
|
+
[k: string]: string[];
|
16
|
+
};
|
14
17
|
private readonly allTargetNames;
|
15
18
|
constructor(extraTargetDependencies: TargetDependencies, projectGraph: ProjectGraph);
|
16
19
|
processTasks(projectNames: string[], targets: string[], configuration: string, overrides: Object, excludeTaskDependencies: boolean): string[];
|
@@ -17,6 +17,7 @@ class ProcessTasks {
|
|
17
17
|
this.seen = new Set();
|
18
18
|
this.tasks = {};
|
19
19
|
this.dependencies = {};
|
20
|
+
this.continuousDependencies = {};
|
20
21
|
const allTargetNames = new Set();
|
21
22
|
for (const projectName in projectGraph.nodes) {
|
22
23
|
const project = projectGraph.nodes[projectName];
|
@@ -36,6 +37,7 @@ class ProcessTasks {
|
|
36
37
|
const task = this.createTask(id, project, target, resolvedConfiguration, overrides);
|
37
38
|
this.tasks[task.id] = task;
|
38
39
|
this.dependencies[task.id] = [];
|
40
|
+
this.continuousDependencies[task.id] = [];
|
39
41
|
}
|
40
42
|
}
|
41
43
|
}
|
@@ -50,11 +52,15 @@ class ProcessTasks {
|
|
50
52
|
if (!initialTasks[t]) {
|
51
53
|
delete this.tasks[t];
|
52
54
|
delete this.dependencies[t];
|
55
|
+
delete this.continuousDependencies[t];
|
53
56
|
}
|
54
57
|
}
|
55
58
|
for (let d of Object.keys(this.dependencies)) {
|
56
59
|
this.dependencies[d] = this.dependencies[d].filter((dd) => !!initialTasks[dd]);
|
57
60
|
}
|
61
|
+
for (let d of Object.keys(this.continuousDependencies)) {
|
62
|
+
this.continuousDependencies[d] = this.continuousDependencies[d].filter((dd) => !!initialTasks[dd]);
|
63
|
+
}
|
58
64
|
}
|
59
65
|
filterDummyTasks(this.dependencies);
|
60
66
|
for (const taskId of Object.keys(this.dependencies)) {
|
@@ -64,7 +70,16 @@ class ProcessTasks {
|
|
64
70
|
];
|
65
71
|
}
|
66
72
|
}
|
67
|
-
|
73
|
+
filterDummyTasks(this.continuousDependencies);
|
74
|
+
for (const taskId of Object.keys(this.continuousDependencies)) {
|
75
|
+
if (this.continuousDependencies[taskId].length > 0) {
|
76
|
+
this.continuousDependencies[taskId] = [
|
77
|
+
...new Set(this.continuousDependencies[taskId].filter((d) => d !== taskId)).values(),
|
78
|
+
];
|
79
|
+
}
|
80
|
+
}
|
81
|
+
return Object.keys(this.tasks).filter((d) => this.dependencies[d].length === 0 &&
|
82
|
+
this.continuousDependencies[d].length === 0);
|
68
83
|
}
|
69
84
|
processTask(task, projectUsedToDeriveDependencies, configuration, overrides) {
|
70
85
|
const seenKey = `${task.id}-${projectUsedToDeriveDependencies}`;
|
@@ -106,15 +121,21 @@ class ProcessTasks {
|
|
106
121
|
if ((0, project_graph_utils_1.projectHasTarget)(selfProject, dependencyConfig.target)) {
|
107
122
|
const resolvedConfiguration = this.resolveConfiguration(selfProject, dependencyConfig.target, configuration);
|
108
123
|
const selfTaskId = this.getId(selfProject.name, dependencyConfig.target, resolvedConfiguration);
|
109
|
-
if (task.id !== selfTaskId) {
|
110
|
-
this.dependencies[task.id].push(selfTaskId);
|
111
|
-
}
|
112
124
|
if (!this.tasks[selfTaskId]) {
|
113
125
|
const newTask = this.createTask(selfTaskId, selfProject, dependencyConfig.target, resolvedConfiguration, taskOverrides);
|
114
126
|
this.tasks[selfTaskId] = newTask;
|
115
127
|
this.dependencies[selfTaskId] = [];
|
128
|
+
this.continuousDependencies[selfTaskId] = [];
|
116
129
|
this.processTask(newTask, newTask.target.project, configuration, overrides);
|
117
130
|
}
|
131
|
+
if (task.id !== selfTaskId) {
|
132
|
+
if (this.tasks[selfTaskId].continuous) {
|
133
|
+
this.continuousDependencies[task.id].push(selfTaskId);
|
134
|
+
}
|
135
|
+
else {
|
136
|
+
this.dependencies[task.id].push(selfTaskId);
|
137
|
+
}
|
138
|
+
}
|
118
139
|
}
|
119
140
|
}
|
120
141
|
processTasksForDependencies(projectUsedToDeriveDependencies, dependencyConfig, configuration, task, taskOverrides, overrides) {
|
@@ -129,13 +150,20 @@ class ProcessTasks {
|
|
129
150
|
if ((0, project_graph_utils_1.projectHasTarget)(depProject, dependencyConfig.target)) {
|
130
151
|
const resolvedConfiguration = this.resolveConfiguration(depProject, dependencyConfig.target, configuration);
|
131
152
|
const depTargetId = this.getId(depProject.name, dependencyConfig.target, resolvedConfiguration);
|
153
|
+
const depTargetConfiguration = this.projectGraph.nodes[depProject.name].data.targets[dependencyConfig.target];
|
132
154
|
if (task.id !== depTargetId) {
|
133
|
-
|
155
|
+
if (depTargetConfiguration.continuous) {
|
156
|
+
this.continuousDependencies[task.id].push(depTargetId);
|
157
|
+
}
|
158
|
+
else {
|
159
|
+
this.dependencies[task.id].push(depTargetId);
|
160
|
+
}
|
134
161
|
}
|
135
162
|
if (!this.tasks[depTargetId]) {
|
136
163
|
const newTask = this.createTask(depTargetId, depProject, dependencyConfig.target, resolvedConfiguration, taskOverrides);
|
137
164
|
this.tasks[depTargetId] = newTask;
|
138
165
|
this.dependencies[depTargetId] = [];
|
166
|
+
this.continuousDependencies[depTargetId] = [];
|
139
167
|
this.processTask(newTask, newTask.target.project, configuration, overrides);
|
140
168
|
}
|
141
169
|
}
|
@@ -147,6 +175,7 @@ class ProcessTasks {
|
|
147
175
|
DUMMY_TASK_TARGET, undefined);
|
148
176
|
this.dependencies[task.id].push(dummyId);
|
149
177
|
this.dependencies[dummyId] ??= [];
|
178
|
+
this.continuousDependencies[dummyId] ??= [];
|
150
179
|
const noopTask = this.createDummyTask(dummyId, task);
|
151
180
|
this.processTask(noopTask, depProject.name, configuration, overrides);
|
152
181
|
}
|
@@ -179,6 +208,7 @@ class ProcessTasks {
|
|
179
208
|
outputs: (0, utils_1.getOutputs)(this.projectGraph.nodes, qualifiedTarget, interpolatedOverrides),
|
180
209
|
cache: project.data.targets[target].cache,
|
181
210
|
parallelism: project.data.targets[target].parallelism ?? true,
|
211
|
+
continuous: project.data.targets[target].continuous ?? false,
|
182
212
|
};
|
183
213
|
}
|
184
214
|
resolveConfiguration(project, target, configuration) {
|
@@ -204,6 +234,7 @@ function createTaskGraph(projectGraph, extraTargetDependencies, projectNames, ta
|
|
204
234
|
roots,
|
205
235
|
tasks: p.tasks,
|
206
236
|
dependencies: p.dependencies,
|
237
|
+
continuousDependencies: p.continuousDependencies,
|
207
238
|
};
|
208
239
|
}
|
209
240
|
function mapTargetDefaultsToDependencies(defaults) {
|
@@ -1,7 +1,9 @@
|
|
1
1
|
import { DefaultTasksRunnerOptions } from './default-tasks-runner';
|
2
2
|
import { Batch } from './tasks-schedule';
|
3
|
-
import { BatchResults } from './batch/batch-messages';
|
4
3
|
import { Task, TaskGraph } from '../config/task-graph';
|
4
|
+
import { PseudoTtyProcess } from './pseudo-terminal';
|
5
|
+
import { BatchProcess } from './running-tasks/batch-process';
|
6
|
+
import { RunningTask } from './running-tasks/running-task';
|
5
7
|
export declare class ForkedProcessTaskRunner {
|
6
8
|
private readonly options;
|
7
9
|
cliPath: string;
|
@@ -10,17 +12,14 @@ export declare class ForkedProcessTaskRunner {
|
|
10
12
|
private pseudoTerminal;
|
11
13
|
constructor(options: DefaultTasksRunnerOptions);
|
12
14
|
init(): Promise<void>;
|
13
|
-
forkProcessForBatch({ executorName, taskGraph: batchTaskGraph }: Batch, fullTaskGraph: TaskGraph, env: NodeJS.ProcessEnv): Promise<
|
15
|
+
forkProcessForBatch({ executorName, taskGraph: batchTaskGraph }: Batch, fullTaskGraph: TaskGraph, env: NodeJS.ProcessEnv): Promise<BatchProcess>;
|
14
16
|
forkProcessLegacy(task: Task, { temporaryOutputPath, streamOutput, pipeOutput, taskGraph, env, }: {
|
15
17
|
temporaryOutputPath: string;
|
16
18
|
streamOutput: boolean;
|
17
19
|
pipeOutput: boolean;
|
18
20
|
taskGraph: TaskGraph;
|
19
21
|
env: NodeJS.ProcessEnv;
|
20
|
-
}): Promise<
|
21
|
-
code: number;
|
22
|
-
terminalOutput: string;
|
23
|
-
}>;
|
22
|
+
}): Promise<RunningTask>;
|
24
23
|
forkProcess(task: Task, { temporaryOutputPath, streamOutput, taskGraph, env, disablePseudoTerminal, }: {
|
25
24
|
temporaryOutputPath: string;
|
26
25
|
streamOutput: boolean;
|
@@ -28,15 +27,10 @@ export declare class ForkedProcessTaskRunner {
|
|
28
27
|
taskGraph: TaskGraph;
|
29
28
|
env: NodeJS.ProcessEnv;
|
30
29
|
disablePseudoTerminal: boolean;
|
31
|
-
}): Promise<
|
32
|
-
code: number;
|
33
|
-
terminalOutput: string;
|
34
|
-
}>;
|
30
|
+
}): Promise<RunningTask | PseudoTtyProcess>;
|
35
31
|
private forkProcessWithPseudoTerminal;
|
36
|
-
private forkProcessPipeOutputCapture;
|
37
32
|
private forkProcessWithPrefixAndNotTTY;
|
38
33
|
private forkProcessDirectOutputCapture;
|
39
|
-
private readTerminalOutput;
|
40
34
|
private writeTerminalOutput;
|
41
35
|
private setupProcessEventListeners;
|
42
36
|
}
|