diff --git a/packages/eslint/src/generators/init/init-migration.ts b/packages/eslint/src/generators/init/init-migration.ts index 15e86df79b..2469606f8b 100644 --- a/packages/eslint/src/generators/init/init-migration.ts +++ b/packages/eslint/src/generators/init/init-migration.ts @@ -1,5 +1,6 @@ import { addDependenciesToPackageJson, + GeneratorCallback, joinPathFragments, offsetFromRoot, ProjectConfiguration, @@ -15,7 +16,7 @@ import { getGlobalFlatEslintConfiguration, } from './global-eslint-config'; import { useFlatConfig } from '../../utils/flat-config'; -import { eslintVersion } from '../../utils/versions'; +import { eslintVersion, nxVersion } from '../../utils/versions'; import { addBlockToFlatConfigExport, addImportToFlatConfig, @@ -31,7 +32,7 @@ export function migrateConfigToMonorepoStyle( tree: Tree, unitTestRunner: string, keepExistingVersions?: boolean -): void { +): GeneratorCallback { const rootEslintConfig = findEslintFile(tree); let skipCleanup = false; if ( @@ -105,6 +106,14 @@ export function migrateConfigToMonorepoStyle( } } }); + + return addDependenciesToPackageJson( + tree, + {}, + { + '@nx/eslint-plugin': nxVersion, + } + ); } export function findLintTarget( diff --git a/packages/eslint/src/generators/lint-project/lint-project-convert-monorepo.spec.ts b/packages/eslint/src/generators/lint-project/lint-project-convert-monorepo.spec.ts new file mode 100644 index 0000000000..5ff5f556f3 --- /dev/null +++ b/packages/eslint/src/generators/lint-project/lint-project-convert-monorepo.spec.ts @@ -0,0 +1,92 @@ +import { + addProjectConfiguration, + ProjectGraph, + readJson, + Tree, +} from '@nx/devkit'; + +import { Linter } from '../utils/linter'; +import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; +import { lintProjectGenerator } from './lint-project'; + +let projectGraph: ProjectGraph; + +jest.mock('@nx/devkit', () => ({ + ...jest.requireActual('@nx/devkit'), + createProjectGraphAsync: jest + .fn() + .mockImplementation(async () => projectGraph), +})); + +describe('@nx/eslint:lint-project (convert to monorepo style)', () => { + let tree: Tree; + + const defaultOptions = { + skipFormat: false, + addPlugin: true, + }; + + beforeEach(() => { + tree = createTreeWithEmptyWorkspace(); + const rootpkg = { + root: '.', + projectType: 'library' as const, + targets: { + 'eslint:lint': { + executor: 'nx:run-commands', + options: { + command: 'eslint .', + }, + }, + }, + }; + projectGraph = { + nodes: { + rootpkg: { + type: 'lib', + name: 'rootpkg', + data: rootpkg, + }, + }, + dependencies: {}, + }; + addProjectConfiguration(tree, 'rootpkg', rootpkg); + tree.write( + '.eslintrc.cjs', + ` + module.exports = { + root: true, + env: { browser: true, es2020: true }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react-hooks/recommended', + ], + ignorePatterns: ['dist', '.eslintrc.cjs'], + parser: '@typescript-eslint/parser', + } + ` + ); + }); + + it('should generate a eslint config and configure the target in project configuration', async () => { + addProjectConfiguration(tree, 'nestedpkg', { + root: 'nestedpkg', + projectType: 'library', + targets: {}, + }); + + await lintProjectGenerator(tree, { + ...defaultOptions, + linter: Linter.EsLint, + project: 'nestedpkg', + setParserOptionsProject: false, + }); + + expect(readJson(tree, 'package.json')).toMatchObject({ + devDependencies: { + '@nx/eslint-plugin': expect.any(String), + }, + }); + }); +}); diff --git a/packages/eslint/src/generators/lint-project/lint-project.ts b/packages/eslint/src/generators/lint-project/lint-project.ts index dba6c0a9f4..a0f941dda2 100644 --- a/packages/eslint/src/generators/lint-project/lint-project.ts +++ b/packages/eslint/src/generators/lint-project/lint-project.ts @@ -1,16 +1,16 @@ import { createProjectGraphAsync, + formatFiles, GeneratorCallback, NxJsonConfiguration, + offsetFromRoot, ProjectConfiguration, ProjectGraph, - Tree, - readNxJson, - formatFiles, - offsetFromRoot, readJson, + readNxJson, readProjectConfiguration, runTasksInSerial, + Tree, updateJson, updateProjectConfiguration, writeJson, @@ -21,10 +21,7 @@ import { findEslintFile } from '../utils/eslint-file'; import { join } from 'path'; import { lintInitGenerator } from '../init/init'; import type { Linter } from 'eslint'; -import { - findLintTarget, - migrateConfigToMonorepoStyle, -} from '../init/init-migration'; +import { migrateConfigToMonorepoStyle } from '../init/init-migration'; import { getProjects } from 'nx/src/generators/utils/project-configuration'; import { useFlatConfig } from '../../utils/flat-config'; import { @@ -36,7 +33,6 @@ import { import { baseEsLintConfigFile, baseEsLintFlatConfigFile, - ESLINT_CONFIG_FILENAMES, } from '../../utils/config-file'; import { hasEslintPlugin } from '../utils/plugin'; import { setupRootEsLint } from './setup-root-eslint'; @@ -144,12 +140,13 @@ export async function lintProjectGeneratorInternal( filteredProjects.push(project); } }); - migrateConfigToMonorepoStyle( + const migrateTask = migrateConfigToMonorepoStyle( filteredProjects, tree, options.unitTestRunner, options.keepExistingVersions ); + tasks.push(migrateTask); } }