diff --git a/packages/linter/src/generators/init/init.spec.ts b/packages/linter/src/generators/init/init.spec.ts index d92b7577ca135..ad74deebd4b94 100644 --- a/packages/linter/src/generators/init/init.spec.ts +++ b/packages/linter/src/generators/init/init.spec.ts @@ -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', () => { @@ -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', () => { diff --git a/packages/linter/src/generators/init/init.ts b/packages/linter/src/generators/init/init.ts index fe0952bdeac22..f4ea0f565d3f0 100644 --- a/packages/linter/src/generators/init/init.ts +++ b/packages/linter/src/generators/init/init.ts @@ -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, @@ -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; @@ -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 () => {}; } diff --git a/packages/linter/src/generators/lint-project/__snapshots__/lint-project.spec.ts.snap b/packages/linter/src/generators/lint-project/__snapshots__/lint-project.spec.ts.snap index cd40f6eaa46d6..6f961ef85b50a 100644 --- a/packages/linter/src/generators/lint-project/__snapshots__/lint-project.spec.ts.snap +++ b/packages/linter/src/generators/lint-project/__snapshots__/lint-project.spec.ts.snap @@ -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\\": [ diff --git a/packages/linter/src/generators/lint-project/lint-project.spec.ts b/packages/linter/src/generators/lint-project/lint-project.spec.ts index c49373877b605..d3d8b5ef26687 100644 --- a/packages/linter/src/generators/lint-project/lint-project.spec.ts +++ b/packages/linter/src/generators/lint-project/lint-project.spec.ts @@ -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', () => { @@ -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', () => { diff --git a/packages/linter/src/generators/lint-project/lint-project.ts b/packages/linter/src/generators/lint-project/lint-project.ts index 645d44a9bb082..b7bdb98841267 100644 --- a/packages/linter/src/generators/lint-project/lint-project.ts +++ b/packages/linter/src/generators/lint-project/lint-project.ts @@ -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 { @@ -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: [ diff --git a/packages/linter/src/generators/utils/eslint-file.spec.ts b/packages/linter/src/generators/utils/eslint-file.spec.ts new file mode 100644 index 0000000000000..bb2aac3b783b3 --- /dev/null +++ b/packages/linter/src/generators/utils/eslint-file.spec.ts @@ -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'); + }); + }); +}); diff --git a/packages/linter/src/generators/utils/eslint-file.ts b/packages/linter/src/generators/utils/eslint-file.ts new file mode 100644 index 0000000000000..c4717c4f0f498 --- /dev/null +++ b/packages/linter/src/generators/utils/eslint-file.ts @@ -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'; +}