import {BaseContext, Builtins, Cli} from 'clipanion'; import type {UsageError} from 'clipanion'; import {version as corepackVersion} from '../package.json'; import {Engine, PackageManagerRequest} from './Engine'; import {CacheCommand} from './commands/Cache'; import {DisableCommand} from './commands/Disable'; import {EnableCommand} from './commands/Enable'; import {InstallGlobalCommand} from './commands/InstallGlobal'; import {InstallLocalCommand} from './commands/InstallLocal'; import {PackCommand} from './commands/Pack'; import {UpCommand} from './commands/Up'; import {UseCommand} from './commands/Use'; import {HydrateCommand} from './commands/deprecated/Hydrate'; import {PrepareCommand} from './commands/deprecated/Prepare'; export type CustomContext = {cwd: string, engine: Engine}; export type Context = BaseContext & CustomContext; function getPackageManagerRequestFromCli(parameter: string | undefined, engine: Engine): PackageManagerRequest | null { if (!parameter) return null; const match = parameter.match(/^([^@]*)(?:@(.*))?$/); if (!match) return null; const [, binaryName, binaryVersion] = match; const packageManager = engine.getPackageManagerFor(binaryName)!; if (packageManager == null && binaryVersion == null) return null; return { packageManager, binaryName, binaryVersion: binaryVersion || null, }; } function isUsageError(error: any): error is UsageError { return error?.name === `UsageError`; } export async function runMain(argv: Array) { const engine = new Engine(); const [firstArg, ...restArgs] = argv; const request = getPackageManagerRequestFromCli(firstArg, engine); if (!request) { // If the first argument doesn't match any supported package manager, we fallback to the standard Corepack CLI const cli = new Cli({ binaryLabel: `Corepack`, binaryName: `corepack`, binaryVersion: corepackVersion, }); cli.register(Builtins.HelpCommand); cli.register(Builtins.VersionCommand); cli.register(CacheCommand); cli.register(DisableCommand); cli.register(EnableCommand); cli.register(InstallGlobalCommand); cli.register(InstallLocalCommand); cli.register(PackCommand); cli.register(UpCommand); cli.register(UseCommand); // Deprecated commands cli.register(HydrateCommand); cli.register(PrepareCommand); const context = { ...Cli.defaultContext, cwd: process.cwd(), engine, }; const code = await cli.run(argv, context); if (code !== 0) { process.exitCode ??= code; } } else { try { await engine.executePackageManagerRequest(request, { cwd: process.cwd(), args: restArgs, }); } catch (error) { if (isUsageError(error)) { console.error(error.message); process.exit(1); } throw error; } } }