rock
Version:
Command-line interface for Rock - a React Native development toolkit
101 lines • 4.02 kB
JavaScript
import { createRequire } from 'node:module';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { getConfig } from '@rock-js/config';
import { colorLink, logger, resolveFilenameUp, RockError, } from '@rock-js/tools';
import { Command } from 'commander';
import { checkDeprecatedOptions } from './checkDeprecatedOptions.js';
import { cleanPlugin } from './plugins/clean.js';
import { fingerprintPlugin } from './plugins/fingerprint.js';
import { logConfigPlugin } from './plugins/logConfig.js';
import { remoteCachePlugin } from './plugins/remoteCache.js';
const require = createRequire(import.meta.url);
const __dirname = dirname(fileURLToPath(import.meta.url));
const { version } = require(resolveFilenameUp(__dirname, 'package.json'));
export const cli = async ({ cwd, argv }) => {
if (argv) {
logger.setVerbose(argv.includes('--verbose'));
checkDeprecatedOptions(argv);
}
const program = new Command();
program
.name('rock')
.description('Rock CLI.')
.option('--verbose', 'enable verbose logging')
.version(version);
const internalPlugins = [
remoteCachePlugin,
logConfigPlugin,
fingerprintPlugin,
cleanPlugin,
];
// Register commands from the config
const config = await getConfig(cwd, internalPlugins);
ensureUniqueCommands(config.commands);
config.commands?.forEach((command) => {
const cmd = program
.command(command.name)
.description(command.description || '')
.action(async (...args) => {
try {
await command.action(...args);
}
catch (error) {
if (error instanceof RockError) {
if (logger.isVerbose()) {
logger.error(error);
}
else {
logger.error(error.message);
if (error.cause) {
logger.error(`Cause: ${error.cause}`);
}
}
}
else {
logger.error(`Unexpected error while running "${command.name}":`, error);
}
process.exit(1);
}
});
// Positional args
for (const arg of command.args || []) {
cmd.argument(arg.name, arg.description, arg.default);
}
// Flags
for (const opt of command.options || []) {
// Note: we cannot use default idempotent parse, as it prevents us from using variadic options.
if (opt.parse) {
cmd.option(opt.name, opt.description, opt.parse, opt.default);
}
else {
cmd.option(opt.name, opt.description, opt.default);
}
}
});
await program.parseAsync(argv);
};
function ensureUniqueCommands(commands) {
if (!commands)
return;
const commandNames = new Map();
for (const command of commands) {
if (commandNames.has(command.name)) {
const duplicate = commandNames.get(command.name);
const samePluginTwice = command.__origin === duplicate.__origin;
if (samePluginTwice) {
logger.error(`Found duplicated command "${command.name}" registered twice by the same "${command.__origin}" plugin in ${colorLink('rock.config.mjs')} file.
Please declare the plugin only once.`);
}
else {
logger.error(`Found duplicated command "${command.name}" registered by 2 plugins in ${colorLink('rock.config.mjs')} file:
1. Added by "${command.__origin}" plugin
2. Added by "${duplicate.__origin}" plugin
Command names must be unique. Please check if you import a plugin multiple times or use incompatible plugins.`);
}
process.exit(1);
}
commandNames.set(command.name, command);
}
}
//# sourceMappingURL=cli.js.map