@nx/devkit 23.2.0-beta.5 → 23.2.0-beta.6

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,6 +1,8 @@
1
1
  import { Tree } from 'nx/src/devkit-exports';
2
2
  /**
3
- * Formats all the created or updated files using Prettier
3
+ * Formats the created or updated files using Prettier, skipping `node_modules`,
4
+ * `.git`, the nx and yarn caches, and anything the workspace's root
5
+ * `.gitignore` or `.prettierignore` covers
4
6
  * @param tree - the file system tree
5
7
  * @param options - options for the formatFiles function
6
8
  *
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const devkit_exports_1 = require("nx/src/devkit-exports");
6
6
  const devkit_internals_1 = require("nx/src/devkit-internals");
7
7
  const path = tslib_1.__importStar(require("path"));
8
+ const nx_ignore_internals_1 = require("../utils/nx-ignore-internals");
8
9
  // Prettier v3 (ESM) exposes its API as named exports; v2 (CJS) exposes it under
9
10
  // `.default` when loaded via `import()`. Return whichever carries the API, or
10
11
  // null if prettier isn't installed.
@@ -18,7 +19,9 @@ async function importPrettier() {
18
19
  }
19
20
  }
20
21
  /**
21
- * Formats all the created or updated files using Prettier
22
+ * Formats the created or updated files using Prettier, skipping `node_modules`,
23
+ * `.git`, the nx and yarn caches, and anything the workspace's root
24
+ * `.gitignore` or `.prettierignore` covers
22
25
  * @param tree - the file system tree
23
26
  * @param options - options for the formatFiles function
24
27
  *
@@ -56,7 +59,16 @@ async function formatFiles(tree, options = {}) {
56
59
  catch { }
57
60
  if (!prettier)
58
61
  return;
59
- const files = new Set(tree.listChanges().filter((file) => file.type !== 'DELETE'));
62
+ // `getFileInfo` below looks like it filters ignored files but only covers its
63
+ // own built-in `node_modules` skip: with no `ignorePath` it never reads the
64
+ // workspace's ignore files, so `ignored` is false for everything else
65
+ // (measured).
66
+ //
67
+ // The optional call is the older-nx path - see `NOTHING_IGNORED`.
68
+ const { isIgnoredFile } = (0, devkit_internals_1.createPrettierIgnoreChecker)?.(tree) ?? nx_ignore_internals_1.NOTHING_IGNORED;
69
+ const files = new Set(tree
70
+ .listChanges()
71
+ .filter((file) => file.type !== 'DELETE' && !isIgnoredFile(file.path)));
60
72
  const changedPrettierInTree = getChangedPrettierConfigInTree(tree);
61
73
  await Promise.all(Array.from(files).map(async (file) => {
62
74
  try {
@@ -1,5 +1,12 @@
1
1
  import type { Tree } from 'nx/src/devkit-exports';
2
2
  /**
3
3
  * Utility to act on all files in a tree that are not ignored by git.
4
+ *
5
+ * Ignore files cascade, so a nested `.gitignore` covers the files under it and a
6
+ * nested negation overrides the root. They are read from the tree, not disk, so
7
+ * one a generator wrote in the same run counts.
8
+ *
9
+ * `node_modules`, `.git` and the nx and yarn caches are never visited, whatever
10
+ * the workspace's ignore files say.
4
11
  */
5
12
  export declare function visitNotIgnoredFiles(tree: Tree, dirPath: string, visitor: (path: string) => void): void;
@@ -3,25 +3,50 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.visitNotIgnoredFiles = visitNotIgnoredFiles;
4
4
  const devkit_internals_1 = require("nx/src/devkit-internals");
5
5
  const path_1 = require("path");
6
+ const nx_ignore_internals_1 = require("../utils/nx-ignore-internals");
6
7
  /**
7
8
  * Utility to act on all files in a tree that are not ignored by git.
9
+ *
10
+ * Ignore files cascade, so a nested `.gitignore` covers the files under it and a
11
+ * nested negation overrides the root. They are read from the tree, not disk, so
12
+ * one a generator wrote in the same run counts.
13
+ *
14
+ * `node_modules`, `.git` and the nx and yarn caches are never visited, whatever
15
+ * the workspace's ignore files say.
8
16
  */
