Skip to content

Commit ef8c4ed

Browse files
authored
feat(linter): add rule for dependency checking (nrwl#17581)
1 parent 1891add commit ef8c4ed

File tree

14 files changed

+2016
-49
lines changed

14 files changed

+2016
-49
lines changed

.eslintrc.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,12 @@
3030
},
3131
"overrides": [
3232
{
33-
"files": ["**/executors/**/schema.json", "**/generators/**/schema.json"],
33+
"files": ["*.json"],
3434
"parser": "jsonc-eslint-parser",
35+
"rules": {}
36+
},
37+
{
38+
"files": ["**/executors/**/schema.json", "**/generators/**/schema.json"],
3539
"rules": {
3640
"@nx/workspace/valid-schema-description": "error"
3741
}

e2e/linter/src/linter.test.ts

+87
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
runCLI,
1010
uniq,
1111
updateFile,
12+
updateJson,
1213
} from '@nx/e2e/utils';
1314
import * as ts from 'typescript';
1415

@@ -435,6 +436,92 @@ describe('Linter', () => {
435436
);
436437
});
437438
});
439+
440+
describe('dependency checks', () => {
441+
beforeAll(() => {
442+
updateJson(`libs/${mylib}/.eslintrc.json`, (json) => {
443+
json.overrides = [
444+
...json.overrides,
445+
{
446+
files: ['*.json'],
447+
parser: 'jsonc-eslint-parser',
448+
rules: {
449+
'@nx/dependency-checks': 'error',
450+
},
451+
},
452+
];
453+
return json;
454+
});
455+
updateJson(`libs/${mylib}/project.json`, (json) => {
456+
json.targets.lint.options.lintFilePatterns = [
457+
`libs/${mylib}/**/*.ts`,
458+
`libs/${mylib}/project.json`,
459+
`libs/${mylib}/package.json`,
460+
];
461+
return json;
462+
});
463+
});
464+
465+
it('should report dependency check issues', () => {
466+
const rootPackageJson = readJson('package.json');
467+
const nxVersion = rootPackageJson.devDependencies.nx;
468+
const swcCoreVersion = rootPackageJson.devDependencies['@swc/core'];
469+
const swcHelpersVersion = rootPackageJson.dependencies['@swc/helpers'];
470+
471+
let out = runCLI(`lint ${mylib}`, { silenceError: true });
472+
expect(out).toContain('All files pass linting');
473+
474+
// make an explict dependency to nx
475+
updateFile(
476+
`libs/${mylib}/src/lib/${mylib}.ts`,
477+
(content) =>
478+
`import { names } from '@nx/devkit';\n\n` +
479+
content.replace(/return .*;/, `return names(${mylib}).className;`)
480+
);
481+
482+
// output should now report missing dependencies section
483+
out = runCLI(`lint ${mylib}`, { silenceError: true });
484+
expect(out).toContain(
485+
'Dependency sections are missing from the "package.json"'
486+
);
487+
488+
// should fix the missing section issue
489+
out = runCLI(`lint ${mylib} --fix`, { silenceError: true });
490+
expect(out).toContain(
491+
`Successfully ran target lint for project ${mylib}`
492+
);
493+
const packageJson = readJson(`libs/${mylib}/package.json`);
494+
expect(packageJson).toMatchInlineSnapshot(`
495+
{
496+
"dependencies": {
497+
"@nx/devkit": "${nxVersion}",
498+
"@swc/core": "${swcCoreVersion}",
499+
"@swc/helpers": "${swcHelpersVersion}",
500+
"nx": "${nxVersion}",
501+
},
502+
"name": "@proj/${mylib}",
503+
"type": "commonjs",
504+
"version": "0.0.1",
505+
}
506+
`);
507+
508+
// intentionally set the invalid version
509+
updateJson(`libs/${mylib}/package.json`, (json) => {
510+
json.dependencies['@nx/devkit'] = '100.0.0';
511+
return json;
512+
});
513+
out = runCLI(`lint ${mylib}`, { silenceError: true });
514+
expect(out).toContain(
515+
`The version specifier does not contain the installed version of "@nx/devkit" package: ${nxVersion}`
516+
);
517+
518+
// should fix the version mismatch issue
519+
out = runCLI(`lint ${mylib} --fix`, { silenceError: true });
520+
expect(out).toContain(
521+
`Successfully ran target lint for project ${mylib}`
522+
);
523+
});
524+
});
438525
});
439526

440527
describe('Root projects migration', () => {

nx.json

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
"{projectRoot}/generators.json",
106106
"{projectRoot}/executors.json",
107107
"{projectRoot}/package.json",
108+
"{projectRoot}/project.json",
108109
"{projectRoot}/migrations.json"
109110
]
110111
},

packages/eslint-plugin/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"@typescript-eslint/utils": "^5.58.0",
4040
"chalk": "^4.1.0",
4141
"confusing-browser-globals": "^1.0.9",
42+
"jsonc-eslint-parser": "^2.1.0",
4243
"semver": "7.3.4"
4344
},
4445
"publishConfig": {

packages/eslint-plugin/src/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ import nxPluginChecksRule, {
1515
RULE_NAME as nxPluginChecksRuleName,
1616
} from './rules/nx-plugin-checks';
1717

18+
import dependencyChecks, {
19+
RULE_NAME as dependencyChecksRuleName,
20+
} from './rules/dependency-checks';
21+
1822
// Resolve any custom rules that might exist in the current workspace
1923
import { workspaceRules } from './resolve-workspace-rules';
2024

@@ -32,6 +36,7 @@ module.exports = {
3236
rules: {
3337
[enforceModuleBoundariesRuleName]: enforceModuleBoundaries,
3438
[nxPluginChecksRuleName]: nxPluginChecksRule,
39+
[dependencyChecksRuleName]: dependencyChecks,
3540
...workspaceRules,
3641
},
3742
};

0 commit comments

Comments
 (0)