2023-08-01 16:20:17 -03:00
|
|
|
#!node
|
2023-08-03 14:19:00 -03:00
|
|
|
import path from 'node:path';
|
2023-08-01 16:20:17 -03:00
|
|
|
import { createSpinner } from 'nanospinner';
|
|
|
|
|
import glob from 'picomatch';
|
|
|
|
|
import c from 'picocolors';
|
2023-08-01 16:55:49 -03:00
|
|
|
import Workspace from './workspace.js';
|
2023-08-01 16:20:17 -03:00
|
|
|
|
|
|
|
|
export default class Cli {
|
|
|
|
|
/** @type {string} */
|
|
|
|
|
dir = process.cwd();
|
|
|
|
|
|
|
|
|
|
/** @type {import('./types').Config[]} */
|
|
|
|
|
configs;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {{
|
|
|
|
|
* configs: import('./types').Config[]
|
|
|
|
|
* packages?: string[],
|
2023-08-03 14:19:00 -03:00
|
|
|
* workspace?: import('./types').Package[],
|
2023-08-01 16:20:17 -03:00
|
|
|
* directory?: string,
|
|
|
|
|
* debug?: boolean,
|
|
|
|
|
* }} options - Cli options
|
|
|
|
|
*/
|
|
|
|
|
constructor(options) {
|
|
|
|
|
this.configs = options?.configs;
|
|
|
|
|
this.dir = path.normalize(options.directory ?? this.dir);
|
|
|
|
|
this.debug = options.debug ?? this.debug;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {import('./types').Package} pkg - Package to detect from
|
|
|
|
|
* @param {import('./types').Config['options']} options - Options to be passed
|
|
|
|
|
* @param {boolean} single - Whether to only detect one option
|
|
|
|
|
* @param {import('nanospinner').Spinner} spinner - Spinner to update
|
|
|
|
|
* @returns {string[]} - The detected options
|
|
|
|
|
*/
|
|
|
|
|
detectOptions(pkg, options, single, spinner) {
|
|
|
|
|
|
|
|
|
|
/** @type {string[]} */
|
|
|
|
|
const detectedOptions = [];
|
|
|
|
|
|
|
|
|
|
for (const option of options) {
|
|
|
|
|
|
|
|
|
|
spinner.update({
|
|
|
|
|
text: `Configuring ${c.bold(c.blue(pkg.name))}${c.dim(`: option ${c.bold(option.name)}`)}`,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (option.detect === true) {
|
|
|
|
|
detectedOptions.push(option.name);
|
|
|
|
|
spinner.update({
|
|
|
|
|
text: `Configuring ${c.bold(c.blue(pkg.name))}${c.dim(`: option ${c.bold(option.name)} ${c.green('✓')}`)}`,
|
|
|
|
|
});
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (!option.detect) continue;
|
|
|
|
|
|
2023-08-03 14:19:00 -03:00
|
|
|
const match = glob(option.detect);
|
2023-08-01 16:20:17 -03:00
|
|
|
|
|
|
|
|
const files = pkg.files.filter(f => match ? match(f) : false);
|
|
|
|
|
const directories = pkg.directories.filter(f => match ? match(f) : false);
|
|
|
|
|
|
|
|
|
|
if (files.length > 0 || directories.length > 0) {
|
|
|
|
|
detectedOptions.push(option.name);
|
|
|
|
|
spinner.update({
|
|
|
|
|
text: `Configuring ${c.bold(c.blue(pkg.name))}${c.dim(`: option ${c.bold(option.name)} ${c.green('✔')}`)}`,
|
|
|
|
|
});
|
|
|
|
|
if (single) break;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
spinner.update({
|
|
|
|
|
text: `Configuring ${c.bold(c.blue(pkg.name))}${c.dim(`: option ${c.bold(option.name)} ${c.red('✖')}`)}`,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return detectedOptions;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-03 10:55:56 -03:00
|
|
|
/**
|
|
|
|
|
* @param {import('./types').Package} pkg - The package to detect configs
|
|
|
|
|
* @returns {import('./types').Package['config']} - Detected configs record
|
|
|
|
|
*/
|
|
|
|
|
detectConfig(pkg) {
|
|
|
|
|
|
|
|
|
|
const spinner = createSpinner(`Configuring ${c.bold(c.blue(pkg.name))}`);
|
|
|
|
|
spinner.start();
|
|
|
|
|
|
|
|
|
|
/** @type {import('./types').Package['config']} */
|
|
|
|
|
const pkgConfig = {};
|
|
|
|
|
|
|
|
|
|
for (const config of this.configs) {
|
|
|
|
|
pkgConfig[config.name] = this.detectOptions(
|
|
|
|
|
pkg,
|
|
|
|
|
config.options,
|
|
|
|
|
config.type === 'single',
|
|
|
|
|
spinner,
|
|
|
|
|
);
|
|
|
|
|
spinner.update({ text: `Configuring ${c.bold(c.blue(pkg.name))}${c.dim(`: config ${config.name}`)}` });
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-03 14:19:00 -03:00
|
|
|
spinner.success({ text: `Configuring ${c.bold(c.blue(pkg.name))}\n${c.dim(JSON.stringify(pkgConfig))}\n` });
|
2023-08-03 10:55:56 -03:00
|
|
|
return pkgConfig;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-01 16:20:17 -03:00
|
|
|
async run() {
|
2023-08-03 14:19:00 -03:00
|
|
|
let packages = await new Workspace(this.dir).getPackages();
|
2023-08-01 16:20:17 -03:00
|
|
|
|
2023-08-03 14:19:00 -03:00
|
|
|
packages = packages.map(
|
2023-08-01 16:20:17 -03:00
|
|
|
pkg => {
|
|
|
|
|
pkg.config = this.detectConfig(pkg); return pkg;
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
2023-08-03 14:19:00 -03:00
|
|
|
console.log(packages);
|
2023-08-01 16:20:17 -03:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|