9
17
  function visitNotIgnoredFiles(tree, dirPath = tree.root, visitor) {
10
- const ig = (0, devkit_internals_1.getIgnoreObjectForTree)(tree);
11
- dirPath = normalizePathRelativeToRoot(dirPath, tree.root);
12
- if (dirPath !== '' && ig?.ignores(dirPath)) {
18
+ (0, nx_ignore_internals_1.assertNxSupportsIgnoreCheckers)();
19
+ // Built once for the whole traversal.
20
+ const isIgnored = (0, devkit_internals_1.createGitIgnoreChecker)(tree);
21
+ const start = normalizePathRelativeToRoot(dirPath, tree.root);
22
+ // The caller's own directory is the only one nothing has checked - every
23
+ // deeper one is checked before it is descended into.
24
+ if (start !== '' && isIgnored.isIgnoredDirectory(start)) {
13
25
  return;
14
26
  }
27
+ visitDirectory(tree, start, visitor, isIgnored);
28
+ }
29
+ /**
30
+ * Callers must have cleared `dirPath` already - both call sites do.
31
+ *
32
+ * Not descending into an ignored directory is what makes the answers match git,
33
+ * not just what makes them fast: git refuses to re-include a file inside an
34
+ * excluded directory, and `isIgnoredFile` alone does not implement that rule
35
+ * (see `isIgnoredByChain`). Flattening this into a per-file filter would start
36
+ * visiting files git ignores.
37
+ */
38
+ function visitDirectory(tree, dirPath, visitor, isIgnored) {
15
39
  for (const child of tree.children(dirPath)) {
16
- const fullPath = (0, path_1.join)(dirPath, child);
17
- if (ig?.ignores(fullPath)) {
18
- continue;
19
- }
40
+ // Joined as POSIX rather than with `path.join`: tree paths are POSIX, and
41
+ // on Windows a backslash-separated path silently matches nothing.
42
+ const fullPath = dirPath ? `${dirPath}/${child}` : child;
20
43
  if (tree.isFile(fullPath)) {
21
- visitor(fullPath);
44
+ if (!isIgnored.isIgnoredFile(fullPath)) {
45
+ visitor(fullPath);
46
+ }
22
47
  }
23
- else {
24
- visitNotIgnoredFiles(tree, fullPath, visitor);
48
+ else if (!isIgnored.isIgnoredDirectory(fullPath)) {
49
+ visitDirectory(tree, fullPath, visitor, isIgnored);
25
50
  }
26
51
  }
27
52
  }
@@ -141,9 +141,13 @@ class DevkitTreeFromAngularDevkitTree {
141
141
  return (0, path_1.relative)(this.root, (0, path_1.join)(this.root, path));
142
142
  }
143
143
  read(filePath, encoding) {
144
- return encoding
145
- ? this.tree.read(filePath).toString(encoding)
146
- : this.tree.read(filePath);
144
+ // The schematics tree already returns null for a missing file, so honouring
145
+ // the `Tree` contract is a matter of not dereferencing it.
146
+ const content = this.tree.read(filePath);
147
+ if (content === null) {
148
+ return null;
149
+ }
150
+ return encoding ? content.toString(encoding) : content;
147
151
  }
148
152
  rename(from, to) {
149
153
  this.tree.rename(from, to);
@@ -0,0 +1,23 @@
1
+ import type { TreeIgnoreChecker } from 'nx/src/devkit-internals';
2
+ /**
3
+ * `@nx/devkit`'s `nx` peer spans a major either side, so an older nx that
4
+ * predates the ignore checkers can legally be installed alongside it, and a
5
+ * missing CommonJS named export arrives as `undefined` rather than as a load
6
+ * error. The two callers want opposite things from that, so they get different
7
+ * helpers - see `NOTHING_IGNORED` for the other half.
8
+ *
9
+ * A tree walk cannot degrade: without a checker nothing would be ignored, and
10
+ * the walker would descend into `node_modules` and hand a migration every file
11
+ * in it to rewrite. That is worse than the older nx's own behaviour, which at
12
+ * least read the root `.gitignore`, so this fails instead - once, by name.
13
+ */
14
+ export declare function assertNxSupportsIgnoreCheckers(): void;
15
+ /**
16
+ * The degrade the other way, for formatting.
17
+ *
18
+ * Filtering nothing is what devkit did before the checkers existed - with no
19
+ * `ignorePath`, prettier's own `getFileInfo` never read the workspace's ignore
20
+ * files either (measured) - so an older nx gets the formatting behaviour it has
21
+ * always had rather than a generator that refuses to run.
22
+ */
23
+ export declare const NOTHING_IGNORED: TreeIgnoreChecker;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NOTHING_IGNORED = void 0;
4
+ exports.assertNxSupportsIgnoreCheckers = assertNxSupportsIgnoreCheckers;
5
+ const devkit_internals_1 = require("nx/src/devkit-internals");
6
+ /**
7
+ * `@nx/devkit`'s `nx` peer spans a major either side, so an older nx that
8
+ * predates the ignore checkers can legally be installed alongside it, and a
9
+ * missing CommonJS named export arrives as `undefined` rather than as a load
10
+ * error. The two callers want opposite things from that, so they get different
11
+ * helpers - see `NOTHING_IGNORED` for the other half.
12
+ *
13
+ * A tree walk cannot degrade: without a checker nothing would be ignored, and
14
+ * the walker would descend into `node_modules` and hand a migration every file
15
+ * in it to rewrite. That is worse than the older nx's own behaviour, which at
16
+ * least read the root `.gitignore`, so this fails instead - once, by name.
17
+ */
18
+ function assertNxSupportsIgnoreCheckers() {
19
+ if (devkit_internals_1.createGitIgnoreChecker) {
20
+ return;
21
+ }
22
+ throw new Error('The installed version of nx does not export the ignore checkers that @nx/devkit needs to decide which files a generator may touch. ' +
23
+ 'This happens when nx and @nx/devkit are on different major versions. Run `nx migrate latest` to bring them into line.');
24
+ }
25
+ /**
26
+ * The degrade the other way, for formatting.
27
+ *
28
+ * Filtering nothing is what devkit did before the checkers existed - with no
29
+ * `ignorePath`, prettier's own `getFileInfo` never read the workspace's ignore
30
+ * files either (measured) - so an older nx gets the formatting behaviour it has
31
+ * always had rather than a generator that refuses to run.
32
+ */
33
+ exports.NOTHING_IGNORED = {
34
+ isIgnoredFile: () => false,
35
+ isIgnoredDirectory: () => false,
36
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/devkit",
3
- "version": "23.2.0-beta.5",
3
+ "version": "23.2.0-beta.6",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "files": [
@@ -68,7 +68,7 @@
68
68
  },
69
69
  "devDependencies": {
70
70
  "jest": "30.3.0",
71
- "nx": "23.2.0-beta.5"
71
+ "nx": "23.2.0-beta.6"
72
72
  },
73
73
  "peerDependencies": {
74
74
  "nx": ">= 22 <= 24 || ^23.0.0-0"