feat: ✨ merge configurations to root config
This commit is contained in:
@@ -6,6 +6,7 @@ import c from 'picocolors';
|
||||
import path from 'node:path';
|
||||
import { createSpinner } from 'nanospinner';
|
||||
import count from './lib/count.js';
|
||||
import prompts from 'prompts';
|
||||
|
||||
export default class Cli {
|
||||
|
||||
@@ -54,12 +55,29 @@ export default class Cli {
|
||||
return pkg;
|
||||
});
|
||||
|
||||
spinner.success({ text:
|
||||
'Detecting workspace configuration ' +
|
||||
c.dim(`${count.packagesWithConfigs(packages)} configs founded`),
|
||||
spinner.success({
|
||||
text:
|
||||
'Detecting workspace configuration ' +
|
||||
c.dim(`${count.packagesWithConfigs(packages)} configs founded\n`),
|
||||
});
|
||||
|
||||
packages = await processor.questionConfig(packages, configs.filter(c => c.manual));
|
||||
const merge = this.args.mergeToRoot ?? packages.length > 1 ?
|
||||
/** @type {{merge: boolean}} */
|
||||
(await prompts({
|
||||
name: 'merge',
|
||||
message:
|
||||
`Would you like to merge all configuration files into one root ${c.blue('eslint.config.js?')}` +
|
||||
c.italic(c.dim('\nAll configurations will be applied to the entire workspace and packages')),
|
||||
initial: true,
|
||||
type: 'confirm',
|
||||
})).merge : true;
|
||||
|
||||
console.log(c.dim('\nPlease select which options you prefer\n'));
|
||||
|
||||
packages = await processor.questionConfig(
|
||||
merge ? workspace.mergePackages(packages) : packages,
|
||||
configs.filter(c => c.manual),
|
||||
);
|
||||
|
||||
const configsMaps = processor.generateConfigMap(packages);
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
*/
|
||||
function packagesWithConfigs(packages) {
|
||||
return packages.map(p =>
|
||||
Object.entries(p.config ?? {})
|
||||
.filter(([, options]) => options.length > 0).length,
|
||||
[...p.config?.values() ?? []].filter((options) => options.length > 0).length,
|
||||
).reduce((partial, sum) => partial + sum, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,8 @@ export default class Workspace {
|
||||
|
||||
/**
|
||||
* @param {string} directory - The directory to get the workspace from
|
||||
* @param {string[]} [packagePatterns] - List of package patterns
|
||||
* @param {string[] | false} [packagePatterns]
|
||||
* List of package patterns (`false` to explicitly tell that this workspace is not a monorepo)
|
||||
*/
|
||||
constructor(directory, packagePatterns) {
|
||||
this.dir = directory;
|
||||
@@ -157,8 +158,6 @@ export default class Workspace {
|
||||
async getPackages() {
|
||||
|
||||
const paths = await this.getPaths();
|
||||
const packagePatterns = this.packagePatterns ?? await this.getPackagePatterns();
|
||||
const packagePaths = paths.directories.filter(d => picomatch.isMatch(d, packagePatterns));
|
||||
|
||||
/** @type {import('./types').Package} */
|
||||
const rootPackage = {
|
||||
@@ -169,6 +168,11 @@ export default class Workspace {
|
||||
directories: paths.directories,
|
||||
};
|
||||
|
||||
if (this.packagePatterns === false) return [rootPackage];
|
||||
|
||||
const packagePatterns = this.packagePatterns ?? await this.getPackagePatterns();
|
||||
const packagePaths = paths.directories.filter(d => picomatch.isMatch(d, packagePatterns));
|
||||
|
||||
/** @type {import('./types').Package[]} */
|
||||
const packages = [];
|
||||
|
||||
@@ -196,4 +200,48 @@ export default class Workspace {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./types').Package[]} packages - Packages to be merged into root
|
||||
* @returns {[import('./types').Package]} A array containing only the root package
|
||||
*/
|
||||
mergePackages(packages) {
|
||||
|
||||
const rootPackage = packages.find(p => p.root) ?? packages[0];
|
||||
|
||||
const merged = packages.reduce((accumulated, pkg) => {
|
||||
|
||||
const files = [...new Set([
|
||||
...accumulated.files,
|
||||
...pkg.files.map(f => join(pkg.path, f)),
|
||||
]
|
||||
.map(p => p.replace(`${rootPackage.path}/`, '')),
|
||||
)];
|
||||
|
||||
const directories = [...new Set([
|
||||
...accumulated.directories,
|
||||
...pkg.directories.map(d => join(pkg.path, d)),
|
||||
]
|
||||
.map(p => p.replace(`${rootPackage.path}/`, ''))),
|
||||
];
|
||||
|
||||
const mergedConfig = new Map();
|
||||
for (const [config, options] of pkg.config ?? []) {
|
||||
const accumulatedOptions = accumulated.config?.get(config) ?? [];
|
||||
mergedConfig.set(config, [...new Set([...options, ...accumulatedOptions])]);
|
||||
}
|
||||
|
||||
return {
|
||||
root: true,
|
||||
path: rootPackage.path,
|
||||
name: rootPackage.name,
|
||||
files,
|
||||
directories,
|
||||
config: mergedConfig,
|
||||
};
|
||||
}, rootPackage);
|
||||
|
||||
return [merged];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user