@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
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type CachedPluginCapabilities, NxPluginCapabilities as NxPluginCapabilitiesStore } from '../../native';
|
|
2
|
+
export type NxPluginCapabilities = CachedPluginCapabilities;
|
|
3
|
+
export declare function getNxPluginCapabilitiesStore(): NxPluginCapabilitiesStore | null;
|
|
4
|
+
export declare function noteGraphReadFromCache(computedAt: number | undefined): void;
|
|
5
|
+
/** Null means "load them", never "no plugin registers anything". */
|
|
6
|
+
export declare function capabilitiesOfNxPluginsReadFromCache(): NxPluginCapabilities[] | null;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getNxPluginCapabilitiesStore = getNxPluginCapabilitiesStore;
|
|
4
|
+
exports.noteGraphReadFromCache = noteGraphReadFromCache;
|
|
5
|
+
exports.capabilitiesOfNxPluginsReadFromCache = capabilitiesOfNxPluginsReadFromCache;
|
|
6
|
+
const native_1 = require("../../native");
|
|
7
|
+
const db_connection_1 = require("../../utils/db-connection");
|
|
8
|
+
let store;
|
|
9
|
+
function getNxPluginCapabilitiesStore() {
|
|
10
|
+
// The database is not part of the WASM build.
|
|
11
|
+
if (native_1.IS_WASM) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
// Checkout-local: the rows describe this checkout's graph.
|
|
15
|
+
store ??= new native_1.NxPluginCapabilities((0, db_connection_1.getLocalDbConnection)());
|
|
16
|
+
return store;
|
|
17
|
+
}
|
|
18
|
+
let computedAtOfGraphReadFromCache;
|
|
19
|
+
function noteGraphReadFromCache(computedAt) {
|
|
20
|
+
computedAtOfGraphReadFromCache = computedAt;
|
|
21
|
+
}
|
|
22
|
+
/** Null means "load them", never "no plugin registers anything". */
|
|
23
|
+
function capabilitiesOfNxPluginsReadFromCache() {
|
|
24
|
+
if (computedAtOfGraphReadFromCache === undefined) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return (getNxPluginCapabilitiesStore()?.get(computedAtOfGraphReadFromCache) ?? null);
|
|
28
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { PostTasksExecutionContext } from './public-api';
|
|
2
|
+
/**
|
|
3
|
+
* A {@link PostTasksExecutionContext} whose terminal outputs have been lifted
|
|
4
|
+
* out of `taskResults` and into a map of the paths holding them, so it can
|
|
5
|
+
* cross a process boundary.
|
|
6
|
+
*
|
|
7
|
+
* `taskResults` carries every task's full output inline, so the sender copies
|
|
8
|
+
* every one of those strings into the serialized payload and pushes the whole
|
|
9
|
+
* thing across the socket, once per boundary. The strings themselves exist
|
|
10
|
+
* either way: the runner puts them on each result as its task completes, and
|
|
11
|
+
* the receiver reads them back eagerly. The bytes are
|
|
12
|
+
* already on disk at `<cacheDir>/terminalOutputs/<hash>`, so transports carry
|
|
13
|
+
* paths and each receiver reads them back before any plugin sees the context.
|
|
14
|
+
*
|
|
15
|
+
* This is no longer a crash fix. The fallback used to be
|
|
16
|
+
* `v8.serialize(...).toString('binary')`, which put an oversized payload back
|
|
17
|
+
* through V8's maximum string length after `JSON.stringify` had already hit it,
|
|
18
|
+
* so both arms threw. `serialize` returns bytes now and the ceiling is gone;
|
|
19
|
+
* what is left is the cost of moving the payload at all.
|
|
20
|
+
*
|
|
21
|
+
* The paths live here rather than in `terminalOutput` so that field never
|
|
22
|
+
* holds two meanings: a stubbed result carries no `terminalOutput` at all, so
|
|
23
|
+
* a transport that forgets to rehydrate hands a plugin a missing value rather
|
|
24
|
+
* than a filename shaped exactly like real output. The map is required, so a
|
|
25
|
+
* stubbed context cannot typecheck without one.
|
|
26
|
+
*/
|
|
27
|
+
export type StubbedPostTasksExecutionContext = PostTasksExecutionContext & {
|
|
28
|
+
/**
|
|
29
|
+
* Path to the terminal output of each stubbed task, keyed by task id. Out of
|
|
30
|
+
* band because a task can print anything, so no in-band marker is safe from
|
|
31
|
+
* a task that prints it.
|
|
32
|
+
*/
|
|
33
|
+
stubbedTerminalOutputs: Record<string, string>;
|
|
34
|
+
};
|
|
35
|
+
export type MaybeStubbedPostTasksExecutionContext = PostTasksExecutionContext | StubbedPostTasksExecutionContext;
|
|
36
|
+
/**
|
|
37
|
+
* Swaps outputs out for paths ahead of a transport. Idempotent, so a context
|
|
38
|
+
* already stubbed for the daemon can be passed on to a plugin worker as-is.
|
|
39
|
+
*/
|
|
40
|
+
export declare function stubTerminalOutputs(context: MaybeStubbedPostTasksExecutionContext): MaybeStubbedPostTasksExecutionContext;
|
|
41
|
+
/**
|
|
42
|
+
* Reads the outputs back. A no-op on a context that was never stubbed, which
|
|
43
|
+
* is every in-process plugin run without the daemon.
|
|
44
|
+
*
|
|
45
|
+
* The reads are issued together rather than awaited one at a time: a run has
|
|
46
|
+
* one file per task, they are independent, and this sits between the tasks
|
|
47
|
+
* finishing and the first plugin seeing the results - so serializing it would
|
|
48
|
+
* add up every file's latency in front of that.
|
|
49
|
+
*/
|
|
50
|
+
export declare function rehydrateTerminalOutputs(context: MaybeStubbedPostTasksExecutionContext): Promise<PostTasksExecutionContext>;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stubTerminalOutputs = stubTerminalOutputs;
|
|
4
|
+
exports.rehydrateTerminalOutputs = rehydrateTerminalOutputs;
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const promises_1 = require("node:fs/promises");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const terminal_output_path_1 = require("../../tasks-runner/terminal-output-path");
|
|
9
|
+
const logger_1 = require("../../utils/logger");
|
|
10
|
+
function isStubbed(context) {
|
|
11
|
+
return !!context.stubbedTerminalOutputs;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Swaps outputs out for paths ahead of a transport. Idempotent, so a context
|
|
15
|
+
* already stubbed for the daemon can be passed on to a plugin worker as-is.
|
|
16
|
+
*/
|
|
17
|
+
function stubTerminalOutputs(context) {
|
|
18
|
+
if (!context.taskResults) {
|
|
19
|
+
return context;
|
|
20
|
+
}
|
|
21
|
+
const stubbedTerminalOutputs = {
|
|
22
|
+
...(isStubbed(context) ? context.stubbedTerminalOutputs : {}),
|
|
23
|
+
};
|
|
24
|
+
const taskResults = {};
|
|
25
|
+
let swapped = false;
|
|
26
|
+
for (const [id, result] of Object.entries(context.taskResults)) {
|
|
27
|
+
const path = id in stubbedTerminalOutputs ? null : stubbablePath(result);
|
|
28
|
+
if (path) {
|
|
29
|
+
const { terminalOutput, ...withoutOutput } = result;
|
|
30
|
+
stubbedTerminalOutputs[id] = path;
|
|
31
|
+
taskResults[id] = withoutOutput;
|
|
32
|
+
swapped = true;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
taskResults[id] = result;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Nothing to swap: hand back the context as it came, so a run with no
|
|
39
|
+
// outputs on disk sends exactly what it sent before. Covers the
|
|
40
|
+
// already-stubbed case too, which keeps its own map by staying untouched.
|
|
41
|
+
if (!swapped) {
|
|
42
|
+
return context;
|
|
43
|
+
}
|
|
44
|
+
return { ...context, taskResults, stubbedTerminalOutputs };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Reads the outputs back. A no-op on a context that was never stubbed, which
|
|
48
|
+
* is every in-process plugin run without the daemon.
|
|
49
|
+
*
|
|
50
|
+
* The reads are issued together rather than awaited one at a time: a run has
|
|
51
|
+
* one file per task, they are independent, and this sits between the tasks
|
|
52
|
+
* finishing and the first plugin seeing the results - so serializing it would
|
|
53
|
+
* add up every file's latency in front of that.
|
|
54
|
+
*/
|
|
55
|
+
async function rehydrateTerminalOutputs(context) {
|
|
56
|
+
if (!isStubbed(context)) {
|
|
57
|
+
return context;
|
|
58
|
+
}
|
|
59
|
+
const taskResults = { ...context.taskResults };
|
|
60
|
+
const reads = Object.entries(context.stubbedTerminalOutputs)
|
|
61
|
+
// A stub whose result is gone has nothing to attach the bytes to, so it is
|
|
62
|
+
// dropped before the read rather than after it.
|
|
63
|
+
.filter(([id]) => taskResults[id])
|
|
64
|
+
.map(async ([id, path]) => {
|
|
65
|
+
const terminalOutput = await readTerminalOutput(path);
|
|
66
|
+
taskResults[id] = { ...taskResults[id], terminalOutput };
|
|
67
|
+
});
|
|
68
|
+
await Promise.all(reads);
|
|
69
|
+
const { stubbedTerminalOutputs, ...rehydrated } = {
|
|
70
|
+
...context,
|
|
71
|
+
taskResults,
|
|
72
|
+
};
|
|
73
|
+
return rehydrated;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The path to swap in, or null to leave the output inline. A task that failed
|
|
77
|
+
* before it was hashed has no path, and a task that never ran has no file —
|
|
78
|
+
* both keep whatever they already carry rather than losing it.
|
|
79
|
+
*/
|
|
80
|
+
function stubbablePath(result) {
|
|
81
|
+
if (result.terminalOutput === undefined) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
const hash = result.task?.hash;
|
|
85
|
+
if (!hash) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
// `getCustomHasher` lets a plugin return any string, and this one reaches a
|
|
89
|
+
// read, so the sink is kept inside the cache dir here rather than trusted to
|
|
90
|
+
// the hasher. A hash that needed stripping resolves to a file that does not
|
|
91
|
+
// exist, which falls back to sending the output inline.
|
|
92
|
+
const path = (0, terminal_output_path_1.terminalOutputPathForHash)((0, node_path_1.basename)(hash));
|
|
93
|
+
return (0, node_fs_1.existsSync)(path) ? path : null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* A path that no longer resolves means the bytes are gone. Saying so with
|
|
97
|
+
* `undefined` — already a legal value, skipped tasks have it — beats leaving
|
|
98
|
+
* the path, which would have plugins treat a filename as the output.
|
|
99
|
+
*/
|
|
100
|
+
async function readTerminalOutput(path) {
|
|
101
|
+
if (!path) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
return await (0, promises_1.readFile)(path, 'utf-8');
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
logger_1.logger.warn(`Nx could not read a task's terminal output from ${path}: ${e.message}`);
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PreTasksExecutionContext } from './public-api';
|
|
2
|
+
import { type MaybeStubbedPostTasksExecutionContext } from './task-results-stub';
|
|
2
3
|
export declare function runPreTasksExecution(pluginContext: PreTasksExecutionContext): Promise<NodeJS.ProcessEnv[]>;
|
|
3
|
-
export declare function runPostTasksExecution(context:
|
|
4
|
+
export declare function runPostTasksExecution(context: MaybeStubbedPostTasksExecutionContext): Promise<void>;
|
|
@@ -7,8 +7,18 @@ const get_plugins_1 = require("./get-plugins");
|
|
|
7
7
|
const is_on_daemon_1 = require("../../daemon/is-on-daemon");
|
|
8
8
|
const client_1 = require("../../daemon/client/client");
|
|
9
9
|
const workspace_root_1 = require("../../utils/workspace-root");
|
|
10
|
+
const task_results_stub_1 = require("./task-results-stub");
|
|
11
|
+
const nx_plugin_capabilities_1 = require("./nx-plugin-capabilities");
|
|
12
|
+
/** True only when the cached graph's recorded rows show no plugin has `hook`; unknown is false. */
|
|
13
|
+
function knownThatNoPluginRegisters(hook) {
|
|
14
|
+
const recorded = (0, nx_plugin_capabilities_1.capabilitiesOfNxPluginsReadFromCache)();
|
|
15
|
+
return !!recorded && !recorded.some((capabilities) => capabilities[hook]);
|
|
16
|
+
}
|
|
10
17
|
async function runPreTasksExecution(pluginContext) {
|
|
11
18
|
if ((0, is_on_daemon_1.isOnDaemon)() || !(0, client_1.isDaemonEnabled)()) {
|
|
19
|
+
if (knownThatNoPluginRegisters('hasPreTasksExecution')) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
12
22
|
performance.mark(`preTasksExecution:start`);
|
|
13
23
|
const plugins = await (0, get_plugins_1.getPlugins)((0, nx_json_1.readNxJson)(pluginContext.workspaceRoot), pluginContext.workspaceRoot);
|
|
14
24
|
const envs = await Promise.all(plugins
|
|
@@ -44,6 +54,9 @@ function applyProcessEnvs(envs) {
|
|
|
44
54
|
}
|
|
45
55
|
async function runPostTasksExecution(context) {
|
|
46
56
|
if ((0, is_on_daemon_1.isOnDaemon)() || !(0, client_1.isDaemonEnabled)()) {
|
|
57
|
+
if (knownThatNoPluginRegisters('hasPostTasksExecution')) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
47
60
|
performance.mark(`postTasksExecution:start`);
|
|
48
61
|
const plugins = await (0, get_plugins_1.getPlugins)((0, nx_json_1.readNxJson)(workspace_root_1.workspaceRoot));
|
|
49
62
|
await Promise.all(plugins
|
|
@@ -62,6 +75,6 @@ async function runPostTasksExecution(context) {
|
|
|
62
75
|
performance.measure(`postTasksExecution`, `postTasksExecution:start`, `postTasksExecution:end`);
|
|
63
76
|
}
|
|
64
77
|
else {
|
|
65
|
-
await client_1.daemonClient.runPostTasksExecution(context);
|
|
78
|
+
await client_1.daemonClient.runPostTasksExecution((0, task_results_stub_1.stubTerminalOutputs)(context));
|
|
66
79
|
}
|
|
67
80
|
}
|
|
@@ -26,9 +26,11 @@ const logger_1 = require("../utils/logger");
|
|
|
26
26
|
const output_1 = require("../utils/output");
|
|
27
27
|
const strip_indents_1 = require("../utils/strip-indents");
|
|
28
28
|
const workspace_root_1 = require("../utils/workspace-root");
|
|
29
|
+
const workspace_context_1 = require("../utils/workspace-context");
|
|
29
30
|
const build_project_graph_1 = require("./build-project-graph");
|
|
30
31
|
const error_types_1 = require("./error-types");
|
|
31
32
|
const nx_deps_cache_1 = require("./nx-deps-cache");
|
|
33
|
+
const nx_plugin_capabilities_1 = require("./plugins/nx-plugin-capabilities");
|
|
32
34
|
const get_plugins_1 = require("./plugins/get-plugins");
|
|
33
35
|
const retrieve_workspace_files_1 = require("./utils/retrieve-workspace-files");
|
|
34
36
|
const handle_import_1 = require("../utils/handle-import");
|
|
@@ -39,16 +41,21 @@ const handle_import_1 = require("../utils/handle-import");
|
|
|
39
41
|
* @throws {Error} if there is no cached ProjectGraph to read from
|
|
40
42
|
*/
|
|
41
43
|
function readCachedProjectGraph(minimumComputedAt) {
|
|
42
|
-
const
|
|
43
|
-
if (!
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
const cached = (0, nx_deps_cache_1.readProjectGraphCache)(minimumComputedAt);
|
|
45
|
+
if (!cached) {
|
|
46
|
+
throw noCachedProjectGraphError();
|
|
47
|
+
}
|
|
48
|
+
return cached.projectGraph;
|
|
49
|
+
}
|
|
50
|
+
function noCachedProjectGraphError() {
|
|
51
|
+
const angularSpecificError = (0, fileutils_1.fileExists)(`${workspace_root_1.workspaceRoot}/angular.json`)
|
|
52
|
+
? (0, strip_indents_1.stripIndents) `
|
|
46
53
|
Make sure invoke 'node ./decorate-angular-cli.js' in your postinstall script.
|
|
47
54
|
The decorated CLI will compute the project graph.
|
|
48
55
|
'ng --help' should say 'Smart Monorepos · Fast Builds'.
|
|
49
56
|
`
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
: '';
|
|
58
|
+
return new Error((0, strip_indents_1.stripIndents) `
|
|
52
59
|
[readCachedProjectGraph] ERROR: No cached ProjectGraph is available.
|
|
53
60
|
|
|
54
61
|
If you are leveraging \`readCachedProjectGraph()\` directly then you will need to refactor your usage to first ensure that
|
|
@@ -58,8 +65,6 @@ function readCachedProjectGraph(minimumComputedAt) {
|
|
|
58
65
|
|
|
59
66
|
${angularSpecificError}
|
|
60
67
|
`);
|
|
61
|
-
}
|
|
62
|
-
return projectGraphCache;
|
|
63
68
|
}
|
|
64
69
|
function readCachedProjectConfiguration(projectName) {
|
|
65
70
|
const graph = readCachedProjectGraph();
|
|
@@ -85,8 +90,11 @@ function readProjectsConfigurationFromProjectGraph(projectGraph) {
|
|
|
85
90
|
}
|
|
86
91
|
async function buildProjectGraphAndSourceMapsWithoutDaemon() {
|
|
87
92
|
preventRecursionInGraphConstruction();
|
|
93
|
+
// Answer from the plugins loaded below, not an earlier cached graph's rows.
|
|
94
|
+
(0, nx_plugin_capabilities_1.noteGraphReadFromCache)(undefined);
|
|
88
95
|
global.NX_GRAPH_CREATION = true;
|
|
89
96
|
const nxJson = (0, nx_json_1.readNxJson)();
|
|
97
|
+
(0, workspace_context_1.refreshWorkspaceContext)(workspace_root_1.workspaceRoot);
|
|
90
98
|
perf_hooks_1.performance.mark('retrieve-project-configurations:start');
|
|
91
99
|
let configurationResult;
|
|
92
100
|
let projectConfigurationsError;
|
|
@@ -136,7 +144,12 @@ async function buildProjectGraphAndSourceMapsWithoutDaemon() {
|
|
|
136
144
|
...(projectGraphError?.errors ?? []),
|
|
137
145
|
];
|
|
138
146
|
if (cacheEnabled) {
|
|
139
|
-
|
|
147
|
+
const computedAt = Date.now();
|
|
148
|
+
// Before the graph, so a cached graph never lacks its row.
|
|
149
|
+
if (errors.length === 0) {
|
|
150
|
+
(0, nx_plugin_capabilities_1.getNxPluginCapabilitiesStore)()?.record(computedAt, plugins.map((plugin) => plugin.capabilities()));
|
|
151
|
+
}
|
|
152
|
+
(0, nx_deps_cache_1.writeCache)(projectFileMapCache, projectGraph, sourceMaps, errors, computedAt);
|
|
140
153
|
}
|
|
141
154
|
if (errors.length > 0) {
|
|
142
155
|
throw new error_types_1.ProjectGraphError(errors, projectGraph, sourceMaps);
|
|
@@ -149,14 +162,7 @@ function handleProjectGraphError(opts, e) {
|
|
|
149
162
|
if (opts.exitOnError) {
|
|
150
163
|
const isVerbose = process.env.NX_VERBOSE_LOGGING === 'true';
|
|
151
164
|
if (e instanceof error_types_1.ProjectGraphError) {
|
|
152
|
-
|
|
153
|
-
const bodyLines = isVerbose
|
|
154
|
-
? [e.stack]
|
|
155
|
-
: ['Pass --verbose to see the stacktraces.'];
|
|
156
|
-
output_1.output.error({
|
|
157
|
-
title,
|
|
158
|
-
bodyLines: bodyLines,
|
|
159
|
-
});
|
|
165
|
+
output_1.output.error((0, error_types_1.formatProjectGraphError)(e, isVerbose));
|
|
160
166
|
}
|
|
161
167
|
else if (typeof e.message === 'string') {
|
|
162
168
|
const lines = e.message.split('\n');
|
|
@@ -178,7 +184,12 @@ function handleProjectGraphError(opts, e) {
|
|
|
178
184
|
}
|
|
179
185
|
}
|
|
180
186
|
async function readCachedGraphAndHydrateFileMap(minimumComputedAt) {
|
|
181
|
-
const
|
|
187
|
+
const cached = (0, nx_deps_cache_1.readProjectGraphCache)(minimumComputedAt);
|
|
188
|
+
if (!cached) {
|
|
189
|
+
throw noCachedProjectGraphError();
|
|
190
|
+
}
|
|
191
|
+
const graph = cached.projectGraph;
|
|
192
|
+
(0, nx_plugin_capabilities_1.noteGraphReadFromCache)(cached.computedAt);
|
|
182
193
|
const projectRootMap = Object.fromEntries(Object.entries(graph.nodes).map(([project, { data }]) => [
|
|
183
194
|
data.root,
|
|
184
195
|
project,
|
|
@@ -260,45 +271,33 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
|
|
|
260
271
|
const lock = !native_1.IS_WASM
|
|
261
272
|
? new native_1.FileLock((0, path_1.join)(cache_directory_1.workspaceDataDirectory, 'project-graph.lock'))
|
|
262
273
|
: null;
|
|
263
|
-
let
|
|
264
|
-
while (
|
|
274
|
+
let holdingLock = lock?.tryLock() ?? false;
|
|
275
|
+
while (lock && !holdingLock) {
|
|
265
276
|
logger_1.logger.verbose('Waiting for graph construction in another process to complete');
|
|
266
277
|
const spinner = new delayed_spinner_1.DelayedSpinner('Waiting for graph construction in another process to complete');
|
|
267
278
|
const start = Date.now();
|
|
268
|
-
await lock.wait();
|
|
269
|
-
spinner.cleanup();
|
|
270
|
-
// Note: This will currently throw if any of the caches are missing...
|
|
271
|
-
// It would be nice if one of the processes that was waiting for the lock
|
|
272
|
-
// could pick up the slack and build the graph if it's missing, but
|
|
273
|
-
// we wouldn't want either of the below to happen:
|
|
274
|
-
// - All of the waiting processes to build the graph
|
|
275
|
-
// - Even one of the processes building the graph on a legitimate error
|
|
276
279
|
try {
|
|
277
|
-
|
|
278
|
-
//
|
|
279
|
-
// was computed by the process was already working.
|
|
280
|
+
await lock.wait();
|
|
281
|
+
// A graph computed after this process started waiting is the holder's.
|
|
280
282
|
const graph = await readCachedGraphAndHydrateFileMap(start);
|
|
281
283
|
const sourceMaps = (0, nx_deps_cache_1.readSourceMapsCache)();
|
|
282
284
|
if (!sourceMaps) {
|
|
283
285
|
throw new Error('The project graph was computed in another process, but the source maps are missing.');
|
|
284
286
|
}
|
|
285
|
-
return {
|
|
286
|
-
projectGraph: graph,
|
|
287
|
-
sourceMaps,
|
|
288
|
-
};
|
|
287
|
+
return { projectGraph: graph, sourceMaps };
|
|
289
288
|
}
|
|
290
289
|
catch (e) {
|
|
291
|
-
// If the error is that the cached graph is stale after unlock,
|
|
292
|
-
// the process that was working on the graph must have been canceled,
|
|
293
|
-
// so we will fall through to the normal flow to ensure
|
|
294
|
-
// its created by one of the processes that was waiting
|
|
295
290
|
if (!(e instanceof error_types_1.StaleProjectGraphCacheError)) {
|
|
296
291
|
throw e;
|
|
297
292
|
}
|
|
293
|
+
// The holder stopped without writing a graph: build it here, or wait for
|
|
294
|
+
// whoever took the lock first.
|
|
295
|
+
holdingLock = lock.tryLock();
|
|
296
|
+
}
|
|
297
|
+
finally {
|
|
298
|
+
spinner.cleanup();
|
|
298
299
|
}
|
|
299
|
-
locked = lock.check();
|
|
300
300
|
}
|
|
301
|
-
lock?.lock();
|
|
302
301
|
try {
|
|
303
302
|
const res = await buildProjectGraphAndSourceMapsWithoutDaemon();
|
|
304
303
|
perf_hooks_1.performance.measure('createProjectGraphAsync >> retrieve-project-configurations', 'retrieve-project-configurations:start', 'retrieve-project-configurations:end');
|
|
@@ -323,7 +322,9 @@ async function createProjectGraphAndSourceMapsAsync(opts = {
|
|
|
323
322
|
handleProjectGraphError(opts, e);
|
|
324
323
|
}
|
|
325
324
|
finally {
|
|
326
|
-
|
|
325
|
+
if (holdingLock) {
|
|
326
|
+
lock.unlock();
|
|
327
|
+
}
|
|
327
328
|
}
|
|
328
329
|
}
|
|
329
330
|
else {
|
|
@@ -139,6 +139,60 @@ function mergeConfigurationValue(newConfig, baseConfig, projectConfigSourceMap,
|
|
|
139
139
|
}
|
|
140
140
|
return merged;
|
|
141
141
|
}
|
|
142
|
+
// `ultracache` keeps replace-unless-`'...'` semantics at the object level, but its
|
|
143
|
+
// values still have to be merged per key: neither the wholesale replace nor
|
|
144
|
+
// `mergeObjectWithSpread` recurses, so an `ignoredReads: ['...', 'tmp/**']`
|
|
145
|
+
// would otherwise reach the task graph with `'...'` intact — a glob matching
|
|
146
|
+
// nothing, silently dropping the inherited patterns.
|
|
147
|
+
function mergeUltracache(newUltracache, baseUltracache, projectConfigSourceMap, sourceInformation, targetIdentifier, deferSpreadsWithoutBase) {
|
|
148
|
+
if (newUltracache === undefined) {
|
|
149
|
+
return baseUltracache;
|
|
150
|
+
}
|
|
151
|
+
const sourceMapContext = projectConfigSourceMap
|
|
152
|
+
? {
|
|
153
|
+
sourceMap: projectConfigSourceMap,
|
|
154
|
+
key: `${targetIdentifier}.ultracache`,
|
|
155
|
+
sourceInformation,
|
|
156
|
+
}
|
|
157
|
+
: undefined;
|
|
158
|
+
// Object level first: this settles which keys survive, their order, and
|
|
159
|
+
// their source-map attribution.
|
|
160
|
+
const merged = (0, utils_1.getMergeValueResult)(baseUltracache, newUltracache, sourceMapContext, deferSpreadsWithoutBase);
|
|
161
|
+
if (!merged || typeof merged !== 'object' || Array.isArray(merged)) {
|
|
162
|
+
return merged;
|
|
163
|
+
}
|
|
164
|
+
// Copy before resolving: with no object-level spread `getMergeValueResult`
|
|
165
|
+
// returns `newUltracache` itself, and writing through it would edit the
|
|
166
|
+
// caller's target in place, corrupting later merge layers.
|
|
167
|
+
const resolved = { ...merged };
|
|
168
|
+
// Keys authored before `'...'` let the base win, exactly as they do at the
|
|
169
|
+
// target level. Re-resolving those would overwrite the object-level merge's
|
|
170
|
+
// decision and make authored position meaningless for array keys while
|
|
171
|
+
// still honouring it for scalar ones.
|
|
172
|
+
const authoredKeys = Object.keys(newUltracache);
|
|
173
|
+
const spreadPosition = authoredKeys.indexOf(utils_1.NX_SPREAD_TOKEN);
|
|
174
|
+
const keysBeforeSpread = spreadPosition >= 0
|
|
175
|
+
? new Set(authoredKeys.slice(0, spreadPosition))
|
|
176
|
+
: new Set();
|
|
177
|
+
// Then re-resolve any key the target authored as an array, so a nested
|
|
178
|
+
// `'...'` expands against the inherited value rather than surviving as a
|
|
179
|
+
// literal element.
|
|
180
|
+
for (const key of Object.keys(resolved)) {
|
|
181
|
+
if (!Array.isArray(newUltracache[key]))
|
|
182
|
+
continue;
|
|
183
|
+
if (keysBeforeSpread.has(key) && baseUltracache && key in baseUltracache) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
resolved[key] = (0, utils_1.getMergeValueResult)(baseUltracache?.[key], newUltracache[key], projectConfigSourceMap
|
|
187
|
+
? {
|
|
188
|
+
sourceMap: projectConfigSourceMap,
|
|
189
|
+
key: `${targetIdentifier}.ultracache.${key}`,
|
|
190
|
+
sourceInformation,
|
|
191
|
+
}
|
|
192
|
+
: undefined, deferSpreadsWithoutBase);
|
|
193
|
+
}
|
|
194
|
+
return resolved;
|
|
195
|
+
}
|
|
142
196
|
function mergeConfigurations(newConfigurations, baseConfigurations, projectConfigSourceMap, sourceInformation, targetIdentifier, deferSpreadsWithoutBase) {
|
|
143
197
|
const mergedConfigurations = {};
|
|
144
198
|
// Keys before '...' let base win for shared names; keys after '...'
|
|
@@ -305,6 +359,7 @@ function mergeTargetConfigurations(target, baseTarget, projectConfigSourceMap, s
|
|
|
305
359
|
const skipForOwnMerge = new Set([
|
|
306
360
|
'options',
|
|
307
361
|
'configurations',
|
|
362
|
+
'ultracache',
|
|
308
363
|
utils_1.NX_SPREAD_TOKEN,
|
|
309
364
|
]);
|
|
310
365
|
const processKey = (key) => {
|
|
@@ -428,6 +483,18 @@ function mergeTargetConfigurations(target, baseTarget, projectConfigSourceMap, s
|
|
|
428
483
|
sourceInformation;
|
|
429
484
|
}
|
|
430
485
|
}
|
|
486
|
+
// merge ultracache if either side declares one
|
|
487
|
+
// as with options, an incompatible target discards the base.
|
|
488
|
+
// `ultracache` is in `skipForOwnMerge` so the key-by-key pass leaves it to
|
|
489
|
+
// this block; removing it from that set would change only the key's position
|
|
490
|
+
// in the result, since this overwrites whatever the generic pass produced.
|
|
491
|
+
if ('ultracache' in target ||
|
|
492
|
+
(isCompatible && baseTarget && 'ultracache' in baseTarget)) {
|
|
493
|
+
const mergedUltracache = mergeUltracache(target.ultracache, isCompatible ? baseTarget?.ultracache : undefined, projectConfigSourceMap, sourceInformation, targetIdentifier, deferSpreadsWithoutBase);
|
|
494
|
+
if (mergedUltracache !== undefined) {
|
|
495
|
+
result.ultracache = mergedUltracache;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
431
498
|
if (target.metadata) {
|
|
432
499
|
result.metadata = mergeMetadata(projectConfigSourceMap, sourceInformation, `${targetIdentifier}.metadata`, target.metadata, baseTarget?.metadata);
|
|
433
500
|
}
|
|
@@ -10,6 +10,7 @@ const output_1 = require("../../../utils/output");
|
|
|
10
10
|
const to_project_name_1 = require("../../../config/to-project-name");
|
|
11
11
|
const error_types_1 = require("../../error-types");
|
|
12
12
|
const target_merging_1 = require("./target-merging");
|
|
13
|
+
const utils_1 = require("./utils");
|
|
13
14
|
const node_fs_1 = require("node:fs");
|
|
14
15
|
const git_worktrees_1 = require("../../../utils/git-worktrees");
|
|
15
16
|
const path_1 = require("path");
|
|
@@ -176,6 +177,87 @@ function warnAboutLegacyCachedTargets(legacyCacheReads) {
|
|
|
176
177
|
bodyLines,
|
|
177
178
|
});
|
|
178
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Nothing downstream rejects a key it does not know — the Rust hasher drops it,
|
|
182
|
+
* the Cloud runner reads only the keys it reads, and the Kotlin API decodes with
|
|
183
|
+
* `ignoreUnknownKeys`. So a typo is silent everywhere else, and this is the only
|
|
184
|
+
* place a misspelled option can be reported at all. `'...'` is listed because a
|
|
185
|
+
* spread with no base to resolve against survives merging.
|
|
186
|
+
*/
|
|
187
|
+
const KNOWN_ULTRACACHE_KEYS = new Set([
|
|
188
|
+
'mode',
|
|
189
|
+
'ignoredReads',
|
|
190
|
+
'ignoredWrites',
|
|
191
|
+
utils_1.NX_SPREAD_TOKEN,
|
|
192
|
+
]);
|
|
193
|
+
const ULTRACACHE_MODES = ['on', 'warn', 'error', 'off'];
|
|
194
|
+
function describeUltracacheValue(value) {
|
|
195
|
+
if (Array.isArray(value))
|
|
196
|
+
return 'an array';
|
|
197
|
+
if (value === null)
|
|
198
|
+
return 'null';
|
|
199
|
+
return `a ${typeof value}`;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Describes every way an `ultracache` violates the shape the schema forbids.
|
|
203
|
+
*
|
|
204
|
+
* The schema is editor-only, and everything downstream — the Rust task hasher,
|
|
205
|
+
* the cloud runner's Go and Kotlin deserializers — is strict. A bad value that
|
|
206
|
+
* gets this far is reported far from its source, or silently drops the task's
|
|
207
|
+
* tracking, so it is worth reporting here where the project, target and file
|
|
208
|
+
* are all still in hand.
|
|
209
|
+
*
|
|
210
|
+
* Returns messages rather than throwing: only a WorkspaceValidityError is
|
|
211
|
+
* collected by `validateAndNormalizeProjectRootMap`, and anything else escapes
|
|
212
|
+
* as far as the daemon, which exits on an error it cannot classify.
|
|
213
|
+
*/
|
|
214
|
+
function validateTargetUltracache(ultracache, projectName, projectRoot, targetName, sourceMaps) {
|
|
215
|
+
if (ultracache === undefined) {
|
|
216
|
+
return [];
|
|
217
|
+
}
|
|
218
|
+
const targetSourceMaps = sourceMaps?.[projectRoot];
|
|
219
|
+
const [file, plugin] = targetSourceMaps?.[`targets.${targetName}.ultracache`] ??
|
|
220
|
+
targetSourceMaps?.[`targets.${targetName}`] ??
|
|
221
|
+
[];
|
|
222
|
+
const origin = file
|
|
223
|
+
? ` (defined in ${file})`
|
|
224
|
+
: plugin
|
|
225
|
+
? ` (defined by ${plugin})`
|
|
226
|
+
: '';
|
|
227
|
+
const where = `"${targetName}" in project "${projectName}"${origin}`;
|
|
228
|
+
if (!(0, utils_1.isObject)(ultracache)) {
|
|
229
|
+
return [
|
|
230
|
+
`The "ultracache" configuration for target ${where} must be an object, but it is ${describeUltracacheValue(ultracache)}.`,
|
|
231
|
+
];
|
|
232
|
+
}
|
|
233
|
+
const errors = [];
|
|
234
|
+
for (const key of Object.keys(ultracache)) {
|
|
235
|
+
if (!KNOWN_ULTRACACHE_KEYS.has(key)) {
|
|
236
|
+
errors.push(`"ultracache.${key}" for target ${where} is not an ultracache option. Supported options are "mode", "ignoredReads" and "ignoredWrites".`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (ultracache.mode !== undefined &&
|
|
240
|
+
!ULTRACACHE_MODES.includes(ultracache.mode)) {
|
|
241
|
+
const supported = ULTRACACHE_MODES.map((mode) => `"${mode}"`).join(', ');
|
|
242
|
+
errors.push(`"ultracache.mode" for target ${where} must be one of ${supported}, but it is ${typeof ultracache.mode === 'string'
|
|
243
|
+
? `"${ultracache.mode}"`
|
|
244
|
+
: describeUltracacheValue(ultracache.mode)}.`);
|
|
245
|
+
}
|
|
246
|
+
for (const key of ['ignoredReads', 'ignoredWrites']) {
|
|
247
|
+
const value = ultracache[key];
|
|
248
|
+
if (value === undefined)
|
|
249
|
+
continue;
|
|
250
|
+
if (!Array.isArray(value)) {
|
|
251
|
+
errors.push(`"ultracache.${key}" for target ${where} must be an array of glob patterns, but it is ${describeUltracacheValue(value)}.`);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
const badIndex = value.findIndex((glob) => typeof glob !== 'string');
|
|
255
|
+
if (badIndex !== -1) {
|
|
256
|
+
errors.push(`"ultracache.${key}[${badIndex}]" for target ${where} must be a glob pattern string, but it is ${describeUltracacheValue(value[badIndex])}.`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return errors;
|
|
260
|
+
}
|
|
179
261
|
function normalizeTargets(project, sourceMaps, nxJsonConfiguration, workspaceRoot,
|
|
180
262
|
/**
|
|
181
263
|
* Project configurations keyed by project name
|
|
@@ -190,6 +272,7 @@ legacyCacheReads) {
|
|
|
190
272
|
for (const targetName in project.targets) {
|
|
191
273
|
project.targets[targetName] = normalizeTarget(project.targets[targetName], project, workspaceRoot, projects, [project.root, targetName].join(':'));
|
|
192
274
|
const target = project.targets[targetName];
|
|
275
|
+
targetErrorMessage.push(...validateTargetUltracache(target.ultracache, project.name ?? project.root, project.root, targetName, sourceMaps).map((message) => `- ${message}`));
|
|
193
276
|
const targetDefaults = nxJsonConfiguration.targetDefaults;
|
|
194
277
|
if (isLegacyCachedTarget(targetName, targetDefaults, target)) {
|
|
195
278
|
target.cache = true;
|
|
@@ -35,4 +35,5 @@ type SourceMapContext = {
|
|
|
35
35
|
* preserved so a later merge layer can expand it.
|
|
36
36
|
*/
|
|
37
37
|
export declare function getMergeValueResult<T>(baseValue: unknown, newValue: T | undefined, sourceMapContext?: SourceMapContext, deferSpreadsWithoutBase?: boolean): T | undefined;
|
|
38
|
+
export declare function isObject(value: unknown): value is Record<string, unknown>;
|
|
38
39
|
export {};
|
|
@@ -4,6 +4,7 @@ exports.IntegerLikeSpreadKeyError = exports.INTEGER_LIKE_KEY_PATTERN = exports.N
|
|
|
4
4
|
exports.uniqueKeysInObjects = uniqueKeysInObjects;
|
|
5
5
|
exports.assertNoIntegerLikeSpreadKey = assertNoIntegerLikeSpreadKey;
|
|
6
6
|
exports.getMergeValueResult = getMergeValueResult;
|
|
7
|
+
exports.isObject = isObject;
|
|
7
8
|
const source_maps_1 = require("./source-maps");
|
|
8
9
|
exports.NX_SPREAD_TOKEN = '...';
|
|
9
10
|
/**
|
|
@@ -62,13 +62,28 @@ async function runTasks(executorName, projectGraph, batchTaskGraph, fullTaskGrap
|
|
|
62
62
|
catch (e) {
|
|
63
63
|
const isVerbose = tasks[0].overrides.verbose;
|
|
64
64
|
console.error(isVerbose ? e : e.message);
|
|
65
|
+
// `process.exit` does not wait for pipe writes, so the reason this worker
|
|
66
|
+
// died could otherwise be the one line that never arrives.
|
|
67
|
+
await flushStdio();
|
|
65
68
|
process.exit(1);
|
|
66
69
|
}
|
|
67
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Waits until everything written to stdout and stderr so far has reached the
|
|
73
|
+
* pipe. Writes to a pipe are asynchronous, and the parent learns the batch is
|
|
74
|
+
* over through a separate IPC channel - so without this it can be told the batch
|
|
75
|
+
* finished, or see the process exit, while the end of its output is still in
|
|
76
|
+
* memory here. That tail is where a tool reports what went wrong.
|
|
77
|
+
*/
|
|
78
|
+
function flushStdio() {
|
|
79
|
+
const flush = (stream) => new Promise((resolve) => stream.write('', () => resolve()));
|
|
80
|
+
return Promise.all([flush(process.stdout), flush(process.stderr)]).then(() => undefined);
|
|
81
|
+
}
|
|
68
82
|
process.on('message', async (message) => {
|
|
69
83
|
switch (message.type) {
|
|
70
84
|
case batch_messages_1.BatchMessageType.RunTasks: {
|
|
71
85
|
const results = await runTasks(message.executorName, message.projectGraph, message.batchTaskGraph, message.fullTaskGraph);
|
|
86
|
+
await flushStdio();
|
|
72
87
|
process.send({
|
|
73
88
|
type: batch_messages_1.BatchMessageType.CompleteBatchExecution,
|
|
74
89
|
results,
|