nx 22.7.0 → 22.7.1

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.
@@ -155,7 +155,7 @@ class DaemonClient {
155
155
  (0, project_graph_1.preventRecursionInGraphConstruction)();
156
156
  let spinner;
157
157
  // If the graph takes a while to load, we want to show a spinner.
158
- spinner = new delayed_spinner_1.DelayedSpinner('Calculating the project graph on the Nx Daemon').scheduleMessageUpdate('Calculating the project graph on the Nx Daemon is taking longer than expected. Re-run with NX_DAEMON=false to see more details.', { ciDelay: 60_000, delay: 30_000 });
158
+ spinner = new delayed_spinner_1.DelayedSpinner('Calculating the project graph on the Nx Daemon');
159
159
  this.currentSpinner = spinner;
160
160
  try {
161
161
  const response = await this.sendToDaemonViaQueue({
@@ -103,6 +103,8 @@ const DAEMON_ENV_PREFIX_EXCLUSIONS = [
103
103
  'ALACRITTY_',
104
104
  'KONSOLE_',
105
105
  'TMUX',
106
+ // Benchmarking / profiling tools
107
+ 'HYPERFINE_', // hyperfine sets HYPERFINE_RANDOMIZED_ENVIRONMENT_OFFSET for each iteration
106
108
  ];
107
109
  function isExcludedEnvVar(key) {
108
110
  return (DAEMON_ENV_VARS_EXCLUSIONS.has(key) ||
@@ -1,2 +1 @@
1
- export declare function getInstalledNxVersion(): string | null;
2
1
  export declare function isNxVersionMismatch(): boolean;
@@ -1,24 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getInstalledNxVersion = getInstalledNxVersion;
4
3
  exports.isNxVersionMismatch = isNxVersionMismatch;
5
- const fileutils_1 = require("../utils/fileutils");
6
4
  const versions_1 = require("../utils/versions");
7
- const workspace_root_1 = require("../utils/workspace-root");
8
- const installation_directory_1 = require("../utils/installation-directory");
9
- function getInstalledNxVersion() {
10
- try {
11
- const nxPackageJsonPath = require.resolve('nx/package.json', {
12
- paths: (0, installation_directory_1.getNxRequirePaths)(workspace_root_1.workspaceRoot),
13
- });
14
- const { version } = (0, fileutils_1.readJsonFile)(nxPackageJsonPath);
15
- return version;
16
- }
17
- catch {
18
- // node modules are absent
19
- return null;
20
- }
21
- }
5
+ const installed_nx_version_1 = require("../utils/installed-nx-version");
22
6
  function isNxVersionMismatch() {
23
- return getInstalledNxVersion() !== versions_1.nxVersion;
7
+ return (0, installed_nx_version_1.getInstalledNxVersion)() !== versions_1.nxVersion;
24
8
  }
@@ -18,6 +18,7 @@ const workspace_root_1 = require("../../utils/workspace-root");
18
18
  const get_plugins_1 = require("../../project-graph/plugins/get-plugins");
19
19
  const cache_1 = require("../cache");
20
20
  const is_nx_version_mismatch_1 = require("../is-nx-version-mismatch");
21
+ const installed_nx_version_1 = require("../../utils/installed-nx-version");
21
22
  const logger_1 = require("../logger");
22
23
  const configure_ai_agents_1 = require("../message-types/configure-ai-agents");
23
24
  const daemon_message_1 = require("../message-types/daemon-message");
@@ -412,7 +413,7 @@ async function startServer() {
412
413
  logger_1.serverLogger.log(`New daemon starting from: ${__filename}`);
413
414
  logger_1.serverLogger.log(`New daemon __dirname: ${__dirname}`);
414
415
  logger_1.serverLogger.log(`New daemon nxVersion: ${versions_1.nxVersion}`);
415
- logger_1.serverLogger.log(`New daemon getInstalledNxVersion(): ${(0, is_nx_version_mismatch_1.getInstalledNxVersion)()}`);
416
+ logger_1.serverLogger.log(`New daemon getInstalledNxVersion(): ${(0, installed_nx_version_1.getInstalledNxVersion)()}`);
416
417
  // Persist metadata about the background process so that it can be cleaned up later if needed
417
418
  await (0, cache_1.writeDaemonJsonProcessCache)({
418
419
  processId: process.pid,
Binary file
@@ -11,9 +11,9 @@ const tslib_1 = require("tslib");
11
11
  const enquirer_1 = require("enquirer");
12
12
  const node_path_1 = require("node:path");
13
13
  const node_util_1 = require("node:util");
14
- const ora = require('ora');
15
14
  const nx_json_1 = require("../config/nx-json");
16
15
  const client_1 = require("../daemon/client/client");
16
+ const spinner_1 = require("../utils/spinner");
17
17
  const create_task_hasher_1 = require("../hasher/create-task-hasher");
18
18
  const hash_task_1 = require("../hasher/hash-task");
19
19
  const native_1 = require("../native");
@@ -486,8 +486,7 @@ async function ensureWorkspaceIsInSyncAndGetGraphs(projectGraph, nxJson, project
486
486
  const applyChanges = nxJson.sync?.applyChanges === true ||
487
487
  (await promptForApplyingSyncGeneratorChanges());
488
488
  if (applyChanges) {
489
- const spinner = ora('Syncing the workspace...');
490
- spinner.start();
489
+ const spinner = spinner_1.globalSpinner.start('Syncing the workspace...');
491
490
  // Flush sync generator changes to disk
492
491
  const flushResult = await (0, sync_generators_1.flushSyncGeneratorChanges)(results);
493
492
  if ('generatorFailures' in flushResult) {
@@ -57,7 +57,12 @@ class TaskOrchestrator {
57
57
  // region internal state
58
58
  this.batchEnv = (0, task_env_1.getEnvVariablesForBatchProcess)(this.options.skipNxCache, this.options.captureStderr);
59
59
  this.reverseTaskDeps = (0, utils_1.calculateReverseDeps)(this.taskGraph);
60
- this.initializingTaskIds = new Set(this.initiatingTasks.map((t) => t.id));
60
+ // `nx:noop` initiating tasks exit instantly via the fast-path in
61
+ // `spawnProcess`. If we treat the noop itself as the keep-alive anchor for
62
+ // its continuous dependencies, `cleanUpUnneededContinuousTasks` kills those
63
+ // children the moment the noop finishes. Expand through noops so the
64
+ // underlying real tasks become the anchors.
65
+ this.initializingTaskIds = (0, utils_1.expandInitiatingTasksThroughNoop)(this.initiatingTasks, this.taskGraph, this.projectGraph);
61
66
  this.processedTasks = new Map();
62
67
  this.completedTasks = new Map();
63
68
  this.waitingForTasks = [];
@@ -31,6 +31,17 @@ export declare function getOutputsForTargetAndConfiguration(target: Task['target
31
31
  export declare function interpolate(template: string, data: any): string;
32
32
  export declare function getTargetConfigurationForTask(task: Task, projectGraph: ProjectGraph): TargetConfiguration | undefined;
33
33
  export declare function getExecutorNameForTask(task: Task, projectGraph: ProjectGraph): string;
34
+ /**
35
+ * Expand a set of initiating task IDs by walking through any `nx:noop` tasks
36
+ * and replacing them with their direct dependencies + continuous dependencies.
37
+ * Non-noop tasks are kept as-is; cycles are safe.
38
+ *
39
+ * An `nx:noop` executor returns immediately, so if it is the only thing
40
+ * anchoring a continuous child, the child gets killed by
41
+ * `cleanUpUnneededContinuousTasks` the moment the noop completes. Treating the
42
+ * noop's dependencies as the real anchors preserves the intended orchestration.
43
+ */
44
+ export declare function expandInitiatingTasksThroughNoop(initiatingTasks: Task[], taskGraph: TaskGraph, projectGraph: ProjectGraph): Set<string>;
34
45
  export declare function getExecutorForTask(task: Task, projects: Record<string, ProjectConfiguration>): ExecutorConfig & {
35
46
  isNgCompat: boolean;
36
47
  isNxExecutor: boolean;
@@ -14,6 +14,7 @@ exports.getOutputsForTargetAndConfiguration = getOutputsForTargetAndConfiguratio
14
14
  exports.interpolate = interpolate;
15
15
  exports.getTargetConfigurationForTask = getTargetConfigurationForTask;
16
16
  exports.getExecutorNameForTask = getExecutorNameForTask;
17
+ exports.expandInitiatingTasksThroughNoop = expandInitiatingTasksThroughNoop;
17
18
  exports.getExecutorForTask = getExecutorForTask;
18
19
  exports.getCustomHasher = getCustomHasher;
19
20
  exports.removeTasksFromTaskGraph = removeTasksFromTaskGraph;
@@ -291,6 +292,42 @@ function getTargetConfigurationForTask(task, projectGraph) {
291
292
  function getExecutorNameForTask(task, projectGraph) {
292
293
  return getTargetConfigurationForTask(task, projectGraph)?.executor;
293
294
  }
295
+ /**
296
+ * Expand a set of initiating task IDs by walking through any `nx:noop` tasks
297
+ * and replacing them with their direct dependencies + continuous dependencies.
298
+ * Non-noop tasks are kept as-is; cycles are safe.
299
+ *
300
+ * An `nx:noop` executor returns immediately, so if it is the only thing
301
+ * anchoring a continuous child, the child gets killed by
302
+ * `cleanUpUnneededContinuousTasks` the moment the noop completes. Treating the
303
+ * noop's dependencies as the real anchors preserves the intended orchestration.
304
+ */
305
+ function expandInitiatingTasksThroughNoop(initiatingTasks, taskGraph, projectGraph) {
306
+ const expanded = new Set();
307
+ const visited = new Set();
308
+ const queue = initiatingTasks.map((t) => t.id);
309
+ while (queue.length > 0) {
310
+ const taskId = queue.shift();
311
+ if (visited.has(taskId))
312
+ continue;
313
+ visited.add(taskId);
314
+ const task = taskGraph.tasks[taskId];
315
+ if (!task)
316
+ continue;
317
+ if (getExecutorNameForTask(task, projectGraph) === 'nx:noop') {
318
+ for (const dep of taskGraph.dependencies[taskId] ?? []) {
319
+ queue.push(dep);
320
+ }
321
+ for (const dep of taskGraph.continuousDependencies[taskId] ?? []) {
322
+ queue.push(dep);
323
+ }
324
+ }
325
+ else {
326
+ expanded.add(taskId);
327
+ }
328
+ }
329
+ return expanded;
330
+ }
294
331
  function getExecutorForTask(task, projects) {
295
332
  const executor = projects[task.target.project]?.targets?.[task.target.target]?.executor;
296
333
  const [nodeModule, executorName] = (0, executor_utils_1.parseExecutor)(executor);
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Resolve the workspace's installed `nx` version, or `null` if no installed
3
+ * `nx` can be located. Routed through a cache-shielded, self-reference-free
4
+ * `require.resolve` so the answer always reflects the workspace's
5
+ * `node_modules`/PnP store rather than whichever `nx` package happens to be
6
+ * loaded in the current process. See nrwl/nx#35444.
7
+ */
8
+ export declare function getInstalledNxVersion(): string | null;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getInstalledNxVersion = getInstalledNxVersion;
4
+ const tslib_1 = require("tslib");
5
+ const node_module_1 = tslib_1.__importStar(require("node:module"));
6
+ const fileutils_1 = require("./fileutils");
7
+ const workspace_root_1 = require("./workspace-root");
8
+ const installation_directory_1 = require("./installation-directory");
9
+ /**
10
+ * Resolve the workspace's installed `nx` version, or `null` if no installed
11
+ * `nx` can be located. Routed through a cache-shielded, self-reference-free
12
+ * `require.resolve` so the answer always reflects the workspace's
13
+ * `node_modules`/PnP store rather than whichever `nx` package happens to be
14
+ * loaded in the current process. See nrwl/nx#35444.
15
+ */
16
+ function getInstalledNxVersion() {
17
+ const nxPackageJsonPath = resolvePackageJsonWithoutCachePollution('nx', (0, installation_directory_1.getNxRequirePaths)(workspace_root_1.workspaceRoot));
18
+ if (!nxPackageJsonPath) {
19
+ return null;
20
+ }
21
+ try {
22
+ return (0, fileutils_1.readJsonFile)(nxPackageJsonPath).version ?? null;
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ /**
29
+ * Resolve `<packageName>/package.json` via Node's CJS resolver while
30
+ * neutralising both ways `require.resolve(req, { paths })` can lie about
31
+ * the `paths` argument:
32
+ *
33
+ * 1. Process-wide `Module._pathCache` — swapped out for the duration of
34
+ * the call, so any cache entries written are discarded and any
35
+ * previously-poisoned entries are not read. Without this, an
36
+ * in-process load of a second `nx` package (e.g. the temp `nx@latest`
37
+ * install used by the daemon's AI-agents and console-status checks)
38
+ * can poison the cache key this call uses and make us read the temp
39
+ * path instead of the workspace path.
40
+ *
41
+ * 2. Package self-reference — when a file inside package `nx` calls
42
+ * `require.resolve('nx/...')`, Node returns that calling package's
43
+ * own file regardless of `paths`. We avoid that by issuing the
44
+ * resolve from a `createRequire` rooted at a synthetic path that is
45
+ * outside any package, so the resolver has no "self" to reference
46
+ * and must honour `paths`.
47
+ *
48
+ * Node's single-threaded synchronous execution means `require.resolve` does
49
+ * not yield, so no other code in the process can observe the swapped cache.
50
+ */
51
+ function resolvePackageJsonWithoutCachePollution(packageName, requirePaths) {
52
+ // `_pathCache` is an internal Node API not exposed in @types/node.
53
+ const realCache = node_module_1.default._pathCache;
54
+ node_module_1.default._pathCache = Object.create(null);
55
+ try {
56
+ const detachedRequire = (0, node_module_1.createRequire)('/__nx_detached_resolver__/x.js');
57
+ return detachedRequire.resolve(`${packageName}/package.json`, {
58
+ paths: requirePaths,
59
+ });
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ finally {
65
+ node_module_1.default._pathCache = realCache;
66
+ }
67
+ }
@@ -54,7 +54,7 @@ async function globWithWorkspaceContext(workspaceRoot, globs, exclude) {
54
54
  }
55
55
  }
56
56
  async function multiGlobWithWorkspaceContext(workspaceRoot, globs, exclude) {
57
- if ((0, is_on_daemon_1.isOnDaemon)() || !client_1.daemonClient.enabled()) {
57
+ if (workspaceRoot === '/virtual' || (0, is_on_daemon_1.isOnDaemon)() || !client_1.daemonClient.enabled()) {
58
58
  ensureContextAvailable(workspaceRoot);
59
59
  return workspaceContext.multiGlob(globs, exclude);
60
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "22.7.0",
3
+ "version": "22.7.1",
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.",
@@ -171,16 +171,16 @@
171
171
  }
172
172
  },
173
173
  "optionalDependencies": {
174
- "@nx/nx-darwin-arm64": "22.7.0",
175
- "@nx/nx-darwin-x64": "22.7.0",
176
- "@nx/nx-freebsd-x64": "22.7.0",
177
- "@nx/nx-linux-arm-gnueabihf": "22.7.0",
178
- "@nx/nx-linux-arm64-gnu": "22.7.0",
179
- "@nx/nx-linux-arm64-musl": "22.7.0",
180
- "@nx/nx-linux-x64-gnu": "22.7.0",
181
- "@nx/nx-linux-x64-musl": "22.7.0",
182
- "@nx/nx-win32-arm64-msvc": "22.7.0",
183
- "@nx/nx-win32-x64-msvc": "22.7.0"
174
+ "@nx/nx-darwin-arm64": "22.7.1",
175
+ "@nx/nx-darwin-x64": "22.7.1",
176
+ "@nx/nx-freebsd-x64": "22.7.1",
177
+ "@nx/nx-linux-arm-gnueabihf": "22.7.1",
178
+ "@nx/nx-linux-arm64-gnu": "22.7.1",
179
+ "@nx/nx-linux-arm64-musl": "22.7.1",
180
+ "@nx/nx-linux-x64-gnu": "22.7.1",
181
+ "@nx/nx-linux-x64-musl": "22.7.1",
182
+ "@nx/nx-win32-arm64-msvc": "22.7.1",
183
+ "@nx/nx-win32-x64-msvc": "22.7.1"
184
184
  },
185
185
  "nx-migrations": {
186
186
  "migrations": "./migrations.json",