nx 23.0.0-beta.13 → 23.0.0-beta.14

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.
@@ -1,25 +1,35 @@
1
1
  import { Tree } from '../../generators/tree';
2
+ import type { TargetDefaultEntry, TargetDefaultsRecord } from '../../config/nx-json';
2
3
  import type { ProjectGraph } from '../../config/project-graph';
3
4
  /**
4
5
  * Converts the legacy record-shape `targetDefaults` in nx.json to the new
5
6
  * array shape introduced in Nx 23. No-op when `targetDefaults` is absent
6
7
  * or already an array.
7
8
  *
8
- * Disambiguation strategy for record keys (highest precedence first):
9
- * 1. Glob `{ target: key }`.
10
- * 2. Project graph available: replicate legacy lookup by checking whether
11
- * the key matches a target name and/or an executor string anywhere in
12
- * the workspace. Emit one entry, or both when it matches both
13
- * (genuinely ambiguous; safer to duplicate than drop a default).
14
- * If neither matches, the default is dead and we drop the entry.
15
- * 3. No graph: fall back to the syntactic heuristic — `:` (and not a
16
- * glob) → executor; otherwise target.
9
+ * This is a pure shape conversion: every legacy key produces at least one
10
+ * array entry, nothing is ever dropped. A key that looks unused at
11
+ * migration time may still be a live default the target can be added
12
+ * later, and the project graph at migration time can be incomplete.
13
+ *
14
+ * A project graph is built internally (and only when needed) to
15
+ * disambiguate `:`-style keys; see {@link convertTargetDefaultsRecordToArray}.
17
16
  */
18
- export default function convertTargetDefaultsToArray(tree: Tree, projectGraph?: ProjectGraph): Promise<string[]>;
17
+ export default function convertTargetDefaultsToArray(tree: Tree): Promise<string[]>;
19
18
  /**
20
- * Treat a legacy record key as an executor when it contains `:` and is
21
- * not a glob (executor strings are `pkg:name`; globs would also contain
22
- * `*` / `{` / etc., which `isGlobPattern` catches). Used only as a
23
- * syntactic fallback when no graph signal is available.
19
+ * Pure conversion from the legacy record shape to the array shape.
20
+ *
21
+ * Kept separate from the migration entry point and accepting the graph
22
+ * as an explicit argument so the disambiguation logic can be unit tested
23
+ * directly with synthetic graphs. The migration runner never hands a
24
+ * migration a project graph, so this seam is what keeps that behaviour
25
+ * testable without standing up a real workspace.
26
+ *
27
+ * Disambiguation per key:
28
+ * - A glob, or a plain key with no `:`, is unambiguously a target name.
29
+ * - A `:` key is ambiguous (target name vs `pkg:executor` id). When the
30
+ * graph shows it used as a target name, an executor, or both, the
31
+ * matching entry/entries are emitted. With no graph signal, it falls
32
+ * back to the syntactic heuristic (`:` → executor). Either way an entry
33
+ * is always emitted.
24
34
  */
25
- export declare function isExecutorLikeKey(key: string): boolean;
35
+ export declare function convertTargetDefaultsRecordToArray(legacy: TargetDefaultsRecord, graph?: ProjectGraph): TargetDefaultEntry[];
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = convertTargetDefaultsToArray;
4
- exports.isExecutorLikeKey = isExecutorLikeKey;
4
+ exports.convertTargetDefaultsRecordToArray = convertTargetDefaultsRecordToArray;
5
5
  const format_changed_files_with_prettier_if_available_1 = require("../../generators/internal-utils/format-changed-files-with-prettier-if-available");
6
6
  const nx_json_1 = require("../../generators/utils/nx-json");
7
7
  const project_graph_1 = require("../../project-graph/project-graph");
@@ -11,17 +11,15 @@ const globs_1 = require("../../utils/globs");
11
11
  * array shape introduced in Nx 23. No-op when `targetDefaults` is absent
12
12
  * or already an array.
13
13
  *
14
- * Disambiguation strategy for record keys (highest precedence first):
15
- * 1. Glob `{ target: key }`.
16
- * 2. Project graph available: replicate legacy lookup by checking whether
17
- * the key matches a target name and/or an executor string anywhere in
18
- * the workspace. Emit one entry, or both when it matches both
19
- * (genuinely ambiguous; safer to duplicate than drop a default).
20
- * If neither matches, the default is dead and we drop the entry.
21
- * 3. No graph: fall back to the syntactic heuristic — `:` (and not a
22
- * glob) → executor; otherwise target.
14
+ * This is a pure shape conversion: every legacy key produces at least one
15
+ * array entry, nothing is ever dropped. A key that looks unused at
16
+ * migration time may still be a live default the target can be added
17
+ * later, and the project graph at migration time can be incomplete.
18
+ *
19
+ * A project graph is built internally (and only when needed) to
20
+ * disambiguate `:`-style keys; see {@link convertTargetDefaultsRecordToArray}.
23
21
  */
