feat(linter): Support --print-config feature of ESLint (#18260)
This commit is contained in:
parent
554bea7a4c
commit
30c3e9925a
@ -128,6 +128,11 @@
|
||||
"type": "string",
|
||||
"enum": ["off", "warn", "error"],
|
||||
"description": "The equivalent of the `--report-unused-disable-directives` flag on the ESLint CLI."
|
||||
},
|
||||
"printConfig": {
|
||||
"type": "string",
|
||||
"description": "The equivalent of the `--print-config` flag on the ESLint CLI.",
|
||||
"x-completion-type": "file"
|
||||
}
|
||||
},
|
||||
"required": ["lintFilePatterns"],
|
||||
|
||||
@ -246,6 +246,21 @@ describe('Linter', () => {
|
||||
'A project tagged with "validtag" can only depend on libs tagged with "validtag"'
|
||||
);
|
||||
}, 1000000);
|
||||
|
||||
it('should print the effective configuration for a file specified using --printConfig', () => {
|
||||
const eslint = readJson('.eslintrc.json');
|
||||
eslint.overrides.push({
|
||||
files: ['src/index.ts'],
|
||||
rules: {
|
||||
'specific-rule': 'off',
|
||||
},
|
||||
});
|
||||
updateFile('.eslintrc.json', JSON.stringify(eslint, null, 2));
|
||||
const out = runCLI(`lint ${myapp} --printConfig src/index.ts`, {
|
||||
silenceError: true,
|
||||
});
|
||||
expect(out).toContain('"specific-rule": [');
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
describe('workspace boundary rules', () => {
|
||||
|
||||
@ -25,6 +25,9 @@ class MockESLint {
|
||||
loadFormatter = mockLoadFormatter;
|
||||
isPathIgnored = mockIsPathIgnored;
|
||||
lintFiles = mockLintFiles;
|
||||
calculateConfigForFile(file: string) {
|
||||
return { file: file };
|
||||
}
|
||||
}
|
||||
|
||||
const mockResolveAndInstantiateESLint = jest.fn().mockReturnValue(
|
||||
@ -65,6 +68,7 @@ function createValidRunBuilderOptions(
|
||||
rulesdir: [],
|
||||
resolvePluginsRelativeTo: null,
|
||||
reportUnusedDisableDirectives: null,
|
||||
printConfig: null,
|
||||
...additionalOptions,
|
||||
};
|
||||
}
|
||||
@ -619,4 +623,30 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this
|
||||
);
|
||||
expect(fs.writeFileSync).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should print the ESLint configuration for a specified file if printConfiguration is specified', async () => {
|
||||
setupMocks();
|
||||
jest.spyOn(console, 'log');
|
||||
const result = await lintExecutor(
|
||||
createValidRunBuilderOptions({
|
||||
lintFilePatterns: [],
|
||||
eslintConfig: './.eslintrc.json',
|
||||
fix: true,
|
||||
cache: true,
|
||||
cacheLocation: 'cacheLocation1',
|
||||
format: 'stylish',
|
||||
force: false,
|
||||
silent: false,
|
||||
ignorePath: null,
|
||||
maxWarnings: null,
|
||||
outputFile: null,
|
||||
quiet: false,
|
||||
reportUnusedDisableDirectives: null,
|
||||
printConfig: 'test-source.ts',
|
||||
}),
|
||||
mockContext
|
||||
);
|
||||
expect(console.log).toHaveBeenCalledWith('{\n "file": "test-source.ts"\n}');
|
||||
expect(result).toEqual({ success: true });
|
||||
});
|
||||
});
|
||||
|
||||
@ -39,6 +39,8 @@ export default async function run(
|
||||
? join(options.cacheLocation, projectName)
|
||||
: undefined;
|
||||
|
||||
const { printConfig, ...normalizedOptions } = options;
|
||||
|
||||
/**
|
||||
* Until ESLint v9 is released and the new so called flat config is the default
|
||||
* we only want to support it if the user has explicitly opted into it by converting
|
||||
@ -49,7 +51,7 @@ export default async function run(
|
||||
);
|
||||
const { eslint, ESLint } = await resolveAndInstantiateESLint(
|
||||
eslintConfigPath,
|
||||
options,
|
||||
normalizedOptions,
|
||||
useFlatConfig
|
||||
);
|
||||
|
||||
@ -63,10 +65,25 @@ export default async function run(
|
||||
throw new Error('ESLint must be version 7.6 or higher.');
|
||||
}
|
||||
|
||||
if (printConfig) {
|
||||
try {
|
||||
const fileConfig = await eslint.calculateConfigForFile(printConfig);
|
||||
console.log(JSON.stringify(fileConfig, null, ' '));
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return {
|
||||
success: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let lintResults: ESLint.LintResult[] = [];
|
||||
|
||||
try {
|
||||
lintResults = await eslint.lintFiles(options.lintFilePatterns);
|
||||
lintResults = await eslint.lintFiles(normalizedOptions.lintFilePatterns);
|
||||
} catch (err) {
|
||||
if (
|
||||
err.message.includes(
|
||||
@ -98,7 +115,7 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this
|
||||
if (lintResults.length === 0) {
|
||||
const ignoredPatterns = (
|
||||
await Promise.all(
|
||||
options.lintFilePatterns.map(async (pattern) =>
|
||||
normalizedOptions.lintFilePatterns.map(async (pattern) =>
|
||||
(await eslint.isPathIgnored(pattern)) ? pattern : null
|
||||
)
|
||||
)
|
||||
@ -121,12 +138,12 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this
|
||||
await ESLint.outputFixes(lintResults);
|
||||
|
||||
// if quiet, only show errors
|
||||
if (options.quiet) {
|
||||
if (normalizedOptions.quiet) {
|
||||
console.debug('Quiet mode enabled - filtering out warnings\n');
|
||||
lintResults = ESLint.getErrorResults(lintResults);
|
||||
}
|
||||
|
||||
const formatter = await eslint.loadFormatter(options.format);
|
||||
const formatter = await eslint.loadFormatter(normalizedOptions.format);
|
||||
|
||||
let totalErrors = 0;
|
||||
let totalWarnings = 0;
|
||||
@ -140,8 +157,8 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this
|
||||
|
||||
const formattedResults = await formatter.format(lintResults);
|
||||
|
||||
if (options.outputFile) {
|
||||
const pathToOutputFile = join(context.root, options.outputFile);
|
||||
if (normalizedOptions.outputFile) {
|
||||
const pathToOutputFile = join(context.root, normalizedOptions.outputFile);
|
||||
mkdirSync(dirname(pathToOutputFile), { recursive: true });
|
||||
writeFileSync(pathToOutputFile, formattedResults);
|
||||
} else {
|
||||
@ -162,8 +179,9 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this
|
||||
|
||||
return {
|
||||
success:
|
||||
options.force ||
|
||||
normalizedOptions.force ||
|
||||
(totalErrors === 0 &&
|
||||
(options.maxWarnings === -1 || totalWarnings <= options.maxWarnings)),
|
||||
(normalizedOptions.maxWarnings === -1 ||
|
||||
totalWarnings <= normalizedOptions.maxWarnings)),
|
||||
};
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ export interface Schema extends JsonObject {
|
||||
rulesdir: string[];
|
||||
resolvePluginsRelativeTo: string | null;
|
||||
reportUnusedDisableDirectives: Linter.RuleLevel | null;
|
||||
printConfig?: string | null;
|
||||
}
|
||||
|
||||
type Formatter =
|
||||
|
||||
@ -132,6 +132,11 @@
|
||||
"type": "string",
|
||||
"enum": ["off", "warn", "error"],
|
||||
"description": "The equivalent of the `--report-unused-disable-directives` flag on the ESLint CLI."
|
||||
},
|
||||
"printConfig": {
|
||||
"type": "string",
|
||||
"description": "The equivalent of the `--print-config` flag on the ESLint CLI.",
|
||||
"x-completion-type": "file"
|
||||
}
|
||||
},
|
||||
"required": ["lintFilePatterns"],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user