Skip to content

Commit

Permalink
fix: group files by config (closes xojs#599)
Browse files Browse the repository at this point in the history
  • Loading branch information
spence-s committed Oct 19, 2021
1 parent eefd88a commit ffc4823
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 43 deletions.
98 changes: 59 additions & 39 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'node:path';
import {ESLint} from 'eslint';
import {globby, isGitIgnoredSync} from 'globby';
import {isEqual} from 'lodash-es';
import {isEqual, groupBy} from 'lodash-es';
import micromatch from 'micromatch';
import arrify from 'arrify';
import slash from 'slash';
Expand All @@ -12,30 +12,6 @@ import {
} from './lib/options-manager.js';
import {mergeReports, processReport, getIgnoredReport} from './lib/report.js';

const runEslint = async (lint, options) => {
const {filePath, eslintOptions, isQuiet} = options;
const {cwd, baseConfig: {ignorePatterns}} = eslintOptions;

if (
filePath
&& (
micromatch.isMatch(path.relative(cwd, filePath), ignorePatterns)
|| isGitIgnoredSync({cwd, ignore: ignorePatterns})(filePath)
)
) {
return getIgnoredReport(filePath);
}

const eslint = new ESLint(eslintOptions);

if (filePath && await eslint.isPathIgnored(filePath)) {
return getIgnoredReport(filePath);
}

const report = await lint(eslint);
return processReport(report, {isQuiet});
};

const globFiles = async (patterns, options) => {
const {ignores, extensions, cwd} = (await mergeWithFileConfig(options)).options;

Expand All @@ -59,32 +35,76 @@ const getConfig = async options => {

const lintText = async (string, options) => {
options = await parseOptions(options);
const {filePath, warnIgnored, eslintOptions} = options;
const {ignorePatterns} = eslintOptions.baseConfig;
const {filePath, warnIgnored, eslintOptions, isQuiet} = options;
const {cwd, baseConfig: {ignorePatterns}} = eslintOptions;

if (typeof filePath !== 'string' && !isEqual(getIgnores({}), ignorePatterns)) {
throw new Error('The `ignores` option requires the `filePath` option to be defined.');
}

return runEslint(
eslint => eslint.lintText(string, {filePath, warnIgnored}),
options,
);
};
if (
filePath
&& (
micromatch.isMatch(path.relative(cwd, filePath), ignorePatterns)
|| isGitIgnoredSync({cwd, ignore: ignorePatterns})(filePath)
)
) {
return getIgnoredReport(filePath);
}

const lintFile = async (filePath, options) => runEslint(
eslint => eslint.lintFiles([filePath]),
await parseOptions({...options, filePath}),
);
const eslint = new ESLint(eslintOptions);

if (filePath && await eslint.isPathIgnored(filePath)) {
return getIgnoredReport(filePath);
}

const report = await eslint.lintText(string, {filePath, warnIgnored});
return processReport(report, {isQuiet});
};

const lintFiles = async (patterns, options) => {
const files = await globFiles(patterns, options);

const reports = await Promise.all(
files.map(filePath => lintFile(filePath, options)),
const allOptions = await Promise.all(
files.map(filePath => parseOptions({...options, filePath})),
);

const report = mergeReports(reports.filter(({isIgnored}) => !isIgnored));
// Files with same `xoConfigPath` can lint together
// https://github.com/xojs/xo/issues/599
const groups = groupBy(allOptions, 'xoConfigPath');

const reports = await Promise.all(
Object.values(groups)
.map(async filesWithOptions => {
const options = filesWithOptions[0];
const eslint = new ESLint(options.eslintOptions);
const files = [];

for (const options of filesWithOptions) {
const {filePath, eslintOptions} = options;
const {cwd, baseConfig: {ignorePatterns}} = eslintOptions;
if (filePath
&& (
micromatch.isMatch(path.relative(cwd, filePath), ignorePatterns)
|| isGitIgnoredSync({cwd, ignore: ignorePatterns})(filePath)
)) {
continue;
}

// eslint-disable-next-line no-await-in-loop
if ((await eslint.isPathIgnored(filePath))) {
continue;
}

files.push(filePath);
}

const report = await eslint.lintFiles(files);

return processReport(report, {isQuiet: options.isQuiet});
}));

const report = mergeReports(reports);

return report;
};
Expand Down
14 changes: 10 additions & 4 deletions lib/options-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,19 @@ const mergeWithFileConfig = async options => {

const searchPath = options.filePath || options.cwd;

const {config: xoOptions, filepath: xoConfigPath} = (await configExplorer.search(searchPath)) || {};
let {config: xoOptions, filepath: xoConfigPath} = (await configExplorer.search(searchPath)) || {};
const {config: enginesOptions} = (await pkgConfigExplorer.search(searchPath)) || {};

options = mergeOptions(options, xoOptions, enginesOptions);
options.cwd = xoConfigPath && path.dirname(xoConfigPath) !== options.cwd ? path.resolve(options.cwd, path.dirname(xoConfigPath)) : options.cwd;

if (options.filePath) {
({options} = applyOverrides(options.filePath, options));
const overrides = applyOverrides(options.filePath, options);
options = overrides.options;

if (overrides.hash) {
xoConfigPath += overrides.hash;
}
}

const prettierOptions = options.prettier ? await prettier.resolveConfig(searchPath, {editorconfig: true}) || {} : {};
Expand All @@ -132,7 +137,7 @@ const mergeWithFileConfig = async options => {
await fs.writeFile(options.tsConfigPath, JSON.stringify(config));
}

return {options, prettierOptions};
return {options, prettierOptions, xoConfigPath};
};

/**
Expand Down Expand Up @@ -538,13 +543,14 @@ const gatherImportResolvers = options => {

const parseOptions = async options => {
options = normalizeOptions(options);
const {options: foundOptions, prettierOptions} = await mergeWithFileConfig(options);
const {options: foundOptions, prettierOptions, xoConfigPath} = await mergeWithFileConfig(options);
const {filePath, warnIgnored, ...eslintOptions} = buildConfig(foundOptions, prettierOptions);
return {
filePath,
warnIgnored,
isQuiet: options.quiet,
eslintOptions,
xoConfigPath,
};
};

Expand Down

0 comments on commit ffc4823

Please sign in to comment.