<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
181 lines
4.7 KiB
TypeScript
181 lines
4.7 KiB
TypeScript
import {
|
|
createProjectGraphAsync,
|
|
formatFiles,
|
|
names,
|
|
type TargetConfiguration,
|
|
type Tree,
|
|
} from '@nx/devkit';
|
|
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';
|
|
import {
|
|
processTargetOutputs,
|
|
toProjectRelativePath,
|
|
} from '@nx/devkit/src/generators/plugin-migrations/plugin-migration-utils';
|
|
|
|
interface Schema {
|
|
project?: string;
|
|
skipFormat?: boolean;
|
|
}
|
|
|
|
export async function convertToInferred(tree: Tree, options: Schema) {
|
|
const projectGraph = await createProjectGraphAsync();
|
|
|
|
const migratedProjectsModern =
|
|
await migrateExecutorToPlugin<EslintPluginOptions>(
|
|
tree,
|
|
projectGraph,
|
|
'@nx/eslint:lint',
|
|
'@nx/eslint/plugin',
|
|
(targetName) => ({ targetName }),
|
|
postTargetTransformer,
|
|
createNodesV2,
|
|
options.project
|
|
);
|
|
|
|
const migratedProjectsLegacy =
|
|
await migrateExecutorToPlugin<EslintPluginOptions>(
|
|
tree,
|
|
projectGraph,
|
|
'@nrwl/linter:eslint',
|
|
'@nx/eslint/plugin',
|
|
(targetName) => ({ targetName }),
|
|
postTargetTransformer,
|
|
createNodesV2,
|
|
options.project
|
|
);
|
|
|
|
const migratedProjects =
|
|
migratedProjectsModern.size + migratedProjectsLegacy.size;
|
|
if (migratedProjects === 0) {
|
|
throw new Error('Could not find any targets to migrate.');
|
|
}
|
|
|
|
if (!options.skipFormat) {
|
|
await formatFiles(tree);
|
|
}
|
|
}
|
|
|
|
function postTargetTransformer(
|
|
target: TargetConfiguration,
|
|
tree: Tree,
|
|
projectDetails: { projectName: string; root: string },
|
|
inferredTargetConfiguration: TargetConfiguration
|
|
): TargetConfiguration {
|
|
if (target.inputs) {
|
|
const inputs = target.inputs.filter(
|
|
(input) =>
|
|
typeof input === 'string' &&
|
|
![
|
|
'default',
|
|
'{workspaceRoot}/.eslintrc.json',
|
|
'{workspaceRoot}/.eslintignore',
|
|
'{workspaceRoot}/eslint.config.js',
|
|
].includes(input)
|
|
);
|
|
if (inputs.length === 0) {
|
|
delete target.inputs;
|
|
}
|
|
}
|
|
|
|
if (target.options) {
|
|
handlePropertiesInOptions(target.options, projectDetails, target);
|
|
}
|
|
|
|
if (target.configurations) {
|
|
for (const configurationName in target.configurations) {
|
|
const configuration = target.configurations[configurationName];
|
|
handlePropertiesInOptions(configuration, projectDetails, target);
|
|
}
|
|
|
|
if (Object.keys(target.configurations).length !== 0) {
|
|
for (const configuration in target.configurations) {
|
|
if (Object.keys(target.configurations[configuration]).length === 0) {
|
|
delete target.configurations[configuration];
|
|
}
|
|
}
|
|
if (Object.keys(target.configurations).length === 0) {
|
|
delete target.configurations;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (target.outputs) {
|
|
processTargetOutputs(target, [], inferredTargetConfiguration, {
|
|
projectName: projectDetails.projectName,
|
|
projectRoot: projectDetails.root,
|
|
});
|
|
}
|
|
|
|
return target;
|
|
}
|
|
|
|
function handlePropertiesInOptions(
|
|
options: Record<string, any>,
|
|
projectDetails: { projectName: string; root: string },
|
|
target: TargetConfiguration
|
|
) {
|
|
if ('eslintConfig' in options) {
|
|
options.config = toProjectRelativePath(
|
|
options.eslintConfig,
|
|
projectDetails.root
|
|
);
|
|
delete options.eslintConfig;
|
|
}
|
|
|
|
if ('force' in options) {
|
|
delete options.force;
|
|
}
|
|
|
|
if ('silent' in options) {
|
|
delete options.silent;
|
|
}
|
|
|
|
if ('hasTypeAwareRules' in options) {
|
|
delete options.hasTypeAwareRules;
|
|
}
|
|
|
|
if ('errorOnUnmatchedPattern' in options) {
|
|
if (!options.errorOnUnmatchedPattern) {
|
|
options['no-error-on-unmatched-pattern'] = true;
|
|
}
|
|
delete options.errorOnUnmatchedPattern;
|
|
}
|
|
|
|
if ('outputFile' in options) {
|
|
target.outputs ??= [];
|
|
target.outputs.push(options.outputFile);
|
|
}
|
|
|
|
for (const key in targetOptionsToCliMap) {
|
|
if (options[key]) {
|
|
const prevValue = options[key];
|
|
delete options[key];
|
|
options[targetOptionsToCliMap[key]] = prevValue;
|
|
}
|
|
}
|
|
|
|
if ('lintFilePatterns' in options) {
|
|
const normalizedLintFilePatterns = options.lintFilePatterns.map(
|
|
(pattern) => {
|
|
return interpolate(pattern, {
|
|
workspaceRoot: '',
|
|
projectRoot: projectDetails.root,
|
|
projectName: projectDetails.projectName,
|
|
});
|
|
}
|
|
);
|
|
|
|
options.args = normalizedLintFilePatterns.map((pattern) =>
|
|
pattern.startsWith(projectDetails.root)
|
|
? pattern.replace(new RegExp(`^${projectDetails.root}/`), './')
|
|
: pattern
|
|
);
|
|
|
|
delete options.lintFilePatterns;
|
|
}
|
|
}
|
|
|
|
export default convertToInferred;
|