@depup/nx 23.1.3-depup.0 → 23.2.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 +5 -4
- package/changes.json +10 -6
- package/dist/bin/init-local.js +3 -5
- package/dist/bin/nx.js +1 -0
- package/dist/src/adapter/ngcli-adapter.js +60 -1
- package/dist/src/ai/constants.d.ts +15 -0
- package/dist/src/ai/constants.js +17 -1
- package/dist/src/ai/set-up-ai-agents/set-up-ai-agents.js +57 -9
- package/dist/src/ai/utils.d.ts +13 -0
- package/dist/src/ai/utils.js +29 -0
- package/dist/src/analytics/analytics.js +2 -4
- package/dist/src/command-line/completion/command-object.js +7 -12
- package/dist/src/command-line/configure-ai-agents/configure-ai-agents.js +42 -31
- package/dist/src/command-line/format/format.js +84 -101
- package/dist/src/command-line/generate/generate.js +35 -35
- package/dist/src/command-line/import/import.js +29 -38
- package/dist/src/command-line/init/ai-agent-prompts.js +5 -11
- package/dist/src/command-line/init/command-object.js +4 -2
- package/dist/src/command-line/init/configure-plugins.js +4 -1
- package/dist/src/command-line/init/implementation/add-nx-to-monorepo.js +12 -32
- package/dist/src/command-line/init/implementation/add-nx-to-nest.js +17 -21
- package/dist/src/command-line/init/implementation/add-nx-to-npm-repo.js +8 -21
- package/dist/src/command-line/init/implementation/add-nx-to-turborepo.js +3 -17
- package/dist/src/command-line/init/implementation/angular/index.js +10 -15
- package/dist/src/command-line/init/implementation/angular/legacy-angular-versions.js +2 -0
- package/dist/src/command-line/init/implementation/angular/standalone-workspace.js +8 -2
- package/dist/src/command-line/init/implementation/check-compatible-with-plugins.js +2 -0
- package/dist/src/command-line/init/implementation/dot-nx/add-nx-scripts.js +5 -0
- package/dist/src/command-line/init/implementation/format.d.ts +18 -0
- package/dist/src/command-line/init/implementation/format.js +114 -0
- package/dist/src/command-line/init/implementation/utils.js +8 -8
- package/dist/src/command-line/init/init-v1.js +15 -18
- package/dist/src/command-line/init/init-v2.js +77 -66
- package/dist/src/command-line/migrate/agentic/definitions.js +36 -9
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +37 -22
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +30 -39
- package/dist/src/command-line/migrate/agentic/handoff.d.ts +7 -7
- package/dist/src/command-line/migrate/agentic/handoff.js +13 -10
- package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.d.ts +7 -12
- package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.js +7 -0
- package/dist/src/command-line/migrate/agentic/run-step.d.ts +10 -0
- package/dist/src/command-line/migrate/agentic/run-step.js +1 -0
- package/dist/src/command-line/migrate/agentic/runner.js +24 -24
- package/dist/src/command-line/migrate/agentic/select.d.ts +10 -2
- package/dist/src/command-line/migrate/agentic/select.js +30 -32
- package/dist/src/command-line/migrate/agentic/types.d.ts +33 -3
- package/dist/src/command-line/migrate/agentic/types.js +35 -0
- package/dist/src/command-line/migrate/command-object.d.ts +6 -0
- package/dist/src/command-line/migrate/command-object.js +19 -1
- package/dist/src/command-line/migrate/execute-migration.d.ts +28 -9
- package/dist/src/command-line/migrate/execute-migration.js +112 -27
- package/dist/src/command-line/migrate/migrate-analytics.d.ts +35 -0
- package/dist/src/command-line/migrate/migrate-analytics.js +64 -0
- package/dist/src/command-line/migrate/migrate-commits.d.ts +38 -8
- package/dist/src/command-line/migrate/migrate-commits.js +130 -15
- package/dist/src/command-line/migrate/migrate-config.d.ts +13 -12
- package/dist/src/command-line/migrate/migrate-config.js +22 -14
- package/dist/src/command-line/migrate/migrate-output.d.ts +45 -7
- package/dist/src/command-line/migrate/migrate-output.js +52 -8
- package/dist/src/command-line/migrate/migrate-ui-api.d.ts +2 -1
- package/dist/src/command-line/migrate/migrate-ui-api.js +16 -7
- package/dist/src/command-line/migrate/migrate.d.ts +24 -55
- package/dist/src/command-line/migrate/migrate.js +553 -226
- package/dist/src/command-line/migrate/migration-shape.d.ts +8 -0
- package/dist/src/command-line/migrate/multi-major.js +7 -10
- package/dist/src/command-line/migrate/resolve-package-version.js +4 -8
- package/dist/src/command-line/migrate/run/agent-output.d.ts +20 -0
- package/dist/src/command-line/migrate/run/agent-output.js +65 -0
- package/dist/src/command-line/migrate/run/index.d.ts +9 -0
- package/dist/src/command-line/migrate/run/index.js +23 -0
- package/dist/src/command-line/migrate/run/orchestrator.d.ts +20 -0
- package/dist/src/command-line/migrate/run/orchestrator.js +1200 -0
- package/dist/src/command-line/migrate/run/run-id.d.ts +16 -0
- package/dist/src/command-line/migrate/run/run-id.js +56 -0
- package/dist/src/command-line/migrate/run/run-state.d.ts +157 -0
- package/dist/src/command-line/migrate/run/run-state.js +438 -0
- package/dist/src/command-line/migrate/run/state-lock.d.ts +25 -0
- package/dist/src/command-line/migrate/run/state-lock.js +76 -0
- package/dist/src/command-line/migrate/run/state-machine.d.ts +84 -0
- package/dist/src/command-line/migrate/run/state-machine.js +315 -0
- package/dist/src/command-line/migrate/run/util.d.ts +59 -0
- package/dist/src/command-line/migrate/run/util.js +148 -0
- package/dist/src/command-line/migrate/run/worker.d.ts +16 -0
- package/dist/src/command-line/migrate/run/worker.js +682 -0
- package/dist/src/command-line/migrate/run-migration-process.js +6 -5
- package/dist/src/command-line/migrate/safe-prompt.d.ts +14 -26
- package/dist/src/command-line/migrate/safe-prompt.js +32 -43
- package/dist/src/command-line/migrate/sort-migrations.d.ts +16 -0
- package/dist/src/command-line/migrate/sort-migrations.js +32 -0
- package/dist/src/command-line/migrate/step-actions.d.ts +5 -0
- package/dist/src/command-line/migrate/step-actions.js +12 -0
- package/dist/src/command-line/migrate/text.d.ts +18 -0
- package/dist/src/command-line/migrate/text.js +26 -0
- package/dist/src/command-line/migrate/version-skew-guard.d.ts +60 -0
- package/dist/src/command-line/migrate/version-skew-guard.js +175 -0
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +16 -20
- package/dist/src/command-line/nx-cloud/start-nx-agents/command-object.d.ts +2 -0
- package/dist/src/command-line/nx-cloud/start-nx-agents/command-object.js +16 -0
- package/dist/src/command-line/nx-cloud/start-nx-agents/start-nx-agents.d.ts +4 -0
- package/dist/src/command-line/nx-cloud/start-nx-agents/start-nx-agents.js +13 -0
- package/dist/src/command-line/nx-commands.js +26 -24
- package/dist/src/command-line/release/changelog.js +6 -17
- package/dist/src/command-line/release/plan.js +15 -28
- package/dist/src/command-line/release/publish.js +5 -0
- package/dist/src/command-line/release/release.js +6 -17
- package/dist/src/command-line/release/utils/release-graph.d.ts +1 -0
- package/dist/src/command-line/release/utils/release-graph.js +10 -2
- package/dist/src/command-line/release/utils/remote-release-clients/github.js +10 -22
- package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +13 -22
- package/dist/src/command-line/release/utils/resolve-semver-specifier.js +19 -41
- package/dist/src/command-line/release/version/resolve-current-version.js +7 -10
- package/dist/src/command-line/release/version.js +2 -2
- package/dist/src/command-line/reset/reset.js +17 -15
- package/dist/src/command-line/yargs-utils/shared-options.d.ts +1 -1
- package/dist/src/command-line/yargs-utils/shared-options.js +3 -1
- package/dist/src/config/misc-interfaces.d.ts +19 -7
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/core/graph/styles.js +1 -1
- package/dist/src/daemon/client/client.d.ts +2 -7
- package/dist/src/daemon/client/client.js +113 -28
- package/dist/src/daemon/client/daemon-environment.d.ts +35 -0
- package/dist/src/daemon/client/daemon-environment.js +106 -6
- package/dist/src/daemon/client/daemon-socket-messenger.d.ts +1 -1
- package/dist/src/daemon/client/daemon-socket-messenger.js +8 -3
- package/dist/src/daemon/is-v8-serializer-enabled.d.ts +2 -2
- package/dist/src/daemon/is-v8-serializer-enabled.js +2 -2
- package/dist/src/daemon/sandbox-socket-hint.d.ts +27 -0
- package/dist/src/daemon/sandbox-socket-hint.js +136 -0
- package/dist/src/daemon/server/client-socket-context.d.ts +1 -1
- package/dist/src/daemon/server/client-socket-context.js +2 -3
- package/dist/src/daemon/server/dotenv-graph-changes.d.ts +97 -0
- package/dist/src/daemon/server/dotenv-graph-changes.js +284 -0
- package/dist/src/daemon/server/handle-client-env.d.ts +8 -0
- package/dist/src/daemon/server/handle-client-env.js +92 -0
- package/dist/src/daemon/server/handle-outputs-changes.d.ts +10 -0
- package/dist/src/daemon/server/handle-outputs-changes.js +86 -0
- package/dist/src/daemon/server/project-graph-incremental-recomputation.d.ts +21 -0
- package/dist/src/daemon/server/project-graph-incremental-recomputation.js +159 -6
- package/dist/src/daemon/server/server.js +36 -72
- package/dist/src/daemon/server/shutdown-utils.d.ts +1 -1
- package/dist/src/daemon/server/shutdown-utils.js +2 -2
- package/dist/src/daemon/socket-utils.d.ts +26 -7
- package/dist/src/daemon/socket-utils.js +45 -31
- package/dist/src/daemon/tmp-dir.d.ts +10 -0
- package/dist/src/daemon/tmp-dir.js +21 -37
- package/dist/src/devkit-internals.d.ts +19 -8
- package/dist/src/devkit-internals.js +47 -6
- package/dist/src/executors/run-commands/running-tasks.js +46 -29
- package/dist/src/generators/internal-utils/{format-changed-files-with-prettier-if-available.d.ts → format-changed-files.d.ts} +6 -6
- package/dist/src/generators/internal-utils/format-changed-files.js +163 -0
- package/dist/src/generators/testing-utils/create-tree-with-empty-workspace.d.ts +15 -0
- package/dist/src/generators/testing-utils/create-tree-with-empty-workspace.js +21 -3
- package/dist/src/migrations/update-15-0-0/prefix-outputs.js +2 -2
- package/dist/src/migrations/update-16-0-0/remove-nrwl-cli.js +2 -2
- package/dist/src/migrations/update-16-0-0/update-depends-on-to-tokens.js +2 -2
- package/dist/src/migrations/update-16-0-0/update-nx-cloud-runner.js +2 -2
- package/dist/src/migrations/update-16-2-0/remove-run-commands-output-path.js +2 -2
- package/dist/src/migrations/update-17-0-0/rm-default-collection-npm-scope.js +2 -2
- package/dist/src/migrations/update-17-0-0/use-minimal-config-for-tasks-runner-options.js +2 -2
- package/dist/src/migrations/update-17-2-0/move-default-base.js +2 -2
- package/dist/src/migrations/update-18-0-0/disable-crystal-for-existing-workspaces.js +2 -2
- package/dist/src/migrations/update-19-2-4/set-project-name.js +2 -2
- package/dist/src/migrations/update-20-0-0/move-use-daemon-process.js +2 -2
- package/dist/src/migrations/update-20-0-1/use-legacy-cache.js +2 -2
- package/dist/src/migrations/update-21-0-0/release-changelog-config-changes.js +2 -2
- package/dist/src/migrations/update-21-0-0/release-version-config-changes.js +2 -2
- package/dist/src/migrations/update-21-0-0/remove-custom-tasks-runner.js +2 -2
- package/dist/src/migrations/update-21-0-0/remove-legacy-cache.js +2 -2
- package/dist/src/migrations/update-22-0-0/consolidate-release-tag-config.js +2 -2
- package/dist/src/migrations/update-22-0-0/release-version-config-changes.js +2 -2
- package/dist/src/migrations/update-22-2-0/add-self-healing-to-gitignore.js +2 -2
- package/dist/src/migrations/update-22-6-0/add-claude-settings-local-to-git-ignore.js +2 -2
- package/dist/src/migrations/update-22-6-0/add-claude-worktrees-to-git-ignore.js +2 -2
- package/dist/src/migrations/update-22-7-0/add-polygraph-to-git-ignore.js +2 -2
- package/dist/src/migrations/update-23-0-0/add-migrate-runs-to-git-ignore.js +2 -2
- package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.js +2 -2
- package/dist/src/native/index.d.ts +7 -3
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +3 -3
- package/dist/src/nx-cloud/utilities/url-shorten.d.ts +1 -4
- package/dist/src/nx-cloud/utilities/url-shorten.js +9 -8
- package/dist/src/plugins/js/lock-file/lock-file.d.ts +46 -4
- package/dist/src/plugins/js/lock-file/lock-file.js +192 -15
- package/dist/src/plugins/js/lock-file/npm-parser.js +10 -3
- package/dist/src/plugins/js/lock-file/pnpm-parser.js +356 -62
- package/dist/src/plugins/js/lock-file/project-graph-pruning.d.ts +25 -1
- package/dist/src/plugins/js/lock-file/project-graph-pruning.js +78 -4
- package/dist/src/plugins/js/lock-file/pruned-output.d.ts +330 -0
- package/dist/src/plugins/js/lock-file/pruned-output.js +1441 -0
- package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.d.ts +1 -0
- package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +6 -5
- package/dist/src/plugins/js/utils/register.d.ts +11 -0
- package/dist/src/plugins/js/utils/register.js +40 -6
- package/dist/src/project-graph/plugins/get-plugins.d.ts +27 -1
- package/dist/src/project-graph/plugins/get-plugins.js +110 -5
- package/dist/src/project-graph/plugins/isolation/enabled.js +1 -4
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.d.ts +16 -0
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +69 -11
- package/dist/src/project-graph/plugins/isolation/messaging.js +1 -3
- package/dist/src/project-graph/plugins/isolation/plugin-worker.js +23 -2
- package/dist/src/project-graph/project-graph.js +27 -2
- package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.d.ts +7 -0
- package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.js +14 -6
- package/dist/src/project-graph/utils/project-configuration/target-defaults.js +47 -21
- package/dist/src/tasks-runner/is-tui-enabled.js +3 -1
- package/dist/src/tasks-runner/life-cycle.d.ts +2 -2
- package/dist/src/tasks-runner/life-cycle.js +2 -2
- package/dist/src/tasks-runner/life-cycles/performance-report.d.ts +12 -0
- package/dist/src/tasks-runner/life-cycles/performance-report.js +62 -3
- package/dist/src/tasks-runner/life-cycles/static-run-many-terminal-output-life-cycle.d.ts +26 -1
- package/dist/src/tasks-runner/life-cycles/static-run-many-terminal-output-life-cycle.js +99 -5
- package/dist/src/tasks-runner/life-cycles/static-run-one-terminal-output-life-cycle.d.ts +26 -0
- package/dist/src/tasks-runner/life-cycles/static-run-one-terminal-output-life-cycle.js +113 -17
- package/dist/src/tasks-runner/pseudo-ipc.js +14 -13
- package/dist/src/tasks-runner/pseudo-terminal.d.ts +17 -3
- package/dist/src/tasks-runner/pseudo-terminal.js +22 -10
- package/dist/src/tasks-runner/run-command.js +32 -39
- package/dist/src/tasks-runner/running-tasks/batch-process.d.ts +55 -0
- package/dist/src/tasks-runner/running-tasks/batch-process.js +161 -8
- package/dist/src/tasks-runner/task-env.d.ts +25 -0
- package/dist/src/tasks-runner/task-env.js +39 -0
- package/dist/src/tasks-runner/task-orchestrator.d.ts +68 -0
- package/dist/src/tasks-runner/task-orchestrator.js +159 -8
- package/dist/src/utils/analytics-enabled.d.ts +7 -0
- package/dist/src/utils/analytics-enabled.js +11 -0
- package/dist/src/utils/analytics-prompt.js +4 -7
- package/dist/src/utils/cache-directory.d.ts +62 -3
- package/dist/src/utils/cache-directory.js +276 -25
- package/dist/src/utils/catalog/bun-manager-utils.d.ts +8 -0
- package/dist/src/utils/catalog/bun-manager-utils.js +174 -0
- package/dist/src/utils/catalog/bun-manager.d.ts +28 -0
- package/dist/src/utils/catalog/bun-manager.js +130 -0
- package/dist/src/utils/catalog/index.d.ts +1 -1
- package/dist/src/utils/catalog/index.js +1 -1
- package/dist/src/utils/catalog/manager-factory.js +3 -0
- package/dist/src/utils/catalog/manager-utils.d.ts +8 -1
- package/dist/src/utils/catalog/manager-utils.js +9 -4
- package/dist/src/utils/catalog/manager.d.ts +13 -1
- package/dist/src/utils/catalog/manager.js +30 -0
- package/dist/src/utils/catalog/pnpm-manager.d.ts +2 -1
- package/dist/src/utils/catalog/pnpm-manager.js +3 -0
- package/dist/src/utils/catalog/types.d.ts +4 -0
- package/dist/src/utils/catalog/yarn-manager.d.ts +6 -2
- package/dist/src/utils/catalog/yarn-manager.js +23 -32
- package/dist/src/utils/child-process.d.ts +31 -1
- package/dist/src/utils/child-process.js +103 -0
- package/dist/src/utils/chunkify.d.ts +7 -1
- package/dist/src/utils/chunkify.js +10 -3
- package/dist/src/utils/consume-messages-from-socket.d.ts +42 -7
- package/dist/src/utils/consume-messages-from-socket.js +273 -38
- package/dist/src/utils/db-connection.js +8 -16
- package/dist/src/utils/exit-codes.d.ts +9 -0
- package/dist/src/utils/exit-codes.js +19 -0
- package/dist/src/utils/formatters/index.d.ts +13 -0
- package/dist/src/utils/formatters/index.js +74 -0
- package/dist/src/utils/formatters/oxfmt.d.ts +32 -0
- package/dist/src/utils/formatters/oxfmt.js +764 -0
- package/dist/src/utils/formatters/prettier.d.ts +26 -0
- package/dist/src/utils/formatters/prettier.js +201 -0
- package/dist/src/utils/formatters/shared.d.ts +5 -0
- package/dist/src/utils/formatters/shared.js +8 -0
- package/dist/src/utils/git-utils.d.ts +38 -2
- package/dist/src/utils/git-utils.js +422 -19
- package/dist/src/utils/has-nx-js-plugin.d.ts +1 -1
- package/dist/src/utils/has-nx-js-plugin.js +1 -1
- package/dist/src/utils/ignore.d.ts +47 -5
- package/dist/src/utils/ignore.js +93 -11
- package/dist/src/utils/kill-child-on-host-exit.d.ts +7 -0
- package/dist/src/utils/kill-child-on-host-exit.js +42 -0
- package/dist/src/utils/nx-console-prompt.js +3 -6
- package/dist/src/utils/nx-tmp-dir.d.ts +5 -0
- package/dist/src/utils/nx-tmp-dir.js +7 -2
- package/dist/src/utils/output.d.ts +153 -0
- package/dist/src/utils/output.js +289 -5
- package/dist/src/utils/owned-private-dir.d.ts +13 -0
- package/dist/src/utils/owned-private-dir.js +39 -0
- package/dist/src/utils/package-json.d.ts +2 -0
- package/dist/src/utils/package-manager.js +17 -7
- package/dist/src/utils/params.d.ts +7 -1
- package/dist/src/utils/params.js +64 -6
- package/dist/src/utils/permission-errors.d.ts +11 -0
- package/dist/src/utils/permission-errors.js +17 -0
- package/dist/src/utils/plugins/core-plugins.js +4 -0
- package/dist/src/utils/prompt-helpers.d.ts +53 -0
- package/dist/src/utils/prompt-helpers.js +111 -0
- package/dist/src/utils/socket-refused-exit-code.d.ts +15 -0
- package/dist/src/utils/socket-refused-exit-code.js +18 -0
- package/dist/src/utils/write-formatted-json-file.d.ts +3 -2
- package/dist/src/utils/write-formatted-json-file.js +5 -4
- package/package.json +29 -20
- package/dist/src/generators/internal-utils/format-changed-files-with-prettier-if-available.js +0 -88
- package/dist/src/utils/is-using-prettier.d.ts +0 -3
- package/dist/src/utils/is-using-prettier.js +0 -62
|
@@ -1,25 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GitRepository = void 0;
|
|
3
|
+
exports.GIT_SHA = exports.GitRepository = void 0;
|
|
4
4
|
exports.cloneFromUpstream = cloneFromUpstream;
|
|
5
5
|
exports.parseVcsRemoteUrl = parseVcsRemoteUrl;
|
|
6
|
+
exports.locateGitDir = locateGitDir;
|
|
6
7
|
exports.getVcsRemoteInfo = getVcsRemoteInfo;
|
|
7
8
|
exports.getGitRootPath = getGitRootPath;
|
|
8
9
|
exports.getGitRootRelativePath = getGitRootRelativePath;
|
|
9
10
|
exports.isShallowRepository = isShallowRepository;
|
|
10
11
|
exports.getFirstCommitSha = getFirstCommitSha;
|
|
11
12
|
exports.isGitRepository = isGitRepository;
|
|
13
|
+
exports.getGitRepositoryStatus = getGitRepositoryStatus;
|
|
14
|
+
exports.getGitCurrentBranch = getGitCurrentBranch;
|
|
15
|
+
exports.getGitRemoteNames = getGitRemoteNames;
|
|
16
|
+
exports.getWorkingTreeStatus = getWorkingTreeStatus;
|
|
12
17
|
exports.hasUncommittedChanges = hasUncommittedChanges;
|
|
18
|
+
exports.getPathCommitExposure = getPathCommitExposure;
|
|
13
19
|
exports.getUncommittedChangesSnapshot = getUncommittedChangesSnapshot;
|
|
14
20
|
exports.commitChanges = commitChanges;
|
|
15
21
|
exports.tryCommitChanges = tryCommitChanges;
|
|
16
22
|
exports.getLatestCommitSha = getLatestCommitSha;
|
|
23
|
+
exports.isAncestorCommit = isAncestorCommit;
|
|
17
24
|
const tslib_1 = require("tslib");
|
|
18
25
|
const child_process_1 = require("child_process");
|
|
19
26
|
const crypto = tslib_1.__importStar(require("crypto"));
|
|
20
27
|
const fs = tslib_1.__importStar(require("fs"));
|
|
21
28
|
const path_1 = require("path");
|
|
22
|
-
const
|
|
29
|
+
const owned_private_dir_1 = require("./owned-private-dir");
|
|
23
30
|
function execFileAsync(file, args, execOptions) {
|
|
24
31
|
return new Promise((res, rej) => {
|
|
25
32
|
(0, child_process_1.execFile)(file, args, { ...execOptions, windowsHide: true }, (err, stdout) => {
|
|
@@ -253,7 +260,239 @@ function parseVcsRemoteUrl(url) {
|
|
|
253
260
|
}
|
|
254
261
|
return null;
|
|
255
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* Where `directory`'s repository keeps its working root and its shared config.
|
|
265
|
+
*
|
|
266
|
+
* Walking up for `.git` is what lets the caller answer "which repo, and where
|
|
267
|
+
* am I inside it" without spawning git. It also reports the root as the caller
|
|
268
|
+
* referred to it, where `git rev-parse --show-toplevel` reports the realpath —
|
|
269
|
+
* relevant wherever a path crosses a symlink, macOS's /tmp being the common
|
|
270
|
+
* case.
|
|
271
|
+
*
|
|
272
|
+
* A linked worktree and a submodule both have `.git` as a FILE holding
|
|
273
|
+
* `gitdir: <path>`, and their remotes live in the shared common dir rather than
|
|
274
|
+
* in that per-worktree gitdir, which `commondir` names when it is not the
|
|
275
|
+
* gitdir itself.
|
|
276
|
+
*/
|
|
277
|
+
/**
|
|
278
|
+
* Contents of `path`, or null unless it is a regular file belonging to us.
|
|
279
|
+
*
|
|
280
|
+
* Three flags carry three separate guarantees, and the read needs all of them:
|
|
281
|
+
* `O_NOFOLLOW` refuses a symlink, keeping the read inside the repository;
|
|
282
|
+
* `O_NONBLOCK` stops a FIFO blocking the open forever, which at module scope of
|
|
283
|
+
* `cache-directory.ts` would hang every command in the workspace before it
|
|
284
|
+
* printed anything; and taking the type and owner from `fstat` on the
|
|
285
|
+
* descriptor that is then read leaves no window for the path to be swapped
|
|
286
|
+
* between the check and the read.
|
|
287
|
+
*/
|
|
288
|
+
function readOwnedFileSync(path) {
|
|
289
|
+
let fd;
|
|
290
|
+
try {
|
|
291
|
+
fd = fs.openSync(path, fs.constants.O_RDONLY |
|
|
292
|
+
(fs.constants.O_NOFOLLOW ?? 0) |
|
|
293
|
+
(fs.constants.O_NONBLOCK ?? 0));
|
|
294
|
+
const stats = fs.fstatSync(fd);
|
|
295
|
+
if (!stats.isFile() ||
|
|
296
|
+
(typeof process.getuid === 'function' && stats.uid !== process.getuid())) {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
return fs.readFileSync(fd, 'utf8');
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
finally {
|
|
305
|
+
if (fd !== undefined) {
|
|
306
|
+
try {
|
|
307
|
+
fs.closeSync(fd);
|
|
308
|
+
}
|
|
309
|
+
catch { }
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
function locateGitDir(directory) {
|
|
314
|
+
let current = (0, path_1.resolve)(directory);
|
|
315
|
+
// Terminates at the filesystem root, where `dirname` is a fixed point.
|
|
316
|
+
while ((0, path_1.dirname)(current) !== current) {
|
|
317
|
+
const located = gitDirAt(current);
|
|
318
|
+
if (located !== undefined) {
|
|
319
|
+
return located;
|
|
320
|
+
}
|
|
321
|
+
current = (0, path_1.dirname)(current);
|
|
322
|
+
}
|
|
323
|
+
// The root itself: check it directly rather than walking past it.
|
|
324
|
+
return gitDirAt(current) ?? null;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* The repository whose working root is `directory`, or:
|
|
328
|
+
*
|
|
329
|
+
* - `null` when a `.git` is there but is not one we will read, which ends the
|
|
330
|
+
* walk rather than continuing past it -- git would not look further either.
|
|
331
|
+
* - `undefined` when there is no `.git` there at all, so the caller keeps
|
|
332
|
+
* walking up.
|
|
333
|
+
*/
|
|
334
|
+
function gitDirAt(directory) {
|
|
335
|
+
const dotGit = (0, path_1.join)(directory, '.git');
|
|
336
|
+
let entry;
|
|
337
|
+
try {
|
|
338
|
+
entry = fs.statSync(dotGit);
|
|
339
|
+
}
|
|
340
|
+
catch {
|
|
341
|
+
return undefined;
|
|
342
|
+
}
|
|
343
|
+
if (entry.isDirectory()) {
|
|
344
|
+
// A directory named `.git` is not a repository. Git checks this before
|
|
345
|
+
// reading config, and asking git is what this function replaced -- so
|
|
346
|
+
// without it a `.git` planted in any writable ancestor (`/tmp` is 1777)
|
|
347
|
+
// decides the workspace identity for everything beneath it.
|
|
348
|
+
if (!fs.existsSync((0, path_1.join)(dotGit, 'HEAD')) ||
|
|
349
|
+
!fs.existsSync((0, path_1.join)(dotGit, 'objects'))) {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
// Shape says it is a repository; ownership says it is ours. A real
|
|
353
|
+
// repository belonging to another user passes the check above, and git
|
|
354
|
+
// refuses exactly that (`safe.directory`, CVE-2022-24765). `lstat`
|
|
355
|
+
// inside also refuses a symlink standing in for `.git`.
|
|
356
|
+
return (0, owned_private_dir_1.isOwnedRealDirectory)(dotGit)
|
|
357
|
+
? { gitRoot: directory, commonDir: dotGit }
|
|
358
|
+
: null;
|
|
359
|
+
}
|
|
360
|
+
if (entry.isFile()) {
|
|
361
|
+
const pointer = readOwnedFileSync(dotGit)?.match(/^gitdir:\s*(.+)$/m);
|
|
362
|
+
if (!pointer) {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
const gitDir = (0, path_1.resolve)(directory, pointer[1].trim());
|
|
366
|
+
// No commondir file: the gitdir is its own common dir.
|
|
367
|
+
const shared = readOwnedFileSync((0, path_1.join)(gitDir, 'commondir'))?.trim();
|
|
368
|
+
const commonDir = shared ? (0, path_1.resolve)(gitDir, shared) : gitDir;
|
|
369
|
+
// `gitdir:` and `commondir` are paths taken from file contents, so this
|
|
370
|
+
// branch can be pointed anywhere; the directory checks above apply to it
|
|
371
|
+
// just as much.
|
|
372
|
+
return (0, owned_private_dir_1.isOwnedRealDirectory)(commonDir)
|
|
373
|
+
? { gitRoot: directory, commonDir }
|
|
374
|
+
: null;
|
|
375
|
+
}
|
|
376
|
+
return undefined;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Remote name -> url from a git config file, or null when this parser cannot
|
|
380
|
+
* answer for the whole file.
|
|
381
|
+
*
|
|
382
|
+
* Null on `include`/`includeIf` specifically: git resolves those by reading
|
|
383
|
+
* other files, so a remote could live somewhere this does not look, and
|
|
384
|
+
* answering from a partial view would be worse than paying for git.
|
|
385
|
+
*/
|
|
386
|
+
function parseGitConfigRemotes(contents) {
|
|
387
|
+
const remotes = {};
|
|
388
|
+
let remoteName = null;
|
|
389
|
+
for (const rawLine of contents.split('\n')) {
|
|
390
|
+
const line = rawLine.trim();
|
|
391
|
+
if (!line || line.startsWith('#') || line.startsWith(';')) {
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
if (line.startsWith('[')) {
|
|
395
|
+
const close = line.indexOf(']');
|
|
396
|
+
const section = (close === -1 ? line.slice(1) : line.slice(1, close)).trim();
|
|
397
|
+
if (/^include(If)?\b/i.test(section)) {
|
|
398
|
+
return null;
|
|
399
|
+
}
|
|
400
|
+
// `git remote -v` prints the rewritten url; resolving `insteadOf` here
|
|
401
|
+
// would mean reimplementing the longest-prefix match, so defer instead.
|
|
402
|
+
// A rewrite in the *global* config stays an accepted divergence: this
|
|
403
|
+
// parser deliberately never opens `~/.gitconfig`.
|
|
404
|
+
if (/^url\s+"/i.test(section)) {
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
const named = section.match(/^remote\s+"(.*)"$/i);
|
|
408
|
+
remoteName = named ? named[1] : null;
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
if (!remoteName) {
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
const equals = line.indexOf('=');
|
|
415
|
+
if (equals === -1) {
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
if (line.slice(0, equals).trim().toLowerCase() !== 'url') {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
const raw = line.slice(equals + 1).trim();
|
|
422
|
+
// Git ends a value at an unquoted `#`/`;` and honours `\` escapes. Both are
|
|
423
|
+
// enough to change the url, and reimplementing them is how a parser starts
|
|
424
|
+
// answering confidently wrong, so hand the file to git when either appears.
|
|
425
|
+
if (/[#;\\]/.test(raw)) {
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
const value = raw.replace(/^"(.*)"$/, '$1');
|
|
429
|
+
if (value.includes('"')) {
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
// `remote.<name>.url` is multi-valued and git fetches from the first, so
|
|
433
|
+
// taking the first here matches it.
|
|
434
|
+
if (remotes[remoteName] === undefined) {
|
|
435
|
+
remotes[remoteName] = value;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return remotes;
|
|
439
|
+
}
|
|
440
|
+
/** `origin`, then `upstream`, then `base`, then whichever came first. */
|
|
441
|
+
function selectRemote(found, first) {
|
|
442
|
+
for (const remote of ['origin', 'upstream', 'base']) {
|
|
443
|
+
if (found[remote]) {
|
|
444
|
+
return found[remote];
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return first;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* The remote read straight from `.git/config`, or null when that cannot settle
|
|
451
|
+
* it and git itself has to be asked.
|
|
452
|
+
*
|
|
453
|
+
* Worth having because this runs on the import path of every Nx process:
|
|
454
|
+
* `cacheDir` is resolved at module scope, which reaches the repo identity, and
|
|
455
|
+
* `git remote -v` spawns a shell and git to answer a question a file read
|
|
456
|
+
* answers in microseconds.
|
|
457
|
+
*/
|
|
458
|
+
function remoteInfoFromGitConfig(directory) {
|
|
459
|
+
try {
|
|
460
|
+
const located = locateGitDir(directory);
|
|
461
|
+
if (!located) {
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
const contents = readOwnedFileSync((0, path_1.join)(located.commonDir, 'config'));
|
|
465
|
+
if (contents === null) {
|
|
466
|
+
return null;
|
|
467
|
+
}
|
|
468
|
+
const remotes = parseGitConfigRemotes(contents);
|
|
469
|
+
if (!remotes) {
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
472
|
+
const found = {};
|
|
473
|
+
let first = null;
|
|
474
|
+
for (const [name, url] of Object.entries(remotes)) {
|
|
475
|
+
const info = parseVcsRemoteUrl(url);
|
|
476
|
+
if (info && !found[name]) {
|
|
477
|
+
found[name] = info;
|
|
478
|
+
first ??= info;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return selectRemote(found, first);
|
|
482
|
+
}
|
|
483
|
+
catch {
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
256
487
|
function getVcsRemoteInfo(directory) {
|
|
488
|
+
const fromConfig = remoteInfoFromGitConfig(directory ?? process.cwd());
|
|
489
|
+
if (fromConfig) {
|
|
490
|
+
return fromConfig;
|
|
491
|
+
}
|
|
492
|
+
// Reached when there is no readable config, no remote in it, or an `include`
|
|
493
|
+
// this parser will not follow. Note for anyone running a spec that asserts no
|
|
494
|
+
// subprocess: a repository with no remote at all lands here every time, so
|
|
495
|
+
// the shell-out is on the failure path rather than gone.
|
|
257
496
|
try {
|
|
258
497
|
const gitRemote = (0, child_process_1.execSync)('git remote -v', {
|
|
259
498
|
stdio: 'pipe',
|
|
@@ -266,7 +505,6 @@ function getVcsRemoteInfo(directory) {
|
|
|
266
505
|
return null;
|
|
267
506
|
}
|
|
268
507
|
const lines = gitRemote.split('\n').filter((line) => line.trim());
|
|
269
|
-
const remotesPriority = ['origin', 'upstream', 'base'];
|
|
270
508
|
const foundRemotes = {};
|
|
271
509
|
let firstRemote = null;
|
|
272
510
|
for (const line of lines) {
|
|
@@ -282,20 +520,20 @@ function getVcsRemoteInfo(directory) {
|
|
|
282
520
|
}
|
|
283
521
|
}
|
|
284
522
|
}
|
|
285
|
-
|
|
286
|
-
for (const remote of remotesPriority) {
|
|
287
|
-
if (foundRemotes[remote]) {
|
|
288
|
-
return foundRemotes[remote];
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
// Return first found remote
|
|
292
|
-
return firstRemote;
|
|
523
|
+
return selectRemote(foundRemotes, firstRemote);
|
|
293
524
|
}
|
|
294
525
|
catch (e) {
|
|
295
526
|
return null;
|
|
296
527
|
}
|
|
297
528
|
}
|
|
298
529
|
function getGitRootPath(cwd) {
|
|
530
|
+
const located = locateGitDir(cwd ?? process.cwd());
|
|
531
|
+
if (located) {
|
|
532
|
+
return located.gitRoot;
|
|
533
|
+
}
|
|
534
|
+
// Outside a repository this throws, which is what `getGitRootRelativePath`
|
|
535
|
+
// turns into null. Kept as the fallback rather than the primary so the common
|
|
536
|
+
// case pays no subprocess.
|
|
299
537
|
return (0, child_process_1.execFileSync)('git', ['rev-parse', '--show-toplevel'], {
|
|
300
538
|
cwd,
|
|
301
539
|
windowsHide: true,
|
|
@@ -367,21 +605,134 @@ function isGitRepository(directory) {
|
|
|
367
605
|
return false;
|
|
368
606
|
}
|
|
369
607
|
}
|
|
608
|
+
/**
|
|
609
|
+
* Like `isGitRepository`, but separates "this is not a git repository" from
|
|
610
|
+
* "the probe itself failed" (git not installed, permissions). Callers gating
|
|
611
|
+
* destructive or unverifiable behavior on the answer must fail closed on
|
|
612
|
+
* 'unknown' instead of reading a broken probe as a missing repository.
|
|
613
|
+
*/
|
|
614
|
+
function getGitRepositoryStatus(directory) {
|
|
615
|
+
try {
|
|
616
|
+
(0, child_process_1.execSync)('git rev-parse --is-inside-work-tree', {
|
|
617
|
+
stdio: 'pipe',
|
|
618
|
+
cwd: directory,
|
|
619
|
+
windowsHide: true,
|
|
620
|
+
// Force untranslated messages; the classification matches on the
|
|
621
|
+
// English "not a git repository".
|
|
622
|
+
env: { ...process.env, LC_ALL: 'C' },
|
|
623
|
+
});
|
|
624
|
+
return 'git';
|
|
625
|
+
}
|
|
626
|
+
catch (err) {
|
|
627
|
+
const stderr = err?.stderr?.toString() ?? '';
|
|
628
|
+
return /not a git repository/i.test(stderr) ? 'not-git' : 'unknown';
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
// Checked-out branch name, or null when there isn't one to act on: a detached
|
|
632
|
+
// HEAD reports the literal "HEAD" (treated as no branch), and any git error
|
|
633
|
+
// (not a repo, no commits yet) also yields null.
|
|
634
|
+
function getGitCurrentBranch(directory) {
|
|
635
|
+
try {
|
|
636
|
+
const branch = (0, child_process_1.execSync)('git rev-parse --abbrev-ref HEAD', {
|
|
637
|
+
encoding: 'utf8',
|
|
638
|
+
cwd: directory,
|
|
639
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
640
|
+
windowsHide: true,
|
|
641
|
+
}).trim();
|
|
642
|
+
return branch && branch !== 'HEAD' ? branch : null;
|
|
643
|
+
}
|
|
644
|
+
catch {
|
|
645
|
+
return null;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
// Names of the remotes configured in the repository, empty when there are
|
|
649
|
+
// none or the probe itself failed.
|
|
650
|
+
function getGitRemoteNames(directory) {
|
|
651
|
+
try {
|
|
652
|
+
return (0, child_process_1.execSync)('git remote', {
|
|
653
|
+
encoding: 'utf8',
|
|
654
|
+
cwd: directory,
|
|
655
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
656
|
+
windowsHide: true,
|
|
657
|
+
})
|
|
658
|
+
.split('\n')
|
|
659
|
+
.map((name) => name.trim())
|
|
660
|
+
.filter(Boolean);
|
|
661
|
+
}
|
|
662
|
+
catch {
|
|
663
|
+
return [];
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
// Tri-state working-tree probe: 'unknown' means the probe itself failed (git
|
|
667
|
+
// missing, spawn failure, permissions), not that the tree is clean. Callers
|
|
668
|
+
// that gate destructive actions on tree cleanliness must treat 'unknown' as
|
|
669
|
+
// unsafe rather than clean.
|
|
670
|
+
// `excludePaths` are left out of the probe the way `tryCommitChanges` leaves
|
|
671
|
+
// them out of the commit, so a tree dirty only under them reads as clean. An
|
|
672
|
+
// exclude-only pathspec still covers the whole tree, matching `git add -A`.
|
|
673
|
+
function getWorkingTreeStatus(directory, excludePaths = []) {
|
|
674
|
+
const pathspecs = excludePaths
|
|
675
|
+
.map((excludePath) => ` ":(exclude)${excludePath}"`)
|
|
676
|
+
.join('');
|
|
677
|
+
try {
|
|
678
|
+
const out = (0, child_process_1.execSync)(`git status --porcelain${pathspecs ? ` --${pathspecs}` : ''}`, {
|
|
679
|
+
encoding: 'utf8',
|
|
680
|
+
cwd: directory,
|
|
681
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
682
|
+
windowsHide: true,
|
|
683
|
+
});
|
|
684
|
+
return out.trim() === '' ? 'clean' : 'dirty';
|
|
685
|
+
}
|
|
686
|
+
catch {
|
|
687
|
+
return 'unknown';
|
|
688
|
+
}
|
|
689
|
+
}
|
|
370
690
|
// Sync companion to `GitRepository.hasUncommittedChanges` for callers that
|
|
371
|
-
// can't drop into the async class
|
|
372
|
-
//
|
|
373
|
-
function hasUncommittedChanges(directory) {
|
|
691
|
+
// can't drop into the async class. A failed probe reads as false; callers for
|
|
692
|
+
// whom that tolerance is unsafe use `getWorkingTreeStatus` instead.
|
|
693
|
+
function hasUncommittedChanges(directory, excludePaths = []) {
|
|
694
|
+
return getWorkingTreeStatus(directory, excludePaths) === 'dirty';
|
|
695
|
+
}
|
|
696
|
+
// Classifies whether `git add -A` commits made in `directory` can sweep in
|
|
697
|
+
// the directory at `dirPath`. Tracked files stay committable no matter what
|
|
698
|
+
// the ignore rules say (ignore rules never apply to tracked files), so
|
|
699
|
+
// `git ls-files` decides 'tracked' first; `git check-ignore` then splits the
|
|
700
|
+
// untracked remainder into 'ignored' (covered) vs 'unignored' (no
|
|
701
|
+
// coverage). 'unknown' means the probe itself failed (not a git repository,
|
|
702
|
+
// git missing); callers gating destructive behavior on the result must
|
|
703
|
+
// treat it as unsafe.
|
|
704
|
+
function getPathCommitExposure(dirPath, directory) {
|
|
374
705
|
try {
|
|
375
|
-
const
|
|
706
|
+
const tracked = (0, child_process_1.execSync)(`git ls-files -- ${dirPath}`, {
|
|
376
707
|
encoding: 'utf8',
|
|
377
708
|
cwd: directory,
|
|
378
709
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
379
710
|
windowsHide: true,
|
|
380
711
|
});
|
|
381
|
-
|
|
712
|
+
if (tracked.trim() !== '') {
|
|
713
|
+
return 'tracked';
|
|
714
|
+
}
|
|
382
715
|
}
|
|
383
716
|
catch {
|
|
384
|
-
return
|
|
717
|
+
return 'unknown';
|
|
718
|
+
}
|
|
719
|
+
// Query with a trailing slash so git treats the path as a directory even
|
|
720
|
+
// when it does not exist on disk yet: a directory-only ignore rule (a
|
|
721
|
+
// trailing-slash .gitignore entry) does not match a bare query for an
|
|
722
|
+
// absent path, which would misreport covered workspaces as unignored.
|
|
723
|
+
const asDir = dirPath.endsWith('/') ? dirPath : `${dirPath}/`;
|
|
724
|
+
try {
|
|
725
|
+
(0, child_process_1.execSync)(`git check-ignore -q -- ${asDir}`, {
|
|
726
|
+
cwd: directory,
|
|
727
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
728
|
+
windowsHide: true,
|
|
729
|
+
});
|
|
730
|
+
return 'ignored';
|
|
731
|
+
}
|
|
732
|
+
catch (e) {
|
|
733
|
+
// check-ignore exits 1 for "not ignored"; anything else is a probe
|
|
734
|
+
// failure.
|
|
735
|
+
return e?.status === 1 ? 'unignored' : 'unknown';
|
|
385
736
|
}
|
|
386
737
|
}
|
|
387
738
|
// Returns a content-sensitive sha1 snapshot of the working tree state for
|
|
@@ -466,7 +817,12 @@ function commitChanges(commitMessage, directory) {
|
|
|
466
817
|
// We don't want to throw during create-nx-workspace
|
|
467
818
|
// because maybe there was an error when setting up git
|
|
468
819
|
// initially.
|
|
469
|
-
|
|
820
|
+
// Required here, not imported: `logger` reaches `daemon/*`, and this
|
|
821
|
+
// module is on the import path of `cache-directory`, whose bindings
|
|
822
|
+
// `daemon/tmp-dir.ts` reads at module scope. A static import would make
|
|
823
|
+
// that a cycle. This is the only logger use in the file.
|
|
824
|
+
const { logger } = require('./logger');
|
|
825
|
+
logger.verbose(`Git may not be set up correctly for this new workspace.
|
|
470
826
|
${err}`);
|
|
471
827
|
}
|
|
472
828
|
else {
|
|
@@ -485,8 +841,13 @@ function commitChanges(commitMessage, directory) {
|
|
|
485
841
|
* Returns `null` (rather than throwing) when the commit itself succeeded
|
|
486
842
|
* but `git rev-parse HEAD` failed transiently — by contract the diff is
|
|
487
843
|
* no longer in the working tree, so callers must NOT report it as such.
|
|
844
|
+
*
|
|
845
|
+
* `excludePaths` are `directory`-relative paths the commit must not capture,
|
|
846
|
+
* whatever the ignore rules say. Their working-tree files are left intact;
|
|
847
|
+
* only their index entries are put back to HEAD's state. Paths come from
|
|
848
|
+
* callers' own constants, never from user input.
|
|
488
849
|
*/
|
|
489
|
-
function tryCommitChanges(commitMessage, directory) {
|
|
850
|
+
function tryCommitChanges(commitMessage, directory, excludePaths = []) {
|
|
490
851
|
try {
|
|
491
852
|
(0, child_process_1.execSync)('git add -A', {
|
|
492
853
|
encoding: 'utf8',
|
|
@@ -494,6 +855,20 @@ function tryCommitChanges(commitMessage, directory) {
|
|
|
494
855
|
cwd: directory,
|
|
495
856
|
windowsHide: true,
|
|
496
857
|
});
|
|
858
|
+
// Exclusion happens as an unstage rather than an add-time pathspec:
|
|
859
|
+
// `git add` refuses a pathspec naming an ignored directory (exit 1) even
|
|
860
|
+
// as an exclusion, and an add-time pathspec cannot cover entries that
|
|
861
|
+
// were already staged before this call. The reset is relative to cwd, so
|
|
862
|
+
// a workspace nested inside a larger repo excludes its own path; a path
|
|
863
|
+
// with no index entry is a quiet no-op, unborn HEAD included.
|
|
864
|
+
for (const excludePath of excludePaths) {
|
|
865
|
+
(0, child_process_1.execSync)(`git reset -q -- "${excludePath}"`, {
|
|
866
|
+
encoding: 'utf8',
|
|
867
|
+
stdio: 'pipe',
|
|
868
|
+
cwd: directory,
|
|
869
|
+
windowsHide: true,
|
|
870
|
+
});
|
|
871
|
+
}
|
|
497
872
|
(0, child_process_1.execSync)('git commit --no-verify -F -', {
|
|
498
873
|
encoding: 'utf8',
|
|
499
874
|
stdio: 'pipe',
|
|
@@ -528,3 +903,31 @@ function getLatestCommitSha(directory) {
|
|
|
528
903
|
return null;
|
|
529
904
|
}
|
|
530
905
|
}
|
|
906
|
+
/**
|
|
907
|
+
* The shape of a recorded `git rev-parse` output: 40 hex chars, or 64 in a
|
|
908
|
+
* sha256 repository. Anything a caller persists and later interpolates into a
|
|
909
|
+
* command line has to be checked against this first.
|
|
910
|
+
*/
|
|
911
|
+
exports.GIT_SHA = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/i;
|
|
912
|
+
/**
|
|
913
|
+
* Whether `ancestor` is reachable from `descendant`, i.e. resetting to
|
|
914
|
+
* `descendant` keeps `ancestor` in history. Returns false when the answer
|
|
915
|
+
* cannot be established (invalid input, not a repository, unknown commits),
|
|
916
|
+
* so callers treat an unverifiable commit as not preserved.
|
|
917
|
+
*/
|
|
918
|
+
function isAncestorCommit(ancestor, descendant, directory) {
|
|
919
|
+
if (!exports.GIT_SHA.test(ancestor) || !exports.GIT_SHA.test(descendant)) {
|
|
920
|
+
return false;
|
|
921
|
+
}
|
|
922
|
+
try {
|
|
923
|
+
(0, child_process_1.execSync)(`git merge-base --is-ancestor ${ancestor} ${descendant}`, {
|
|
924
|
+
stdio: 'pipe',
|
|
925
|
+
windowsHide: true,
|
|
926
|
+
cwd: directory,
|
|
927
|
+
});
|
|
928
|
+
return true;
|
|
929
|
+
}
|
|
930
|
+
catch {
|
|
931
|
+
return false;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Checks if `@nx/js` is installed by attempting to resolve its `package.json`.
|
|
3
3
|
*
|
|
4
|
-
* Lives in its own module so unit tests can
|
|
4
|
+
* Lives in its own module so unit tests can mock it without having to
|
|
5
5
|
* intercept Node's resolver at the global level. The previous in-`package-json`
|
|
6
6
|
* definition was unreachable to mocks because callers in the same module
|
|
7
7
|
* referenced it via the local lexical binding rather than `module.exports`.
|
|
@@ -5,7 +5,7 @@ const installation_directory_1 = require("./installation-directory");
|
|
|
5
5
|
/**
|
|
6
6
|
* Checks if `@nx/js` is installed by attempting to resolve its `package.json`.
|
|
7
7
|
*
|
|
8
|
-
* Lives in its own module so unit tests can
|
|
8
|
+
* Lives in its own module so unit tests can mock it without having to
|
|
9
9
|
* intercept Node's resolver at the global level. The previous in-`package-json`
|
|
10
10
|
* definition was unreachable to mocks because callers in the same module
|
|
11
11
|
* referenced it via the local lexical binding rather than `module.exports`.
|
|
@@ -62,7 +62,7 @@ export declare function createIgnoreChainResolver(read: (path: string) => string
|
|
|
62
62
|
* that same note. Here they are simply the entry's matchers: any one excluding
|
|
63
63
|
* wins, and a negation counts only if none excluded.
|
|
64
64
|
*
|
|
65
|
-
* Two preconditions,
|
|
65
|
+
* Two preconditions, neither enforced here:
|
|
66
66
|
*
|
|
67
67
|
* - `filePath` is workspace-relative POSIX and must sit under every `dir` in the
|
|
68
68
|
* chain, which holds when the chain came from that file's own directory.
|
|
@@ -70,11 +70,28 @@ export declare function createIgnoreChainResolver(read: (path: string) => string
|
|
|
70
70
|
* re-include a file inside an excluded directory, and this does not implement
|
|
71
71
|
* that rule: asked directly about `dist/keep.ts` with a root `dist/` and a
|
|
72
72
|
* nested `dist/.gitignore` holding `!keep.ts`, it answers "not ignored" where
|
|
73
|
-
* git says ignored (measured).
|
|
74
|
-
*
|
|
75
|
-
*
|
|
73
|
+
* git says ignored (measured). A pruning walk like `visitNotIgnoredFiles`
|
|
74
|
+
* satisfies it by never asking about anything under `dist/`; a per-file
|
|
75
|
+
* caller cannot, so it goes through `createAncestorAwareIgnoreChecker`,
|
|
76
|
+
* which checks the ancestors before asking the chain.
|
|
76
77
|
*/
|
|
77
78
|
export declare function isIgnoredByChain(chain: ScopedIgnoreMatcher[], filePath: string): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* The chain's answers plus git's excluded-ancestor rule: nothing inside an
|
|
81
|
+
* ignored directory can be re-included, so a nested negation must not
|
|
82
|
+
* resurrect a file whose ancestor an outer file excluded - the case
|
|
83
|
+
* `isIgnoredByChain` alone gets wrong (see its second precondition). The
|
|
84
|
+
* oxfmt CLI follows the same rule (measured against 0.60.0: a scan skips a
|
|
85
|
+
* nested `!keep.ts` under a root-ignored `dist/`), so every per-file caller -
|
|
86
|
+
* the cascading tree checkers and the disk-backed resolver in
|
|
87
|
+
* `formatters/oxfmt.ts` - goes through here.
|
|
88
|
+
*
|
|
89
|
+
* A directory's own ignore files cannot un-ignore the directory itself, so
|
|
90
|
+
* its verdict comes from its parent's chain - probed with a trailing slash,
|
|
91
|
+
* which is what makes a directory-only pattern like `dist/` match. Verdicts
|
|
92
|
+
* are memoized per directory, so a batch of files shares its ancestor walks.
|
|
93
|
+
*/
|
|
94
|
+
export declare function createAncestorAwareIgnoreChecker(resolve: (dir: string) => ScopedIgnoreMatcher[]): TreeIgnoreChecker;
|
|
78
95
|
/**
|
|
79
96
|
* Directories that should never be walked, whatever the workspace's own ignore
|
|
80
97
|
* files say - `node_modules`, `.git`, the nx caches.
|
|
@@ -88,7 +105,7 @@ export declare function isIgnoredByChain(chain: ScopedIgnoreMatcher[], filePath:
|
|
|
88
105
|
*/
|
|
89
106
|
export declare function isAlwaysIgnored(path: string): boolean;
|
|
90
107
|
/**
|
|
91
|
-
*
|
|
108
|
+
* A chain's answers as predicates over workspace-relative POSIX paths.
|
|
92
109
|
*
|
|
93
110
|
* Files and directories are asked separately because the answers differ: a
|
|
94
111
|
* pattern is only directory-only if it ends in a slash, and `ignore` will not
|
|
@@ -123,6 +140,31 @@ export declare function createGitIgnoreChecker(tree: Tree): TreeIgnoreChecker;
|
|
|
123
140
|
* Reads from the tree rather than disk, as above.
|
|
124
141
|
*/
|
|
125
142
|
export declare function createPrettierIgnoreChecker(tree: Tree): TreeIgnoreChecker;
|
|
143
|
+
/**
|
|
144
|
+
* What oxfmt ignores: prettier's two files, but resolved from each file's own
|
|
145
|
+
* directory upwards rather than the workspace root - measured against the
|
|
146
|
+
* oxfmt 0.60.0 CLI, which differs from prettier on exactly that axis. Still
|
|
147
|
+
* one matcher per file rather than merged.
|
|
148
|
+
*
|
|
149
|
+
* A config's `ignorePatterns` is not an ignore file and is not read here;
|
|
150
|
+
* `formatFilesWithOxfmt` applies it rooted at that config's directory.
|
|
151
|
+
*/
|
|
152
|
+
export declare function createOxfmtIgnoreChecker(tree: Tree): TreeIgnoreChecker;
|
|
153
|
+
/**
|
|
154
|
+
* Exported, unlike git's and prettier's, because oxfmt has two consumers:
|
|
155
|
+
* this tree-backed checker and the disk-backed resolver in
|
|
156
|
+
* `formatters/oxfmt.ts`. A shared value is the only thing that keeps them
|
|
157
|
+
* agreeing, so do not restate these three anywhere.
|
|
158
|
+
*
|
|
159
|
+
* `satisfies` rather than an annotation keeps the values literal - an
|
|
160
|
+
* annotation widens `cascade` and `merge` to `boolean` (measured in the
|
|
161
|
+
* declaration emit).
|
|
162
|
+
*/
|
|
163
|
+
export declare const OXFMT_IGNORE_OPTIONS: {
|
|
164
|
+
filenames: string[];
|
|
165
|
+
cascade: true;
|
|
166
|
+
merge: false;
|
|
167
|
+
};
|
|
126
168
|
/**
|
|
127
169
|
* `path.dirname` for the workspace-relative POSIX paths the chain is keyed by,
|
|
128
170
|
* except that the workspace root is `''` rather than `.` - that is the key
|