@depup/nx 23.2.1-depup.8 → 23.3.0-depup.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/README.md +7 -18
- package/changes.json +9 -53
- package/dist/bin/init-local.js +7 -1
- package/dist/nx-cloud-internals.d.ts +1 -0
- package/dist/nx-cloud-internals.js +9 -0
- package/dist/plugins/package-json.js +1 -1
- package/dist/src/command-line/add/add.js +5 -1
- package/dist/src/command-line/affected/affected.js +70 -9
- package/dist/src/command-line/affected/command-object.js +1 -1
- package/dist/src/command-line/format/format.js +2 -18
- package/dist/src/command-line/graph/graph.d.ts +31 -0
- package/dist/src/command-line/graph/graph.js +113 -20
- 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 +6 -9
- package/dist/src/command-line/init/init-v2.js +0 -3
- package/dist/src/command-line/migrate/agentic/capture-generator-output.d.ts +25 -0
- package/dist/src/command-line/migrate/agentic/capture-generator-output.js +121 -5
- package/dist/src/command-line/migrate/agentic/close-agent-session.d.ts +21 -0
- package/dist/src/command-line/migrate/agentic/close-agent-session.js +126 -0
- package/dist/src/command-line/migrate/agentic/definitions.d.ts +24 -0
- package/dist/src/command-line/migrate/agentic/definitions.js +79 -20
- 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 +50 -17
- package/dist/src/command-line/migrate/agentic/handoff.js +166 -24
- package/dist/src/command-line/migrate/agentic/instruction-files.d.ts +23 -0
- package/dist/src/command-line/migrate/agentic/instruction-files.js +41 -0
- package/dist/src/command-line/migrate/agentic/master/invocations.d.ts +12 -0
- package/dist/src/command-line/migrate/agentic/master/invocations.js +54 -0
- package/dist/src/command-line/migrate/agentic/master/run-master-session.d.ts +16 -0
- package/dist/src/command-line/migrate/agentic/master/run-master-session.js +175 -0
- package/dist/src/command-line/migrate/agentic/master/spawn-master.d.ts +31 -0
- package/dist/src/command-line/migrate/agentic/master/spawn-master.js +222 -0
- package/dist/src/command-line/migrate/agentic/prompts/final-validation.d.ts +13 -0
- package/dist/src/command-line/migrate/agentic/prompts/final-validation.js +41 -0
- package/dist/src/command-line/migrate/agentic/prompts/fragments.d.ts +17 -0
- package/dist/src/command-line/migrate/agentic/prompts/fragments.js +90 -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 +3 -15
- package/dist/src/command-line/migrate/agentic/runner.js +57 -239
- package/dist/src/command-line/migrate/agentic/terminal-repair.d.ts +1 -0
- package/dist/src/command-line/migrate/agentic/terminal-repair.js +27 -0
- 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/agentic/windows-cmd.d.ts +33 -0
- package/dist/src/command-line/migrate/agentic/windows-cmd.js +88 -0
- package/dist/src/command-line/migrate/command-object.d.ts +2 -0
- package/dist/src/command-line/migrate/command-object.js +11 -1
- package/dist/src/command-line/migrate/deferred-output.d.ts +44 -0
- package/dist/src/command-line/migrate/deferred-output.js +92 -0
- package/dist/src/command-line/migrate/execute-migration.d.ts +9 -3
- package/dist/src/command-line/migrate/execute-migration.js +53 -16
- package/dist/src/command-line/migrate/migrate-analytics.d.ts +34 -9
- package/dist/src/command-line/migrate/migrate-analytics.js +71 -10
- package/dist/src/command-line/migrate/migrate-commits.d.ts +5 -4
- package/dist/src/command-line/migrate/migrate-commits.js +16 -6
- package/dist/src/command-line/migrate/migrate-config.d.ts +5 -2
- package/dist/src/command-line/migrate/migrate-config.js +19 -11
- 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.d.ts +3 -0
- package/dist/src/command-line/migrate/migrate.js +183 -46
- package/dist/src/command-line/migrate/resolve-package-version.js +2 -19
- package/dist/src/command-line/migrate/run/agent-output.d.ts +11 -0
- package/dist/src/command-line/migrate/run/agent-output.js +21 -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 +156 -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/broker.d.ts +150 -0
- package/dist/src/command-line/migrate/run/broker.js +568 -0
- package/dist/src/command-line/migrate/run/clean-retry.d.ts +12 -0
- package/dist/src/command-line/migrate/run/clean-retry.js +99 -0
- package/dist/src/command-line/migrate/run/existing-run-report.d.ts +55 -0
- package/dist/src/command-line/migrate/run/existing-run-report.js +227 -0
- package/dist/src/command-line/migrate/run/give-up.d.ts +41 -0
- package/dist/src/command-line/migrate/run/give-up.js +148 -0
- package/dist/src/command-line/migrate/run/index.d.ts +9 -6
- package/dist/src/command-line/migrate/run/index.js +21 -2
- package/dist/src/command-line/migrate/run/issues.d.ts +127 -0
- package/dist/src/command-line/migrate/run/issues.js +1121 -0
- package/dist/src/command-line/migrate/run/orchestrator.d.ts +59 -1
- package/dist/src/command-line/migrate/run/orchestrator.js +1529 -457
- package/dist/src/command-line/migrate/run/run-id.d.ts +0 -8
- package/dist/src/command-line/migrate/run/run-id.js +0 -30
- package/dist/src/command-line/migrate/run/run-state.d.ts +77 -17
- package/dist/src/command-line/migrate/run/run-state.js +263 -32
- package/dist/src/command-line/migrate/run/runbook.d.ts +18 -0
- package/dist/src/command-line/migrate/run/runbook.js +118 -0
- package/dist/src/command-line/migrate/run/state-lock.d.ts +33 -2
- package/dist/src/command-line/migrate/run/state-lock.js +128 -2
- package/dist/src/command-line/migrate/run/state-machine.d.ts +50 -1
- package/dist/src/command-line/migrate/run/state-machine.js +339 -26
- package/dist/src/command-line/migrate/run/util.d.ts +3 -1
- package/dist/src/command-line/migrate/run/util.js +24 -3
- package/dist/src/command-line/migrate/run/worker.js +290 -129
- package/dist/src/command-line/migrate/step-actions.d.ts +1 -1
- package/dist/src/command-line/migrate/step-actions.js +7 -1
- package/dist/src/command-line/migrate/text.d.ts +6 -0
- package/dist/src/command-line/migrate/text.js +25 -0
- package/dist/src/command-line/migrate/version-skew-guard.js +2 -0
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +5 -11
- package/dist/src/command-line/release/publish.js +11 -8
- package/dist/src/command-line/release/utils/get-touched-projects-for-group.js +3 -3
- package/dist/src/command-line/release/utils/release-graph.js +1 -1
- package/dist/src/command-line/release/utils/remote-release-clients/github.js +5 -8
- 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 +4 -2
- package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.js +37 -3
- package/dist/src/command-line/release/version/version-actions.d.ts +3 -0
- package/dist/src/command-line/reset/reset.js +10 -4
- package/dist/src/command-line/run/run-one.js +5 -1
- package/dist/src/command-line/run-many/run-many.js +6 -12
- package/dist/src/command-line/show/command-object.js +1 -1
- package/dist/src/command-line/show/projects.js +52 -1
- package/dist/src/command-line/yargs-utils/shared-options.d.ts +5 -1
- package/dist/src/command-line/yargs-utils/shared-options.js +38 -4
- package/dist/src/config/task-graph.d.ts +1 -1
- package/dist/src/config/workspace-json-project-json.d.ts +23 -1
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/core/graph/runtime.js +1 -1
- package/dist/src/core/graph/styles.js +1 -1
- package/dist/src/daemon/client/client.d.ts +14 -8
- package/dist/src/daemon/client/client.js +41 -12
- 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/message-types/select-affected-tasks.d.ts +21 -0
- package/dist/src/daemon/message-types/select-affected-tasks.js +11 -0
- package/dist/src/daemon/message-types/ultracache-configuration-version.d.ts +8 -0
- package/dist/src/daemon/message-types/ultracache-configuration-version.js +2 -0
- package/dist/src/daemon/server/dotenv-graph-changes.d.ts +1 -1
- package/dist/src/daemon/server/dotenv-graph-changes.js +2 -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 +10 -2
- package/dist/src/daemon/server/handle-hash-tasks.js +18 -3
- package/dist/src/daemon/server/handle-select-affected-tasks.d.ts +3 -0
- package/dist/src/daemon/server/handle-select-affected-tasks.js +26 -0
- package/dist/src/daemon/server/handle-tasks-execution-hooks.d.ts +3 -2
- package/dist/src/daemon/server/{handle-outputs-changes.d.ts → handle-watch-events.d.ts} +4 -4
- package/dist/src/daemon/server/{handle-outputs-changes.js → handle-watch-events.js} +36 -37
- package/dist/src/daemon/server/outputs-tracking.d.ts +7 -19
- package/dist/src/daemon/server/outputs-tracking.js +7 -107
- package/dist/src/daemon/server/planning-context.d.ts +8 -0
- package/dist/src/daemon/server/planning-context.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 +104 -74
- 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.d.ts +1 -0
- package/dist/src/daemon/server/server.js +54 -30
- package/dist/src/daemon/server/shutdown-utils.d.ts +0 -5
- package/dist/src/daemon/server/shutdown-utils.js +3 -26
- package/dist/src/daemon/server/ultracache-configuration-state.d.ts +7 -0
- package/dist/src/daemon/server/ultracache-configuration-state.js +36 -0
- package/dist/src/devkit-internals.d.ts +3 -1
- package/dist/src/devkit-internals.js +8 -3
- package/dist/src/executors/run-commands/run-commands.impl.d.ts +2 -1
- package/dist/src/executors/run-commands/run-commands.impl.js +19 -5
- package/dist/src/executors/run-commands/running-tasks.d.ts +5 -4
- package/dist/src/executors/run-commands/running-tasks.js +13 -13
- package/dist/src/hasher/create-task-hasher.d.ts +8 -1
- package/dist/src/hasher/create-task-hasher.js +13 -3
- package/dist/src/hasher/hash-plan-inspector.js +2 -2
- package/dist/src/hasher/hash-task.d.ts +2 -2
- package/dist/src/hasher/hash-task.js +28 -17
- package/dist/src/hasher/native-task-hasher-impl.d.ts +20 -4
- package/dist/src/hasher/native-task-hasher-impl.js +75 -9
- package/dist/src/hasher/task-hasher.d.ts +24 -7
- package/dist/src/hasher/task-hasher.js +27 -8
- package/dist/src/hasher/task-planning-context.d.ts +13 -0
- package/dist/src/hasher/task-planning-context.js +12 -0
- package/dist/src/native/index.d.ts +582 -21
- package/dist/src/native/index.js +3 -3
- package/dist/src/native/native-bindings.js +13 -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/native/transform-objects.d.ts +11 -2
- package/dist/src/native/transform-objects.js +46 -0
- package/dist/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +15 -8
- package/dist/src/nx-cloud/update-manager.d.ts +3 -0
- package/dist/src/nx-cloud/update-manager.js +19 -13
- package/dist/src/nx-cloud/utilities/client.d.ts +1 -1
- package/dist/src/nx-cloud/utilities/client.js +1 -1
- package/dist/src/nx-cloud/utilities/is-workspace-claimed.js +2 -1
- package/dist/src/nx-cloud/utilities/nx-cloud-http-client.d.ts +5 -0
- package/dist/src/nx-cloud/utilities/nx-cloud-http-client.js +16 -0
- package/dist/src/nx-cloud/utilities/url-shorten.js +17 -10
- package/dist/src/plugins/js/index.js +45 -64
- package/dist/src/plugins/js/lock-file/lock-file.d.ts +4 -4
- package/dist/src/plugins/js/lock-file/lock-file.js +6 -7
- 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/project-graph/affected/lock-file-changes.d.ts +10 -2
- package/dist/src/plugins/js/project-graph/affected/lock-file-changes.js +51 -29
- package/dist/src/plugins/js/project-graph/affected/npm-packages.d.ts +10 -2
- package/dist/src/plugins/js/project-graph/affected/npm-packages.js +32 -11
- package/dist/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +22 -18
- package/dist/src/plugins/js/utils/register.js +13 -4
- package/dist/src/plugins/package-json/create-nodes.d.ts +2 -2
- package/dist/src/plugins/package-json/create-nodes.js +13 -13
- package/dist/src/project-graph/affected/affected-project-graph-models.d.ts +14 -0
- package/dist/src/project-graph/affected/affected-project-graph.js +5 -18
- package/dist/src/project-graph/affected/affected-projects.d.ts +7 -0
- package/dist/src/project-graph/affected/affected-projects.js +42 -0
- package/dist/src/project-graph/affected/affected-reasons.d.ts +116 -0
- package/dist/src/project-graph/affected/affected-reasons.js +459 -0
- package/dist/src/project-graph/affected/affected-tasks.d.ts +103 -0
- package/dist/src/project-graph/affected/affected-tasks.js +386 -0
- package/dist/src/project-graph/affected/print-explanation.d.ts +11 -0
- package/dist/src/project-graph/affected/print-explanation.js +44 -0
- 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 +12 -3
- 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/project-graph/utils/project-configuration/target-merging.js +67 -0
- package/dist/src/project-graph/utils/project-configuration/target-normalization.js +83 -0
- package/dist/src/project-graph/utils/project-configuration/utils.d.ts +1 -0
- package/dist/src/project-graph/utils/project-configuration/utils.js +1 -0
- package/dist/src/tasks-runner/batch/run-batch.js +15 -0
- package/dist/src/tasks-runner/cache.d.ts +37 -2
- package/dist/src/tasks-runner/cache.js +42 -1
- package/dist/src/tasks-runner/create-task-graph.d.ts +24 -1
- package/dist/src/tasks-runner/create-task-graph.js +57 -2
- 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 +11 -10
- package/dist/src/tasks-runner/init-tasks-runner.d.ts +7 -2
- package/dist/src/tasks-runner/init-tasks-runner.js +15 -7
- 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.d.ts +41 -5
- package/dist/src/tasks-runner/run-command.js +98 -22
- 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-io-service.d.ts +11 -3
- package/dist/src/tasks-runner/task-io-service.js +14 -5
- package/dist/src/tasks-runner/task-orchestrator.d.ts +71 -4
- package/dist/src/tasks-runner/task-orchestrator.js +266 -66
- package/dist/src/tasks-runner/tasks-runner.d.ts +2 -0
- 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.d.ts +5 -0
- package/dist/src/tasks-runner/utils.js +14 -2
- package/dist/src/ultracache/config.d.ts +21 -0
- package/dist/src/ultracache/config.js +29 -0
- package/dist/src/ultracache/fetch.d.ts +21 -0
- package/dist/src/ultracache/fetch.js +43 -0
- package/dist/src/ultracache/overrides.d.ts +17 -0
- package/dist/src/ultracache/overrides.js +61 -0
- package/dist/src/ultracache/report.d.ts +13 -0
- package/dist/src/ultracache/report.js +62 -0
- package/dist/src/ultracache/store.d.ts +41 -0
- package/dist/src/ultracache/store.js +158 -0
- package/dist/src/utils/ab-testing.d.ts +4 -1
- package/dist/src/utils/ab-testing.js +22 -19
- 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 +20 -0
- package/dist/src/utils/command-line-utils.js +10 -3
- package/dist/src/utils/create-cli-options.d.ts +6 -0
- package/dist/src/utils/create-cli-options.js +29 -0
- package/dist/src/utils/db-connection.d.ts +2 -0
- package/dist/src/utils/db-connection.js +2 -0
- 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/git-utils.d.ts +19 -0
- package/dist/src/utils/git-utils.js +97 -39
- package/dist/src/utils/handle-errors.js +5 -43
- package/dist/src/utils/http-client.d.ts +27 -0
- package/dist/src/utils/http-client.js +193 -0
- package/dist/src/utils/installed-nx-version.js +2 -48
- package/dist/src/utils/json-diff.d.ts +4 -2
- package/dist/src/utils/json-diff.js +6 -94
- package/dist/src/utils/min-release-age/packument.js +1 -1
- package/dist/src/utils/nx-cloud-utils.d.ts +2 -0
- package/dist/src/utils/nx-cloud-utils.js +6 -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 +49 -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/project-graph-utils.d.ts +2 -0
- package/dist/src/utils/project-graph-utils.js +12 -0
- 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 +51 -3
- package/dist/src/utils/workspace-context.js +174 -10
- package/package.json +36 -98
- package/schemas/nx-schema.json +38 -0
- package/schemas/project-schema.json +35 -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
- package/dist/src/nx-cloud/utilities/axios.d.ts +0 -4
- package/dist/src/nx-cloud/utilities/axios.js +0 -17
- package/dist/src/project-graph/affected/locators/project-glob-changes.d.ts +0 -2
- package/dist/src/project-graph/affected/locators/project-glob-changes.js +0 -47
- package/dist/src/project-graph/affected/locators/workspace-json-changes.d.ts +0 -4
- package/dist/src/project-graph/affected/locators/workspace-json-changes.js +0 -47
- package/dist/src/project-graph/affected/locators/workspace-projects.d.ts +0 -3
- package/dist/src/project-graph/affected/locators/workspace-projects.js +0 -74
- package/dist/src/utils/collapse-expanded-outputs.d.ts +0 -10
- package/dist/src/utils/collapse-expanded-outputs.js +0 -72
|
@@ -12,7 +12,6 @@ const project_graph_1 = require("../project-graph/project-graph");
|
|
|
12
12
|
const run_commands_impl_1 = require("../executors/run-commands/run-commands.impl");
|
|
13
13
|
const hash_task_1 = require("../hasher/hash-task");
|
|
14
14
|
const task_graph_utils_1 = require("./task-graph-utils");
|
|
15
|
-
const task_hasher_1 = require("../hasher/task-hasher");
|
|
16
15
|
const native_1 = require("../native");
|
|
17
16
|
const db_connection_1 = require("../utils/db-connection");
|
|
18
17
|
const exit_codes_1 = require("../utils/exit-codes");
|
|
@@ -37,9 +36,24 @@ const utils_1 = require("./utils");
|
|
|
37
36
|
function resolveBatchTaskStatus(result) {
|
|
38
37
|
return result.status ?? (result.success ? 'success' : 'failure');
|
|
39
38
|
}
|
|
39
|
+
/** Whether a path names a file with bytes in it. */
|
|
40
|
+
function hasContent(path) {
|
|
41
|
+
try {
|
|
42
|
+
return (0, fs_1.statSync)(path).size > 0;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
40
48
|
class TaskOrchestrator {
|
|
41
49
|
// endregion internal state
|
|
42
|
-
constructor(hasher, initiatingProject, initiatingTasks, projectGraph, taskGraph, nxJson, options, bail, daemon,
|
|
50
|
+
constructor(hasher, initiatingProject, initiatingTasks, projectGraph, taskGraph, nxJson, options, bail, daemon,
|
|
51
|
+
/** What the user named; undefined means they named nothing. */
|
|
52
|
+
specifiedOutputStyle,
|
|
53
|
+
/** What this run renders with, after defaults. */
|
|
54
|
+
resolvedOutputStyle, fullTaskGraph = taskGraph,
|
|
55
|
+
/** Tasks the up-front pass left to hash once the tasks they read from have run. */
|
|
56
|
+
deferredTaskIds) {
|
|
43
57
|
this.hasher = hasher;
|
|
44
58
|
this.initiatingProject = initiatingProject;
|
|
45
59
|
this.initiatingTasks = initiatingTasks;
|
|
@@ -49,8 +63,10 @@ class TaskOrchestrator {
|
|
|
49
63
|
this.options = options;
|
|
50
64
|
this.bail = bail;
|
|
51
65
|
this.daemon = daemon;
|
|
52
|
-
this.
|
|
66
|
+
this.specifiedOutputStyle = specifiedOutputStyle;
|
|
67
|
+
this.resolvedOutputStyle = resolvedOutputStyle;
|
|
53
68
|
this.fullTaskGraph = fullTaskGraph;
|
|
69
|
+
this.deferredTaskIds = deferredTaskIds;
|
|
54
70
|
this.taskDetails = (0, hash_task_1.getTaskDetails)();
|
|
55
71
|
this.cache = (0, cache_1.getCache)(this.options);
|
|
56
72
|
this.tuiEnabled = (0, is_tui_enabled_1.isTuiEnabled)();
|
|
@@ -85,6 +101,9 @@ class TaskOrchestrator {
|
|
|
85
101
|
// miss waiting for a worker slot is re-queried (including the remote
|
|
86
102
|
// retrieval) on every coordinator cycle.
|
|
87
103
|
this.cacheMissedHashes = new Set();
|
|
104
|
+
// The files the cache just wrote or restored, by task id, for postRunSteps
|
|
105
|
+
// to hand the daemon instead of it walking the outputs again.
|
|
106
|
+
this.copiedOutputFiles = new Map();
|
|
88
107
|
this.completedTasks = new Map();
|
|
89
108
|
this.waitingForTasks = [];
|
|
90
109
|
this.pendingDiscreteWorkers = new Set();
|
|
@@ -106,6 +125,13 @@ class TaskOrchestrator {
|
|
|
106
125
|
this.continuousTaskExitHandled = new Map();
|
|
107
126
|
this.cleanupPromise = null;
|
|
108
127
|
this.signalHandlers = [];
|
|
128
|
+
// Tasks whose runner already owns the write to
|
|
129
|
+
// `<cacheDir>/terminalOutputs/<hash>` — forked processes write it as they
|
|
130
|
+
// exit, and the paths that never spawn one write it inline. The backstop in
|
|
131
|
+
// postRunSteps consults this so a task's output is written exactly once.
|
|
132
|
+
this.tasksWithPersistedOutput = new Set();
|
|
133
|
+
/** Batches whose worker log was handed to the life cycle, so it must survive. */
|
|
134
|
+
this.announcedBatchLogs = new Set();
|
|
109
135
|
}
|
|
110
136
|
async init() {
|
|
111
137
|
this.setupSignalHandlers();
|
|
@@ -158,6 +184,10 @@ class TaskOrchestrator {
|
|
|
158
184
|
perf_hooks_1.performance.measure('task-execution', 'task-execution:start', 'task-execution:end');
|
|
159
185
|
if (!this.stopRequested) {
|
|
160
186
|
this.cache.removeOldCacheRecords();
|
|
187
|
+
// Free function, not a cache method: `BatchProcess` writes these logs
|
|
188
|
+
// whichever cache implementation is active. It no-ops under WASM, where
|
|
189
|
+
// the native half does not exist.
|
|
190
|
+
(0, cache_1.sweepBatchOutputs)();
|
|
161
191
|
}
|
|
162
192
|
await this.cleanup();
|
|
163
193
|
await this.dispose();
|
|
@@ -377,7 +407,9 @@ class TaskOrchestrator {
|
|
|
377
407
|
// Copy outputs in parallel for tasks that need it.
|
|
378
408
|
await Promise.all(cacheHits.map(async ({ task, cachedResult }) => {
|
|
379
409
|
if (shouldCopyMap.get(task.hash)) {
|
|
380
|
-
await this.cache.copyFilesFromCache(task.hash, cachedResult, task.outputs);
|
|
410
|
+
const files = await this.cache.copyFilesFromCache(task.hash, cachedResult, task.outputs);
|
|
411
|
+
if (files)
|
|
412
|
+
this.copiedOutputFiles.set(task.id, files);
|
|
381
413
|
}
|
|
382
414
|
}));
|
|
383
415
|
// Derive status, print terminal output, build results.
|
|
@@ -452,8 +484,8 @@ class TaskOrchestrator {
|
|
|
452
484
|
* Hash all batch tasks and resolve cache hits topologically.
|
|
453
485
|
*
|
|
454
486
|
* Walks the task graph level by level. Every task gets a preliminary hash
|
|
455
|
-
* (so startTasks always has a valid hash for Cloud). Tasks
|
|
456
|
-
* whose deps weren't cached are ineligible for cache lookup but still
|
|
487
|
+
* (so startTasks always has a valid hash for Cloud). Tasks the up-front
|
|
488
|
+
* pass deferred, whose deps weren't cached, are ineligible for cache lookup but still
|
|
457
489
|
* receive a preliminary hash — they'll be re-hashed after execution.
|
|
458
490
|
*/
|
|
459
491
|
async applyBatchCachedResults(batch, doNotSkipCache, groupId) {
|
|
@@ -473,8 +505,7 @@ class TaskOrchestrator {
|
|
|
473
505
|
for (const task of rootTasks) {
|
|
474
506
|
const depIds = batch.taskGraph.dependencies[task.id];
|
|
475
507
|
const hasNonCachedDep = depIds.some((id) => nonCachedTaskIds.has(id));
|
|
476
|
-
if (hasNonCachedDep &&
|
|
477
|
-
(0, task_hasher_1.getInputs)(task, this.projectGraph, this.nxJson).depsOutputs.length > 0) {
|
|
508
|
+
if (hasNonCachedDep && this.deferredTaskIds?.has(task.id)) {
|
|
478
509
|
nonCachedTaskIds.add(task.id);
|
|
479
510
|
needsRehashAfterExecution.add(task.id);
|
|
480
511
|
}
|
|
@@ -530,7 +561,7 @@ class TaskOrchestrator {
|
|
|
530
561
|
await Promise.all(nonCachedTasks.map((task) => this.options.lifeCycle.scheduleTask(task)));
|
|
531
562
|
await this.preRunSteps(nonCachedTasks, { groupId });
|
|
532
563
|
}
|
|
533
|
-
// Phase 2: Run non-cached tasks, then re-hash
|
|
564
|
+
// Phase 2: Run non-cached tasks, then re-hash tasks that read their outputs
|
|
534
565
|
const taskIdsToSkip = cachedResults.map((r) => r.task.id);
|
|
535
566
|
let batchResults = [];
|
|
536
567
|
if (taskIdsToSkip.length < tasks.length) {
|
|
@@ -543,7 +574,7 @@ class TaskOrchestrator {
|
|
|
543
574
|
executorName: batch.executorName,
|
|
544
575
|
taskGraph: runGraph,
|
|
545
576
|
}, this.batchEnv, groupId);
|
|
546
|
-
// Re-hash
|
|
577
|
+
// Re-hash tasks that read dep outputs — those outputs are now on disk
|
|
547
578
|
const tasksToRehash = batchResults
|
|
548
579
|
.filter((r) => needsRehashAfterExecution.has(r.task.id) &&
|
|
549
580
|
(r.status === 'success' || r.status === 'failure'))
|
|
@@ -586,7 +617,7 @@ class TaskOrchestrator {
|
|
|
586
617
|
const runBatchStart = perf_hooks_1.performance.mark('TaskOrchestrator-run-batch:start');
|
|
587
618
|
let batchProcess;
|
|
588
619
|
try {
|
|
589
|
-
batchProcess = await this.forkedProcessTaskRunner.forkProcessForBatch(batch, this.projectGraph, this.fullTaskGraph, env);
|
|
620
|
+
batchProcess = await this.forkedProcessTaskRunner.forkProcessForBatch(batch, this.projectGraph, this.fullTaskGraph, env, (0, output_1.printsTaskOutput)(this.resolvedOutputStyle));
|
|
590
621
|
// Stream output from batch process to the batch
|
|
591
622
|
batchProcess.onOutput((output) => {
|
|
592
623
|
this.options.lifeCycle.appendBatchOutput?.(batch.id, output);
|
|
@@ -633,9 +664,13 @@ class TaskOrchestrator {
|
|
|
633
664
|
terminalOutput: result.terminalOutput,
|
|
634
665
|
};
|
|
635
666
|
});
|
|
667
|
+
// The capture stream buffers, so both readers below would otherwise be
|
|
668
|
+
// racing bytes that have not reached the file yet.
|
|
669
|
+
await batchProcess.flushCapturedOutput();
|
|
636
670
|
if ((0, output_1.shouldGroupBatchOutput)()) {
|
|
637
671
|
this.renderBatchOutputSafely(batch.id, () => this.printGroupedBatchOutput(batch, taskResults, batchProcess.getCapturedOutputPath()));
|
|
638
672
|
}
|
|
673
|
+
this.announceBatchWorkerLog(batch.id, taskResults, batchProcess.getCapturedOutputPath());
|
|
639
674
|
return taskResults;
|
|
640
675
|
}
|
|
641
676
|
catch (e) {
|
|
@@ -652,15 +687,19 @@ class TaskOrchestrator {
|
|
|
652
687
|
terminalOutput: isBatchStopping ? '' : (e.stack ?? e.message ?? ''),
|
|
653
688
|
};
|
|
654
689
|
});
|
|
690
|
+
await batchProcess?.flushCapturedOutput();
|
|
691
|
+
this.announceBatchWorkerLog(batch.id, taskResults, batchProcess?.getCapturedOutputPath());
|
|
655
692
|
// The worker died without reporting results, so nothing was attributed to
|
|
656
693
|
// 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
|
-
|
|
694
|
+
// stdout/stderr, held back under grouping - surface it as one fold. Under
|
|
695
|
+
// a style that prints nothing there is no fold; the log is announced by
|
|
696
|
+
// path above instead. Outside both, it already streamed live. This
|
|
697
|
+
// matters just as much when the batch was stopped: every task
|
|
698
|
+
// is marked stopped whether or not it finished, so the log is the only
|
|
699
|
+
// record of what got through. Only the exit-code error is dropped there,
|
|
700
|
+
// since it restates the cancellation.
|
|
701
|
+
if ((0, output_1.shouldGroupBatchOutput)() &&
|
|
702
|
+
(0, output_1.printsTaskOutput)(this.resolvedOutputStyle)) {
|
|
664
703
|
const capturedOutputPath = batchProcess?.getCapturedOutputPath();
|
|
665
704
|
const trailer = isBatchStopping ? undefined : e.message;
|
|
666
705
|
if (capturedOutputPath || trailer) {
|
|
@@ -673,11 +712,42 @@ class TaskOrchestrator {
|
|
|
673
712
|
return taskResults;
|
|
674
713
|
}
|
|
675
714
|
finally {
|
|
676
|
-
|
|
715
|
+
// Kept only when something failed and the log was announced; an all-green
|
|
716
|
+
// batch's chatter explains nothing and would sit in `batchOutputs/` until
|
|
717
|
+
// the sweep.
|
|
718
|
+
if (!this.announcedBatchLogs.has(batch.id)) {
|
|
719
|
+
batchProcess?.discardCapturedOutput();
|
|
720
|
+
}
|
|
677
721
|
const runBatchEnd = perf_hooks_1.performance.mark('TaskOrchestrator-run-batch:end');
|
|
678
722
|
perf_hooks_1.performance.measure('TaskOrchestrator-run-batch', runBatchStart.name, runBatchEnd.name);
|
|
679
723
|
}
|
|
680
724
|
}
|
|
725
|
+
/**
|
|
726
|
+
* Tells the life cycle where the batch worker's own log is, when something
|
|
727
|
+
* failed and a style that prints nothing would otherwise leave it unread.
|
|
728
|
+
*
|
|
729
|
+
* The path is announced rather than the bytes copied into a task: one worker
|
|
730
|
+
* produces one log, it explains the batch rather than any single task, and a
|
|
731
|
+
* task's own output file is read back verbatim on a cache hit.
|
|
732
|
+
*/
|
|
733
|
+
announceBatchWorkerLog(batchId, results, capturedOutputPath) {
|
|
734
|
+
if (!capturedOutputPath || (0, output_1.printsTaskOutput)(this.resolvedOutputStyle)) {
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
const failed = results.some((r) => r.status === 'failure' || r.status === 'stopped');
|
|
738
|
+
if (!failed) {
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
// The path is minted when the file is opened, before any byte reaches it,
|
|
742
|
+
// so a capture that failed on its first write leaves one that exists and is
|
|
743
|
+
// empty. Announcing that offers the reader an address holding nothing.
|
|
744
|
+
// Checked after the flush, so the size is what a reader will actually see.
|
|
745
|
+
if (!hasContent(capturedOutputPath)) {
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
this.announcedBatchLogs.add(batchId);
|
|
749
|
+
this.options.lifeCycle.batchOutputAvailable?.(batchId, capturedOutputPath);
|
|
750
|
+
}
|
|
681
751
|
/**
|
|
682
752
|
* Rendering a batch's output must never change the batch's results. A throw
|
|
683
753
|
* from the printer would otherwise land in `runBatch`'s own error handling:
|
|
@@ -741,17 +811,20 @@ class TaskOrchestrator {
|
|
|
741
811
|
* A batch that never reported results is handled by the caller instead.
|
|
742
812
|
*/
|
|
743
813
|
printGroupedBatchOutput(batch, taskResults, capturedOutputPath) {
|
|
744
|
-
//
|
|
745
|
-
//
|
|
746
|
-
//
|
|
747
|
-
//
|
|
748
|
-
//
|
|
814
|
+
// Reads `resolvedOutputStyle` - what the run actually renders with. The
|
|
815
|
+
// streaming decision deliberately reads `specifiedOutputStyle` instead,
|
|
816
|
+
// since it has to tell a named style from an inferred default. `this.options`
|
|
817
|
+
// has its own `outputStyle`, merged from `nx.json`'s tasksRunnerOptions, so
|
|
818
|
+
// the two disagree whenever a style is configured there but not named on the
|
|
819
|
+
// command line.
|
|
749
820
|
const printsFullOutput = (0, output_1.printsFullTaskOutput)({
|
|
750
821
|
verbose: this.options.verbose,
|
|
751
|
-
outputStyle: this.
|
|
822
|
+
outputStyle: this.resolvedOutputStyle,
|
|
752
823
|
});
|
|
753
824
|
const batchOwnsTheDiagnostic = taskResults.some((r) => r.status === 'failure' || r.status === 'stopped');
|
|
754
|
-
if ((
|
|
825
|
+
if ((0, output_1.printsTaskOutput)(this.resolvedOutputStyle) &&
|
|
826
|
+
(printsFullOutput || batchOwnsTheDiagnostic) &&
|
|
827
|
+
capturedOutputPath) {
|
|
755
828
|
// No redirect lines: every task renders itself below, so there is nothing
|
|
756
829
|
// to redirect anyone to.
|
|
757
830
|
this.printBatchFold(batch, taskResults, { capturedOutputPath }, { redirectLines: false });
|
|
@@ -866,6 +939,10 @@ class TaskOrchestrator {
|
|
|
866
939
|
if (this.completedTasks.has(task.id))
|
|
867
940
|
return;
|
|
868
941
|
const terminalOutput = e?.message ?? '';
|
|
942
|
+
// The worker rejected, so whatever the runner was going to leave on disk
|
|
943
|
+
// either never landed or can't be trusted. Hand the file back to
|
|
944
|
+
// postRunSteps so the failure itself is what the task's output path holds.
|
|
945
|
+
this.tasksWithPersistedOutput.delete(task.id);
|
|
869
946
|
this.options.lifeCycle.printTaskTerminalOutput(task, 'failure', terminalOutput);
|
|
870
947
|
await this.postRunSteps([{ task, status: 'failure', terminalOutput }], doNotSkipCache, groupId);
|
|
871
948
|
}
|
|
@@ -880,7 +957,12 @@ class TaskOrchestrator {
|
|
|
880
957
|
await this.preRunSteps([task], { groupId });
|
|
881
958
|
const pipeOutput = await this.pipeOutputCapture(task);
|
|
882
959
|
const temporaryOutputPath = this.cache.temporaryOutputPath(task);
|
|
883
|
-
|
|
960
|
+
// `summary` prints log paths rather than logs, and `shouldStreamOutput`
|
|
961
|
+
// would otherwise stream the initiating project's output in full - the one
|
|
962
|
+
// task a run-one is most likely to have. Continuous tasks are deliberately
|
|
963
|
+
// NOT suppressed the same way; see `startContinuousTask`.
|
|
964
|
+
const streamOutput = (0, output_1.isStaticOutputStyle)(this.specifiedOutputStyle) ||
|
|
965
|
+
!(0, output_1.printsTaskOutput)(this.resolvedOutputStyle)
|
|
884
966
|
? false
|
|
885
967
|
: (0, utils_1.shouldStreamOutput)(task, this.initiatingProject);
|
|
886
968
|
const env = pipeOutput
|
|
@@ -943,7 +1025,7 @@ class TaskOrchestrator {
|
|
|
943
1025
|
};
|
|
944
1026
|
const runningTask = await (0, run_commands_impl_1.runCommands)(runCommandsOptions, {
|
|
945
1027
|
root: workspace_root_1.workspaceRoot, // only root is needed in runCommands
|
|
946
|
-
}, task
|
|
1028
|
+
}, task);
|
|
947
1029
|
this.runningRunCommandsTasks.set(task.id, runningTask);
|
|
948
1030
|
runningTask.onExit(() => {
|
|
949
1031
|
this.runningRunCommandsTasks.delete(task.id);
|
|
@@ -970,13 +1052,18 @@ class TaskOrchestrator {
|
|
|
970
1052
|
});
|
|
971
1053
|
}
|
|
972
1054
|
}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
runningTask.onExit((code, terminalOutput) => {
|
|
1055
|
+
runningTask.onExit((code, terminalOutput) => {
|
|
1056
|
+
if (!streamOutput && !shouldPrefix) {
|
|
976
1057
|
this.options.lifeCycle.printTaskTerminalOutput(task, code === 0 ? 'success' : 'failure', terminalOutput);
|
|
1058
|
+
}
|
|
1059
|
+
// A continuous task never reaches postRunSteps, so exiting is its
|
|
1060
|
+
// only chance to leave its output on disk. A discrete one is written
|
|
1061
|
+
// there instead, whatever its output style — writing here too would
|
|
1062
|
+
// just duplicate it.
|
|
1063
|
+
if (task.continuous) {
|
|
977
1064
|
(0, fs_1.writeFileSync)(temporaryOutputPath, terminalOutput);
|
|
978
|
-
}
|
|
979
|
-
}
|
|
1065
|
+
}
|
|
1066
|
+
});
|
|
980
1067
|
return runningTask;
|
|
981
1068
|
}
|
|
982
1069
|
catch (e) {
|
|
@@ -988,6 +1075,7 @@ class TaskOrchestrator {
|
|
|
988
1075
|
}
|
|
989
1076
|
const terminalOutput = e.stack ?? e.message ?? '';
|
|
990
1077
|
(0, fs_1.writeFileSync)(temporaryOutputPath, terminalOutput);
|
|
1078
|
+
this.tasksWithPersistedOutput.add(task.id);
|
|
991
1079
|
return new noop_child_process_1.NoopChildProcess({
|
|
992
1080
|
code: 1,
|
|
993
1081
|
terminalOutput,
|
|
@@ -996,6 +1084,7 @@ class TaskOrchestrator {
|
|
|
996
1084
|
}
|
|
997
1085
|
else if (targetConfiguration.executor === 'nx:noop') {
|
|
998
1086
|
(0, fs_1.writeFileSync)(temporaryOutputPath, '');
|
|
1087
|
+
this.tasksWithPersistedOutput.add(task.id);
|
|
999
1088
|
return new noop_child_process_1.NoopChildProcess({
|
|
1000
1089
|
code: 0,
|
|
1001
1090
|
terminalOutput: '',
|
|
@@ -1004,6 +1093,12 @@ class TaskOrchestrator {
|
|
|
1004
1093
|
else {
|
|
1005
1094
|
// cache prep
|
|
1006
1095
|
const runningTask = await this.runTaskInForkedProcess(task, env, pipeOutput, temporaryOutputPath, streamOutput);
|
|
1096
|
+
// Every forked path leaves the file behind whatever the output style:
|
|
1097
|
+
// the pseudo-terminal and prefixed processes write it when they exit,
|
|
1098
|
+
// the direct-output capture has the child write it itself, and the
|
|
1099
|
+
// fork-failure fallback writes the error. Continuous tasks depend on
|
|
1100
|
+
// that — they never reach postRunSteps.
|
|
1101
|
+
this.tasksWithPersistedOutput.add(task.id);
|
|
1007
1102
|
if (this.tuiEnabled) {
|
|
1008
1103
|
if (runningTask instanceof pseudo_terminal_1.PseudoTtyProcess) {
|
|
1009
1104
|
// This is an external of a the pseudo terminal where a task is running and can be passed to the TUI
|
|
@@ -1056,9 +1151,14 @@ class TaskOrchestrator {
|
|
|
1056
1151
|
if (process.env.NX_VERBOSE_LOGGING === 'true') {
|
|
1057
1152
|
console.error(e);
|
|
1058
1153
|
}
|
|
1154
|
+
const terminalOutput = e.stack ?? e.message ?? '';
|
|
1155
|
+
// No process ever started, so nothing else will write the file. Record
|
|
1156
|
+
// why, so the task's terminal output path resolves to the fork error
|
|
1157
|
+
// rather than to nothing.
|
|
1158
|
+
(0, fs_1.writeFileSync)(temporaryOutputPath, terminalOutput);
|
|
1059
1159
|
return new noop_child_process_1.NoopChildProcess({
|
|
1060
1160
|
code: 1,
|
|
1061
|
-
terminalOutput
|
|
1161
|
+
terminalOutput,
|
|
1062
1162
|
});
|
|
1063
1163
|
}
|
|
1064
1164
|
}
|
|
@@ -1091,7 +1191,13 @@ class TaskOrchestrator {
|
|
|
1091
1191
|
const pipeOutput = await this.pipeOutputCapture(task);
|
|
1092
1192
|
// obtain metadata
|
|
1093
1193
|
const temporaryOutputPath = this.cache.temporaryOutputPath(task);
|
|
1094
|
-
|
|
1194
|
+
// Deliberately not gated on `printsTaskOutput`, unlike `runTaskDirectly`.
|
|
1195
|
+
// `SummaryTerminalOutputLifeCycle.printTaskTerminalOutput` is a no-op and it
|
|
1196
|
+
// only reports at `endCommand`, which never runs for a task that does not
|
|
1197
|
+
// end - so suppressing here would leave a `nx serve` under `summary` with a
|
|
1198
|
+
// permanently silent terminal and no file to read yet. Streaming is the only
|
|
1199
|
+
// channel a continuous task has.
|
|
1200
|
+
const streamOutput = (0, output_1.isStaticOutputStyle)(this.specifiedOutputStyle)
|
|
1095
1201
|
? false
|
|
1096
1202
|
: (0, utils_1.shouldStreamOutput)(task, this.initiatingProject);
|
|
1097
1203
|
let env = pipeOutput
|
|
@@ -1108,6 +1214,9 @@ class TaskOrchestrator {
|
|
|
1108
1214
|
this.continuousTaskExitHandled.set(task.id, new Promise((resolve) => {
|
|
1109
1215
|
childProcess.onExit(async (code) => {
|
|
1110
1216
|
await this.handleContinuousTaskExit(code, task, groupId, true);
|
|
1217
|
+
// Registered after the runner's own exit handler, which is what
|
|
1218
|
+
// wrote the file.
|
|
1219
|
+
this.recordContinuousTerminalOutput(task);
|
|
1111
1220
|
resolve();
|
|
1112
1221
|
});
|
|
1113
1222
|
}));
|
|
@@ -1125,52 +1234,143 @@ class TaskOrchestrator {
|
|
|
1125
1234
|
}
|
|
1126
1235
|
async postRunSteps(results, shouldCache, groupId) {
|
|
1127
1236
|
const now = Date.now();
|
|
1128
|
-
const
|
|
1129
|
-
for (const { task, status } of results) {
|
|
1237
|
+
for (const { task } of results) {
|
|
1130
1238
|
// Only set endTime as fallback (batch provides timing via result.task)
|
|
1131
1239
|
task.endTime ??= now;
|
|
1240
|
+
}
|
|
1241
|
+
// Caller decides whether these results should be written to the cache.
|
|
1242
|
+
// Cache replays pass false so a replayed failure (reported as 'failure' so
|
|
1243
|
+
// it counts as a failed run) isn't re-written to the cache on every replay.
|
|
1244
|
+
const resultsToCache = shouldCache && !this.stopRequested ? this.resultsToCache(results) : [];
|
|
1245
|
+
// Resolved before the cache writes so the two never write the same file.
|
|
1246
|
+
this.persistTerminalOutputs(results, resultsToCache);
|
|
1247
|
+
if (resultsToCache.length > 0) {
|
|
1248
|
+
// cache the results
|
|
1249
|
+
perf_hooks_1.performance.mark('cache-results-start');
|
|
1250
|
+
await Promise.all(resultsToCache.map(async ({ task, code, terminalOutput, outputs }) => {
|
|
1251
|
+
const files = await this.cache.put(task, terminalOutput, outputs, code);
|
|
1252
|
+
if (files)
|
|
1253
|
+
this.copiedOutputFiles.set(task.id, files);
|
|
1254
|
+
}));
|
|
1255
|
+
perf_hooks_1.performance.mark('cache-results-end');
|
|
1256
|
+
perf_hooks_1.performance.measure('cache-results', 'cache-results-start', 'cache-results-end');
|
|
1257
|
+
}
|
|
1258
|
+
const tasksToRecord = [];
|
|
1259
|
+
for (const { task, status } of results) {
|
|
1260
|
+
const files = this.copiedOutputFiles.get(task.id);
|
|
1261
|
+
this.copiedOutputFiles.delete(task.id);
|
|
1132
1262
|
// Skip recording for tasks whose outputs already match the cache —
|
|
1133
1263
|
// the daemon already has the correct hash recorded.
|
|
1134
1264
|
if (!this.stopRequested &&
|
|
1135
1265
|
task.outputs.length > 0 &&
|
|
1136
1266
|
status !== 'local-cache-kept-existing') {
|
|
1137
|
-
tasksToRecord.push({ outputs: task.outputs, hash: task.hash });
|
|
1267
|
+
tasksToRecord.push({ outputs: task.outputs, hash: task.hash, files });
|
|
1138
1268
|
}
|
|
1139
1269
|
}
|
|
1140
1270
|
if (tasksToRecord.length > 0) {
|
|
1141
1271
|
await this.recordOutputsHashBatch(tasksToRecord);
|
|
1142
1272
|
}
|
|
1143
|
-
// Caller decides whether these results should be written to the cache.
|
|
1144
|
-
// Cache replays pass false so a replayed failure (reported as 'failure' so
|
|
1145
|
-
// it counts as a failed run) isn't re-written to the cache on every replay.
|
|
1146
|
-
if (shouldCache && !this.stopRequested) {
|
|
1147
|
-
// cache the results
|
|
1148
|
-
perf_hooks_1.performance.mark('cache-results-start');
|
|
1149
|
-
await Promise.all(results
|
|
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)));
|
|
1168
|
-
perf_hooks_1.performance.mark('cache-results-end');
|
|
1169
|
-
perf_hooks_1.performance.measure('cache-results', 'cache-results-start', 'cache-results-end');
|
|
1170
|
-
}
|
|
1171
1273
|
await this.complete(results, groupId);
|
|
1172
1274
|
await this.scheduleNextTasksAndReleaseThreads();
|
|
1173
1275
|
}
|
|
1276
|
+
/**
|
|
1277
|
+
* The results `cache.put` will write, in the shape it wants them. Pulled out
|
|
1278
|
+
* of postRunSteps so the terminal-output backstop can be told exactly which
|
|
1279
|
+
* tasks the cache is already writing a file for.
|
|
1280
|
+
*/
|
|
1281
|
+
resultsToCache(results) {
|
|
1282
|
+
return results
|
|
1283
|
+
.filter(({ status }) => status !== 'local-cache' &&
|
|
1284
|
+
status !== 'local-cache-kept-existing' &&
|
|
1285
|
+
status !== 'remote-cache' &&
|
|
1286
|
+
status !== 'skipped' &&
|
|
1287
|
+
status !== 'stopped')
|
|
1288
|
+
.map((result) => ({
|
|
1289
|
+
...result,
|
|
1290
|
+
code: result.status === 'local-cache' ||
|
|
1291
|
+
result.status === 'local-cache-kept-existing' ||
|
|
1292
|
+
result.status === 'remote-cache' ||
|
|
1293
|
+
result.status === 'success'
|
|
1294
|
+
? 0
|
|
1295
|
+
: 1,
|
|
1296
|
+
outputs: result.task.outputs,
|
|
1297
|
+
}))
|
|
1298
|
+
.filter(({ task, code }) => this.shouldCacheTaskResult(task, code))
|
|
1299
|
+
.filter(({ terminalOutput, outputs }) => terminalOutput || outputs);
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Guarantee that every task that actually ran leaves its terminal output at
|
|
1303
|
+
* `<cacheDir>/terminalOutputs/<hash>`, whatever its cache setting, output
|
|
1304
|
+
* style, or batch membership. That path is what `--output-style=summary`
|
|
1305
|
+
* addresses each failure by, what the DB cache reads back on a hit
|
|
1306
|
+
* (`build_cached_result`), and what Nx Cloud falls back to reading when a
|
|
1307
|
+
* task's in-memory output is undefined, so a task that reaches a terminal
|
|
1308
|
+
* state without a file there is a dangling reference.
|
|
1309
|
+
*
|
|
1310
|
+
* Batch tasks are why this exists. Their output only ever arrives over IPC,
|
|
1311
|
+
* so the sole thing that ever put it on disk was `cache.put` — leaving a
|
|
1312
|
+
* `cache:false` batch task (the shape CI runs under `NX_BATCH_MODE`) with no
|
|
1313
|
+
* file at all.
|
|
1314
|
+
*
|
|
1315
|
+
* Written exactly once per task: tasks whose runner owns the file are
|
|
1316
|
+
* recorded in `tasksWithPersistedOutput`, and tasks `cache.put` is about to
|
|
1317
|
+
* write are skipped here. Cache hits are skipped by status — their output was
|
|
1318
|
+
* read from this very file — except a replayed cached *failure*, which comes
|
|
1319
|
+
* back as `failure` and is rewritten with the bytes it was just read with.
|
|
1320
|
+
* Skipped tasks never ran, so there is nothing to write.
|
|
1321
|
+
*
|
|
1322
|
+
* Every file written without a cache entry behind it is then registered with
|
|
1323
|
+
* the cache, because `removeOldCacheRecords` only collects hashes it finds in
|
|
1324
|
+
* the database — an unregistered file would never be cleaned up. That covers
|
|
1325
|
+
* files this method wrote AND ones a runner wrote, which are equally
|
|
1326
|
+
* invisible to the GC.
|
|
1327
|
+
*/
|
|
1328
|
+
persistTerminalOutputs(results, resultsToCache) {
|
|
1329
|
+
const writtenByCache = new Set(resultsToCache.map(({ task }) => task.id));
|
|
1330
|
+
const toRecord = [];
|
|
1331
|
+
for (const { task, status, terminalOutput } of results) {
|
|
1332
|
+
if (terminalOutput === undefined ||
|
|
1333
|
+
// A task that failed before it was hashed has no path to write to.
|
|
1334
|
+
!task.hash ||
|
|
1335
|
+
status === 'skipped' ||
|
|
1336
|
+
status === 'local-cache' ||
|
|
1337
|
+
status === 'local-cache-kept-existing' ||
|
|
1338
|
+
status === 'remote-cache' ||
|
|
1339
|
+
// `cache.put` writes the file and records the hash itself.
|
|
1340
|
+
writtenByCache.has(task.id)) {
|
|
1341
|
+
continue;
|
|
1342
|
+
}
|
|
1343
|
+
if (!this.tasksWithPersistedOutput.has(task.id)) {
|
|
1344
|
+
this.tasksWithPersistedOutput.add(task.id);
|
|
1345
|
+
(0, fs_1.writeFileSync)(this.cache.temporaryOutputPath(task), terminalOutput);
|
|
1346
|
+
}
|
|
1347
|
+
toRecord.push({
|
|
1348
|
+
hash: task.hash,
|
|
1349
|
+
size: Buffer.byteLength(terminalOutput),
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
if (toRecord.length > 0) {
|
|
1353
|
+
this.cache.recordTerminalOutputs(toRecord);
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
/**
|
|
1357
|
+
* Register a continuous task's terminal output with the cache so the GC can
|
|
1358
|
+
* collect it. Continuous tasks never reach postRunSteps — their file is
|
|
1359
|
+
* written by whichever runner ran them, as the process exits — so this is
|
|
1360
|
+
* the only place their hash gets recorded. Read off disk rather than from a
|
|
1361
|
+
* result, because a continuous task completes without one.
|
|
1362
|
+
*/
|
|
1363
|
+
recordContinuousTerminalOutput(task) {
|
|
1364
|
+
if (!task.hash)
|
|
1365
|
+
return;
|
|
1366
|
+
try {
|
|
1367
|
+
const { size } = (0, fs_1.statSync)(this.cache.temporaryOutputPath(task));
|
|
1368
|
+
this.cache.recordTerminalOutputs([{ hash: task.hash, size }]);
|
|
1369
|
+
}
|
|
1370
|
+
catch {
|
|
1371
|
+
// Exit handler: a throw here would be an unhandled rejection.
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1174
1374
|
async scheduleNextTasksAndReleaseThreads() {
|
|
1175
1375
|
if (this.stopRequested) {
|
|
1176
1376
|
this.waitingForTasks.forEach((f) => f(null));
|
|
@@ -19,6 +19,8 @@ export type TasksRunner<T = unknown> = (tasks: Task[], options: T, context?: {
|
|
|
19
19
|
taskGraph?: TaskGraph;
|
|
20
20
|
hasher?: TaskHasher;
|
|
21
21
|
daemon?: DaemonClient;
|
|
22
|
+
/** Tasks hashed only once the tasks they read outputs from have run. */
|
|
23
|
+
deferredTaskIds?: ReadonlySet<string>;
|
|
22
24
|
}) => any | Promise<{
|
|
23
25
|
[id: string]: TaskStatus;
|
|
24
26
|
}>;
|
|
@@ -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
|
+
}
|
|
@@ -49,6 +49,11 @@ export declare function getExecutorForTask(task: Task, projects: Record<string,
|
|
|
49
49
|
isNxExecutor: boolean;
|
|
50
50
|
};
|
|
51
51
|
export declare function getCustomHasher(task: Task, projects: Record<string, ProjectConfiguration>): CustomHasher | null;
|
|
52
|
+
/**
|
|
53
|
+
* `taskGraph` pruned to `required`, which must already hold its dependencies.
|
|
54
|
+
* Unknown ids are ignored: a sync generator can remove a task after selection.
|
|
55
|
+
*/
|
|
56
|
+
export declare function pruneToSelectedTasks(taskGraph: TaskGraph, required: Iterable<string>): TaskGraph;
|
|
52
57
|
export declare function removeTasksFromTaskGraph(graph: TaskGraph, ids: string[]): TaskGraph;
|
|
53
58
|
export declare function calculateReverseDeps(taskGraph: TaskGraph): Record<string, string[]>;
|
|
54
59
|
export declare function getCliPath(): string;
|
|
@@ -17,6 +17,7 @@ exports.getExecutorNameForTask = getExecutorNameForTask;
|
|
|
17
17
|
exports.expandInitiatingTasksThroughNoop = expandInitiatingTasksThroughNoop;
|
|
18
18
|
exports.getExecutorForTask = getExecutorForTask;
|
|
19
19
|
exports.getCustomHasher = getCustomHasher;
|
|
20
|
+
exports.pruneToSelectedTasks = pruneToSelectedTasks;
|
|
20
21
|
exports.removeTasksFromTaskGraph = removeTasksFromTaskGraph;
|
|
21
22
|
exports.calculateReverseDeps = calculateReverseDeps;
|
|
22
23
|
exports.getCliPath = getCliPath;
|
|
@@ -221,7 +222,10 @@ function getOutputsForTargetAndConfiguration(taskTargetOrTask, overridesOrNode,
|
|
|
221
222
|
validateOutputs(targetConfiguration.outputs);
|
|
222
223
|
const result = new Set();
|
|
223
224
|
for (const output of targetConfiguration.outputs) {
|
|
224
|
-
|
|
225
|
+
// A leading `!` is negation, not part of the path: strip it so
|
|
226
|
+
// `{workspaceRoot}` still sits where interpolate requires it.
|
|
227
|
+
const isNegated = output.startsWith('!');
|
|
228
|
+
const interpolatedOutput = interpolate(isNegated ? output.substring(1) : output, {
|
|
225
229
|
projectRoot: node.data.root,
|
|
226
230
|
projectName: node.name,
|
|
227
231
|
project: { ...node.data, name: node.name }, // this is legacy
|
|
@@ -229,7 +233,7 @@ function getOutputsForTargetAndConfiguration(taskTargetOrTask, overridesOrNode,
|
|
|
229
233
|
});
|
|
230
234
|
if (!!interpolatedOutput &&
|
|
231
235
|
!interpolatedOutput.match(/{(projectRoot|workspaceRoot|(options.*))}/)) {
|
|
232
|
-
result.add(interpolatedOutput);
|
|
236
|
+
result.add(isNegated ? `!${interpolatedOutput}` : interpolatedOutput);
|
|
233
237
|
}
|
|
234
238
|
}
|
|
235
239
|
return Array.from(result);
|
|
@@ -341,6 +345,14 @@ function getCustomHasher(task, projects) {
|
|
|
341
345
|
const factory = getExecutorForTask(task, projects).hasherFactory;
|
|
342
346
|
return factory ? factory() : null;
|
|
343
347
|
}
|
|
348
|
+
/**
|
|
349
|
+
* `taskGraph` pruned to `required`, which must already hold its dependencies.
|
|
350
|
+
* Unknown ids are ignored: a sync generator can remove a task after selection.
|
|
351
|
+
*/
|
|
352
|
+
function pruneToSelectedTasks(taskGraph, required) {
|
|
353
|
+
const keep = new Set(required);
|
|
354
|
+
return removeTasksFromTaskGraph(taskGraph, Object.keys(taskGraph.tasks).filter((id) => !keep.has(id)));
|
|
355
|
+
}
|
|
344
356
|
function removeTasksFromTaskGraph(graph, ids) {
|
|
345
357
|
const newGraph = removeIdsFromTaskGraph(graph, ids, graph.tasks);
|
|
346
358
|
return {
|