Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(linter): Generator creating .eslintrc.json at the root path even when .eslintrc.js already exist #10080

Merged
merged 3 commits into from
May 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 11 additions & 2 deletions packages/linter/src/generators/init/init.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Linter } from '../utils/linter';
import { Tree } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';

import { Linter } from '../utils/linter';
import { lintInitGenerator } from './init';

describe('@nrwl/linter:init', () => {
Expand All @@ -20,6 +19,16 @@ describe('@nrwl/linter:init', () => {

expect(tree.read('.eslintrc.json', 'utf-8')).toMatchSnapshot();
});

it('should not generate the global eslint config if it already exist', async () => {
tree.write('.eslintrc.js', '{}');

await lintInitGenerator(tree, {
linter: Linter.EsLint,
});

expect(tree.exists('.eslintrc.json')).toBe(false);
});
});

describe('tslint', () => {
Expand Down
6 changes: 4 additions & 2 deletions packages/linter/src/generators/init/init.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { GeneratorCallback, Tree } from '@nrwl/devkit';
import {
addDependenciesToPackageJson,
removeDependenciesFromPackageJson,
updateJson,
writeJson,
} from '@nrwl/devkit';
import type { GeneratorCallback, Tree } from '@nrwl/devkit';
import {
buildAngularVersion,
eslintConfigPrettierVersion,
Expand All @@ -13,7 +13,9 @@ import {
tslintVersion,
typescriptESLintVersion,
} from '../../utils/versions';

import { Linter } from '../utils/linter';
import { containsEslint } from '../utils/eslint-file';

export interface LinterInitOptions {
linter?: Linter;
Expand Down Expand Up @@ -165,7 +167,7 @@ function initTsLint(tree: Tree, options: LinterInitOptions): GeneratorCallback {
}

function initEsLint(tree: Tree, options: LinterInitOptions): GeneratorCallback {
if (tree.exists('/.eslintrc.json')) {
if (containsEslint(tree)) {
return () => {};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`@nrwl/linter:lint-project --linter eslint should extend to .eslintrc.js when an .eslintrc.js already exist 1`] = `
"{
\\"extends\\": [
\\"../../.eslintrc.js\\"
],
\\"ignorePatterns\\": [
\\"!**/*\\"
],
\\"overrides\\": [
{
\\"files\\": [
\\"*.ts\\",
\\"*.tsx\\",
\\"*.js\\",
\\"*.jsx\\"
],
\\"rules\\": {}
},
{
\\"files\\": [
\\"*.ts\\",
\\"*.tsx\\"
],
\\"rules\\": {}
},
{
\\"files\\": [
\\"*.js\\",
\\"*.jsx\\"
],
\\"rules\\": {}
}
]
}
"
`;

exports[`@nrwl/linter:lint-project --linter eslint should generate a eslint config 1`] = `
"{
\\"extends\\": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
Tree,
addProjectConfiguration,
readProjectConfiguration,
Tree,
} from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';

import { Linter } from '../utils/linter';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { lintProjectGenerator } from './lint-project';

describe('@nrwl/linter:lint-project', () => {
Expand Down Expand Up @@ -63,6 +63,22 @@ describe('@nrwl/linter:lint-project', () => {
}
`);
});

it('should extend to .eslintrc.js when an .eslintrc.js already exist', async () => {
tree.write('.eslintrc.js', '{}');

await lintProjectGenerator(tree, {
...defaultOptions,
linter: Linter.EsLint,
eslintFilePatterns: ['**/*.ts'],
project: 'test-lib',
setParserOptionsProject: false,
});

expect(
tree.read('libs/test-lib/.eslintrc.json', 'utf-8')
).toMatchSnapshot();
});
});

describe('tslint', () => {
Expand Down
6 changes: 4 additions & 2 deletions packages/linter/src/generators/lint-project/lint-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
updateProjectConfiguration,
writeJson,
} from '@nrwl/devkit';
import { join } from 'path';

import { Linter } from '../utils/linter';
import { findEslintFile } from '../utils/eslint-file';
import { join } from 'path';
import { lintInitGenerator } from '../init/init';

interface LintProjectOptions {
Expand Down Expand Up @@ -40,7 +42,7 @@ function createEsLintConfiguration(
setParserOptionsProject: boolean
) {
writeJson(tree, join(projectConfig.root, `.eslintrc.json`), {
extends: [`${offsetFromRoot(projectConfig.root)}.eslintrc.json`],
extends: [`${offsetFromRoot(projectConfig.root)}${findEslintFile(tree)}`],
// Include project files to be linted since the global one excludes all files.
ignorePatterns: ['!**/*'],
overrides: [
Expand Down
55 changes: 55 additions & 0 deletions packages/linter/src/generators/utils/eslint-file.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { containsEslint, findEslintFile } from './eslint-file';

import { Tree } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';

describe('@nrwl/linter:eslint-file', () => {
let tree: Tree;

beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});

describe('containsEslint', () => {
it('should return false when calling containsEslint without a eslint config', () => {
expect(containsEslint(tree)).toBe(false);
});

it('should return true when calling containsEslint with a .eslintrc.json config', () => {
tree.write('.eslintrc.json', '{}');
expect(containsEslint(tree)).toBe(true);
});

it('should return true when calling containsEslint with a .eslintrc.js config', () => {
tree.write('.eslintrc.js', '{}');
expect(containsEslint(tree)).toBe(true);
});

it('should return false when calling containsEslint witn an incorrect eslint file name', () => {
tree.write('.eslintrc.yaml', '{}');
expect(containsEslint(tree)).toBe(false);
});
});

describe('findEslintFile', () => {
it('should return default name when calling findEslintFile when no eslint is found', () => {
expect(findEslintFile(tree)).toBe('eslintrc.json');
});

it('should return the name of the eslint config when calling findEslintFile', () => {
tree.write('.eslintrc.json', '{}');
expect(findEslintFile(tree)).toBe('.eslintrc.json');
});

it('should return the name of the eslint config when calling findEslintFile', () => {
tree.write('.eslintrc.js', '{}');
expect(findEslintFile(tree)).toBe('.eslintrc.js');
});

it('should return default name when calling findEslintFile when no eslint is found', () => {
tree.write('.eslintrc.yaml', '{}');

expect(findEslintFile(tree)).toBe('eslintrc.json');
});
});
});
22 changes: 22 additions & 0 deletions packages/linter/src/generators/utils/eslint-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Tree } from '@nrwl/devkit';

const eslintFileList = ['.eslintrc.json', '.eslintrc.js'];

export function containsEslint(tree: Tree): boolean {
for (const file of eslintFileList) {
if (tree.exists(file)) {
return true;
}
}
return false;
}

export function findEslintFile(tree: Tree): string {
for (const file of eslintFileList) {
if (tree.exists(file)) {
return file;
}
}
// Default file
return 'eslintrc.json';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AloisH @FrozenPandaz I know this has already been merged, but why wasn't this .eslintrc.json?

It has changed the behaviour inside of packages/linter/src/generators/lint-project/lint-project.ts above

eslintrc.json without a leading dot is not ever referenced by https://eslint.org/docs/user-guide/configuring/configuration-files.

This seems to be intentional because you have multiple unit tests asserting this, but I haven't understood why we would want to make this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @JamesHenry ! I think I made a mistake ! Thank you for noticing it !
I got one test trying it but I think I just forgot to put a dot.

Should we revert this PR so I can make a new commit fixing it ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless @FrozenPandaz disagrees I think a fast follow on PR would be ok, if will you have chance to do that today?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries, I'll follow up with a fix. 👍

}