nx 23.2.1 → 23.3.0-beta.1
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/format.js +2 -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 -1
- 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/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 +4 -2
- package/dist/src/daemon/client/client.js +20 -11
- package/dist/src/daemon/message-types/run-tasks-execution-hooks.d.ts +3 -2
- 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 +99 -69
- 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 +28 -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 +202 -21
- package/dist/src/native/index.js +3 -3
- package/dist/src/native/native-bindings.js +3 -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/plugins/isolation/isolated-plugin.js +2 -1
- 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 +3 -2
- package/dist/src/project-graph/plugins/loaded-nx-plugin.js +5 -1
- 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 +2 -1
- package/dist/src/project-graph/project-graph.js +2 -0
- 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 +3 -0
- package/dist/src/utils/ab-testing.js +11 -3
- 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/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/provenance.js +20 -4
- package/dist/src/utils/workspace-context.d.ts +47 -3
- package/dist/src/utils/workspace-context.js +162 -10
- package/package.json +12 -12
- 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
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.relativeServerProcess = void 0;
|
|
4
|
+
exports.registerDaemonForRestartChecks = registerDaemonForRestartChecks;
|
|
5
|
+
exports.fileNames = fileNames;
|
|
6
|
+
exports.changedPaths = changedPaths;
|
|
7
|
+
exports.restartDaemonIfIgnoreFilesChanged = restartDaemonIfIgnoreFilesChanged;
|
|
8
|
+
exports.stopDaemonIfReplaced = stopDaemonIfReplaced;
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const path_2 = require("../../utils/path");
|
|
11
|
+
const workspace_root_1 = require("../../utils/workspace-root");
|
|
12
|
+
const cache_1 = require("../cache");
|
|
13
|
+
const shutdown_utils_1 = require("./shutdown-utils");
|
|
14
|
+
// Kept apart from server.ts: the recomputation module needs these, and
|
|
15
|
+
// importing server.ts starts a server.
|
|
16
|
+
let daemon;
|
|
17
|
+
function registerDaemonForRestartChecks(server, sockets) {
|
|
18
|
+
daemon = { server, sockets };
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The daemon's own process file, workspace-relative. It lives under the
|
|
22
|
+
* hardcoded-ignored .nx/workspace-data, so the watch admits it explicitly;
|
|
23
|
+
* that is how a daemon learns it has been replaced.
|
|
24
|
+
*/
|
|
25
|
+
exports.relativeServerProcess = (0, path_2.normalizePath)((0, path_1.relative)(workspace_root_1.workspaceRoot, cache_1.serverProcessJsonPath));
|
|
26
|
+
/** The paths out of a list of files and their hashes. */
|
|
27
|
+
function fileNames(files) {
|
|
28
|
+
return files.map(({ file }) => file);
|
|
29
|
+
}
|
|
30
|
+
function changedPaths(batch) {
|
|
31
|
+
return [
|
|
32
|
+
...fileNames(batch.createdFiles),
|
|
33
|
+
...fileNames(batch.updatedFiles),
|
|
34
|
+
...batch.deletedFiles,
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
// Mirrors the per-directory ignore files create_filter reads (watch_filterer.rs).
|
|
38
|
+
// The sources it honours that cannot trigger a restart from here — because they
|
|
39
|
+
// are never watched — only take effect on the next daemon start: .git/info/exclude
|
|
40
|
+
// (under the hardcoded-ignored .git), the global core.excludesFile (outside the
|
|
41
|
+
// tree), and parent .gitignore files above the workspace root.
|
|
42
|
+
const IGNORE_FILE_NAMES = ['.gitignore', '.nxignore'];
|
|
43
|
+
/**
|
|
44
|
+
* The watch's ignore rules are fixed when it starts, so an ignore-file edit
|
|
45
|
+
* needs a daemon restart to take effect. True when it stopped the daemon.
|
|
46
|
+
*/
|
|
47
|
+
function restartDaemonIfIgnoreFilesChanged(paths) {
|
|
48
|
+
for (const path of paths) {
|
|
49
|
+
const basename = path.slice(path.lastIndexOf('/') + 1);
|
|
50
|
+
if (IGNORE_FILE_NAMES.includes(basename)) {
|
|
51
|
+
stopDaemon('Stopping the daemon the set of ignored files changed (native)');
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Stops this daemon when the events show another process has written the
|
|
59
|
+
* daemon's process file. True when it stopped the daemon.
|
|
60
|
+
*/
|
|
61
|
+
function stopDaemonIfReplaced(events) {
|
|
62
|
+
const replaced = events.some((event) => event.path === exports.relativeServerProcess &&
|
|
63
|
+
(0, cache_1.getDaemonProcessIdSync)() !== process.pid);
|
|
64
|
+
if (replaced) {
|
|
65
|
+
stopDaemon('this process is no longer the current daemon (native)');
|
|
66
|
+
}
|
|
67
|
+
return replaced;
|
|
68
|
+
}
|
|
69
|
+
function stopDaemon(reason) {
|
|
70
|
+
if (!daemon)
|
|
71
|
+
return;
|
|
72
|
+
(0, shutdown_utils_1.handleServerProcessTermination)({
|
|
73
|
+
server: daemon.server,
|
|
74
|
+
reason,
|
|
75
|
+
sockets: daemon.sockets,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
@@ -14,7 +14,6 @@ const native_1 = require("../../native");
|
|
|
14
14
|
const consume_messages_from_socket_1 = require("../../utils/consume-messages-from-socket");
|
|
15
15
|
require("../../utils/perf-logging");
|
|
16
16
|
const versions_1 = require("../../utils/versions");
|
|
17
|
-
const workspace_context_1 = require("../../utils/workspace-context");
|
|
18
17
|
const workspace_root_1 = require("../../utils/workspace-root");
|
|
19
18
|
const cache_1 = require("../cache");
|
|
20
19
|
const is_nx_version_mismatch_1 = require("../is-nx-version-mismatch");
|
|
@@ -38,7 +37,6 @@ const task_history_1 = require("../message-types/task-history");
|
|
|
38
37
|
const update_workspace_context_1 = require("../message-types/update-workspace-context");
|
|
39
38
|
const socket_utils_1 = require("../socket-utils");
|
|
40
39
|
const file_change_events_1 = require("./file-watching/file-change-events");
|
|
41
|
-
const route_workspace_changes_1 = require("./file-watching/route-workspace-changes");
|
|
42
40
|
const file_watcher_sockets_1 = require("./file-watching/file-watcher-sockets");
|
|
43
41
|
const handle_configure_ai_agents_1 = require("./handle-configure-ai-agents");
|
|
44
42
|
const handle_context_file_data_1 = require("./handle-context-file-data");
|
|
@@ -62,10 +60,11 @@ const handle_tasks_execution_hooks_1 = require("./handle-tasks-execution-hooks")
|
|
|
62
60
|
const handle_update_workspace_context_1 = require("./handle-update-workspace-context");
|
|
63
61
|
const handle_outputs_changes_1 = require("./handle-outputs-changes");
|
|
64
62
|
const project_graph_incremental_recomputation_1 = require("./project-graph-incremental-recomputation");
|
|
63
|
+
const restart_checks_1 = require("./restart-checks");
|
|
65
64
|
const project_graph_listener_sockets_1 = require("./project-graph-listener-sockets");
|
|
66
65
|
const shutdown_utils_1 = require("./shutdown-utils");
|
|
67
66
|
const sync_generators_1 = require("./sync-generators");
|
|
68
|
-
const
|
|
67
|
+
const workspace_context_1 = require("../../utils/workspace-context");
|
|
69
68
|
let workspaceWatcherError;
|
|
70
69
|
global.NX_DAEMON = true;
|
|
71
70
|
process.env.NX_DAEMON_PROCESS = 'true';
|
|
@@ -146,6 +145,9 @@ async function handleMessage(socket, data) {
|
|
|
146
145
|
else if (payload.type === 'HASH_TASKS') {
|
|
147
146
|
await handleResult(socket, 'HASH_TASKS', () => (0, handle_hash_tasks_1.handleHashTasks)(payload), mode);
|
|
148
147
|
}
|
|
148
|
+
else if (payload.type === 'HASH_TASKS_UPFRONT') {
|
|
149
|
+
await handleResult(socket, 'HASH_TASKS_UPFRONT', () => (0, handle_hash_tasks_1.handleHashTasksUpfront)(payload), mode);
|
|
150
|
+
}
|
|
149
151
|
else if (payload.type === 'PROCESS_IN_BACKGROUND') {
|
|
150
152
|
await handleResult(socket, 'PROCESS_IN_BACKGROUND', () => (0, handle_process_in_background_1.handleProcessInBackground)(payload), mode);
|
|
151
153
|
}
|
|
@@ -323,7 +325,7 @@ function lockFileHashChanged() {
|
|
|
323
325
|
* we need to recompute the cached serialized project graph so that it is readily
|
|
324
326
|
* available for the next client request to the server.
|
|
325
327
|
*/
|
|
326
|
-
const handleWorkspaceChanges =
|
|
328
|
+
const handleWorkspaceChanges = (err, batch) => {
|
|
327
329
|
if (workspaceWatcherError) {
|
|
328
330
|
logger_1.serverLogger.watcherLog('Skipping handleWorkspaceChanges because of a previously recorded watcher error.');
|
|
329
331
|
return;
|
|
@@ -338,8 +340,7 @@ const handleWorkspaceChanges = async (err, changeEvents) => {
|
|
|
338
340
|
(0, file_watcher_sockets_1.notifyFileWatcherSocketsOfError)(error);
|
|
339
341
|
return;
|
|
340
342
|
}
|
|
341
|
-
|
|
342
|
-
(0, route_workspace_changes_1.routeWorkspaceChanges)(changeEvents);
|
|
343
|
+
(0, project_graph_incremental_recomputation_1.routeAppliedChanges)(batch);
|
|
343
344
|
}
|
|
344
345
|
catch (err) {
|
|
345
346
|
logger_1.serverLogger.watcherLog(`Unexpected workspace error`, err.message);
|
|
@@ -349,14 +350,17 @@ const handleWorkspaceChanges = async (err, changeEvents) => {
|
|
|
349
350
|
}
|
|
350
351
|
};
|
|
351
352
|
async function startServer() {
|
|
352
|
-
//
|
|
353
|
-
//
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
(0,
|
|
353
|
+
// The workspace context owns the daemon's one watch and starts it before
|
|
354
|
+
// it scans, so a file written during boot is visible to one or the other.
|
|
355
|
+
if (!(0, workspace_context_1.isWatchingWorkspaceContext)()) {
|
|
356
|
+
(0, restart_checks_1.registerDaemonForRestartChecks)(server, exports.openSockets);
|
|
357
|
+
(0, workspace_context_1.setupWorkspaceContext)(workspace_root_1.workspaceRoot, {
|
|
358
|
+
watch: true,
|
|
359
|
+
alwaysWatch: [restart_checks_1.relativeServerProcess],
|
|
360
|
+
});
|
|
361
|
+
(0, workspace_context_1.subscribeToWorkspaceChanges)(workspace_root_1.workspaceRoot, handleWorkspaceChanges);
|
|
357
362
|
logger_1.serverLogger.watcherLog(`Subscribed to changes within: ${workspace_root_1.workspaceRoot} (native)`);
|
|
358
363
|
}
|
|
359
|
-
(0, workspace_context_1.setupWorkspaceContext)(workspace_root_1.workspaceRoot);
|
|
360
364
|
// Initialize analytics for daemon process
|
|
361
365
|
await (0, analytics_1.startAnalytics)();
|
|
362
366
|
const socketPath = (0, socket_utils_1.getFullOsSocketPath)();
|
|
@@ -434,15 +438,21 @@ async function startServer() {
|
|
|
434
438
|
}
|
|
435
439
|
// this triggers the storage of the lock file hash
|
|
436
440
|
daemonIsOutdated();
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
441
|
+
// Every event the watch delivers, gitignored outputs and dotenv
|
|
442
|
+
// files included.
|
|
443
|
+
(0, workspace_context_1.subscribeToWatchEvents)(workspace_root_1.workspaceRoot, (err, events) => {
|
|
444
|
+
if (!err && events && (0, restart_checks_1.stopDaemonIfReplaced)(events)) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
if (err || events?.length) {
|
|
448
|
+
(0, handle_outputs_changes_1.handleOutputsChanges)(err, events);
|
|
449
|
+
}
|
|
450
|
+
});
|
|
440
451
|
// listen for project graph recomputation events to collect and schedule sync generators
|
|
441
452
|
(0, project_graph_incremental_recomputation_1.registerProjectGraphRecomputationListener)(sync_generators_1.collectAndScheduleSyncGenerators);
|
|
442
453
|
// register file change listener to invalidate sync generator cache
|
|
443
454
|
(0, file_change_events_1.registerFileChangeListener)(sync_generators_1.clearSyncGeneratorsCache);
|
|
444
|
-
|
|
445
|
-
(0, project_graph_incremental_recomputation_1.scheduleProjectGraphRecomputation)([], [], []);
|
|
455
|
+
(0, project_graph_incremental_recomputation_1.scheduleInitialProjectGraphComputation)();
|
|
446
456
|
// Kick off Nx Console check in background to prime the cache
|
|
447
457
|
(0, handle_nx_console_1.handleGetNxConsoleStatus)().catch(() => {
|
|
448
458
|
// Ignore errors, this is a background operation
|
|
@@ -454,7 +464,7 @@ async function startServer() {
|
|
|
454
464
|
return resolve(server);
|
|
455
465
|
}
|
|
456
466
|
catch (err) {
|
|
457
|
-
await handleWorkspaceChanges(err,
|
|
467
|
+
await handleWorkspaceChanges(err, null);
|
|
458
468
|
}
|
|
459
469
|
});
|
|
460
470
|
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import type { Server, Socket } from 'net';
|
|
2
|
-
import type { Watcher } from '../../native';
|
|
3
2
|
export declare const SERVER_INACTIVITY_TIMEOUT_MS: 10800000;
|
|
4
|
-
export declare function storeWatcherInstance(instance: Watcher): void;
|
|
5
|
-
export declare function getWatcherInstance(): Watcher;
|
|
6
|
-
export declare function storeOutputWatcherInstance(instance: Watcher): void;
|
|
7
|
-
export declare function getOutputWatcherInstance(): Watcher;
|
|
8
3
|
interface HandleServerProcessTerminationParams {
|
|
9
4
|
server: Server;
|
|
10
5
|
reason: string;
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SERVER_INACTIVITY_TIMEOUT_MS = void 0;
|
|
4
|
-
exports.storeWatcherInstance = storeWatcherInstance;
|
|
5
|
-
exports.getWatcherInstance = getWatcherInstance;
|
|
6
|
-
exports.storeOutputWatcherInstance = storeOutputWatcherInstance;
|
|
7
|
-
exports.getOutputWatcherInstance = getOutputWatcherInstance;
|
|
8
4
|
exports.handleServerProcessTermination = handleServerProcessTermination;
|
|
9
5
|
exports.handleServerProcessTerminationWithRestart = handleServerProcessTerminationWithRestart;
|
|
10
6
|
exports.resetInactivityTimeout = resetInactivityTimeout;
|
|
@@ -15,6 +11,7 @@ const workspace_root_1 = require("../../utils/workspace-root");
|
|
|
15
11
|
const logger_1 = require("../logger");
|
|
16
12
|
const socket_utils_1 = require("../socket-utils");
|
|
17
13
|
const cache_1 = require("../cache");
|
|
14
|
+
const workspace_context_1 = require("../../utils/workspace-context");
|
|
18
15
|
const error_types_1 = require("../../project-graph/error-types");
|
|
19
16
|
const get_plugins_1 = require("../../project-graph/plugins/get-plugins");
|
|
20
17
|
const consume_messages_from_socket_1 = require("../../utils/consume-messages-from-socket");
|
|
@@ -61,20 +58,6 @@ async function startNewDaemonInBackground() {
|
|
|
61
58
|
backgroundProcess.unref();
|
|
62
59
|
logger_1.serverLogger.log('Started new daemon process in background');
|
|
63
60
|
}
|
|
64
|
-
let watcherInstance;
|
|
65
|
-
function storeWatcherInstance(instance) {
|
|
66
|
-
watcherInstance = instance;
|
|
67
|
-
}
|
|
68
|
-
function getWatcherInstance() {
|
|
69
|
-
return watcherInstance;
|
|
70
|
-
}
|
|
71
|
-
let outputWatcherInstance;
|
|
72
|
-
function storeOutputWatcherInstance(instance) {
|
|
73
|
-
outputWatcherInstance = instance;
|
|
74
|
-
}
|
|
75
|
-
function getOutputWatcherInstance() {
|
|
76
|
-
return outputWatcherInstance;
|
|
77
|
-
}
|
|
78
61
|
async function handleServerProcessTermination({ server, reason, sockets, }) {
|
|
79
62
|
await performShutdown(server, reason, sockets);
|
|
80
63
|
}
|
|
@@ -95,14 +78,8 @@ async function performShutdown(server, reason, sockets) {
|
|
|
95
78
|
socket.destroy();
|
|
96
79
|
}
|
|
97
80
|
});
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
logger_1.serverLogger.watcherLog(`Stopping the watcher for ${workspace_root_1.workspaceRoot} (sources)`);
|
|
101
|
-
}
|
|
102
|
-
if (outputWatcherInstance) {
|
|
103
|
-
await outputWatcherInstance.stop();
|
|
104
|
-
logger_1.serverLogger.watcherLog(`Stopping the watcher for ${workspace_root_1.workspaceRoot} (outputs)`);
|
|
105
|
-
}
|
|
81
|
+
(0, workspace_context_1.stopWatchingWorkspaceContext)();
|
|
82
|
+
logger_1.serverLogger.watcherLog(`Stopping the watch for ${workspace_root_1.workspaceRoot}`);
|
|
106
83
|
(0, cache_1.deleteDaemonJsonProcessCache)();
|
|
107
84
|
(0, get_plugins_1.cleanupPlugins)();
|
|
108
85
|
// Clean up shared latest Nx installation
|
|
@@ -31,29 +31,29 @@ async function hashTasksThatDoNotDependOnOutputsOfOtherTasks(hasher, projectGrap
|
|
|
31
31
|
const customHasher = (0, utils_1.getCustomHasher)(task, projects);
|
|
32
32
|
return { task, customHasher };
|
|
33
33
|
}));
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
(0, task_hasher_1.getInputs)(task, projectGraph, nxJson).depsOutputs.length > 0);
|
|
42
|
-
})
|
|
34
|
+
// Custom hashers can read other tasks' outputs, so they hash at run time,
|
|
35
|
+
// and so does a task whose own inputs read them. The hasher still decides
|
|
36
|
+
// for the rest: outputs also arrive through a dependency's named input or
|
|
37
|
+
// a continuous server, which only planning reveals.
|
|
38
|
+
const candidates = tasksWithHashers
|
|
39
|
+
.filter(({ task, customHasher }) => !customHasher &&
|
|
40
|
+
!readsDependencyOutputs(task, taskGraph, projectGraph, nxJson))
|
|
43
41
|
.map((t) => t.task);
|
|
44
42
|
const perTaskEnvs = {};
|
|
45
|
-
for (const task of
|
|
43
|
+
for (const task of candidates) {
|
|
46
44
|
perTaskEnvs[task.id] = (0, task_env_1.getTaskSpecificEnv)(task, projectGraph);
|
|
47
45
|
}
|
|
48
|
-
const hashes = await hasher.
|
|
46
|
+
const hashes = await hasher.hashTasksUpfront(candidates, taskGraph, perTaskEnvs);
|
|
47
|
+
const tasksToHash = candidates.filter((task) => task.id in hashes);
|
|
49
48
|
const ioService = (0, task_io_service_1.getTaskIOService)();
|
|
50
49
|
const hasInputSubscribers = ioService.hasTaskInputSubscribers();
|
|
51
|
-
for (
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
for (const task of tasksToHash) {
|
|
51
|
+
const hash = hashes[task.id];
|
|
52
|
+
task.hash = hash.value;
|
|
53
|
+
task.hashDetails = hash.details;
|
|
54
54
|
// Notify TaskIOService of hash inputs
|
|
55
|
-
if (hasInputSubscribers &&
|
|
56
|
-
ioService.notifyTaskInputs(
|
|
55
|
+
if (hasInputSubscribers && hash.inputs) {
|
|
56
|
+
ioService.notifyTaskInputs(task.id, hash.inputs);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
if (tasksDetails?.recordTaskDetails) {
|
|
@@ -67,6 +67,10 @@ async function hashTasksThatDoNotDependOnOutputsOfOtherTasks(hasher, projectGrap
|
|
|
67
67
|
performance.mark('hashMultipleTasks:end');
|
|
68
68
|
performance.measure('hashMultipleTasks', 'hashMultipleTasks:start', 'hashMultipleTasks:end');
|
|
69
69
|
}
|
|
70
|
+
function readsDependencyOutputs(task, taskGraph, projectGraph, nxJson) {
|
|
71
|
+
return (taskGraph.dependencies[task.id]?.length > 0 &&
|
|
72
|
+
(0, task_hasher_1.getInputs)(task, projectGraph, nxJson).depsOutputs.length > 0);
|
|
73
|
+
}
|
|
70
74
|
async function hashTask(hasher, projectGraph, taskGraph, task, env, taskDetails) {
|
|
71
75
|
performance.mark('hashSingleTask:start');
|
|
72
76
|
const projectsConfigurations = (0, project_graph_1.readProjectsConfigurationFromProjectGraph)(projectGraph);
|
|
@@ -2,6 +2,7 @@ import { NxJsonConfiguration } from '../config/nx-json';
|
|
|
2
2
|
import { ProjectGraph } from '../config/project-graph';
|
|
3
3
|
import { Task, TaskGraph } from '../config/task-graph';
|
|
4
4
|
import { ExternalObject, FileData, HasherOptions, HashPlanner, ProjectGraph as NativeProjectGraph, NxWorkspaceFilesExternals, TaskHasher } from '../native';
|
|
5
|
+
import type { IgnoredIndexReader } from '../native';
|
|
5
6
|
import { PartialHash, TaskHasherImpl } from './task-hasher';
|
|
6
7
|
export declare class NativeTaskHasherImpl implements TaskHasherImpl {
|
|
7
8
|
hasher: TaskHasher;
|
|
@@ -9,10 +10,17 @@ export declare class NativeTaskHasherImpl implements TaskHasherImpl {
|
|
|
9
10
|
projectGraphRef: ExternalObject<NativeProjectGraph>;
|
|
10
11
|
allWorkspaceFilesRef: ExternalObject<FileData[]>;
|
|
11
12
|
projectFileMapRef: ExternalObject<Record<string, FileData[]>>;
|
|
13
|
+
ignoredIndexRef: ExternalObject<IgnoredIndexReader>;
|
|
12
14
|
options: HasherOptions | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Plans of the last up-front batch and the task graph they were built for.
|
|
17
|
+
* The tasks that batch deferred hash from them later without planning again.
|
|
18
|
+
*/
|
|
19
|
+
private upfrontPlans;
|
|
13
20
|
constructor(workspaceRoot: string, nxJson: NxJsonConfiguration, projectGraph: ProjectGraph, externals: NxWorkspaceFilesExternals, options: {
|
|
14
21
|
selectivelyHashTsConfig: boolean;
|
|
15
22
|
});
|
|
16
23
|
hashTask(task: Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv, cwd?: string, collectInputs?: boolean): Promise<PartialHash>;
|
|
17
24
|
hashTasks(tasks: Task[], taskGraph: TaskGraph, perTaskEnvs: Record<string, NodeJS.ProcessEnv>, cwd?: string, collectInputs?: boolean): Promise<PartialHash[]>;
|
|
25
|
+
hashTasksUpfront(tasks: Task[], taskGraph: TaskGraph, perTaskEnvs: Record<string, NodeJS.ProcessEnv>, cwd?: string, collectInputs?: boolean): Promise<Record<string, PartialHash>>;
|
|
18
26
|
}
|
|
@@ -8,9 +8,15 @@ const task_io_service_1 = require("../tasks-runner/task-io-service");
|
|
|
8
8
|
const fileutils_1 = require("../utils/fileutils");
|
|
9
9
|
class NativeTaskHasherImpl {
|
|
10
10
|
constructor(workspaceRoot, nxJson, projectGraph, externals, options) {
|
|
11
|
+
/**
|
|
12
|
+
* Plans of the last up-front batch and the task graph they were built for.
|
|
13
|
+
* The tasks that batch deferred hash from them later without planning again.
|
|
14
|
+
*/
|
|
15
|
+
this.upfrontPlans = null;
|
|
11
16
|
this.projectGraphRef = (0, native_1.transferProjectGraph)((0, transform_objects_1.transformProjectGraphForRust)(projectGraph));
|
|
12
17
|
this.allWorkspaceFilesRef = externals.allWorkspaceFiles;
|
|
13
18
|
this.projectFileMapRef = externals.projectFiles;
|
|
19
|
+
this.ignoredIndexRef = externals.ignoredIndex;
|
|
14
20
|
let tsconfig = {};
|
|
15
21
|
let paths = {};
|
|
16
22
|
let rootTsConfigPath = (0, typescript_1.getRootTsConfigPath)();
|
|
@@ -22,17 +28,54 @@ class NativeTaskHasherImpl {
|
|
|
22
28
|
}
|
|
23
29
|
}
|
|
24
30
|
this.planner = new native_1.HashPlanner(nxJson, this.projectGraphRef);
|
|
25
|
-
this.hasher = new native_1.TaskHasher(workspaceRoot, this.projectGraphRef, this.projectFileMapRef, this.allWorkspaceFilesRef, Buffer.from(JSON.stringify(tsconfig)), paths, rootTsConfigPath, options);
|
|
31
|
+
this.hasher = new native_1.TaskHasher(workspaceRoot, this.projectGraphRef, this.projectFileMapRef, this.allWorkspaceFilesRef, Buffer.from(JSON.stringify(tsconfig)), paths, rootTsConfigPath, options, this.ignoredIndexRef);
|
|
26
32
|
}
|
|
27
33
|
async hashTask(task, taskGraph, env, cwd, collectInputs) {
|
|
28
34
|
const hashes = await this.hashTasks([task], taskGraph, { [task.id]: env }, cwd, collectInputs);
|
|
29
35
|
return hashes[0];
|
|
30
36
|
}
|
|
31
37
|
async hashTasks(tasks, taskGraph, perTaskEnvs, cwd, collectInputs) {
|
|
32
|
-
const
|
|
38
|
+
const envs = perTaskEnvs;
|
|
33
39
|
const shouldCollectInputs = collectInputs ?? (0, task_io_service_1.getTaskIOService)().hasTaskInputSubscribers();
|
|
34
|
-
const
|
|
40
|
+
const resolvedCwd = cwd ?? process.cwd();
|
|
41
|
+
const hashes = {};
|
|
42
|
+
let unplanned = tasks.map((t) => t.id);
|
|
43
|
+
if (this.upfrontPlans &&
|
|
44
|
+
unplanned.some((id) => this.upfrontPlans.taskIds.has(id)) &&
|
|
45
|
+
this.upfrontPlans.fingerprint === taskGraphFingerprint(taskGraph)) {
|
|
46
|
+
Object.assign(hashes, this.hasher.hashPlansFor(this.upfrontPlans.plans, unplanned, envs, resolvedCwd, shouldCollectInputs));
|
|
47
|
+
unplanned = unplanned.filter((id) => !(id in hashes));
|
|
48
|
+
}
|
|
49
|
+
if (unplanned.length > 0) {
|
|
50
|
+
const plans = this.planner.getPlansReference(unplanned, taskGraph);
|
|
51
|
+
Object.assign(hashes, this.hasher.hashPlans(plans, envs, resolvedCwd, shouldCollectInputs));
|
|
52
|
+
}
|
|
35
53
|
return tasks.map((t) => hashes[t.id]);
|
|
36
54
|
}
|
|
55
|
+
async hashTasksUpfront(tasks, taskGraph, perTaskEnvs, cwd, collectInputs) {
|
|
56
|
+
const plans = this.planner.getPlansReference(tasks.map((t) => t.id), taskGraph);
|
|
57
|
+
this.upfrontPlans = {
|
|
58
|
+
fingerprint: taskGraphFingerprint(taskGraph),
|
|
59
|
+
taskIds: new Set(tasks.map((t) => t.id)),
|
|
60
|
+
plans,
|
|
61
|
+
};
|
|
62
|
+
const shouldCollectInputs = collectInputs ?? (0, task_io_service_1.getTaskIOService)().hasTaskInputSubscribers();
|
|
63
|
+
return this.hasher.hashPlansUpfront(plans, perTaskEnvs, cwd ?? process.cwd(), shouldCollectInputs);
|
|
64
|
+
}
|
|
37
65
|
}
|
|
38
66
|
exports.NativeTaskHasherImpl = NativeTaskHasherImpl;
|
|
67
|
+
/**
|
|
68
|
+
* Everything the planner reads from a task graph: each task's target and
|
|
69
|
+
* outputs, and the graph's edges. The project graph and nx.json are fixed for
|
|
70
|
+
* the life of a hasher, so equal fingerprints mean equal plans. A run's
|
|
71
|
+
* results (hash, timings) are left out so hashing one task does not
|
|
72
|
+
* invalidate the plans of the rest.
|
|
73
|
+
*/
|
|
74
|
+
function taskGraphFingerprint(taskGraph) {
|
|
75
|
+
const parts = [];
|
|
76
|
+
for (const id of Object.keys(taskGraph.tasks).sort()) {
|
|
77
|
+
const task = taskGraph.tasks[id];
|
|
78
|
+
parts.push(id, task.target.project, task.target.target, task.target.configuration ?? '', (task.outputs ?? []).join(','), (taskGraph.dependencies[id] ?? []).join(','), (taskGraph.continuousDependencies[id] ?? []).join(','));
|
|
79
|
+
}
|
|
80
|
+
return (0, native_1.hashArray)(parts);
|
|
81
|
+
}
|
|
@@ -60,6 +60,12 @@ export interface TaskHasher {
|
|
|
60
60
|
* tasks actually differ.
|
|
61
61
|
*/
|
|
62
62
|
hashTasks(tasks: Task[], taskGraph: TaskGraph, perTaskEnvs: Record<string, NodeJS.ProcessEnv>, cwd?: string): Promise<Hash[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Hash the tasks whose hash needs no output of another task, keyed by
|
|
65
|
+
* task id. A task absent from the result hashes once the tasks it reads
|
|
66
|
+
* from have run.
|
|
67
|
+
*/
|
|
68
|
+
hashTasksUpfront(tasks: Task[], taskGraph: TaskGraph, perTaskEnvs: Record<string, NodeJS.ProcessEnv>, cwd?: string): Promise<Record<string, Hash>>;
|
|
63
69
|
}
|
|
64
70
|
export interface TaskHasherImpl {
|
|
65
71
|
/**
|
|
@@ -70,6 +76,7 @@ export interface TaskHasherImpl {
|
|
|
70
76
|
*/
|
|
71
77
|
hashTasks(tasks: Task[], taskGraph: TaskGraph, perTaskEnvs: Record<string, NodeJS.ProcessEnv>, cwd?: string, collectInputs?: boolean): Promise<PartialHash[]>;
|
|
72
78
|
hashTask(task: Task, taskGraph: TaskGraph, env: NodeJS.ProcessEnv, cwd?: string, collectInputs?: boolean): Promise<PartialHash>;
|
|
79
|
+
hashTasksUpfront(tasks: Task[], taskGraph: TaskGraph, perTaskEnvs: Record<string, NodeJS.ProcessEnv>, cwd?: string, collectInputs?: boolean): Promise<Record<string, PartialHash>>;
|
|
73
80
|
}
|
|
74
81
|
export type Hasher = TaskHasher;
|
|
75
82
|
export declare class DaemonBasedTaskHasher implements TaskHasher {
|
|
@@ -77,6 +84,7 @@ export declare class DaemonBasedTaskHasher implements TaskHasher {
|
|
|
77
84
|
private readonly runnerOptions;
|
|
78
85
|
constructor(daemonClient: DaemonClient, runnerOptions: any);
|
|
79
86
|
hashTasks(tasks: Task[], taskGraph: TaskGraph, envOrPerTaskEnvs: NodeJS.ProcessEnv | Record<string, NodeJS.ProcessEnv>): Promise<Hash[]>;
|
|
87
|
+
hashTasksUpfront(tasks: Task[], taskGraph: TaskGraph, perTaskEnvs: Record<string, NodeJS.ProcessEnv>): Promise<Record<string, Hash>>;
|
|
80
88
|
hashTask(task: Task, taskGraph?: TaskGraph, env?: NodeJS.ProcessEnv): Promise<Hash>;
|
|
81
89
|
}
|
|
82
90
|
export declare class InProcessTaskHasher implements TaskHasher {
|
|
@@ -87,6 +95,7 @@ export declare class InProcessTaskHasher implements TaskHasher {
|
|
|
87
95
|
private taskHasher;
|
|
88
96
|
constructor(projectGraph: ProjectGraph, nxJson: NxJsonConfiguration, externalRustReferences: NxWorkspaceFilesExternals | null, options: any);
|
|
89
97
|
hashTasks(tasks: Task[], taskGraph: TaskGraph, envOrPerTaskEnvs: NodeJS.ProcessEnv | Record<string, NodeJS.ProcessEnv>, cwd?: string, collectInputs?: boolean): Promise<Hash[]>;
|
|
98
|
+
hashTasksUpfront(tasks: Task[], taskGraph: TaskGraph, perTaskEnvs: Record<string, NodeJS.ProcessEnv>, cwd?: string, collectInputs?: boolean): Promise<Record<string, Hash>>;
|
|
90
99
|
hashTask(task: Task, taskGraph?: TaskGraph, env?: NodeJS.ProcessEnv, cwd?: string, collectInputs?: boolean): Promise<Hash>;
|
|
91
100
|
private createHashDetails;
|
|
92
101
|
private hashCommand;
|
|
@@ -52,6 +52,10 @@ class DaemonBasedTaskHasher {
|
|
|
52
52
|
const collectInputs = (0, task_io_service_1.getTaskIOService)().hasTaskInputSubscribers();
|
|
53
53
|
return this.daemonClient.hashTasks(this.runnerOptions, tasks, taskGraph, normalizePerTaskEnvs(tasks, envOrPerTaskEnvs), process.cwd(), collectInputs);
|
|
54
54
|
}
|
|
55
|
+
async hashTasksUpfront(tasks, taskGraph, perTaskEnvs) {
|
|
56
|
+
const collectInputs = (0, task_io_service_1.getTaskIOService)().hasTaskInputSubscribers();
|
|
57
|
+
return this.daemonClient.hashTasksUpfront(this.runnerOptions, tasks, taskGraph, perTaskEnvs, process.cwd(), collectInputs);
|
|
58
|
+
}
|
|
55
59
|
async hashTask(task, taskGraph, env) {
|
|
56
60
|
return (await this.hashTasks([task], taskGraph, {
|
|
57
61
|
[task.id]: env ?? process.env,
|
|
@@ -73,6 +77,16 @@ class InProcessTaskHasher {
|
|
|
73
77
|
const hashes = await this.taskHasher.hashTasks(tasks, taskGraph, normalizePerTaskEnvs(tasks, envOrPerTaskEnvs), cwd ?? process.cwd(), collectInputs);
|
|
74
78
|
return tasks.map((task, index) => this.createHashDetails(task, hashes[index]));
|
|
75
79
|
}
|
|
80
|
+
async hashTasksUpfront(tasks, taskGraph, perTaskEnvs, cwd, collectInputs) {
|
|
81
|
+
const hashes = await this.taskHasher.hashTasksUpfront(tasks, taskGraph, perTaskEnvs, cwd ?? process.cwd(), collectInputs);
|
|
82
|
+
const result = {};
|
|
83
|
+
for (const task of tasks) {
|
|
84
|
+
if (hashes[task.id]) {
|
|
85
|
+
result[task.id] = this.createHashDetails(task, hashes[task.id]);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
76
90
|
async hashTask(task, taskGraph, env, cwd, collectInputs) {
|
|
77
91
|
const res = await this.taskHasher.hashTask(task, taskGraph, env ?? process.env, cwd ?? process.cwd(), collectInputs);
|
|
78
92
|
return this.createHashDetails(task, res);
|