nx 23.1.0 → 23.2.0-beta.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/dist/src/ai/configure-ai-agents-disclaimer.d.ts +5 -0
- package/dist/src/ai/configure-ai-agents-disclaimer.js +31 -0
- package/dist/src/command-line/add/add.js +8 -1
- package/dist/src/command-line/import/import.js +1 -1
- package/dist/src/command-line/init/configure-plugins.js +3 -2
- package/dist/src/command-line/init/implementation/add-nx-to-monorepo.js +4 -2
- package/dist/src/command-line/init/implementation/add-nx-to-nest.js +4 -3
- package/dist/src/command-line/init/implementation/add-nx-to-npm-repo.js +4 -3
- package/dist/src/command-line/init/implementation/add-nx-to-turborepo.js +4 -3
- package/dist/src/command-line/init/implementation/angular/index.js +4 -2
- package/dist/src/command-line/init/implementation/utils.d.ts +3 -3
- package/dist/src/command-line/init/implementation/utils.js +22 -3
- package/dist/src/command-line/migrate/migrate.d.ts +13 -0
- package/dist/src/command-line/migrate/migrate.js +45 -0
- package/dist/src/command-line/release/utils/git.js +6 -2
- package/dist/src/command-line/show/show-target/info.js +11 -2
- package/dist/src/daemon/client/client.d.ts +0 -2
- package/dist/src/daemon/client/client.js +17 -19
- package/dist/src/devkit-internals.d.ts +2 -0
- package/dist/src/devkit-internals.js +7 -1
- package/dist/src/native/index.d.ts +1 -1
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/plugins/js/lock-file/npm-parser.js +71 -27
- package/dist/src/plugins/js/lock-file/pnpm-parser.js +46 -15
- package/dist/src/plugins/js/lock-file/project-graph-pruning.js +1 -1
- package/dist/src/plugins/js/lock-file/yarn-parser.js +32 -5
- package/dist/src/plugins/js/utils/register.d.ts +18 -0
- package/dist/src/plugins/js/utils/register.js +81 -0
- package/dist/src/plugins/js/utils/typescript.d.ts +9 -0
- package/dist/src/plugins/js/utils/typescript.js +15 -0
- package/dist/src/project-graph/error-types.js +41 -1
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +4 -0
- package/dist/src/project-graph/plugins/transpiler.js +4 -0
- package/dist/src/project-graph/utils/project-configuration/name-substitution-manager.d.ts +9 -12
- package/dist/src/project-graph/utils/project-configuration/name-substitution-manager.js +77 -61
- package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.d.ts +1 -1
- package/dist/src/project-graph/utils/project-configuration/project-nodes-manager.js +1 -1
- package/dist/src/project-graph/utils/project-configuration-utils.js +4 -6
- package/dist/src/tasks-runner/life-cycles/performance-analysis.d.ts +2 -0
- package/dist/src/tasks-runner/life-cycles/performance-analysis.js +15 -6
- package/dist/src/tasks-runner/life-cycles/performance-report.d.ts +2 -0
- package/dist/src/tasks-runner/life-cycles/performance-report.js +11 -2
- package/dist/src/tasks-runner/run-command.js +5 -3
- package/dist/src/utils/acknowledge-build-scripts.d.ts +13 -0
- package/dist/src/utils/acknowledge-build-scripts.js +100 -0
- package/dist/src/utils/catalog/manager-utils.d.ts +1 -2
- package/dist/src/utils/catalog/manager-utils.js +22 -5
- package/dist/src/utils/catalog/pnpm-manager.d.ts +1 -0
- package/dist/src/utils/catalog/pnpm-manager.js +3 -15
- package/dist/src/utils/catalog/yarn-manager.d.ts +1 -0
- package/dist/src/utils/catalog/yarn-manager.js +3 -15
- package/dist/src/utils/git-utils.d.ts +2 -3
- package/dist/src/utils/git-utils.js +101 -47
- package/dist/src/utils/min-release-age/behavior/pnpm.js +9 -7
- package/dist/src/utils/provenance.js +12 -2
- package/migrations.json +7 -1
- package/package.json +11 -11
- package/dist/src/migrations/update-17-3-0/nx-release-path.d.ts +0 -3
- package/dist/src/migrations/update-17-3-0/nx-release-path.js +0 -47
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { AgentStatusInfo } from '../daemon/message-types/configure-ai-agents';
|
|
2
|
+
/**
|
|
3
|
+
* Whether to show the "configure-ai-agents is outdated" banner after a task run.
|
|
4
|
+
*/
|
|
5
|
+
export declare function shouldPrintConfigureAiAgentsDisclaimer(outdatedAgents: AgentStatusInfo[], workspaceRoot: string): boolean;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.shouldPrintConfigureAiAgentsDisclaimer = shouldPrintConfigureAiAgentsDisclaimer;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const detect_ai_agent_1 = require("./detect-ai-agent");
|
|
6
|
+
const constants_1 = require("./constants");
|
|
7
|
+
/**
|
|
8
|
+
* Whether to show the "configure-ai-agents is outdated" banner after a task run.
|
|
9
|
+
*/
|
|
10
|
+
function shouldPrintConfigureAiAgentsDisclaimer(outdatedAgents, workspaceRoot) {
|
|
11
|
+
if (outdatedAgents.length === 0) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
const detectedAgent = (0, detect_ai_agent_1.detectAiAgent)();
|
|
15
|
+
if (detectedAgent) {
|
|
16
|
+
return outdatedAgents.some((agent) => agent.name === detectedAgent);
|
|
17
|
+
}
|
|
18
|
+
// Unsupported agents (e.g. qwen) cannot be configured via `nx configure-ai-agents`.
|
|
19
|
+
// If the repo already has Nx rules in AGENTS.md, skip the misleading warning.
|
|
20
|
+
const agentsMd = (0, constants_1.agentsMdPath)(workspaceRoot);
|
|
21
|
+
if (!(0, fs_1.existsSync)(agentsMd)) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const content = (0, fs_1.readFileSync)(agentsMd, 'utf-8');
|
|
26
|
+
return !constants_1.rulesRegex.test(content);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -38,9 +38,16 @@ async function installPackage(pkgName, version, nxJson) {
|
|
|
38
38
|
const pmv = (0, package_manager_1.getPackageManagerVersion)(pm);
|
|
39
39
|
const pmc = (0, package_manager_1.getPackageManagerCommand)(pm);
|
|
40
40
|
// if we explicitly specify latest in yarn berry, it won't resolve the version
|
|
41
|
-
|
|
41
|
+
let command = pm === 'yarn' && (0, semver_1.gte)(pmv, '2.0.0') && version === 'latest'
|
|
42
42
|
? `${pmc.addDev} ${pkgName}`
|
|
43
43
|
: `${pmc.addDev} ${pkgName}@${version}`;
|
|
44
|
+
// pnpm 11+ fails the install when the plugin's own dependency tree
|
|
45
|
+
// carries unacknowledged build scripts, and the plugin's generators can
|
|
46
|
+
// only record allowBuilds decisions after this install. Warn and skip
|
|
47
|
+
// for this one install, like pnpm 10 did.
|
|
48
|
+
if (pm === 'pnpm' && (0, semver_1.gte)(pmv, '11.0.0')) {
|
|
49
|
+
command += ' --config.strictDepBuilds=false';
|
|
50
|
+
}
|
|
44
51
|
await new Promise((resolve) => (0, child_process_1.exec)(command, {
|
|
45
52
|
windowsHide: true,
|
|
46
53
|
}, (error, stdout, stderr) => {
|
|
@@ -489,7 +489,7 @@ async function runInstallDestinationRepo(packageManager, destinationGitClient) {
|
|
|
489
489
|
output_1.output.log({
|
|
490
490
|
title: 'Installing dependencies for imported code',
|
|
491
491
|
});
|
|
492
|
-
(0, utils_1.runInstall)(workspace_root_1.workspaceRoot, (0, package_manager_1.getPackageManagerCommand)(packageManager));
|
|
492
|
+
(0, utils_1.runInstall)(workspace_root_1.workspaceRoot, packageManager, (0, package_manager_1.getPackageManagerCommand)(packageManager));
|
|
493
493
|
await destinationGitClient.amendCommit();
|
|
494
494
|
}
|
|
495
495
|
catch (e) {
|
|
@@ -25,8 +25,9 @@ function installPluginPackages(repoRoot, pmc = (0, package_manager_1.getPackageM
|
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
if ((0, fs_1.existsSync)((0, path_1.join)(repoRoot, 'package.json'))) {
|
|
28
|
-
(0,
|
|
29
|
-
(0, utils_1.
|
|
28
|
+
const packageManager = (0, package_manager_1.detectPackageManager)(repoRoot);
|
|
29
|
+
(0, utils_1.addDepsToPackageJson)(repoRoot, packageManager, plugins);
|
|
30
|
+
(0, utils_1.runInstall)(repoRoot, packageManager, pmc);
|
|
30
31
|
}
|
|
31
32
|
else {
|
|
32
33
|
const nxJson = (0, configuration_1.readNxJson)(repoRoot);
|
|
@@ -7,6 +7,7 @@ const ignore = require("ignore");
|
|
|
7
7
|
const path_1 = require("path");
|
|
8
8
|
const fileutils_1 = require("../../../utils/fileutils");
|
|
9
9
|
const output_1 = require("../../../utils/output");
|
|
10
|
+
const package_manager_1 = require("../../../utils/package-manager");
|
|
10
11
|
const utils_1 = require("./utils");
|
|
11
12
|
const connect_to_nx_cloud_1 = require("../../nx-cloud/connect/connect-to-nx-cloud");
|
|
12
13
|
async function addNxToMonorepo(options, guided = true) {
|
|
@@ -76,9 +77,10 @@ async function addNxToMonorepo(options, guided = true) {
|
|
|
76
77
|
}
|
|
77
78
|
(0, utils_1.createNxJsonFile)(repoRoot, targetDefaults, cacheableOperations, scriptOutputs);
|
|
78
79
|
(0, utils_1.updateGitIgnore)(repoRoot);
|
|
79
|
-
(0,
|
|
80
|
+
const packageManager = (0, package_manager_1.detectPackageManager)(repoRoot);
|
|
81
|
+
(0, utils_1.addDepsToPackageJson)(repoRoot, packageManager);
|
|
80
82
|
output_1.output.log({ title: '📦 Installing dependencies' });
|
|
81
|
-
(0, utils_1.runInstall)(repoRoot);
|
|
83
|
+
(0, utils_1.runInstall)(repoRoot, packageManager);
|
|
82
84
|
if (nxCloudChoice === 'yes') {
|
|
83
85
|
output_1.output.log({ title: '🛠️ Setting up Nx Cloud' });
|
|
84
86
|
await (0, utils_1.initCloud)('nx-init-monorepo');
|
|
@@ -86,9 +86,10 @@ async function addNxToNest(options, packageJson) {
|
|
|
86
86
|
: 'skip';
|
|
87
87
|
}
|
|
88
88
|
(0, utils_1.createNxJsonFile)(repoRoot, [], [...cacheableOperations, ...nestCacheableScripts], scriptOutputs);
|
|
89
|
-
const
|
|
89
|
+
const packageManager = (0, package_manager_1.detectPackageManager)(repoRoot);
|
|
90
|
+
const pmc = (0, package_manager_1.getPackageManagerCommand)(packageManager);
|
|
90
91
|
(0, utils_1.updateGitIgnore)(repoRoot);
|
|
91
|
-
(0, utils_1.addDepsToPackageJson)(repoRoot);
|
|
92
|
+
(0, utils_1.addDepsToPackageJson)(repoRoot, packageManager);
|
|
92
93
|
addNestPluginToPackageJson(repoRoot);
|
|
93
94
|
(0, utils_1.markRootPackageJsonAsNxProjectLegacy)(repoRoot, cacheableOperations, pmc);
|
|
94
95
|
createProjectJson(repoRoot, packageJson, nestCLIConfiguration);
|
|
@@ -98,7 +99,7 @@ async function addNxToNest(options, packageJson) {
|
|
|
98
99
|
updateTsConfig(repoRoot, nestCLIConfiguration.sourceRoot);
|
|
99
100
|
}
|
|
100
101
|
output_1.output.log({ title: '📦 Installing dependencies' });
|
|
101
|
-
(0, utils_1.runInstall)(repoRoot);
|
|
102
|
+
(0, utils_1.runInstall)(repoRoot, packageManager, pmc);
|
|
102
103
|
if (nxCloudChoice === 'yes') {
|
|
103
104
|
output_1.output.log({ title: '🛠️ Setting up Nx Cloud' });
|
|
104
105
|
await (0, utils_1.initCloud)('nx-init-nest');
|
|
@@ -61,9 +61,10 @@ async function addNxToNpmRepo(options, guided = true) {
|
|
|
61
61
|
: 'skip';
|
|
62
62
|
}
|
|
63
63
|
(0, utils_1.createNxJsonFile)(repoRoot, [], cacheableOperations, scriptOutputs);
|
|
64
|
-
const
|
|
64
|
+
const packageManager = (0, package_manager_1.detectPackageManager)(repoRoot);
|
|
65
|
+
const pmc = (0, package_manager_1.getPackageManagerCommand)(packageManager);
|
|
65
66
|
(0, utils_1.updateGitIgnore)(repoRoot);
|
|
66
|
-
(0, utils_1.addDepsToPackageJson)(repoRoot);
|
|
67
|
+
(0, utils_1.addDepsToPackageJson)(repoRoot, packageManager);
|
|
67
68
|
if (options.legacy) {
|
|
68
69
|
(0, utils_1.markRootPackageJsonAsNxProjectLegacy)(repoRoot, cacheableOperations, pmc);
|
|
69
70
|
}
|
|
@@ -71,7 +72,7 @@ async function addNxToNpmRepo(options, guided = true) {
|
|
|
71
72
|
(0, utils_1.markPackageJsonAsNxProject)((0, path_1.join)(repoRoot, 'package.json'));
|
|
72
73
|
}
|
|
73
74
|
output_1.output.log({ title: '📦 Installing dependencies' });
|
|
74
|
-
(0, utils_1.runInstall)(repoRoot, pmc);
|
|
75
|
+
(0, utils_1.runInstall)(repoRoot, packageManager, pmc);
|
|
75
76
|
if (nxCloudChoice === 'yes') {
|
|
76
77
|
output_1.output.log({ title: '🛠️ Setting up Nx Cloud' });
|
|
77
78
|
await (0, utils_1.initCloud)('nx-init-npm-repo');
|
|
@@ -42,9 +42,10 @@ async function addNxToTurborepo(_options) {
|
|
|
42
42
|
// Apply fallback JSON write
|
|
43
43
|
(0, fileutils_1.writeJsonFile)(nxJsonPath, nxJson);
|
|
44
44
|
}
|
|
45
|
-
const
|
|
45
|
+
const packageManager = (0, package_manager_1.detectPackageManager)(repoRoot);
|
|
46
|
+
const pmc = (0, package_manager_1.getPackageManagerCommand)(packageManager);
|
|
46
47
|
(0, utils_1.updateGitIgnore)(repoRoot);
|
|
47
|
-
(0, utils_1.addDepsToPackageJson)(repoRoot);
|
|
48
|
+
(0, utils_1.addDepsToPackageJson)(repoRoot, packageManager);
|
|
48
49
|
output_1.output.log({ title: '📦 Installing dependencies' });
|
|
49
|
-
(0, utils_1.runInstall)(repoRoot, pmc);
|
|
50
|
+
(0, utils_1.runInstall)(repoRoot, packageManager, pmc);
|
|
50
51
|
}
|
|
@@ -7,6 +7,7 @@ const fileutils_1 = require("../../../../utils/fileutils");
|
|
|
7
7
|
const versions_1 = require("../../../../utils/versions");
|
|
8
8
|
const object_sort_1 = require("../../../../utils/object-sort");
|
|
9
9
|
const output_1 = require("../../../../utils/output");
|
|
10
|
+
const package_manager_1 = require("../../../../utils/package-manager");
|
|
10
11
|
const package_json_1 = require("../../../../utils/package-json");
|
|
11
12
|
const utils_1 = require("../utils");
|
|
12
13
|
const integrated_workspace_1 = require("./integrated-workspace");
|
|
@@ -86,9 +87,10 @@ async function collectCacheableOperations(options) {
|
|
|
86
87
|
return cacheableOperations;
|
|
87
88
|
}
|
|
88
89
|
function installDependencies() {
|
|
89
|
-
(0,
|
|
90
|
+
const packageManager = (0, package_manager_1.detectPackageManager)(repoRoot);
|
|
91
|
+
(0, utils_1.addDepsToPackageJson)(repoRoot, packageManager);
|
|
90
92
|
addPluginDependencies();
|
|
91
|
-
(0, utils_1.runInstall)(repoRoot);
|
|
93
|
+
(0, utils_1.runInstall)(repoRoot, packageManager);
|
|
92
94
|
}
|
|
93
95
|
function addPluginDependencies() {
|
|
94
96
|
const packageJsonPath = (0, path_1.join)(repoRoot, 'package.json');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NxJsonConfiguration, TargetDefaultEntry, TargetDefaults } from '../../../config/nx-json';
|
|
2
2
|
import { PackageJson } from '../../../utils/package-json';
|
|
3
|
-
import { PackageManagerCommands } from '../../../utils/package-manager';
|
|
3
|
+
import { PackageManager, PackageManagerCommands } from '../../../utils/package-manager';
|
|
4
4
|
export declare function createNxJsonFile(repoRoot: string, topologicalTargets: string[], cacheableOperations: string[], scriptOutputs: {
|
|
5
5
|
[name: string]: string;
|
|
6
6
|
}): void;
|
|
@@ -13,9 +13,9 @@ export declare function createNxJsonFile(repoRoot: string, topologicalTargets: s
|
|
|
13
13
|
*/
|
|
14
14
|
export declare function upsertTargetDefaultEntry(targetDefaults: TargetDefaults, target: string, patch: Partial<TargetDefaultEntry>): void;
|
|
15
15
|
export declare function createNxJsonFromTurboJson(turboJson: Record<string, any>): NxJsonConfiguration;
|
|
16
|
-
export declare function addDepsToPackageJson(repoRoot: string, additionalPackages?: string[]): void;
|
|
16
|
+
export declare function addDepsToPackageJson(repoRoot: string, packageManager: PackageManager, additionalPackages?: string[]): void;
|
|
17
17
|
export declare function updateGitIgnore(root: string): void;
|
|
18
|
-
export declare function runInstall(repoRoot: string, pmc?: PackageManagerCommands): void;
|
|
18
|
+
export declare function runInstall(repoRoot: string, packageManager?: PackageManager, pmc?: PackageManagerCommands): void;
|
|
19
19
|
/**
|
|
20
20
|
* Coerce any thrown value into a non-empty telemetry string. The naive
|
|
21
21
|
* `error.message || String(error)` yields "" for bare `new Error()`.
|
|
@@ -18,9 +18,11 @@ exports.printFinalMessage = printFinalMessage;
|
|
|
18
18
|
exports.isMonorepo = isMonorepo;
|
|
19
19
|
const child_process_1 = require("child_process");
|
|
20
20
|
const path_1 = require("path");
|
|
21
|
+
const semver_1 = require("semver");
|
|
21
22
|
const fileutils_1 = require("../../../utils/fileutils");
|
|
22
23
|
const output_1 = require("../../../utils/output");
|
|
23
24
|
const package_manager_1 = require("../../../utils/package-manager");
|
|
25
|
+
const acknowledge_build_scripts_1 = require("../../../utils/acknowledge-build-scripts");
|
|
24
26
|
const path_2 = require("../../../utils/path");
|
|
25
27
|
const versions_1 = require("../../../utils/versions");
|
|
26
28
|
const fs_1 = require("fs");
|
|
@@ -207,7 +209,7 @@ function createNxJsonFromTurboJson(turboJson) {
|
|
|
207
209
|
}
|
|
208
210
|
return nxJson;
|
|
209
211
|
}
|
|
210
|
-
function addDepsToPackageJson(repoRoot, additionalPackages) {
|
|
212
|
+
function addDepsToPackageJson(repoRoot, packageManager, additionalPackages) {
|
|
211
213
|
const path = (0, path_2.joinPathFragments)(repoRoot, `package.json`);
|
|
212
214
|
const json = (0, fileutils_1.readJsonFile)(path);
|
|
213
215
|
if (!json.devDependencies)
|
|
@@ -219,6 +221,9 @@ function addDepsToPackageJson(repoRoot, additionalPackages) {
|
|
|
219
221
|
}
|
|
220
222
|
}
|
|
221
223
|
(0, fileutils_1.writeJsonFile)(path, json);
|
|
224
|
+
// nx has a postinstall script, which pnpm 11+ refuses to install
|
|
225
|
+
// unacknowledged.
|
|
226
|
+
(0, acknowledge_build_scripts_1.acknowledgeBuildScripts)(repoRoot, packageManager, { nx: true });
|
|
222
227
|
}
|
|
223
228
|
function updateGitIgnore(root) {
|
|
224
229
|
const ignorePath = (0, path_1.join)(root, '.gitignore');
|
|
@@ -251,9 +256,23 @@ function updateGitIgnore(root) {
|
|
|
251
256
|
}
|
|
252
257
|
catch { }
|
|
253
258
|
}
|
|
254
|
-
function runInstall(repoRoot, pmc = (0, package_manager_1.getPackageManagerCommand)()) {
|
|
259
|
+
function runInstall(repoRoot, packageManager = (0, package_manager_1.detectPackageManager)(repoRoot), pmc = (0, package_manager_1.getPackageManagerCommand)(packageManager)) {
|
|
260
|
+
let command = pmc.install;
|
|
261
|
+
// Plugins added during init can pull build-script deps whose allowBuilds
|
|
262
|
+
// entries are only recorded by their init generators after this install;
|
|
263
|
+
// warn and skip for this one install, like pnpm 10 did.
|
|
264
|
+
if (packageManager === 'pnpm') {
|
|
265
|
+
try {
|
|
266
|
+
if ((0, semver_1.gte)((0, package_manager_1.getPackageManagerVersion)('pnpm', repoRoot), '11.0.0')) {
|
|
267
|
+
command += ' --config.strictDepBuilds=false';
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
// The version cannot be probed; run the install unmodified.
|
|
272
|
+
}
|
|
273
|
+
}
|
|
255
274
|
try {
|
|
256
|
-
(0, child_process_1.execSync)(
|
|
275
|
+
(0, child_process_1.execSync)(command, {
|
|
257
276
|
stdio: ['ignore', 'ignore', 'pipe'],
|
|
258
277
|
encoding: 'utf8',
|
|
259
278
|
cwd: repoRoot,
|
|
@@ -217,6 +217,19 @@ export declare function resolveCreateCommits(args: {
|
|
|
217
217
|
warning?: string;
|
|
218
218
|
error?: string;
|
|
219
219
|
};
|
|
220
|
+
/**
|
|
221
|
+
* Confirms before creating per-migration commits while the user sits on the
|
|
222
|
+
* repository's default branch, so migrations don't silently commit there (most
|
|
223
|
+
* relevant since `--agentic` enables commits by default). Only the default
|
|
224
|
+
* branch triggers a prompt; a detached HEAD, a different branch, or an
|
|
225
|
+
* unresolved default branch all proceed untouched. Callers gate this on
|
|
226
|
+
* commits being effective and prompting being possible, so non-interactive
|
|
227
|
+
* runs (CI, `--no-interactive`) never reach here.
|
|
228
|
+
*/
|
|
229
|
+
export declare function confirmCommitsOnDefaultBranch(args: {
|
|
230
|
+
currentBranch: string | null;
|
|
231
|
+
defaultBranch: string | null;
|
|
232
|
+
}): Promise<boolean>;
|
|
220
233
|
/**
|
|
221
234
|
* Resolves whether the framework-owned generic-validation agent step should run
|
|
222
235
|
* after generator-only migrations.
|
|
@@ -11,6 +11,7 @@ exports.isNpmPeerDepsError = isNpmPeerDepsError;
|
|
|
11
11
|
exports.resolveAgenticRunId = resolveAgenticRunId;
|
|
12
12
|
exports.formatSkippedPromptsNextStep = formatSkippedPromptsNextStep;
|
|
13
13
|
exports.resolveCreateCommits = resolveCreateCommits;
|
|
14
|
+
exports.confirmCommitsOnDefaultBranch = confirmCommitsOnDefaultBranch;
|
|
14
15
|
exports.resolveShouldRunValidation = resolveShouldRunValidation;
|
|
15
16
|
exports.executeMigrations = executeMigrations;
|
|
16
17
|
exports.runNxOrAngularMigration = runNxOrAngularMigration;
|
|
@@ -39,6 +40,7 @@ const tar_1 = require("../../utils/tar");
|
|
|
39
40
|
const write_formatted_json_file_1 = require("../../utils/write-formatted-json-file");
|
|
40
41
|
const logger_1 = require("../../utils/logger");
|
|
41
42
|
const git_utils_1 = require("../../utils/git-utils");
|
|
43
|
+
const command_line_utils_1 = require("../../utils/command-line-utils");
|
|
42
44
|
const package_json_1 = require("../../utils/package-json");
|
|
43
45
|
const package_manager_1 = require("../../utils/package-manager");
|
|
44
46
|
const errors_1 = require("../../utils/min-release-age/errors");
|
|
@@ -1784,6 +1786,30 @@ function resolveCreateCommits(args) {
|
|
|
1784
1786
|
: undefined,
|
|
1785
1787
|
};
|
|
1786
1788
|
}
|
|
1789
|
+
/**
|
|
1790
|
+
* Confirms before creating per-migration commits while the user sits on the
|
|
1791
|
+
* repository's default branch, so migrations don't silently commit there (most
|
|
1792
|
+
* relevant since `--agentic` enables commits by default). Only the default
|
|
1793
|
+
* branch triggers a prompt; a detached HEAD, a different branch, or an
|
|
1794
|
+
* unresolved default branch all proceed untouched. Callers gate this on
|
|
1795
|
+
* commits being effective and prompting being possible, so non-interactive
|
|
1796
|
+
* runs (CI, `--no-interactive`) never reach here.
|
|
1797
|
+
*/
|
|
1798
|
+
async function confirmCommitsOnDefaultBranch(args) {
|
|
1799
|
+
const { currentBranch, defaultBranch } = args;
|
|
1800
|
+
if (!currentBranch || !defaultBranch || currentBranch !== defaultBranch) {
|
|
1801
|
+
return true;
|
|
1802
|
+
}
|
|
1803
|
+
const { proceed } = await (0, safe_prompt_1.migratePrompt)([
|
|
1804
|
+
{
|
|
1805
|
+
name: 'proceed',
|
|
1806
|
+
type: 'confirm',
|
|
1807
|
+
message: `You're on the default branch '${currentBranch}'. nx migrate will create a commit for each migration on this branch. Continue?`,
|
|
1808
|
+
initial: false,
|
|
1809
|
+
},
|
|
1810
|
+
]);
|
|
1811
|
+
return proceed;
|
|
1812
|
+
}
|
|
1787
1813
|
/**
|
|
1788
1814
|
* Resolves whether the framework-owned generic-validation agent step should run
|
|
1789
1815
|
* after generator-only migrations.
|
|
@@ -2304,6 +2330,25 @@ async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, c
|
|
|
2304
2330
|
if (createCommitsWarning) {
|
|
2305
2331
|
output_1.output.warn({ title: createCommitsWarning });
|
|
2306
2332
|
}
|
|
2333
|
+
if (effectiveCreateCommits && (0, safe_prompt_1.canPrompt)(opts.interactive)) {
|
|
2334
|
+
const currentBranch = (0, git_utils_1.getGitCurrentBranch)(root);
|
|
2335
|
+
// `getBaseRef` may carry an `origin/` prefix (set by the CI-workflow
|
|
2336
|
+
// generator); compare against the local branch name.
|
|
2337
|
+
const defaultBranch = (0, command_line_utils_1.getBaseRef)((0, configuration_1.readNxJson)(root)).replace(/^origin\//, '');
|
|
2338
|
+
const proceed = await confirmCommitsOnDefaultBranch({
|
|
2339
|
+
currentBranch,
|
|
2340
|
+
defaultBranch,
|
|
2341
|
+
});
|
|
2342
|
+
if (!proceed) {
|
|
2343
|
+
output_1.output.log({
|
|
2344
|
+
title: `Skipped running migrations to avoid committing to the default branch '${currentBranch}'.`,
|
|
2345
|
+
bodyLines: [
|
|
2346
|
+
'Switch to a different branch and re-run, or re-run and confirm to proceed.',
|
|
2347
|
+
],
|
|
2348
|
+
});
|
|
2349
|
+
return;
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2307
2352
|
const shouldRunValidation = resolveShouldRunValidation({
|
|
2308
2353
|
validate: opts.validate,
|
|
2309
2354
|
agenticKind: agentic.kind,
|
|
@@ -443,8 +443,10 @@ function extractReferencesFromCommit(commit) {
|
|
|
443
443
|
references.push({ type: 'issue', value: m[1] });
|
|
444
444
|
}
|
|
445
445
|
}
|
|
446
|
-
// Extract issue references from commit body
|
|
447
|
-
|
|
446
|
+
// Extract issue references from commit body, only when linked via a closing
|
|
447
|
+
// keyword so that other repos' issue numbers mentioned in prose are not
|
|
448
|
+
// picked up (e.g. "web-infra-dev/rspack#2292")
|
|
449
|
+
for (const m of commit.body.matchAll(IssueClosingKeywordRE)) {
|
|
448
450
|
if (!references.some((i) => i.value === m[1])) {
|
|
449
451
|
references.push({ type: 'issue', value: m[1] });
|
|
450
452
|
}
|
|
@@ -473,6 +475,8 @@ const PullRequestRE = /\([ a-z]*(#\d+)\s*\)/gm;
|
|
|
473
475
|
// GitLab style merge request references
|
|
474
476
|
const GitLabMergeRequestRE = /See merge request (?:[a-z0-9/-]+)?(![\d]+)/gim;
|
|
475
477
|
const IssueRE = /(#\d+)/gm;
|
|
478
|
+
// GitHub style issue closing keywords, e.g. "Fixes #1234"
|
|
479
|
+
const IssueClosingKeywordRE = /\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?):?\s+(#\d+)/gim;
|
|
476
480
|
const ChangedFileRegex = /(A|M|D|R\d*|C\d*)\t([^\t\n]*)\t?(.*)?/gm;
|
|
477
481
|
const RevertHashRE = /This reverts commit (?<hash>[\da-f]{40})./gm;
|
|
478
482
|
function parseVersionPlanCommit(commit) {
|
|
@@ -116,8 +116,17 @@ function resolveDependencyProjects(dep, projectName, graph) {
|
|
|
116
116
|
function resolveTaskGraphDependencies(graph, extraTargetDeps, projectName, targetName, configuration, depConfigs) {
|
|
117
117
|
try {
|
|
118
118
|
const taskGraph = (0, create_task_graph_1.createTaskGraph)(graph, extraTargetDeps, [projectName], [targetName], configuration, {});
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
// `createTaskGraph` resolves the target's `defaultConfiguration`, so the real
|
|
120
|
+
// root task id may carry a `:config` suffix that `createTaskId` with the raw
|
|
121
|
+
// configuration would omit. Find the root task by (project, target) instead.
|
|
122
|
+
const rootTask = Object.values(taskGraph.tasks).find((task) => task.target.project === projectName && task.target.target === targetName);
|
|
123
|
+
const rootId = rootTask?.id ?? (0, utils_1.createTaskId)(projectName, targetName, configuration);
|
|
124
|
+
// Continuous dependencies (e.g. dev servers) live in a separate map but are
|
|
125
|
+
// direct dependencies just like the entries in `dependencies`.
|
|
126
|
+
const directDeps = [
|
|
127
|
+
...(taskGraph.dependencies[rootId] ?? []),
|
|
128
|
+
...(taskGraph.continuousDependencies[rootId] ?? []),
|
|
129
|
+
];
|
|
121
130
|
const directDepSet = new Set(directDeps);
|
|
122
131
|
const depSourceIndices = directDeps.map((depTaskId) => {
|
|
123
132
|
const task = taskGraph.tasks[depTaskId];
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.daemonClient = exports.DaemonClient = void 0;
|
|
4
4
|
exports.isDaemonEnabled = isDaemonEnabled;
|
|
5
5
|
const child_process_1 = require("child_process");
|
|
6
|
-
const promises_1 = require("fs/promises");
|
|
7
6
|
const net_1 = require("net");
|
|
8
7
|
const node_fs_1 = require("node:fs");
|
|
9
8
|
const path_1 = require("path");
|
|
@@ -12,6 +11,7 @@ const configuration_1 = require("../../config/configuration");
|
|
|
12
11
|
const nx_json_1 = require("../../config/nx-json");
|
|
13
12
|
const native_1 = require("../../native");
|
|
14
13
|
const error_types_1 = require("../../project-graph/error-types");
|
|
14
|
+
const typescript_1 = require("../../plugins/js/utils/typescript");
|
|
15
15
|
const project_graph_1 = require("../../project-graph/project-graph");
|
|
16
16
|
const consume_messages_from_socket_1 = require("../../utils/consume-messages-from-socket");
|
|
17
17
|
const delayed_spinner_1 = require("../../utils/delayed-spinner");
|
|
@@ -62,8 +62,6 @@ class DaemonClient {
|
|
|
62
62
|
this._daemonStatus = DaemonStatus.DISCONNECTED;
|
|
63
63
|
this._waitForDaemonReady = null;
|
|
64
64
|
this._daemonReady = null;
|
|
65
|
-
this._out = null;
|
|
66
|
-
this._err = null;
|
|
67
65
|
this.fileWatcherReconnecting = false;
|
|
68
66
|
this.fileWatcherCallbacks = new Map();
|
|
69
67
|
this.fileWatcherConfigs = new Map();
|
|
@@ -127,10 +125,6 @@ class DaemonClient {
|
|
|
127
125
|
this.currentResolve = null;
|
|
128
126
|
this.currentReject = null;
|
|
129
127
|
this._enabled = undefined;
|
|
130
|
-
this._out?.close();
|
|
131
|
-
this._err?.close();
|
|
132
|
-
this._out = null;
|
|
133
|
-
this._err = null;
|
|
134
128
|
// Clean up file watcher and project graph listener connections
|
|
135
129
|
this.fileWatcherMessenger?.close();
|
|
136
130
|
this.fileWatcherMessenger = undefined;
|
|
@@ -949,25 +943,29 @@ class DaemonClient {
|
|
|
949
943
|
if (!(0, node_fs_1.existsSync)(tmp_dir_1.DAEMON_OUTPUT_LOG_FILE)) {
|
|
950
944
|
(0, node_fs_1.writeFileSync)(tmp_dir_1.DAEMON_OUTPUT_LOG_FILE, '');
|
|
951
945
|
}
|
|
952
|
-
//
|
|
953
|
-
//
|
|
954
|
-
//
|
|
955
|
-
//
|
|
956
|
-
const
|
|
957
|
-
|
|
958
|
-
(0, promises_1.open)(tmp_dir_1.DAEMON_OUTPUT_LOG_FILE, 'a'),
|
|
959
|
-
]);
|
|
960
|
-
this._out = out;
|
|
961
|
-
this._err = err;
|
|
946
|
+
// Redirect the detached daemon's stdout/stderr into the log file. The
|
|
947
|
+
// child dup's these descriptors at spawn, so we close ours right after
|
|
948
|
+
// instead of holding them for the life of this process (Node >=26 turns a
|
|
949
|
+
// file descriptor closed during garbage collection into a fatal error).
|
|
950
|
+
const outFd = (0, node_fs_1.openSync)(tmp_dir_1.DAEMON_OUTPUT_LOG_FILE, 'a');
|
|
951
|
+
const errFd = (0, node_fs_1.openSync)(tmp_dir_1.DAEMON_OUTPUT_LOG_FILE, 'a');
|
|
962
952
|
logger_1.clientLogger.log(`[Client] Starting new daemon server in background`);
|
|
963
|
-
const backgroundProcess = (0, child_process_1.spawn)(process.execPath, [
|
|
953
|
+
const backgroundProcess = (0, child_process_1.spawn)(process.execPath, [
|
|
954
|
+
// Spawn with the same resolve conditions Nx uses for plugin entries so a
|
|
955
|
+
// source-loaded plugin's transitive workspace imports resolve to source.
|
|
956
|
+
...(0, typescript_1.getPluginResolveConditionNodeArgs)(),
|
|
957
|
+
(0, path_1.join)(__dirname, `../server/start.js`),
|
|
958
|
+
], {
|
|
964
959
|
cwd: workspace_root_1.workspaceRoot,
|
|
965
|
-
stdio: ['ignore',
|
|
960
|
+
stdio: ['ignore', outFd, errFd],
|
|
966
961
|
detached: true,
|
|
967
962
|
windowsHide: true,
|
|
968
963
|
shell: false,
|
|
969
964
|
env: (0, daemon_environment_1.getDaemonEnv)(),
|
|
970
965
|
});
|
|
966
|
+
// The child now owns dup'd copies of the descriptors, so release ours.
|
|
967
|
+
(0, node_fs_1.closeSync)(outFd);
|
|
968
|
+
(0, node_fs_1.closeSync)(errFd);
|
|
971
969
|
// if this process is the process that spawned the daemon,
|
|
972
970
|
// the daemon env is already up to date
|
|
973
971
|
this.envReflectionSent = true;
|
|
@@ -38,3 +38,5 @@ export { PluginCache, safeWriteFileCache } from './utils/plugin-cache-utils';
|
|
|
38
38
|
export { emitPluginWorkerLog } from './project-graph/plugins/isolation/worker-streaming';
|
|
39
39
|
export { resolveImplementation, resolveSchema, ImplementationResolutionError, SchemaResolutionError, } from './config/schema-utils';
|
|
40
40
|
export { resolvePrompt, PromptResolutionError, } from './command-line/migrate/prompt-files';
|
|
41
|
+
export { getCatalogManager, getCatalogDependenciesFromPackageJson, } from './utils/catalog';
|
|
42
|
+
export { acknowledgeBuildScripts } from './utils/acknowledge-build-scripts';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PromptResolutionError = exports.resolvePrompt = exports.SchemaResolutionError = exports.ImplementationResolutionError = exports.resolveSchema = exports.resolveImplementation = exports.emitPluginWorkerLog = exports.safeWriteFileCache = exports.PluginCache = exports.handleImport = exports.signalToCode = exports.globalSpinner = exports.readYamlFile = exports.isUsingPrettierInTree = exports.isCI = exports.interpolate = exports.requireWithTsconfigFallback = exports.forceRegisterEsmLoader = exports.loadTsFile = exports.registerTsProject = exports.LoadedNxPlugin = exports.retrieveProjectConfigurations = exports.findProjectForPath = exports.createProjectRootMappings = exports.createProjectRootMappingsFromProjectConfigurations = exports.hashMultiGlobWithWorkspaceContext = exports.hashWithWorkspaceContext = exports.hashObject = exports.splitByColons = exports.installPackageToTmpAsync = exports.installPackageToTmp = exports.readModulePackageJson = exports.stripIndent = exports.sortObjectByKeys = exports.combineOptionsForExecutor = exports.splitTarget = exports.getIgnoreObjectForTree = exports.readTargetDefaultsForTarget = exports.findMatchingProjects = exports.findMatchingConfigFiles = exports.readProjectConfigurationsFromRootMap = exports.mergeTargetConfigurations = exports.retrieveProjectConfigurationsWithAngularProjects = exports.calculateDefaultProjectName = exports.readNxJsonFromDisk = exports.parseExecutor = exports.getExecutorInformation = exports.createTempNpmDirectory = void 0;
|
|
3
|
+
exports.getCatalogDependenciesFromPackageJson = exports.getCatalogManager = exports.PromptResolutionError = exports.resolvePrompt = exports.SchemaResolutionError = exports.ImplementationResolutionError = exports.resolveSchema = exports.resolveImplementation = exports.emitPluginWorkerLog = exports.safeWriteFileCache = exports.PluginCache = exports.handleImport = exports.signalToCode = exports.globalSpinner = exports.readYamlFile = exports.isUsingPrettierInTree = exports.isCI = exports.interpolate = exports.requireWithTsconfigFallback = exports.forceRegisterEsmLoader = exports.loadTsFile = exports.registerTsProject = exports.LoadedNxPlugin = exports.retrieveProjectConfigurations = exports.findProjectForPath = exports.createProjectRootMappings = exports.createProjectRootMappingsFromProjectConfigurations = exports.hashMultiGlobWithWorkspaceContext = exports.hashWithWorkspaceContext = exports.hashObject = exports.splitByColons = exports.installPackageToTmpAsync = exports.installPackageToTmp = exports.readModulePackageJson = exports.stripIndent = exports.sortObjectByKeys = exports.combineOptionsForExecutor = exports.splitTarget = exports.getIgnoreObjectForTree = exports.readTargetDefaultsForTarget = exports.findMatchingProjects = exports.findMatchingConfigFiles = exports.readProjectConfigurationsFromRootMap = exports.mergeTargetConfigurations = exports.retrieveProjectConfigurationsWithAngularProjects = exports.calculateDefaultProjectName = exports.readNxJsonFromDisk = exports.parseExecutor = exports.getExecutorInformation = exports.createTempNpmDirectory = void 0;
|
|
4
|
+
exports.acknowledgeBuildScripts = void 0;
|
|
4
5
|
const tslib_1 = require("tslib");
|
|
5
6
|
/**
|
|
6
7
|
* Note to developers: STOP! These exports are available via requireNx in @nx/devkit.
|
|
@@ -90,3 +91,8 @@ Object.defineProperty(exports, "SchemaResolutionError", { enumerable: true, get:
|
|
|
90
91
|
var prompt_files_1 = require("./command-line/migrate/prompt-files");
|
|
91
92
|
Object.defineProperty(exports, "resolvePrompt", { enumerable: true, get: function () { return prompt_files_1.resolvePrompt; } });
|
|
92
93
|
Object.defineProperty(exports, "PromptResolutionError", { enumerable: true, get: function () { return prompt_files_1.PromptResolutionError; } });
|
|
94
|
+
var catalog_1 = require("./utils/catalog");
|
|
95
|
+
Object.defineProperty(exports, "getCatalogManager", { enumerable: true, get: function () { return catalog_1.getCatalogManager; } });
|
|
96
|
+
Object.defineProperty(exports, "getCatalogDependenciesFromPackageJson", { enumerable: true, get: function () { return catalog_1.getCatalogDependenciesFromPackageJson; } });
|
|
97
|
+
var acknowledge_build_scripts_1 = require("./utils/acknowledge-build-scripts");
|
|
98
|
+
Object.defineProperty(exports, "acknowledgeBuildScripts", { enumerable: true, get: function () { return acknowledge_build_scripts_1.acknowledgeBuildScripts; } });
|
|
@@ -28,7 +28,7 @@ export declare class ExternalObject<T> {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
export declare class AppLifeCycle {
|
|
31
|
-
constructor(tasks: Array<Task>, initiatingTasks: Array<string>, runMode: RunMode, pinnedTasks: Array<string>, tuiCliArgs: TuiCliArgs, tuiConfig: TuiConfig, titleText: string, workspaceRoot: string, taskGraph: TaskGraph)
|
|
31
|
+
constructor(tasks: Array<Task>, initiatingTasks: Array<string>, runMode: RunMode, pinnedTasks: Array<string>, tuiCliArgs: TuiCliArgs, tuiConfig: TuiConfig, titleText: string, workspaceRoot: string, taskGraph: TaskGraph, isCloudEnabled?: boolean | undefined | null)
|
|
32
32
|
startCommand(threadCount?: number | undefined | null): void
|
|
33
33
|
scheduleTask(task: Task): void
|
|
34
34
|
startTasks(tasks: Array<Task>, metadata: object): void
|
|
Binary file
|
|
Binary file
|