UNPKG

nadle

Version:

A type-safe, Gradle-inspired task runner for Node.js. Sharp tasks. Fast builds.

306 lines (301 loc) 8.78 kB
#!/usr/bin/env node import { SupportReporters } from "./chunk-AHRK4KLP.js"; import { Nadle } from "./chunk-32YKTXZB.js"; import { ConfigurationError, DASH, Messages, SupportLogLevels, UNDERSCORE } from "./chunk-U2TDD2B5.js"; // packages/nadle/src/cli.ts import Process from "process"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; // packages/nadle/src/core/options/cli-options.ts import { CONFIG_FILE_PATTERN } from "@nadle/project-resolver"; var CLIOptions = { configFile: { key: "config", options: { alias: "c", type: "string", description: "Path to config file", defaultDescription: `<cwd>/${CONFIG_FILE_PATTERN}` } }, list: { key: "list", options: { alias: "l", default: false, type: "boolean", description: "List all available tasks" } }, listWorkspaces: { key: "list-workspaces", options: { default: false, type: "boolean", description: "List all available workspaces" } }, parallel: { key: "parallel", options: { default: false, type: "boolean", description: "Run all specified tasks in parallel regardless of their order, while still respecting task dependencies." } }, dryRun: { key: "dry-run", options: { alias: "m", default: false, type: "boolean", description: "Run specified tasks in dry run mode" } }, stacktrace: { key: "stacktrace", options: { default: false, type: "boolean", description: "Print stacktrace on error" } }, showConfig: { key: "show-config", options: { default: false, type: "boolean", description: "Print the resolved configuration" } }, configKey: { key: "config-key", options: { type: "string", description: "Path to a specific resolved configuration value, using dot/bracket notation", defaultDescription: "undefined" } }, footer: { key: "footer", options: { type: "boolean", defaultDescription: "!isCI && isTTY", description: "Enables the in-progress summary footer during task execution" } }, reporter: { key: "reporter", options: { type: "string", defaultDescription: "default", choices: SupportReporters, description: "Output reporter: 'default' (human) or 'agent' (compact, plain, for agents/scripts)" } }, cache: { key: "cache", options: { hidden: true, type: "boolean" } }, // @ts-expect-error to show --no-cache option when using -h noCache: { key: "no-cache", options: { type: "boolean", defaultDescription: "false", description: "Disable task caching. All tasks will be executed and their results will not be stored" } }, cacheDir: { key: "cache-dir", options: { type: "string", defaultDescription: "<projectDir>/node_modules/.cache/nadle", description: "Directory to store task cache results" } }, cleanCache: { key: "clean-cache", options: { type: "boolean", default: false, description: "Deletes all files in the cache directory. Can be used with --cache-dir to specify a custom location" } }, summary: { key: "summary", options: { type: "boolean", default: false, description: "Print a summary of executed tasks at the end of the run" } }, exclude: { key: "exclude", options: { type: "string", alias: "x", description: "Tasks to exclude from execution", array: true, coerce: coerceList } }, logLevel: { key: "log-level", options: { type: "string", defaultDescription: "log", choices: SupportLogLevels, describe: "Set the logging level" } }, minWorkers: { key: "min-workers", options: { type: "string", describe: "Minimum number of workers (integer or percentage)", defaultDescription: "Os.availableParallelism() - 1", coerce: createWorkerCoercer("min") } }, maxWorkers: { key: "max-workers", options: { type: "string", describe: "Maximum number of workers (integer or percentage)", defaultDescription: "Os.availableParallelism() - 1", coerce: createWorkerCoercer("max") } } }; function coerceList(val) { return val.flatMap((v) => v.split(",").map((s) => s.trim())).filter(Boolean); } function createWorkerCoercer(type) { return (workers) => { if (workers === void 0) { return void 0; } if (/^\d+$/.test(workers)) { return Number(workers); } if (/^\d+(\.\d+)?%$/.test(workers)) { return workers; } throw new ConfigurationError(Messages.InvalidWorkerConfig(type, workers)); }; } // packages/nadle/src/core/options/cli-options-resolver.ts var aliases = Object.values(CLIOptions).map(({ options }) => options.alias).filter(Boolean); var exclude = (keyMatcher) => (arg) => { if (typeof keyMatcher === "function" && keyMatcher(arg.key)) { return null; } if (typeof keyMatcher === "string" && arg.key === keyMatcher) { return null; } return arg; }; var transform = (targetKey, options) => (arg) => { if (arg.key !== targetKey) { return arg; } if (arg.value === void 0) { return null; } return { key: options.transformKey ?? arg.key, value: options.transformValue ? options.transformValue(arg.value) : arg.value }; }; var transformers = [ transform("--", { transformKey: "passthroughArgs" }), exclude((key) => aliases.includes(key)), exclude((key) => key.includes(DASH)), exclude("$0"), exclude(UNDERSCORE), transform("config", { transformKey: "configFile" }), transform("cache", { transformValue: Boolean }), transform("exclude", { transformKey: "excludedTasks" }) ]; var transformer = (arg) => { let transformedArg = arg; for (const transformer2 of transformers) { transformedArg = transformer2(transformedArg); if (transformedArg === null) { return null; } } return transformedArg; }; var CLIOptionsResolver = class { static resolve(argv2) { const { tasks = [], ...rest } = argv2; const resolvedOptions = { tasks }; for (const [key, value] of Object.entries(rest)) { const transformedArg = transformer({ key, value }); if (transformedArg) { Object.assign(resolvedOptions, { [transformedArg.key]: transformedArg.value }); } } return resolvedOptions; } }; // packages/nadle/src/cli.ts var argv = yargs(hideBin(Process.argv)).scriptName("nadle").command("$0 [tasks...]", "Execute one or more named tasks").options({ [CLIOptions.list.key]: CLIOptions.list.options, [CLIOptions.cache.key]: CLIOptions.cache.options, [CLIOptions.dryRun.key]: CLIOptions.dryRun.options, [CLIOptions.footer.key]: CLIOptions.footer.options, [CLIOptions.exclude.key]: CLIOptions.exclude.options, [CLIOptions.noCache.key]: CLIOptions.noCache.options, [CLIOptions.summary.key]: CLIOptions.summary.options, [CLIOptions.reporter.key]: CLIOptions.reporter.options, [CLIOptions.parallel.key]: CLIOptions.parallel.options, [CLIOptions.cacheDir.key]: CLIOptions.cacheDir.options, [CLIOptions.logLevel.key]: CLIOptions.logLevel.options, [CLIOptions.configKey.key]: CLIOptions.configKey.options, [CLIOptions.configFile.key]: CLIOptions.configFile.options, [CLIOptions.minWorkers.key]: CLIOptions.minWorkers.options, [CLIOptions.maxWorkers.key]: CLIOptions.maxWorkers.options, [CLIOptions.cleanCache.key]: CLIOptions.cleanCache.options, [CLIOptions.showConfig.key]: CLIOptions.showConfig.options, [CLIOptions.stacktrace.key]: CLIOptions.stacktrace.options, [CLIOptions.listWorkspaces.key]: CLIOptions.listWorkspaces.options }).version("version", "Show version number", Nadle.version).alias("v", "version").help("help", "Show this help").alias("h", "help").group( [ CLIOptions.parallel.key, CLIOptions.exclude.key, CLIOptions.noCache.key, CLIOptions.cleanCache.key, CLIOptions.list.key, CLIOptions.listWorkspaces.key, CLIOptions.dryRun.key, CLIOptions.showConfig.key, CLIOptions.configKey.key, CLIOptions.stacktrace.key ], "Execution options:" ).group( [ CLIOptions.configFile.key, CLIOptions.cacheDir.key, CLIOptions.logLevel.key, CLIOptions.minWorkers.key, CLIOptions.maxWorkers.key, CLIOptions.footer.key, CLIOptions.summary.key ], "General options:" ).group(["help", "version"], "Miscellaneous options:").example("nadle test -- -u", "Run the test task, passing -u through to its underlying command").parserConfiguration({ "populate--": true }).wrap(100).strict().parseSync(); new Nadle(CLIOptionsResolver.resolve(argv)).execute();