@nx/eslint 19.0.0-beta.2 → 19.0.0-beta.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/eslint",
3
- "version": "19.0.0-beta.2",
3
+ "version": "19.0.0-beta.3",
4
4
  "private": false,
5
5
  "description": "The ESLint plugin for Nx contains executors, generators and utilities used for linting JavaScript/TypeScript projects within an Nx workspace.",
6
6
  "repository": {
@@ -33,12 +33,12 @@
33
33
  "js-yaml": "4.1.0"
34
34
  },
35
35
  "dependencies": {
36
- "@nx/devkit": "19.0.0-beta.2",
37
- "@nx/js": "19.0.0-beta.2",
36
+ "@nx/devkit": "19.0.0-beta.3",
37
+ "@nx/js": "19.0.0-beta.3",
38
38
  "eslint": "^8.0.0",
39
39
  "tslib": "^2.3.0",
40
40
  "typescript": "~5.4.2",
41
- "@nx/linter": "19.0.0-beta.2"
41
+ "@nx/linter": "19.0.0-beta.3"
42
42
  },
43
43
  "peerDependenciesMeta": {
44
44
  "js-yaml": {
@@ -13,41 +13,49 @@ exports.createNodes = [
13
13
  config_file_1.baseEsLintConfigFile,
14
14
  config_file_1.baseEsLintFlatConfigFile,
15
15
  ]),
16
- (configFilePath, options, context) => {
16
+ async (configFilePath, options, context) => {
17
17
  options = normalizeOptions(options);
18
+ const configDir = (0, node_path_1.dirname)(configFilePath);
18
19
  // Ensure that configFiles are set, e2e-run fails due to them being undefined in CI (does not occur locally)
19
20
  // TODO(JamesHenry): Further troubleshoot this in CI
20
21
  context.configFiles = context.configFiles ?? [];
21
- // Create a Set of all the directories containing eslint configs
22
- const eslintRoots = new Set(context.configFiles.map(node_path_1.dirname));
23
- const configDir = (0, node_path_1.dirname)(configFilePath);
24
- const childProjectRoots = (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, [
22
+ // Create a Set of all the directories containing eslint configs, and a
23
+ // list of globs to exclude from child projects
24
+ const eslintRoots = new Set();
25
+ const nestedEslintRootPatterns = [];
26
+ for (const configFile of context.configFiles) {
27
+ const eslintRootDir = (0, node_path_1.dirname)(configFile);
28
+ eslintRoots.add(eslintRootDir);
29
+ if (eslintRootDir !== configDir && isSubDir(configDir, eslintRootDir)) {
30
+ nestedEslintRootPatterns.push(`${eslintRootDir}/**/*`);
31
+ }
32
+ }
33
+ const childProjectRoots = new Set();
34
+ const ESLint = resolveESLintClass((0, config_file_1.isFlatConfig)(configFilePath));
35
+ const projectFiles = (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, [
25
36
  'project.json',
26
37
  'package.json',
27
38
  '**/project.json',
28
39
  '**/package.json',
29
- ].map((f) => (0, node_path_1.join)(configDir, f)))
30
- .map((f) => (0, node_path_1.dirname)(f))
31
- .filter((childProjectRoot) => {
32
- // Filter out projects under other eslint configs
33
- let root = childProjectRoot;
34
- // Traverse up from the childProjectRoot to either the workspaceRoot or the dir of this config file
35
- while (root !== (0, node_path_1.dirname)(root) && root !== (0, node_path_1.dirname)(configFilePath)) {
36
- if (eslintRoots.has(root)) {
37
- return false;
38
- }
39
- root = (0, node_path_1.dirname)(root);
40
+ ].map((f) => (0, node_path_1.join)(configDir, f)), nestedEslintRootPatterns.length ? nestedEslintRootPatterns : undefined);
41
+ for (const projectFile of projectFiles) {
42
+ const childProjectRoot = (0, node_path_1.dirname)(projectFile);
43
+ if (childProjectRoots.has(childProjectRoot)) {
44
+ continue;
40
45
  }
41
- return true;
42
- })
43
- .filter((dir) => {
44
46
  // Ignore project roots where the project does not contain any lintable files
45
- const lintableFiles = (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, [
46
- (0, node_path_1.join)(dir, `**/*.{${options.extensions.join(',')}}`),
47
- ]);
48
- return lintableFiles.length > 0;
49
- });
50
- const uniqueChildProjectRoots = Array.from(new Set(childProjectRoots));
47
+ const lintableFiles = (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, [(0, node_path_1.join)(childProjectRoot, `**/*.{${options.extensions.join(',')}}`)], nestedEslintRootPatterns.length ? nestedEslintRootPatterns : undefined);
48
+ const eslint = new ESLint({
49
+ cwd: (0, node_path_1.join)(context.workspaceRoot, childProjectRoot),
50
+ });
51
+ for (const file of lintableFiles) {
52
+ if (!(await eslint.isPathIgnored((0, node_path_1.join)(context.workspaceRoot, file)))) {
53
+ childProjectRoots.add(childProjectRoot);
54
+ break;
55
+ }
56
+ }
57
+ }
58
+ const uniqueChildProjectRoots = Array.from(childProjectRoots);
51
59
  return {
52
60
  projects: getProjectsUsingESLintConfig(configFilePath, uniqueChildProjectRoots, options, context),
53
61
  };
@@ -72,12 +80,12 @@ function getProjectsUsingESLintConfig(configFilePath, childProjectRoots, options
72
80
  eslintConfigs.unshift(rootEslintConfig);
73
81
  }
74
82
  projects[projectRoot] = {
75
- targets: buildEslintTargets(eslintConfigs, projectRoot, options, isStandaloneWorkspace),
83
+ targets: buildEslintTargets(eslintConfigs, projectRoot, context.workspaceRoot, options, isStandaloneWorkspace),
76
84
  };
77
85
  }
78
86
  return projects;
79
87
  }
80
- function buildEslintTargets(eslintConfigs, projectRoot, options, isStandaloneWorkspace = false) {
88
+ function buildEslintTargets(eslintConfigs, projectRoot, workspaceRoot, options, isStandaloneWorkspace = false) {
81
89
  const isRootProject = projectRoot === '.';
82
90
  const targets = {};
83
91
  const targetConfig = {
@@ -91,6 +99,9 @@ function buildEslintTargets(eslintConfigs, projectRoot, options, isStandaloneWor
91
99
  // Certain lint rules can be impacted by changes to dependencies
92
100
  '^default',
93
101
  ...eslintConfigs.map((config) => `{workspaceRoot}/${config}`.replace(`{workspaceRoot}/${projectRoot}`, isRootProject ? '{projectRoot}/' : '{projectRoot}')),
102
+ ...((0, node_fs_1.existsSync)((0, node_path_1.join)(workspaceRoot, projectRoot, '.eslintignore'))
103
+ ? ['{projectRoot}/.eslintignore']
104
+ : []),
94
105
  '{workspaceRoot}/tools/eslint-rules/**/*',
95
106
  { externalDependencies: ['eslint'] },
96
107
  ],
@@ -115,3 +126,30 @@ function normalizeOptions(options) {
115
126
  }
116
127
  return options;
117
128
  }
129
+ function resolveESLintClass(useFlatConfig = false) {
130
+ try {
131
+ if (!useFlatConfig) {
132
+ return require('eslint').ESLint;
133
+ }
134
+ return require('eslint/use-at-your-own-risk').FlatESLint;
135
+ }
136
+ catch {
137
+ throw new Error('Unable to find ESLint. Ensure ESLint is installed.');
138
+ }
139
+ }
140
+ /**
141
+ * Determines if `child` is a subdirectory of `parent`. This is a simplified
142
+ * version that takes into account that paths are always relative to the
143
+ * workspace root.
144
+ */
145
+ function isSubDir(parent, child) {
146
+ if (parent === '.') {
147
+ return true;
148
+ }
149
+ parent = (0, node_path_1.normalize)(parent);
150
+ child = (0, node_path_1.normalize)(child);
151
+ if (!parent.endsWith(node_path_1.sep)) {
152
+ parent += node_path_1.sep;
153
+ }
154
+ return child.startsWith(parent);
155
+ }