nx 23.3.0-beta.0 → 23.3.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/src/command-line/format/format.js +2 -18
- package/dist/src/command-line/graph/graph.js +42 -3
- package/dist/src/command-line/init/implementation/add-nx-to-monorepo.js +0 -3
- package/dist/src/command-line/init/implementation/add-nx-to-nest.js +0 -3
- package/dist/src/command-line/init/implementation/add-nx-to-npm-repo.js +0 -3
- package/dist/src/command-line/init/implementation/angular/index.js +0 -3
- package/dist/src/command-line/init/implementation/angular/legacy-angular-versions.js +0 -3
- package/dist/src/command-line/init/implementation/format.js +2 -3
- package/dist/src/command-line/init/implementation/utils.d.ts +0 -1
- package/dist/src/command-line/init/implementation/utils.js +0 -8
- package/dist/src/command-line/init/init-v2.js +0 -3
- package/dist/src/command-line/migrate/agentic/definitions.js +75 -19
- package/dist/src/command-line/migrate/agentic/format-command.d.ts +14 -0
- package/dist/src/command-line/migrate/agentic/format-command.js +44 -0
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +3 -3
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +3 -3
- package/dist/src/command-line/migrate/agentic/handoff.d.ts +27 -17
- package/dist/src/command-line/migrate/agentic/handoff.js +107 -24
- package/dist/src/command-line/migrate/agentic/instruction-files.d.ts +21 -0
- package/dist/src/command-line/migrate/agentic/instruction-files.js +36 -0
- package/dist/src/command-line/migrate/agentic/prompts/fragments.d.ts +16 -0
- package/dist/src/command-line/migrate/agentic/prompts/fragments.js +70 -0
- package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +4 -3
- package/dist/src/command-line/migrate/agentic/prompts/system-prompt.d.ts +25 -1
- package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +57 -34
- package/dist/src/command-line/migrate/agentic/run-step.js +28 -4
- package/dist/src/command-line/migrate/agentic/runner.d.ts +17 -8
- package/dist/src/command-line/migrate/agentic/runner.js +110 -55
- package/dist/src/command-line/migrate/agentic/types.d.ts +23 -8
- package/dist/src/command-line/migrate/agentic/types.js +10 -7
- package/dist/src/command-line/migrate/migrate-commits.d.ts +1 -0
- package/dist/src/command-line/migrate/migrate-commits.js +9 -0
- package/dist/src/command-line/migrate/migrate-output.d.ts +3 -7
- package/dist/src/command-line/migrate/migrate-output.js +3 -7
- package/dist/src/command-line/migrate/migrate.js +21 -8
- package/dist/src/command-line/migrate/run/agent-output.d.ts +10 -0
- package/dist/src/command-line/migrate/run/agent-output.js +16 -2
- package/dist/src/command-line/migrate/run/agent-work-payload.d.ts +37 -0
- package/dist/src/command-line/migrate/run/agent-work-payload.js +142 -0
- package/dist/src/command-line/migrate/run/atomic-write.d.ts +8 -0
- package/dist/src/command-line/migrate/run/atomic-write.js +17 -0
- package/dist/src/command-line/migrate/run/index.d.ts +1 -1
- package/dist/src/command-line/migrate/run/issues.d.ts +106 -0
- package/dist/src/command-line/migrate/run/issues.js +980 -0
- package/dist/src/command-line/migrate/run/orchestrator.d.ts +1 -0
- package/dist/src/command-line/migrate/run/orchestrator.js +662 -105
- package/dist/src/command-line/migrate/run/run-state.d.ts +43 -8
- package/dist/src/command-line/migrate/run/run-state.js +184 -20
- package/dist/src/command-line/migrate/run/runbook.d.ts +17 -0
- package/dist/src/command-line/migrate/run/runbook.js +97 -0
- package/dist/src/command-line/migrate/run/state-lock.d.ts +2 -2
- package/dist/src/command-line/migrate/run/state-lock.js +2 -2
- package/dist/src/command-line/migrate/run/state-machine.d.ts +5 -1
- package/dist/src/command-line/migrate/run/state-machine.js +27 -1
- package/dist/src/command-line/migrate/run/worker.js +206 -56
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +5 -11
- package/dist/src/command-line/release/publish.js +11 -4
- package/dist/src/command-line/release/utils/remote-release-clients/github.js +3 -3
- package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +3 -3
- package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.d.ts +2 -0
- package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.js +35 -0
- package/dist/src/command-line/report/report.d.ts +2 -0
- package/dist/src/command-line/report/report.js +28 -1
- package/dist/src/command-line/yargs-utils/shared-options.d.ts +1 -1
- package/dist/src/command-line/yargs-utils/shared-options.js +22 -4
- package/dist/src/config/workspace-json-project-json.d.ts +2 -0
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/daemon/client/client.d.ts +6 -2
- package/dist/src/daemon/client/client.js +27 -11
- package/dist/src/daemon/message-types/get-plugin-capabilities.d.ts +5 -0
- package/dist/src/daemon/message-types/get-plugin-capabilities.js +11 -0
- package/dist/src/daemon/message-types/run-tasks-execution-hooks.d.ts +3 -2
- package/dist/src/daemon/server/handle-get-plugin-capabilities.d.ts +2 -0
- package/dist/src/daemon/server/handle-get-plugin-capabilities.js +13 -0
- package/dist/src/daemon/server/handle-hash-tasks.d.ts +8 -2
- package/dist/src/daemon/server/handle-hash-tasks.js +16 -3
- package/dist/src/daemon/server/handle-outputs-changes.d.ts +2 -2
- package/dist/src/daemon/server/handle-outputs-changes.js +21 -6
- package/dist/src/daemon/server/handle-tasks-execution-hooks.d.ts +3 -2
- package/dist/src/daemon/server/outputs-tracking.d.ts +6 -0
- package/dist/src/daemon/server/outputs-tracking.js +18 -0
- package/dist/src/daemon/server/project-graph-incremental-recomputation.d.ts +22 -7
- package/dist/src/daemon/server/project-graph-incremental-recomputation.js +100 -70
- package/dist/src/daemon/server/restart-checks.d.ts +22 -0
- package/dist/src/daemon/server/restart-checks.js +77 -0
- package/dist/src/daemon/server/server.js +33 -18
- package/dist/src/daemon/server/shutdown-utils.d.ts +0 -5
- package/dist/src/daemon/server/shutdown-utils.js +3 -26
- package/dist/src/hasher/hash-task.js +20 -16
- package/dist/src/hasher/native-task-hasher-impl.d.ts +8 -0
- package/dist/src/hasher/native-task-hasher-impl.js +46 -3
- package/dist/src/hasher/task-hasher.d.ts +9 -0
- package/dist/src/hasher/task-hasher.js +14 -0
- package/dist/src/native/index.d.ts +222 -21
- package/dist/src/native/index.js +3 -3
- package/dist/src/native/native-bindings.js +4 -1
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/plugins/js/lock-file/pnpm-parser.js +1 -1
- package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.d.ts +2 -0
- package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +22 -0
- package/dist/src/plugins/js/utils/register.js +2 -1
- package/dist/src/project-graph/affected/locators/project-glob-changes.js +19 -26
- package/dist/src/project-graph/error-types.d.ts +5 -0
- package/dist/src/project-graph/error-types.js +44 -5
- package/dist/src/project-graph/file-utils.d.ts +2 -0
- package/dist/src/project-graph/file-utils.js +6 -1
- package/dist/src/project-graph/nx-deps-cache.d.ts +5 -2
- package/dist/src/project-graph/nx-deps-cache.js +4 -4
- package/dist/src/project-graph/plugins/get-plugins.d.ts +3 -1
- package/dist/src/project-graph/plugins/get-plugins.js +60 -82
- package/dist/src/project-graph/plugins/in-process-loader.d.ts +1 -1
- package/dist/src/project-graph/plugins/in-process-loader.js +1 -4
- package/dist/src/project-graph/plugins/isolation/index.d.ts +1 -1
- package/dist/src/project-graph/plugins/isolation/index.js +3 -1
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.d.ts +8 -0
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +42 -6
- package/dist/src/project-graph/plugins/isolation/load-isolated-plugin.d.ts +10 -1
- package/dist/src/project-graph/plugins/isolation/load-isolated-plugin.js +67 -17
- package/dist/src/project-graph/plugins/isolation/messaging.d.ts +3 -2
- package/dist/src/project-graph/plugins/isolation/plugin-worker.js +5 -1
- package/dist/src/project-graph/plugins/loaded-nx-plugin.d.ts +5 -2
- package/dist/src/project-graph/plugins/loaded-nx-plugin.js +14 -1
- package/dist/src/project-graph/plugins/nx-plugin-capabilities.d.ts +6 -0
- package/dist/src/project-graph/plugins/nx-plugin-capabilities.js +28 -0
- package/dist/src/project-graph/plugins/task-results-stub.d.ts +50 -0
- package/dist/src/project-graph/plugins/task-results-stub.js +111 -0
- package/dist/src/project-graph/plugins/tasks-execution-hooks.d.ts +3 -2
- package/dist/src/project-graph/plugins/tasks-execution-hooks.js +14 -1
- package/dist/src/project-graph/project-graph.js +43 -42
- package/dist/src/tasks-runner/batch/run-batch.js +15 -0
- package/dist/src/tasks-runner/cache.d.ts +35 -0
- package/dist/src/tasks-runner/cache.js +40 -0
- package/dist/src/tasks-runner/create-task-graph.js +1 -0
- package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
- package/dist/src/tasks-runner/forked-process-task-runner.d.ts +1 -1
- package/dist/src/tasks-runner/forked-process-task-runner.js +8 -7
- package/dist/src/tasks-runner/init-tasks-runner.js +5 -1
- package/dist/src/tasks-runner/is-tui-enabled.js +4 -3
- package/dist/src/tasks-runner/life-cycle.d.ts +7 -0
- package/dist/src/tasks-runner/life-cycle.js +7 -0
- package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.d.ts +35 -0
- package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.js +146 -0
- package/dist/src/tasks-runner/prune-task-graph.d.ts +17 -0
- package/dist/src/tasks-runner/prune-task-graph.js +45 -0
- package/dist/src/tasks-runner/run-command.js +14 -3
- package/dist/src/tasks-runner/running-tasks/batch-process.d.ts +93 -19
- package/dist/src/tasks-runner/running-tasks/batch-process.js +184 -88
- package/dist/src/tasks-runner/task-orchestrator.d.ts +64 -2
- package/dist/src/tasks-runner/task-orchestrator.js +232 -46
- package/dist/src/tasks-runner/terminal-output-path.d.ts +11 -0
- package/dist/src/tasks-runner/terminal-output-path.js +18 -0
- package/dist/src/tasks-runner/utils.js +5 -2
- package/dist/src/utils/ab-testing.d.ts +4 -1
- package/dist/src/utils/ab-testing.js +11 -7
- package/dist/src/utils/chunkify.d.ts +1 -7
- package/dist/src/utils/chunkify.js +2 -8
- package/dist/src/utils/command-line-utils.d.ts +19 -0
- package/dist/src/utils/command-line-utils.js +10 -3
- package/dist/src/utils/formatters/index.d.ts +6 -0
- package/dist/src/utils/formatters/index.js +5 -0
- package/dist/src/utils/formatters/prettier.d.ts +0 -8
- package/dist/src/utils/formatters/prettier.js +4 -26
- package/dist/src/utils/handle-errors.js +5 -43
- package/dist/src/utils/installed-nx-version.js +2 -48
- package/dist/src/utils/min-release-age/packument.js +1 -1
- package/dist/src/utils/output.d.ts +22 -3
- package/dist/src/utils/output.js +28 -5
- package/dist/src/utils/package-json.d.ts +25 -0
- package/dist/src/utils/package-json.js +41 -6
- package/dist/src/utils/package-manager.d.ts +6 -0
- package/dist/src/utils/package-manager.js +10 -0
- package/dist/src/utils/plugins/plugin-capabilities.js +7 -2
- package/dist/src/utils/provenance.js +20 -4
- package/dist/src/utils/serialize-overrides-into-command-line.js +2 -4
- package/dist/src/utils/workspace-context.d.ts +47 -3
- package/dist/src/utils/workspace-context.js +162 -10
- package/package.json +12 -13
- package/schemas/nx-schema.json +4 -0
- package/schemas/project-schema.json +4 -0
- package/dist/src/daemon/server/file-watching/route-workspace-changes.d.ts +0 -9
- package/dist/src/daemon/server/file-watching/route-workspace-changes.js +0 -76
- package/dist/src/daemon/server/watcher.d.ts +0 -18
- package/dist/src/daemon/server/watcher.js +0 -126
|
@@ -37,9 +37,22 @@ const utils_1 = require("./utils");
|
|
|
37
37
|
function resolveBatchTaskStatus(result) {
|
|
38
38
|
return result.status ?? (result.success ? 'success' : 'failure');
|
|
39
39
|
}
|
|
40
|
+
/** Whether a path names a file with bytes in it. */
|
|
41
|
+
function hasContent(path) {
|
|
42
|
+
try {
|
|
43
|
+
return (0, fs_1.statSync)(path).size > 0;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
40
49
|
class TaskOrchestrator {
|
|
41
50
|
// endregion internal state
|
|
42
|
-
constructor(hasher, initiatingProject, initiatingTasks, projectGraph, taskGraph, nxJson, options, bail, daemon,
|
|
51
|
+
constructor(hasher, initiatingProject, initiatingTasks, projectGraph, taskGraph, nxJson, options, bail, daemon,
|
|
52
|
+
/** What the user named; undefined means they named nothing. */
|
|
53
|
+
specifiedOutputStyle,
|
|
54
|
+
/** What this run renders with, after defaults. */
|
|
55
|
+
resolvedOutputStyle, fullTaskGraph = taskGraph) {
|
|
43
56
|
this.hasher = hasher;
|
|
44
57
|
this.initiatingProject = initiatingProject;
|
|
45
58
|
this.initiatingTasks = initiatingTasks;
|
|
@@ -49,7 +62,8 @@ class TaskOrchestrator {
|
|
|
49
62
|
this.options = options;
|
|
50
63
|
this.bail = bail;
|
|
51
64
|
this.daemon = daemon;
|
|
52
|
-
this.
|
|
65
|
+
this.specifiedOutputStyle = specifiedOutputStyle;
|
|
66
|
+
this.resolvedOutputStyle = resolvedOutputStyle;
|
|
53
67
|
this.fullTaskGraph = fullTaskGraph;
|
|
54
68
|
this.taskDetails = (0, hash_task_1.getTaskDetails)();
|
|
55
69
|
this.cache = (0, cache_1.getCache)(this.options);
|
|
@@ -106,6 +120,13 @@ class TaskOrchestrator {
|
|
|
106
120
|
this.continuousTaskExitHandled = new Map();
|
|
107
121
|
this.cleanupPromise = null;
|
|
108
122
|
this.signalHandlers = [];
|
|
123
|
+
// Tasks whose runner already owns the write to
|
|
124
|
+
// `<cacheDir>/terminalOutputs/<hash>` — forked processes write it as they
|
|
125
|
+
// exit, and the paths that never spawn one write it inline. The backstop in
|
|
126
|
+
// postRunSteps consults this so a task's output is written exactly once.
|
|
127
|
+
this.tasksWithPersistedOutput = new Set();
|
|
128
|
+
/** Batches whose worker log was handed to the life cycle, so it must survive. */
|
|
129
|
+
this.announcedBatchLogs = new Set();
|
|
109
130
|
}
|
|
110
131
|
async init() {
|
|
111
132
|
this.setupSignalHandlers();
|
|
@@ -158,6 +179,10 @@ class TaskOrchestrator {
|
|
|
158
179
|
perf_hooks_1.performance.measure('task-execution', 'task-execution:start', 'task-execution:end');
|
|
159
180
|
if (!this.stopRequested) {
|
|
160
181
|
this.cache.removeOldCacheRecords();
|
|
182
|
+
// Free function, not a cache method: `BatchProcess` writes these logs
|
|
183
|
+
// whichever cache implementation is active. It no-ops under WASM, where
|
|
184
|
+
// the native half does not exist.
|
|
185
|
+
(0, cache_1.sweepBatchOutputs)();
|
|
161
186
|
}
|
|
162
187
|
await this.cleanup();
|
|
163
188
|
await this.dispose();
|
|
@@ -586,7 +611,7 @@ class TaskOrchestrator {
|
|
|
586
611
|
const runBatchStart = perf_hooks_1.performance.mark('TaskOrchestrator-run-batch:start');
|
|
587
612
|
let batchProcess;
|
|
588
613
|
try {
|
|
589
|
-
batchProcess = await this.forkedProcessTaskRunner.forkProcessForBatch(batch, this.projectGraph, this.fullTaskGraph, env);
|
|
614
|
+
batchProcess = await this.forkedProcessTaskRunner.forkProcessForBatch(batch, this.projectGraph, this.fullTaskGraph, env, (0, output_1.printsTaskOutput)(this.resolvedOutputStyle));
|
|
590
615
|
// Stream output from batch process to the batch
|
|
591
616
|
batchProcess.onOutput((output) => {
|
|
592
617
|
this.options.lifeCycle.appendBatchOutput?.(batch.id, output);
|
|
@@ -633,9 +658,13 @@ class TaskOrchestrator {
|
|
|
633
658
|
terminalOutput: result.terminalOutput,
|
|
634
659
|
};
|
|
635
660
|
});
|
|
661
|
+
// The capture stream buffers, so both readers below would otherwise be
|
|
662
|
+
// racing bytes that have not reached the file yet.
|
|
663
|
+
await batchProcess.flushCapturedOutput();
|
|
636
664
|
if ((0, output_1.shouldGroupBatchOutput)()) {
|
|
637
665
|
this.renderBatchOutputSafely(batch.id, () => this.printGroupedBatchOutput(batch, taskResults, batchProcess.getCapturedOutputPath()));
|
|
638
666
|
}
|
|
667
|
+
this.announceBatchWorkerLog(batch.id, taskResults, batchProcess.getCapturedOutputPath());
|
|
639
668
|
return taskResults;
|
|
640
669
|
}
|
|
641
670
|
catch (e) {
|
|
@@ -652,15 +681,19 @@ class TaskOrchestrator {
|
|
|
652
681
|
terminalOutput: isBatchStopping ? '' : (e.stack ?? e.message ?? ''),
|
|
653
682
|
};
|
|
654
683
|
});
|
|
684
|
+
await batchProcess?.flushCapturedOutput();
|
|
685
|
+
this.announceBatchWorkerLog(batch.id, taskResults, batchProcess?.getCapturedOutputPath());
|
|
655
686
|
// The worker died without reporting results, so nothing was attributed to
|
|
656
687
|
// a task and no per-task output ran. Everything it wrote went to
|
|
657
|
-
// stdout/stderr, held back under
|
|
658
|
-
//
|
|
659
|
-
//
|
|
660
|
-
//
|
|
661
|
-
//
|
|
662
|
-
//
|
|
663
|
-
|
|
688
|
+
// stdout/stderr, held back under grouping - surface it as one fold. Under
|
|
689
|
+
// a style that prints nothing there is no fold; the log is announced by
|
|
690
|
+
// path above instead. Outside both, it already streamed live. This
|
|
691
|
+
// matters just as much when the batch was stopped: every task
|
|
692
|
+
// is marked stopped whether or not it finished, so the log is the only
|
|
693
|
+
// record of what got through. Only the exit-code error is dropped there,
|
|
694
|
+
// since it restates the cancellation.
|
|
695
|
+
if ((0, output_1.shouldGroupBatchOutput)() &&
|
|
696
|
+
(0, output_1.printsTaskOutput)(this.resolvedOutputStyle)) {
|
|
664
697
|
const capturedOutputPath = batchProcess?.getCapturedOutputPath();
|
|
665
698
|
const trailer = isBatchStopping ? undefined : e.message;
|
|
666
699
|
if (capturedOutputPath || trailer) {
|
|
@@ -673,11 +706,42 @@ class TaskOrchestrator {
|
|
|
673
706
|
return taskResults;
|
|
674
707
|
}
|
|
675
708
|
finally {
|
|
676
|
-
|
|
709
|
+
// Kept only when something failed and the log was announced; an all-green
|
|
710
|
+
// batch's chatter explains nothing and would sit in `batchOutputs/` until
|
|
711
|
+
// the sweep.
|
|
712
|
+
if (!this.announcedBatchLogs.has(batch.id)) {
|
|
713
|
+
batchProcess?.discardCapturedOutput();
|
|
714
|
+
}
|
|
677
715
|
const runBatchEnd = perf_hooks_1.performance.mark('TaskOrchestrator-run-batch:end');
|
|
678
716
|
perf_hooks_1.performance.measure('TaskOrchestrator-run-batch', runBatchStart.name, runBatchEnd.name);
|
|
679
717
|
}
|
|
680
718
|
}
|
|
719
|
+
/**
|
|
720
|
+
* Tells the life cycle where the batch worker's own log is, when something
|
|
721
|
+
* failed and a style that prints nothing would otherwise leave it unread.
|
|
722
|
+
*
|
|
723
|
+
* The path is announced rather than the bytes copied into a task: one worker
|
|
724
|
+
* produces one log, it explains the batch rather than any single task, and a
|
|
725
|
+
* task's own output file is read back verbatim on a cache hit.
|
|
726
|
+
*/
|
|
727
|
+
announceBatchWorkerLog(batchId, results, capturedOutputPath) {
|
|
728
|
+
if (!capturedOutputPath || (0, output_1.printsTaskOutput)(this.resolvedOutputStyle)) {
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
const failed = results.some((r) => r.status === 'failure' || r.status === 'stopped');
|
|
732
|
+
if (!failed) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
// The path is minted when the file is opened, before any byte reaches it,
|
|
736
|
+
// so a capture that failed on its first write leaves one that exists and is
|
|
737
|
+
// empty. Announcing that offers the reader an address holding nothing.
|
|
738
|
+
// Checked after the flush, so the size is what a reader will actually see.
|
|
739
|
+
if (!hasContent(capturedOutputPath)) {
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
this.announcedBatchLogs.add(batchId);
|
|
743
|
+
this.options.lifeCycle.batchOutputAvailable?.(batchId, capturedOutputPath);
|
|
744
|
+
}
|
|
681
745
|
/**
|
|
682
746
|
* Rendering a batch's output must never change the batch's results. A throw
|
|
683
747
|
* from the printer would otherwise land in `runBatch`'s own error handling:
|
|
@@ -741,17 +805,20 @@ class TaskOrchestrator {
|
|
|
741
805
|
* A batch that never reported results is handled by the caller instead.
|
|
742
806
|
*/
|
|
743
807
|
printGroupedBatchOutput(batch, taskResults, capturedOutputPath) {
|
|
744
|
-
//
|
|
745
|
-
//
|
|
746
|
-
//
|
|
747
|
-
//
|
|
748
|
-
//
|
|
808
|
+
// Reads `resolvedOutputStyle` - what the run actually renders with. The
|
|
809
|
+
// streaming decision deliberately reads `specifiedOutputStyle` instead,
|
|
810
|
+
// since it has to tell a named style from an inferred default. `this.options`
|
|
811
|
+
// has its own `outputStyle`, merged from `nx.json`'s tasksRunnerOptions, so
|
|
812
|
+
// the two disagree whenever a style is configured there but not named on the
|
|
813
|
+
// command line.
|
|
749
814
|
const printsFullOutput = (0, output_1.printsFullTaskOutput)({
|
|
750
815
|
verbose: this.options.verbose,
|
|
751
|
-
outputStyle: this.
|
|
816
|
+
outputStyle: this.resolvedOutputStyle,
|
|
752
817
|
});
|
|
753
818
|
const batchOwnsTheDiagnostic = taskResults.some((r) => r.status === 'failure' || r.status === 'stopped');
|
|
754
|
-
if ((
|
|
819
|
+
if ((0, output_1.printsTaskOutput)(this.resolvedOutputStyle) &&
|
|
820
|
+
(printsFullOutput || batchOwnsTheDiagnostic) &&
|
|
821
|
+
capturedOutputPath) {
|
|
755
822
|
// No redirect lines: every task renders itself below, so there is nothing
|
|
756
823
|
// to redirect anyone to.
|
|
757
824
|
this.printBatchFold(batch, taskResults, { capturedOutputPath }, { redirectLines: false });
|
|
@@ -866,6 +933,10 @@ class TaskOrchestrator {
|
|
|
866
933
|
if (this.completedTasks.has(task.id))
|
|
867
934
|
return;
|
|
868
935
|
const terminalOutput = e?.message ?? '';
|
|
936
|
+
// The worker rejected, so whatever the runner was going to leave on disk
|
|
937
|
+
// either never landed or can't be trusted. Hand the file back to
|
|
938
|
+
// postRunSteps so the failure itself is what the task's output path holds.
|
|
939
|
+
this.tasksWithPersistedOutput.delete(task.id);
|
|
869
940
|
this.options.lifeCycle.printTaskTerminalOutput(task, 'failure', terminalOutput);
|
|
870
941
|
await this.postRunSteps([{ task, status: 'failure', terminalOutput }], doNotSkipCache, groupId);
|
|
871
942
|
}
|
|
@@ -880,7 +951,12 @@ class TaskOrchestrator {
|
|
|
880
951
|
await this.preRunSteps([task], { groupId });
|
|
881
952
|
const pipeOutput = await this.pipeOutputCapture(task);
|
|
882
953
|
const temporaryOutputPath = this.cache.temporaryOutputPath(task);
|
|
883
|
-
|
|
954
|
+
// `summary` prints log paths rather than logs, and `shouldStreamOutput`
|
|
955
|
+
// would otherwise stream the initiating project's output in full - the one
|
|
956
|
+
// task a run-one is most likely to have. Continuous tasks are deliberately
|
|
957
|
+
// NOT suppressed the same way; see `startContinuousTask`.
|
|
958
|
+
const streamOutput = (0, output_1.isStaticOutputStyle)(this.specifiedOutputStyle) ||
|
|
959
|
+
!(0, output_1.printsTaskOutput)(this.resolvedOutputStyle)
|
|
884
960
|
? false
|
|
885
961
|
: (0, utils_1.shouldStreamOutput)(task, this.initiatingProject);
|
|
886
962
|
const env = pipeOutput
|
|
@@ -970,13 +1046,18 @@ class TaskOrchestrator {
|
|
|
970
1046
|
});
|
|
971
1047
|
}
|
|
972
1048
|
}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
runningTask.onExit((code, terminalOutput) => {
|
|
1049
|
+
runningTask.onExit((code, terminalOutput) => {
|
|
1050
|
+
if (!streamOutput && !shouldPrefix) {
|
|
976
1051
|
this.options.lifeCycle.printTaskTerminalOutput(task, code === 0 ? 'success' : 'failure', terminalOutput);
|
|
1052
|
+
}
|
|
1053
|
+
// A continuous task never reaches postRunSteps, so exiting is its
|
|
1054
|
+
// only chance to leave its output on disk. A discrete one is written
|
|
1055
|
+
// there instead, whatever its output style — writing here too would
|
|
1056
|
+
// just duplicate it.
|
|
1057
|
+
if (task.continuous) {
|
|
977
1058
|
(0, fs_1.writeFileSync)(temporaryOutputPath, terminalOutput);
|
|
978
|
-
}
|
|
979
|
-
}
|
|
1059
|
+
}
|
|
1060
|
+
});
|
|
980
1061
|
return runningTask;
|
|
981
1062
|
}
|
|
982
1063
|
catch (e) {
|
|
@@ -988,6 +1069,7 @@ class TaskOrchestrator {
|
|
|
988
1069
|
}
|
|
989
1070
|
const terminalOutput = e.stack ?? e.message ?? '';
|
|
990
1071
|
(0, fs_1.writeFileSync)(temporaryOutputPath, terminalOutput);
|
|
1072
|
+
this.tasksWithPersistedOutput.add(task.id);
|
|
991
1073
|
return new noop_child_process_1.NoopChildProcess({
|
|
992
1074
|
code: 1,
|
|
993
1075
|
terminalOutput,
|
|
@@ -996,6 +1078,7 @@ class TaskOrchestrator {
|
|
|
996
1078
|
}
|
|
997
1079
|
else if (targetConfiguration.executor === 'nx:noop') {
|
|
998
1080
|
(0, fs_1.writeFileSync)(temporaryOutputPath, '');
|
|
1081
|
+
this.tasksWithPersistedOutput.add(task.id);
|
|
999
1082
|
return new noop_child_process_1.NoopChildProcess({
|
|
1000
1083
|
code: 0,
|
|
1001
1084
|
terminalOutput: '',
|
|
@@ -1004,6 +1087,12 @@ class TaskOrchestrator {
|
|
|
1004
1087
|
else {
|
|
1005
1088
|
// cache prep
|
|
1006
1089
|
const runningTask = await this.runTaskInForkedProcess(task, env, pipeOutput, temporaryOutputPath, streamOutput);
|
|
1090
|
+
// Every forked path leaves the file behind whatever the output style:
|
|
1091
|
+
// the pseudo-terminal and prefixed processes write it when they exit,
|
|
1092
|
+
// the direct-output capture has the child write it itself, and the
|
|
1093
|
+
// fork-failure fallback writes the error. Continuous tasks depend on
|
|
1094
|
+
// that — they never reach postRunSteps.
|
|
1095
|
+
this.tasksWithPersistedOutput.add(task.id);
|
|
1007
1096
|
if (this.tuiEnabled) {
|
|
1008
1097
|
if (runningTask instanceof pseudo_terminal_1.PseudoTtyProcess) {
|
|
1009
1098
|
// This is an external of a the pseudo terminal where a task is running and can be passed to the TUI
|
|
@@ -1056,9 +1145,14 @@ class TaskOrchestrator {
|
|
|
1056
1145
|
if (process.env.NX_VERBOSE_LOGGING === 'true') {
|
|
1057
1146
|
console.error(e);
|
|
1058
1147
|
}
|
|
1148
|
+
const terminalOutput = e.stack ?? e.message ?? '';
|
|
1149
|
+
// No process ever started, so nothing else will write the file. Record
|
|
1150
|
+
// why, so the task's terminal output path resolves to the fork error
|
|
1151
|
+
// rather than to nothing.
|
|
1152
|
+
(0, fs_1.writeFileSync)(temporaryOutputPath, terminalOutput);
|
|
1059
1153
|
return new noop_child_process_1.NoopChildProcess({
|
|
1060
1154
|
code: 1,
|
|
1061
|
-
terminalOutput
|
|
1155
|
+
terminalOutput,
|
|
1062
1156
|
});
|
|
1063
1157
|
}
|
|
1064
1158
|
}
|
|
@@ -1091,7 +1185,13 @@ class TaskOrchestrator {
|
|
|
1091
1185
|
const pipeOutput = await this.pipeOutputCapture(task);
|
|
1092
1186
|
// obtain metadata
|
|
1093
1187
|
const temporaryOutputPath = this.cache.temporaryOutputPath(task);
|
|
1094
|
-
|
|
1188
|
+
// Deliberately not gated on `printsTaskOutput`, unlike `runTaskDirectly`.
|
|
1189
|
+
// `SummaryTerminalOutputLifeCycle.printTaskTerminalOutput` is a no-op and it
|
|
1190
|
+
// only reports at `endCommand`, which never runs for a task that does not
|
|
1191
|
+
// end - so suppressing here would leave a `nx serve` under `summary` with a
|
|
1192
|
+
// permanently silent terminal and no file to read yet. Streaming is the only
|
|
1193
|
+
// channel a continuous task has.
|
|
1194
|
+
const streamOutput = (0, output_1.isStaticOutputStyle)(this.specifiedOutputStyle)
|
|
1095
1195
|
? false
|
|
1096
1196
|
: (0, utils_1.shouldStreamOutput)(task, this.initiatingProject);
|
|
1097
1197
|
let env = pipeOutput
|
|
@@ -1108,6 +1208,9 @@ class TaskOrchestrator {
|
|
|
1108
1208
|
this.continuousTaskExitHandled.set(task.id, new Promise((resolve) => {
|
|
1109
1209
|
childProcess.onExit(async (code) => {
|
|
1110
1210
|
await this.handleContinuousTaskExit(code, task, groupId, true);
|
|
1211
|
+
// Registered after the runner's own exit handler, which is what
|
|
1212
|
+
// wrote the file.
|
|
1213
|
+
this.recordContinuousTerminalOutput(task);
|
|
1111
1214
|
resolve();
|
|
1112
1215
|
});
|
|
1113
1216
|
}));
|
|
@@ -1143,34 +1246,117 @@ class TaskOrchestrator {
|
|
|
1143
1246
|
// Caller decides whether these results should be written to the cache.
|
|
1144
1247
|
// Cache replays pass false so a replayed failure (reported as 'failure' so
|
|
1145
1248
|
// it counts as a failed run) isn't re-written to the cache on every replay.
|
|
1146
|
-
|
|
1249
|
+
const resultsToCache = shouldCache && !this.stopRequested ? this.resultsToCache(results) : [];
|
|
1250
|
+
// Resolved before the cache writes so the two never write the same file.
|
|
1251
|
+
this.persistTerminalOutputs(results, resultsToCache);
|
|
1252
|
+
if (resultsToCache.length > 0) {
|
|
1147
1253
|
// cache the results
|
|
1148
1254
|
perf_hooks_1.performance.mark('cache-results-start');
|
|
1149
|
-
await Promise.all(
|
|
1150
|
-
.filter(({ status }) => status !== 'local-cache' &&
|
|
1151
|
-
status !== 'local-cache-kept-existing' &&
|
|
1152
|
-
status !== 'remote-cache' &&
|
|
1153
|
-
status !== 'skipped' &&
|
|
1154
|
-
status !== 'stopped')
|
|
1155
|
-
.map((result) => ({
|
|
1156
|
-
...result,
|
|
1157
|
-
code: result.status === 'local-cache' ||
|
|
1158
|
-
result.status === 'local-cache-kept-existing' ||
|
|
1159
|
-
result.status === 'remote-cache' ||
|
|
1160
|
-
result.status === 'success'
|
|
1161
|
-
? 0
|
|
1162
|
-
: 1,
|
|
1163
|
-
outputs: result.task.outputs,
|
|
1164
|
-
}))
|
|
1165
|
-
.filter(({ task, code }) => this.shouldCacheTaskResult(task, code))
|
|
1166
|
-
.filter(({ terminalOutput, outputs }) => terminalOutput || outputs)
|
|
1167
|
-
.map(async ({ task, code, terminalOutput, outputs }) => this.cache.put(task, terminalOutput, outputs, code)));
|
|
1255
|
+
await Promise.all(resultsToCache.map(async ({ task, code, terminalOutput, outputs }) => this.cache.put(task, terminalOutput, outputs, code)));
|
|
1168
1256
|
perf_hooks_1.performance.mark('cache-results-end');
|
|
1169
1257
|
perf_hooks_1.performance.measure('cache-results', 'cache-results-start', 'cache-results-end');
|
|
1170
1258
|
}
|
|
1171
1259
|
await this.complete(results, groupId);
|
|
1172
1260
|
await this.scheduleNextTasksAndReleaseThreads();
|
|
1173
1261
|
}
|
|
1262
|
+
/**
|
|
1263
|
+
* The results `cache.put` will write, in the shape it wants them. Pulled out
|
|
1264
|
+
* of postRunSteps so the terminal-output backstop can be told exactly which
|
|
1265
|
+
* tasks the cache is already writing a file for.
|
|
1266
|
+
*/
|
|
1267
|
+
resultsToCache(results) {
|
|
1268
|
+
return results
|
|
1269
|
+
.filter(({ status }) => status !== 'local-cache' &&
|
|
1270
|
+
status !== 'local-cache-kept-existing' &&
|
|
1271
|
+
status !== 'remote-cache' &&
|
|
1272
|
+
status !== 'skipped' &&
|
|
1273
|
+
status !== 'stopped')
|
|
1274
|
+
.map((result) => ({
|
|
1275
|
+
...result,
|
|
1276
|
+
code: result.status === 'local-cache' ||
|
|
1277
|
+
result.status === 'local-cache-kept-existing' ||
|
|
1278
|
+
result.status === 'remote-cache' ||
|
|
1279
|
+
result.status === 'success'
|
|
1280
|
+
? 0
|
|
1281
|
+
: 1,
|
|
1282
|
+
outputs: result.task.outputs,
|
|
1283
|
+
}))
|
|
1284
|
+
.filter(({ task, code }) => this.shouldCacheTaskResult(task, code))
|
|
1285
|
+
.filter(({ terminalOutput, outputs }) => terminalOutput || outputs);
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Guarantee that every task that actually ran leaves its terminal output at
|
|
1289
|
+
* `<cacheDir>/terminalOutputs/<hash>`, whatever its cache setting, output
|
|
1290
|
+
* style, or batch membership. That path is what `--output-style=summary`
|
|
1291
|
+
* addresses each failure by, what the DB cache reads back on a hit
|
|
1292
|
+
* (`build_cached_result`), and what Nx Cloud falls back to reading when a
|
|
1293
|
+
* task's in-memory output is undefined, so a task that reaches a terminal
|
|
1294
|
+
* state without a file there is a dangling reference.
|
|
1295
|
+
*
|
|
1296
|
+
* Batch tasks are why this exists. Their output only ever arrives over IPC,
|
|
1297
|
+
* so the sole thing that ever put it on disk was `cache.put` — leaving a
|
|
1298
|
+
* `cache:false` batch task (the shape CI runs under `NX_BATCH_MODE`) with no
|
|
1299
|
+
* file at all.
|
|
1300
|
+
*
|
|
1301
|
+
* Written exactly once per task: tasks whose runner owns the file are
|
|
1302
|
+
* recorded in `tasksWithPersistedOutput`, and tasks `cache.put` is about to
|
|
1303
|
+
* write are skipped here. Cache hits are skipped by status — their output was
|
|
1304
|
+
* read from this very file — except a replayed cached *failure*, which comes
|
|
1305
|
+
* back as `failure` and is rewritten with the bytes it was just read with.
|
|
1306
|
+
* Skipped tasks never ran, so there is nothing to write.
|
|
1307
|
+
*
|
|
1308
|
+
* Every file written without a cache entry behind it is then registered with
|
|
1309
|
+
* the cache, because `removeOldCacheRecords` only collects hashes it finds in
|
|
1310
|
+
* the database — an unregistered file would never be cleaned up. That covers
|
|
1311
|
+
* files this method wrote AND ones a runner wrote, which are equally
|
|
1312
|
+
* invisible to the GC.
|
|
1313
|
+
*/
|
|
1314
|
+
persistTerminalOutputs(results, resultsToCache) {
|
|
1315
|
+
const writtenByCache = new Set(resultsToCache.map(({ task }) => task.id));
|
|
1316
|
+
const toRecord = [];
|
|
1317
|
+
for (const { task, status, terminalOutput } of results) {
|
|
1318
|
+
if (terminalOutput === undefined ||
|
|
1319
|
+
// A task that failed before it was hashed has no path to write to.
|
|
1320
|
+
!task.hash ||
|
|
1321
|
+
status === 'skipped' ||
|
|
1322
|
+
status === 'local-cache' ||
|
|
1323
|
+
status === 'local-cache-kept-existing' ||
|
|
1324
|
+
status === 'remote-cache' ||
|
|
1325
|
+
// `cache.put` writes the file and records the hash itself.
|
|
1326
|
+
writtenByCache.has(task.id)) {
|
|
1327
|
+
continue;
|
|
1328
|
+
}
|
|
1329
|
+
if (!this.tasksWithPersistedOutput.has(task.id)) {
|
|
1330
|
+
this.tasksWithPersistedOutput.add(task.id);
|
|
1331
|
+
(0, fs_1.writeFileSync)(this.cache.temporaryOutputPath(task), terminalOutput);
|
|
1332
|
+
}
|
|
1333
|
+
toRecord.push({
|
|
1334
|
+
hash: task.hash,
|
|
1335
|
+
size: Buffer.byteLength(terminalOutput),
|
|
1336
|
+
});
|
|
1337
|
+
}
|
|
1338
|
+
if (toRecord.length > 0) {
|
|
1339
|
+
this.cache.recordTerminalOutputs(toRecord);
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
/**
|
|
1343
|
+
* Register a continuous task's terminal output with the cache so the GC can
|
|
1344
|
+
* collect it. Continuous tasks never reach postRunSteps — their file is
|
|
1345
|
+
* written by whichever runner ran them, as the process exits — so this is
|
|
1346
|
+
* the only place their hash gets recorded. Read off disk rather than from a
|
|
1347
|
+
* result, because a continuous task completes without one.
|
|
1348
|
+
*/
|
|
1349
|
+
recordContinuousTerminalOutput(task) {
|
|
1350
|
+
if (!task.hash)
|
|
1351
|
+
return;
|
|
1352
|
+
try {
|
|
1353
|
+
const { size } = (0, fs_1.statSync)(this.cache.temporaryOutputPath(task));
|
|
1354
|
+
this.cache.recordTerminalOutputs([{ hash: task.hash, size }]);
|
|
1355
|
+
}
|
|
1356
|
+
catch {
|
|
1357
|
+
// Exit handler: a throw here would be an unhandled rejection.
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1174
1360
|
async scheduleNextTasksAndReleaseThreads() {
|
|
1175
1361
|
if (this.stopRequested) {
|
|
1176
1362
|
this.waitingForTasks.forEach((f) => f(null));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a task's terminal output lives on disk, for callers that have a hash but
|
|
3
|
+
* no cache instance. Mirrors the native layout (`get_task_outputs_path_internal`
|
|
4
|
+
* in cache.rs) and the legacy cache's `terminalOutputsDir`; both resolve
|
|
5
|
+
* `<cacheDir>/terminalOutputs/<hash>`.
|
|
6
|
+
*
|
|
7
|
+
* Its own module rather than part of `cache.ts` so the graph and plugin paths
|
|
8
|
+
* can resolve a path without pulling the cache — and the database, cloud and
|
|
9
|
+
* task-IO modules behind it — into their import graph.
|
|
10
|
+
*/
|
|
11
|
+
export declare function terminalOutputPathForHash(hash: string): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.terminalOutputPathForHash = terminalOutputPathForHash;
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const cache_directory_1 = require("../utils/cache-directory");
|
|
6
|
+
/**
|
|
7
|
+
* Where a task's terminal output lives on disk, for callers that have a hash but
|
|
8
|
+
* no cache instance. Mirrors the native layout (`get_task_outputs_path_internal`
|
|
9
|
+
* in cache.rs) and the legacy cache's `terminalOutputsDir`; both resolve
|
|
10
|
+
* `<cacheDir>/terminalOutputs/<hash>`.
|
|
11
|
+
*
|
|
12
|
+
* Its own module rather than part of `cache.ts` so the graph and plugin paths
|
|
13
|
+
* can resolve a path without pulling the cache — and the database, cloud and
|
|
14
|
+
* task-IO modules behind it — into their import graph.
|
|
15
|
+
*/
|
|
16
|
+
function terminalOutputPathForHash(hash) {
|
|
17
|
+
return (0, path_1.join)(cache_directory_1.cacheDir, 'terminalOutputs', hash);
|
|
18
|
+
}
|
|
@@ -221,7 +221,10 @@ function getOutputsForTargetAndConfiguration(taskTargetOrTask, overridesOrNode,
|
|
|
221
221
|
validateOutputs(targetConfiguration.outputs);
|
|
222
222
|
const result = new Set();
|
|
223
223
|
for (const output of targetConfiguration.outputs) {
|
|
224
|
-
|
|
224
|
+
// A leading `!` is negation, not part of the path: strip it so
|
|
225
|
+
// `{workspaceRoot}` still sits where interpolate requires it.
|
|
226
|
+
const isNegated = output.startsWith('!');
|
|
227
|
+
const interpolatedOutput = interpolate(isNegated ? output.substring(1) : output, {
|
|
225
228
|
projectRoot: node.data.root,
|
|
226
229
|
projectName: node.name,
|
|
227
230
|
project: { ...node.data, name: node.name }, // this is legacy
|
|
@@ -229,7 +232,7 @@ function getOutputsForTargetAndConfiguration(taskTargetOrTask, overridesOrNode,
|
|
|
229
232
|
});
|
|
230
233
|
if (!!interpolatedOutput &&
|
|
231
234
|
!interpolatedOutput.match(/{(projectRoot|workspaceRoot|(options.*))}/)) {
|
|
232
|
-
result.add(interpolatedOutput);
|
|
235
|
+
result.add(isNegated ? `!${interpolatedOutput}` : interpolatedOutput);
|
|
233
236
|
}
|
|
234
237
|
}
|
|
235
238
|
return Array.from(result);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const NX_CLOUD_URL = "https://nx.dev/nx-cloud";
|
|
2
|
+
export declare const NX_CLOUD_DEMO_URL = "https://cloud.nx.app/demo/intro";
|
|
2
3
|
/**
|
|
3
4
|
* Clickable Nx Cloud marketing link for cloud prompt footers. The visible text
|
|
4
5
|
* stays the clean `NX_CLOUD_URL` while clicks carry UTM attribution; terminals
|
|
@@ -7,6 +8,8 @@ export declare const NX_CLOUD_URL = "https://nx.dev/nx-cloud";
|
|
|
7
8
|
* different commands.
|
|
8
9
|
*/
|
|
9
10
|
export declare function nxCloudHyperlink(utmContent: string): string;
|
|
11
|
+
/** Same as `nxCloudHyperlink`, pointing at the Nx Cloud demo (CLOUD-4640). */
|
|
12
|
+
export declare function nxCloudDemoHyperlink(utmContent: string): string;
|
|
10
13
|
/**
|
|
11
14
|
* Meta payload types for recordStat telemetry (matches CNW format).
|
|
12
15
|
*/
|
|
@@ -25,7 +28,7 @@ export interface RecordStatMetaError {
|
|
|
25
28
|
[key: string]: string | boolean;
|
|
26
29
|
}
|
|
27
30
|
export type RecordStatMeta = RecordStatMetaStart | RecordStatMetaComplete | RecordStatMetaError;
|
|
28
|
-
export type MessageOptionKey = 'yes' | 'skip'
|
|
31
|
+
export type MessageOptionKey = 'yes' | 'skip';
|
|
29
32
|
interface MessageData {
|
|
30
33
|
code: string;
|
|
31
34
|
message: string;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.messages = exports.PromptMessages = exports.NX_CLOUD_URL = void 0;
|
|
3
|
+
exports.messages = exports.PromptMessages = exports.NX_CLOUD_DEMO_URL = exports.NX_CLOUD_URL = void 0;
|
|
4
4
|
exports.nxCloudHyperlink = nxCloudHyperlink;
|
|
5
|
+
exports.nxCloudDemoHyperlink = nxCloudDemoHyperlink;
|
|
5
6
|
exports.recordStat = recordStat;
|
|
6
|
-
const tslib_1 = require("tslib");
|
|
7
7
|
const node_child_process_1 = require("node:child_process");
|
|
8
8
|
const is_ci_1 = require("./is-ci");
|
|
9
9
|
const package_manager_1 = require("./package-manager");
|
|
10
10
|
const get_cloud_options_1 = require("../nx-cloud/utilities/get-cloud-options");
|
|
11
11
|
const terminal_link_1 = require("./terminal-link");
|
|
12
|
-
const pc = tslib_1.__importStar(require("picocolors"));
|
|
13
12
|
exports.NX_CLOUD_URL = 'https://nx.dev/nx-cloud';
|
|
13
|
+
exports.NX_CLOUD_DEMO_URL = 'https://cloud.nx.app/demo/intro';
|
|
14
14
|
/**
|
|
15
15
|
* Clickable Nx Cloud marketing link for cloud prompt footers. The visible text
|
|
16
16
|
* stays the clean `NX_CLOUD_URL` while clicks carry UTM attribution; terminals
|
|
@@ -19,8 +19,14 @@ exports.NX_CLOUD_URL = 'https://nx.dev/nx-cloud';
|
|
|
19
19
|
* different commands.
|
|
20
20
|
*/
|
|
21
21
|
function nxCloudHyperlink(utmContent) {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
return trackedHyperlink(exports.NX_CLOUD_URL, utmContent);
|
|
23
|
+
}
|
|
24
|
+
/** Same as `nxCloudHyperlink`, pointing at the Nx Cloud demo (CLOUD-4640). */
|
|
25
|
+
function nxCloudDemoHyperlink(utmContent) {
|
|
26
|
+
return trackedHyperlink(exports.NX_CLOUD_DEMO_URL, utmContent);
|
|
27
|
+
}
|
|
28
|
+
function trackedHyperlink(url, utmContent) {
|
|
29
|
+
return (0, terminal_link_1.terminalLink)(url, `${url}?utm_source=nx-cli&utm_medium=cli&utm_campaign=nx-cloud-connect&utm_content=${utmContent}`);
|
|
24
30
|
}
|
|
25
31
|
const messageOptions = {
|
|
26
32
|
setupNxCloud: [
|
|
@@ -31,7 +37,6 @@ const messageOptions = {
|
|
|
31
37
|
choices: [
|
|
32
38
|
{ value: 'yes', name: 'Yes' },
|
|
33
39
|
{ value: 'skip', name: 'Skip for now' },
|
|
34
|
-
{ value: 'never', name: pc.dim("No, don't ask again") },
|
|
35
40
|
],
|
|
36
41
|
footer: '\nFree for small teams. Remote caching and task distribution. 2-minute setup:',
|
|
37
42
|
},
|
|
@@ -42,7 +47,6 @@ const messageOptions = {
|
|
|
42
47
|
choices: [
|
|
43
48
|
{ value: 'yes', name: 'Yes' },
|
|
44
49
|
{ value: 'skip', name: 'Skip for now' },
|
|
45
|
-
{ value: 'never', name: pc.dim("No, don't ask again") },
|
|
46
50
|
],
|
|
47
51
|
footer: '\nLearn about it at',
|
|
48
52
|
hint: `\n(it's free and can be disabled any time)`,
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
export declare function chunkify(target: string[], maxChunkLength?: number
|
|
2
|
-
/**
|
|
3
|
-
* How long each entry will be once it reaches the command line. Callers that
|
|
4
|
-
* quote or escape afterwards pass that transformation's length here, so the
|
|
5
|
-
* chunk is sized against what is actually spawned rather than the raw string.
|
|
6
|
-
*/
|
|
7
|
-
measure?: (item: string) => number): string[][];
|
|
1
|
+
export declare function chunkify(target: string[], maxChunkLength?: number): string[][];
|
|
8
2
|
/**
|
|
9
3
|
* Get the maximum length of a command-line argument string based on current platform
|
|
10
4
|
*
|
|
@@ -3,18 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.chunkify = chunkify;
|
|
4
4
|
exports.getMaxArgLength = getMaxArgLength;
|
|
5
5
|
const TERMINAL_SIZE = getMaxArgLength();
|
|
6
|
-
function chunkify(target, maxChunkLength = TERMINAL_SIZE - 500
|
|
7
|
-
/**
|
|
8
|
-
* How long each entry will be once it reaches the command line. Callers that
|
|
9
|
-
* quote or escape afterwards pass that transformation's length here, so the
|
|
10
|
-
* chunk is sized against what is actually spawned rather than the raw string.
|
|
11
|
-
*/
|
|
12
|
-
measure = (item) => item.length) {
|
|
6
|
+
function chunkify(target, maxChunkLength = TERMINAL_SIZE - 500) {
|
|
13
7
|
const chunks = [];
|
|
14
8
|
let currentChunk = [];
|
|
15
9
|
let currentChunkLength = 0;
|
|
16
10
|
for (const file of target) {
|
|
17
|
-
const length =
|
|
11
|
+
const length = file.length;
|
|
18
12
|
if (
|
|
19
13
|
// Prevent empty chunk if first file path is longer than maxChunkLength
|
|
20
14
|
currentChunk.length &&
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Arguments } from 'yargs';
|
|
2
2
|
import { NxJsonConfiguration } from '../config/nx-json';
|
|
3
3
|
import { ProjectGraph } from '../config/project-graph';
|
|
4
|
+
import type { OutputStyle } from '../command-line/yargs-utils/shared-options';
|
|
4
5
|
export interface RawNxArgs extends NxArgs {
|
|
5
6
|
prod?: boolean;
|
|
6
7
|
}
|
|
@@ -28,6 +29,24 @@ export interface NxArgs {
|
|
|
28
29
|
graph?: string | boolean;
|
|
29
30
|
skipNxCache?: boolean;
|
|
30
31
|
skipRemoteCache?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* The style the user named - CLI flag or `NX_DEFAULT_OUTPUT_STYLE`. Left
|
|
34
|
+
* undefined when they named none, and that absence is load-bearing: it is how
|
|
35
|
+
* the streaming and renderer-selection decisions tell "the user wants static"
|
|
36
|
+
* from "we defaulted to static", which stream continuous tasks differently.
|
|
37
|
+
*/
|
|
38
|
+
specifiedOutputStyle?: OutputStyle;
|
|
39
|
+
/**
|
|
40
|
+
* What the run actually renders with, after the TUI, agent and failures-only
|
|
41
|
+
* defaults are applied. Always set. Every decision about what to PRINT reads
|
|
42
|
+
* this; every decision about what the user ASKED FOR reads the field above.
|
|
43
|
+
*/
|
|
44
|
+
resolvedOutputStyle?: OutputStyle;
|
|
45
|
+
/**
|
|
46
|
+
* @deprecated Read `specifiedOutputStyle` for what the user named, or
|
|
47
|
+
* `resolvedOutputStyle` for what the run renders with. This will be removed
|
|
48
|
+
* in Nx 24.
|
|
49
|
+
*/
|
|
31
50
|
outputStyle?: string;
|
|
32
51
|
tui?: boolean;
|
|
33
52
|
nxBail?: boolean;
|