Skip to content

Commit

Permalink
feat(linter): add standalone nx linter (nrwl#2462)
Browse files Browse the repository at this point in the history
  • Loading branch information
rarmatei authored Feb 25, 2020
1 parent cd25970 commit 9d16355
Show file tree
Hide file tree
Showing 21 changed files with 1,467 additions and 61 deletions.
1 change: 1 addition & 0 deletions .cz-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = {
{ name: 'node', description: 'anything Node specific' },
{ name: 'nx-plugin', description: 'anything Nx Plugin specific' },
{ name: 'react', description: 'anything React specific' },
{ name: 'linter', description: 'anything Linter specific' },
{ name: 'storybook', description: 'anything Storybook specific' },
{
name: 'testing',
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ The scope must be one of the following:
- docs - anything related to docs infrastructure
- nextjs - anything Next specific
- node - anything Node specific
- linter - anything Linter specific
- react - anything React specific
- storybook - anything Storybook specific
- testing - anything testing specific (e.g., jest or cypress)
Expand Down
40 changes: 38 additions & 2 deletions docs/angular/api-linter/builders/lint.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ Builder properties can be configured in angular.json when defining the builder,

## Properties

### cache

Default: `false`

Type: `boolean`

Only check changed files.

### cacheLocation

Type: `string`

Path to the cache file or directory.

### config

Type: `string`
Expand All @@ -32,13 +46,21 @@ Type: `boolean`

Fixes linting errors (may overwrite linted files).

### force

Default: `false`

Type: `boolean`

Succeeds even if there was linting errors.

### format

Default: `prose`
Default: `stylish`

Type: `string`

Output format (prose, json, stylish, verbose, pmd, msbuild, checkstyle, vso, fileslist).
ESLint Output formatter (https://eslint.org/docs/user-guide/formatters).

### linter

Expand All @@ -50,6 +72,20 @@ Possible values: `eslint`, `tslint`

The tool to use for running lint checks.

### outputFile

Type: `string`

File to write report to.

### silent

Default: `false`

Type: `boolean`

Hide output text.

### tsConfig

Type: `string`
Expand Down
40 changes: 38 additions & 2 deletions docs/react/api-linter/builders/lint.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ Read more about how to use builders and the CLI here: https://nx.dev/react/guide

## Properties

### cache

Default: `false`

Type: `boolean`

Only check changed files.

### cacheLocation

Type: `string`

Path to the cache file or directory.

### config

Type: `string`
Expand All @@ -33,13 +47,21 @@ Type: `boolean`

Fixes linting errors (may overwrite linted files).

### force

Default: `false`

Type: `boolean`

Succeeds even if there was linting errors.

### format

Default: `prose`
Default: `stylish`

Type: `string`

Output format (prose, json, stylish, verbose, pmd, msbuild, checkstyle, vso, fileslist).
ESLint Output formatter (https://eslint.org/docs/user-guide/formatters).

### linter

Expand All @@ -51,6 +73,20 @@ Possible values: `eslint`, `tslint`

The tool to use for running lint checks.

### outputFile

Type: `string`

File to write report to.

### silent

Default: `false`

Type: `boolean`

Hide output text.

### tsConfig

Type: `string`
Expand Down
40 changes: 38 additions & 2 deletions docs/web/api-linter/builders/lint.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ Read more about how to use builders and the CLI here: https://nx.dev/web/guides/

## Properties

### cache

Default: `false`

Type: `boolean`

Only check changed files.

### cacheLocation

Type: `string`

Path to the cache file or directory.

### config

Type: `string`
Expand All @@ -33,13 +47,21 @@ Type: `boolean`

Fixes linting errors (may overwrite linted files).

### force

Default: `false`

Type: `boolean`

Succeeds even if there was linting errors.

### format

Default: `prose`
Default: `stylish`

Type: `string`

Output format (prose, json, stylish, verbose, pmd, msbuild, checkstyle, vso, fileslist).
ESLint Output formatter (https://eslint.org/docs/user-guide/formatters).

### linter

Expand All @@ -51,6 +73,20 @@ Possible values: `eslint`, `tslint`

The tool to use for running lint checks.

### outputFile

Type: `string`

File to write report to.

### silent

Default: `false`

Type: `boolean`

Hide output text.

### tsConfig

Type: `string`
Expand Down
144 changes: 144 additions & 0 deletions e2e/linter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import {
checkFilesExist,
newProject,
readFile,
readJson,
runCLI,
updateFile,
ensureProject,
uniq,
forEachCli
} from './utils';

forEachCli('nx', () => {
describe('Linter', () => {
it('linting should error when rules are not followed', () => {
ensureProject();
const myapp = uniq('myapp');

runCLI(`generate @nrwl/react:app ${myapp}`);

const eslintrc = readJson('.eslintrc');
eslintrc.rules['no-console'] = 'error';
updateFile('.eslintrc', JSON.stringify(eslintrc, null, 2));

updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);

const out = runCLI(`lint ${myapp}`, { silenceError: true });
expect(out).toContain('Unexpected console statement no-console');
}, 1000000);

it('linting should not error when rules are not followed and the force flag is specified', () => {
ensureProject();
const myapp = uniq('myapp');

runCLI(`generate @nrwl/react:app ${myapp}`);

const eslintrc = readJson('.eslintrc');
eslintrc.rules['no-console'] = 'error';
updateFile('.eslintrc', JSON.stringify(eslintrc, null, 2));

updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);

expect(() => runCLI(`lint ${myapp} --force`)).not.toThrow();
}, 1000000);

it('linting should not error when all rules are followed', () => {
ensureProject();
const myapp = uniq('myapp');

runCLI(`generate @nrwl/react:app ${myapp}`);

const eslintrc = readJson('.eslintrc');
eslintrc.rules['no-console'] = undefined;
updateFile('.eslintrc', JSON.stringify(eslintrc, null, 2));

updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);

const out = runCLI(`lint ${myapp}`, { silenceError: true });
expect(out).toContain('All files pass linting');
}, 1000000);

it('linting should error when an invalid linter is specified', () => {
ensureProject();
const myapp = uniq('myapp');

runCLI(`generate @nrwl/react:app ${myapp}`);

const eslintrc = readJson('.eslintrc');
eslintrc.rules['no-console'] = undefined;
updateFile('.eslintrc', JSON.stringify(eslintrc, null, 2));

updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);

expect(() => runCLI(`lint ${myapp} --linter=tslint`)).toThrow(
/'tslint' option is no longer supported/
);
expect(() => runCLI(`lint ${myapp} --linter=random`)).toThrow(
/Schema validation failed/
);
}, 1000000);

it('linting should generate a default cache file', () => {
newProject();
const myapp = uniq('myapp');

runCLI(`generate @nrwl/react:app ${myapp}`);

expect(() => checkFilesExist(`.eslintcache`)).toThrow();
runCLI(`lint ${myapp} --cache`, { silenceError: true });
expect(() => checkFilesExist(`.eslintcache`)).not.toThrow();
const cacheInfo = readFile('.eslintcache');
expect(cacheInfo).toContain(`${myapp}/src/app/app.spec.tsx`);
}, 1000000);

it('linting should let you specify a cache file location', () => {
newProject();
const myapp = uniq('myapp');

runCLI(`generate @nrwl/react:app ${myapp}`);

expect(() => checkFilesExist(`my-cache`)).toThrow();
runCLI(`lint ${myapp} --cache --cache-location="my-cache"`, {
silenceError: true
});
expect(() => checkFilesExist(`my-cache`)).not.toThrow();
const cacheInfo = readFile('my-cache');
expect(cacheInfo).toContain(`${myapp}/src/app/app.spec.tsx`);
}, 1000000);

it('linting should generate an output file with a specific format', () => {
newProject();
const myapp = uniq('myapp');

runCLI(`generate @nrwl/react:app ${myapp}`);

const eslintrc = readJson('.eslintrc');
eslintrc.rules['no-console'] = 'error';
updateFile('.eslintrc', JSON.stringify(eslintrc, null, 2));
updateFile(`apps/${myapp}/src/main.ts`, `console.log("should fail");`);

const outputFile = 'lint-output.json';
expect(() => {
checkFilesExist(outputFile);
}).toThrow();
const stdout = runCLI(
`lint ${myapp} --output-file="${outputFile}" --format=json`,
{
silenceError: true
}
);
expect(stdout).toContain('Unexpected console statement');
expect(() => checkFilesExist(outputFile)).not.toThrow();
const outputContents = JSON.parse(readFile(outputFile));
const outputForApp: any = Object.values(outputContents).filter(
(result: any) => result.filePath.includes(`${myapp}/src/main.ts`)
)[0];
expect(outputForApp.errorCount).toBe(1);
expect(outputForApp.messages[0].ruleId).toBe('no-console');
expect(outputForApp.messages[0].message).toBe(
'Unexpected console statement.'
);
}, 1000000);
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"@angular-devkit/build-webpack": "~0.900.1",
"@angular-devkit/core": "~9.0.1",
"@angular-devkit/schematics": "~9.0.1",
"@angular-eslint/builder": "0.0.1-alpha.18",
"@angular/cli": "~9.0.1",
"@angular/common": "^9.0.0",
"@angular/compiler": "^9.0.0",
Expand Down Expand Up @@ -82,6 +81,7 @@
"@storybook/react": "5.3.9",
"@svgr/webpack": "^5.2.0",
"@testing-library/react": "9.4.0",
"@types/eslint": "^6.1.8",
"@types/express": "4.17.0",
"@types/fast-levenshtein": "^0.0.1",
"@types/fs-extra": "7.0.0",
Expand Down
7 changes: 4 additions & 3 deletions packages/linter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@
"homepage": "https://nx.dev",
"builders": "./builders.json",
"peerDependencies": {
"@nrwl/workspace": "*"
"@nrwl/workspace": "*",
"eslint": "*",
"typescript": "*"
},
"dependencies": {
"@angular-devkit/architect": "~0.900.1",
"@angular-eslint/builder": "0.0.1-alpha.18"
"@angular-devkit/architect": "~0.900.1"
}
}
Loading

0 comments on commit 9d16355

Please sign in to comment.