Skip to content

Commit

Permalink
feat(linter): migrate to create-nodes-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
AgentEnder committed May 31, 2024
1 parent 1e7cd7e commit af48c90
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {
type TargetConfiguration,
type Tree,
} from '@nx/devkit';
import { createNodes, EslintPluginOptions } from '../../plugins/plugin';
import { migrateExecutorToPluginV1 } from '@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator';
import { createNodesV2, EslintPluginOptions } from '../../plugins/plugin';
import { migrateExecutorToPlugin } from '@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator';
import { targetOptionsToCliMap } from './lib/target-options-map';
import { interpolate } from 'nx/src/tasks-runner/utils';

Expand All @@ -19,26 +19,26 @@ export async function convertToInferred(tree: Tree, options: Schema) {
const projectGraph = await createProjectGraphAsync();

const migratedProjectsModern =
await migrateExecutorToPluginV1<EslintPluginOptions>(
await migrateExecutorToPlugin<EslintPluginOptions>(
tree,
projectGraph,
'@nx/eslint:lint',
'@nx/eslint/plugin',
(targetName) => ({ targetName }),
postTargetTransformer,
createNodes,
createNodesV2,
options.project
);

const migratedProjectsLegacy =
await migrateExecutorToPluginV1<EslintPluginOptions>(
await migrateExecutorToPlugin<EslintPluginOptions>(
tree,
projectGraph,
'@nrwl/linter:eslint',
'@nx/eslint/plugin',
(targetName) => ({ targetName }),
postTargetTransformer,
createNodes,
createNodesV2,
options.project
);

Expand Down
12 changes: 6 additions & 6 deletions packages/eslint/src/generators/init/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import {
Tree,
updateNxJson,
} from '@nx/devkit';
import { addPluginV1 } from '@nx/devkit/src/utils/add-plugin';
import { addPlugin } from '@nx/devkit/src/utils/add-plugin';
import { eslintVersion, nxVersion } from '../../utils/versions';
import { findEslintFile } from '../utils/eslint-file';
import { createNodes } from '../../plugins/plugin';
import { createNodesV2 } from '../../plugins/plugin';
import { hasEslintPlugin } from '../utils/plugin';

export interface LinterInitOptions {
Expand Down Expand Up @@ -73,11 +73,11 @@ export async function initEsLint(
];

if (rootEslintFile && options.addPlugin && !hasPlugin) {
await addPluginV1(
await addPlugin(
tree,
graph,
'@nx/eslint/plugin',
createNodes,
createNodesV2,
{
targetName: lintTargetNames,
},
Expand All @@ -94,11 +94,11 @@ export async function initEsLint(
updateProductionFileset(tree);

if (options.addPlugin) {
await addPluginV1(
await addPlugin(
tree,
graph,
'@nx/eslint/plugin',
createNodes,
createNodesV2,
{
targetName: lintTargetNames,
},
Expand Down
97 changes: 54 additions & 43 deletions packages/eslint/src/plugins/plugin.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { CreateNodesContext } from '@nx/devkit';
import { CreateNodesContextV2 } from '@nx/devkit';
import { minimatch } from 'minimatch';
import { TempFs } from 'nx/src/internal-testing-utils/temp-fs';
import { createNodes } from './plugin';
import { createNodesV2 } from './plugin';
import { mkdirSync, rmdirSync } from 'fs';

jest.mock('nx/src/utils/cache-directory', () => ({
...jest.requireActual('nx/src/utils/cache-directory'),
projectGraphCacheDirectory: 'tmp/project-graph-cache',
}));

describe('@nx/eslint/plugin', () => {
let context: CreateNodesContext;
let context: CreateNodesContextV2;
let tempFs: TempFs;
let configFiles: string[] = [];

beforeEach(async () => {
mkdirSync('tmp/project-graph-cache', { recursive: true });
tempFs = new TempFs('eslint-plugin');
context = {
nxJsonConfiguration: {
Expand All @@ -24,22 +32,22 @@ describe('@nx/eslint/plugin', () => {
},
},
workspaceRoot: tempFs.tempDir,
configFiles: [],
};
});

afterEach(() => {
jest.resetModules();
tempFs.cleanup();
tempFs = null;
rmdirSync('tmp/project-graph-cache', { recursive: true });
});

it('should not create any nodes when there are no eslint configs', async () => {
createFiles({
'package.json': `{}`,
'project.json': `{}`,
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {},
Expand All @@ -53,7 +61,7 @@ describe('@nx/eslint/plugin', () => {
'.eslintrc.json': `{}`,
'package.json': `{}`,
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {},
Expand All @@ -70,7 +78,7 @@ describe('@nx/eslint/plugin', () => {
'project.json': `{}`,
});
// NOTE: It should set ESLINT_USE_FLAT_CONFIG to true because of the use of eslint.config.js
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {},
Expand All @@ -86,7 +94,7 @@ describe('@nx/eslint/plugin', () => {
'src/index.ts': `console.log('hello world')`,
});
// NOTE: The command is specifically targeting the src directory in the case of a standalone Nx workspace
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {
Expand Down Expand Up @@ -127,7 +135,7 @@ describe('@nx/eslint/plugin', () => {
'lib/index.ts': `console.log('hello world')`,
});
// NOTE: The command is specifically targeting the src directory in the case of a standalone Nx workspace
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {
Expand Down Expand Up @@ -169,7 +177,7 @@ describe('@nx/eslint/plugin', () => {
'src/index.ts': `console.log('hello world')`,
});
// NOTE: The command is specifically targeting the src directory in the case of a standalone Nx workspace
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {},
Expand All @@ -184,7 +192,7 @@ describe('@nx/eslint/plugin', () => {
'src/index.ts': `console.log('hello world')`,
});
// NOTE: The command is specifically targeting the src directory in the case of a standalone Nx workspace
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {},
Expand All @@ -199,7 +207,7 @@ describe('@nx/eslint/plugin', () => {
// This file is lintable so create the target
'apps/my-app/index.ts': `console.log('hello world')`,
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {
Expand Down Expand Up @@ -240,7 +248,7 @@ describe('@nx/eslint/plugin', () => {
// This file is lintable so create the target
'apps/my-app/index.ts': `console.log('hello world')`,
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {
Expand Down Expand Up @@ -285,7 +293,7 @@ describe('@nx/eslint/plugin', () => {
'apps/my-app/config-one.yaml': `...`,
'apps/my-app/config-two.yml': `...`,
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {},
Expand All @@ -304,7 +312,7 @@ describe('@nx/eslint/plugin', () => {
'apps/my-app/config-one.yaml': `...`,
'apps/my-app/config-two.yml': `...`,
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {},
Expand All @@ -319,7 +327,7 @@ describe('@nx/eslint/plugin', () => {
// This file is lintable so create the target
'apps/my-app/index.ts': `console.log('hello world')`,
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {},
Expand All @@ -334,7 +342,7 @@ describe('@nx/eslint/plugin', () => {
// This file is lintable so create the target
'apps/my-app/index.ts': `console.log('hello world')`,
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {},
Expand All @@ -353,7 +361,7 @@ describe('@nx/eslint/plugin', () => {
'libs/my-lib/project.json': `{}`,
'libs/my-lib/index.ts': `console.log('hello world')`,
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {
Expand Down Expand Up @@ -423,7 +431,7 @@ describe('@nx/eslint/plugin', () => {
'libs/my-lib/project.json': `{}`,
'libs/my-lib/index.ts': `console.log('hello world')`,
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {},
Expand All @@ -440,7 +448,7 @@ describe('@nx/eslint/plugin', () => {
'libs/my-lib/project.json': `{}`,
'libs/my-lib/index.ts': `console.log('hello world')`,
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {},
Expand All @@ -462,7 +470,7 @@ describe('@nx/eslint/plugin', () => {
'libs/my-lib/index.ts': `console.log('hello world')`,
});
// NOTE: The nested projects have the root level config as an input to their lint targets
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {
Expand Down Expand Up @@ -531,7 +539,7 @@ describe('@nx/eslint/plugin', () => {
'apps/myapp/index.ts': 'console.log("hello world")',
});
// NOTE: The nested projects have the root level config as an input to their lint targets
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {
Expand Down Expand Up @@ -579,7 +587,7 @@ describe('@nx/eslint/plugin', () => {
'apps/myapp/nested/mylib/project.json': '{}',
'apps/myapp/nested/mylib/index.ts': 'console.log("hello world")',
});
expect(await invokeCreateNodesOnMatchingFiles(context, 'lint'))
expect(await invokeCreateNodesV2OnMatchingFiles(context, 'lint'))
.toMatchInlineSnapshot(`
{
"projects": {
Expand Down Expand Up @@ -617,27 +625,30 @@ describe('@nx/eslint/plugin', () => {

function createFiles(fileSys: Record<string, string>) {
tempFs.createFilesSync(fileSys);
// @ts-expect-error update otherwise readonly property for testing
context.configFiles = getMatchingFiles(Object.keys(fileSys));
configFiles = getMatchingFiles(Object.keys(fileSys));
}
});

function getMatchingFiles(allConfigFiles: string[]): string[] {
return allConfigFiles.filter((file) =>
minimatch(file, createNodes[0], { dot: true })
);
}
function getMatchingFiles(allConfigFiles: string[]): string[] {
return allConfigFiles.filter((file) =>
minimatch(file, createNodesV2[0], { dot: true })
);
}

async function invokeCreateNodesOnMatchingFiles(
context: CreateNodesContext,
targetName: string
) {
const aggregateProjects: Record<string, any> = {};
for (const file of context.configFiles) {
const nodes = await createNodes[1](file, { targetName }, context);
Object.assign(aggregateProjects, nodes.projects);
async function invokeCreateNodesV2OnMatchingFiles(
context: CreateNodesContextV2,
targetName: string
) {
const aggregateProjects: Record<string, any> = {};
const results = await createNodesV2[1](
configFiles,
{ targetName },
context
);
for (const [, nodes] of results) {
Object.assign(aggregateProjects, nodes.projects);
}
return {
projects: aggregateProjects,
};
}
return {
projects: aggregateProjects,
};
}
});
Loading

0 comments on commit af48c90

Please sign in to comment.