Colum Ferry f8ffc05e8d
fix(bundling): convert to inferred should handle config file (#26619)
<!-- 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 #
2024-06-21 11:32:04 -04:00

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;