24
- async function convertTargetDefaultsToArray(tree, projectGraph) {
22
+ async function convertTargetDefaultsToArray(tree) {
25
23
  if (!tree.exists('nx.json')) {
26
24
  return [];
27
25
  }
@@ -33,32 +31,59 @@ async function convertTargetDefaultsToArray(tree, projectGraph) {
33
31
  return [];
34
32
  if (Array.isArray(targetDefaults))
35
33
  return [];
36
- const nextSteps = [];
37
- const graph = projectGraph ?? (await tryCreateProjectGraph(nextSteps));
38
34
  const legacy = targetDefaults;
35
+ const nextSteps = [];
36
+ // The graph is only consulted to disambiguate `:`-style keys (target name
37
+ // vs `pkg:executor` id). Skip building it entirely when there are none.
38
+ const graph = Object.keys(legacy).some(isExecutorAmbiguousKey)
39
+ ? await tryCreateProjectGraph(nextSteps)
40
+ : undefined;
41
+ nxJson.targetDefaults = convertTargetDefaultsRecordToArray(legacy, graph);
42
+ (0, nx_json_1.updateNxJson)(tree, nxJson);
43
+ await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree);
44
+ return nextSteps;
45
+ }
46
+ /**
47
+ * Pure conversion from the legacy record shape to the array shape.
48
+ *
49
+ * Kept separate from the migration entry point — and accepting the graph
50
+ * as an explicit argument — so the disambiguation logic can be unit tested
51
+ * directly with synthetic graphs. The migration runner never hands a
52
+ * migration a project graph, so this seam is what keeps that behaviour
53
+ * testable without standing up a real workspace.
54
+ *
55
+ * Disambiguation per key:
56
+ * - A glob, or a plain key with no `:`, is unambiguously a target name.
57
+ * - A `:` key is ambiguous (target name vs `pkg:executor` id). When the
58
+ * graph shows it used as a target name, an executor, or both, the
59
+ * matching entry/entries are emitted. With no graph signal, it falls
60
+ * back to the syntactic heuristic (`:` → executor). Either way an entry
61
+ * is always emitted.
62
+ */
63
+ function convertTargetDefaultsRecordToArray(legacy, graph) {
39
64
  const entries = [];
40
65
  for (const key of Object.keys(legacy)) {
41
66
  const value = legacy[key] ?? {};
42
67
  entries.push(...legacyKeyToEntries(key, value, graph));
43
68
  }
44
- nxJson.targetDefaults = entries;
45
- (0, nx_json_1.updateNxJson)(tree, nxJson);
46
- await (0, format_changed_files_with_prettier_if_available_1.formatChangedFilesWithPrettierIfAvailable)(tree);
47
- return nextSteps;
69
+ return entries;
48
70
  }
49
71
  /**
50
- * Treat a legacy record key as an executor when it contains `:` and is
51
- * not a glob (executor strings are `pkg:name`; globs would also contain
52
- * `*` / `{` / etc., which `isGlobPattern` catches). Used only as a
53
- * syntactic fallback when no graph signal is available.
72
+ * A legacy record key is ambiguous between a target name and an executor
73
+ * id only when it contains `:` and is not a glob (executor ids are
74
+ * `pkg:name`; globs would also contain `*` / `{` / etc., which
75
+ * `isGlobPattern` catches). These are the only keys the graph helps with.
54
76
  */
55
- function isExecutorLikeKey(key) {
77
+ function isExecutorAmbiguousKey(key) {
56
78
  return key.includes(':') && !(0, globs_1.isGlobPattern)(key);
57
79
  }
58
80
  function legacyKeyToEntries(key, value, graph) {
59
- if ((0, globs_1.isGlobPattern)(key)) {
81
+ // Globs and plain (no `:`) keys are unambiguously target names.
82
+ if (!isExecutorAmbiguousKey(key)) {
60
83
  return [{ target: key, ...value }];
61
84
  }
85
+ // A `:` key could be a target name or a `pkg:executor` id. Use the graph
86
+ // to disambiguate when it has something to say.
62
87
  if (graph) {
63
88
  const { matchesTargetName, matchesExecutor } = classifyKeyAgainstGraph(key, graph);
64
89
  if (matchesTargetName && matchesExecutor) {
@@ -71,14 +96,11 @@ function legacyKeyToEntries(key, value, graph) {
71
96
  return [{ target: key, ...value }];
72
97
  if (matchesExecutor)
73
98
  return [{ executor: key, ...value }];
74
- // Graph evidence said no target and no executor in the workspace
75
- // uses this key the default is dead. Drop it rather than guess.
76
- return [];
99
+ // Graph had no signal for this key fall through to the syntactic
100
+ // heuristic rather than dropping the entry.
77
101
  }
78
- // No graph available; fall back to the syntactic heuristic.
79
- return isExecutorLikeKey(key)
80
- ? [{ executor: key, ...value }]
81
- : [{ target: key, ...value }];
102
+ // Syntactic fallback: a `:` key that is not a glob is an executor id.
103
+ return [{ executor: key, ...value }];
82
104
  }
83
105
  function classifyKeyAgainstGraph(key, graph) {
84
106
  let matchesTargetName = false;
Binary file
@@ -1,22 +1,7 @@
1
1
  import type { NxJsonConfiguration } from '../config/nx-json';
2
- import { NxArgs } from '../utils/command-line-utils';
3
2
  import { Task, TaskGraph } from '../config/task-graph';
4
3
  import { LifeCycle, TaskResult } from './life-cycle';
5
4
  import type { ProjectGraph } from '../config/project-graph';
6
5
  import { RunningTask } from './running-tasks/running-task';
7
- /**
8
- * This function is deprecated. Do not use this
9
- * @deprecated This function is deprecated. Do not use this
10
- */
11
- export declare function initTasksRunner(nxArgs: NxArgs): Promise<{
12
- invoke: (opts: {
13
- tasks: Task[];
14
- parallel: number;
15
- }) => Promise<{
16
- status: NodeJS.Process["exitCode"];
17
- taskGraph: TaskGraph;
18
- taskResults: Record<string, TaskResult>;
19
- }>;
20
- }>;
21
6
  export declare function runDiscreteTasks(tasks: Task[], projectGraph: ProjectGraph, taskGraphForHashing: TaskGraph, nxJson: NxJsonConfiguration, lifeCycle: LifeCycle): Promise<Array<Promise<TaskResult[]>>>;
22
7
  export declare function runContinuousTasks(tasks: Task[], projectGraph: ProjectGraph, taskGraphForHashing: TaskGraph, nxJson: NxJsonConfiguration, lifeCycle: LifeCycle): Promise<Record<string, Promise<RunningTask>>>;
@@ -1,78 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.initTasksRunner = initTasksRunner;
4
3
  exports.runDiscreteTasks = runDiscreteTasks;
5
4
  exports.runContinuousTasks = runContinuousTasks;
6
- const nx_json_1 = require("../config/nx-json");
7
- const project_graph_1 = require("../project-graph/project-graph");
8
5
  const run_command_1 = require("./run-command");
9
6
  const invoke_runner_terminal_output_life_cycle_1 = require("./life-cycles/invoke-runner-terminal-output-life-cycle");
10
- const perf_hooks_1 = require("perf_hooks");
11
- const utils_1 = require("./utils");
12
7
  const dotenv_1 = require("../utils/dotenv");
13
8
  const life_cycle_1 = require("./life-cycle");
14
9
  const task_orchestrator_1 = require("./task-orchestrator");
15
10
  const create_task_hasher_1 = require("../hasher/create-task-hasher");
16
11
  const client_1 = require("../daemon/client/client");
17
12
  const task_results_life_cycle_1 = require("./life-cycles/task-results-life-cycle");
18
- /**
19
- * This function is deprecated. Do not use this
20
- * @deprecated This function is deprecated. Do not use this
21
- */
22
- async function initTasksRunner(nxArgs) {
23
- perf_hooks_1.performance.mark('init-local');
24
- (0, dotenv_1.loadRootEnvFiles)();
25
- const nxJson = (0, nx_json_1.readNxJson)();
26
- if (nxArgs.verbose) {
27
- process.env.NX_VERBOSE_LOGGING = 'true';
28
- }
29
- const projectGraph = await (0, project_graph_1.createProjectGraphAsync)({ exitOnError: true });
30
- return {
31
- invoke: async (opts) => {
32
- perf_hooks_1.performance.mark('code-loading:end');
33
- // TODO: This polyfills the outputs if someone doesn't pass a task with outputs. Remove this in Nx 20
34
- opts.tasks.forEach((t) => {
35
- if (!t.outputs) {
36
- t.outputs = (0, utils_1.getOutputs)(projectGraph.nodes, t.target, t.overrides);
37
- }
38
- });
39
- const lifeCycle = new invoke_runner_terminal_output_life_cycle_1.InvokeRunnerTerminalOutputLifeCycle(opts.tasks);
40
- const taskGraph = {
41
- roots: opts.tasks.map((task) => task.id),
42
- tasks: opts.tasks.reduce((acc, task) => {
43
- acc[task.id] = task;
44
- return acc;
45
- }, {}),
46
- dependencies: opts.tasks.reduce((acc, task) => {
47
- acc[task.id] = [];
48
- return acc;
49
- }, {}),
50
- continuousDependencies: opts.tasks.reduce((acc, task) => {
51
- acc[task.id] = [];
52
- return acc;
53
- }, {}),
54
- };
55
- const taskResults = await (0, run_command_1.invokeTasksRunner)({
56
- tasks: opts.tasks,
57
- projectGraph,
58
- taskGraph,
59
- lifeCycle,
60
- nxJson,
61
- nxArgs: { ...nxArgs, parallel: opts.parallel },
62
- loadDotEnvFiles: true,
63
- initiatingProject: null,
64
- initiatingTasks: [],
65
- });
66
- return {
67
- status: Object.values(taskResults).some((taskResult) => taskResult.status === 'failure' || taskResult.status === 'skipped')
68
- ? 1
69
- : 0,
70
- taskGraph,
71
- taskResults,
72
- };
73
- },
74
- };
75
- }
76
13
  async function createOrchestrator(tasks, projectGraph, taskGraphForHashing, nxJson, lifeCycle) {
77
14
  (0, dotenv_1.loadRootEnvFiles)();
78
15
  const invokeRunnerTerminalLifecycle = new invoke_runner_terminal_output_life_cycle_1.InvokeRunnerTerminalOutputLifeCycle(tasks);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "23.0.0-beta.13",
3
+ "version": "23.0.0-beta.14",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
@@ -170,16 +170,16 @@
170
170
  }
171
171
  },
172
172
  "optionalDependencies": {
173
- "@nx/nx-darwin-arm64": "23.0.0-beta.13",
174
- "@nx/nx-darwin-x64": "23.0.0-beta.13",
175
- "@nx/nx-freebsd-x64": "23.0.0-beta.13",
176
- "@nx/nx-linux-arm-gnueabihf": "23.0.0-beta.13",
177
- "@nx/nx-linux-arm64-gnu": "23.0.0-beta.13",
178
- "@nx/nx-linux-arm64-musl": "23.0.0-beta.13",
179
- "@nx/nx-linux-x64-gnu": "23.0.0-beta.13",
180
- "@nx/nx-linux-x64-musl": "23.0.0-beta.13",
181
- "@nx/nx-win32-arm64-msvc": "23.0.0-beta.13",
182
- "@nx/nx-win32-x64-msvc": "23.0.0-beta.13"
173
+ "@nx/nx-darwin-arm64": "23.0.0-beta.14",
174
+ "@nx/nx-darwin-x64": "23.0.0-beta.14",
175
+ "@nx/nx-freebsd-x64": "23.0.0-beta.14",
176
+ "@nx/nx-linux-arm-gnueabihf": "23.0.0-beta.14",
177
+ "@nx/nx-linux-arm64-gnu": "23.0.0-beta.14",
178
+ "@nx/nx-linux-arm64-musl": "23.0.0-beta.14",
179
+ "@nx/nx-linux-x64-gnu": "23.0.0-beta.14",
180
+ "@nx/nx-linux-x64-musl": "23.0.0-beta.14",
181
+ "@nx/nx-win32-arm64-msvc": "23.0.0-beta.14",
182
+ "@nx/nx-win32-x64-msvc": "23.0.0-beta.14"
183
183
  },
184
184
  "nx-migrations": {
185
185
  "migrations": "./migrations.json",
@@ -277,9 +277,6 @@
277
277
  "src/native": [
278
278
  "dist/src/native/index.d.ts"
279
279
  ],
280
- "src": [
281
- "dist/src/index.d.ts"
282
- ],
283
280
  "src/analytics": [
284
281
  "dist/src/analytics/index.d.ts"
285
282
  ],
@@ -389,11 +386,6 @@
389
386
  "types": "./dist/plugins/*.d.ts",
390
387
  "default": "./dist/plugins/*.js"
391
388
  },
392
- "./src": {
393
- "@nx/nx-source": "./src/index.ts",
394
- "types": "./dist/src/index.d.ts",
395
- "default": "./dist/src/index.js"
396
- },
397
389
  "./src/analytics": {
398
390
  "@nx/nx-source": "./src/analytics/index.ts",
399
391
  "types": "./dist/src/analytics/index.d.ts",
@@ -1 +0,0 @@
1
- export { initTasksRunner } from './tasks-runner/init-tasks-runner';
package/dist/src/index.js DELETED
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.initTasksRunner = void 0;
4
- var init_tasks_runner_1 = require("./tasks-runner/init-tasks-runner");
5
- Object.defineProperty(exports, "initTasksRunner", { enumerable: true, get: function () { return init_tasks_runner_1.initTasksRunner; } });