UNPKG

bumpp

Version:

Bump version, commit changes, tag, and push to Git

125 lines (124 loc) 5.32 kB
import { c as isReleaseType, i as versionBump, l as symbols, r as loadBumpConfig, t as bumpConfigDefaults } from "./config-DHzlpbsM.mjs"; import process from "node:process"; import { styleText } from "node:util"; import { NonZeroExitError, x } from "tinyexec"; import { isValid } from "verkit"; import cac from "cac"; //#region package.json var version = "12.0.0"; //#endregion //#region src/cli/parse-args.ts /** * Parses the command-line arguments */ async function parseArgs() { try { const { args, resultArgs } = loadCliArgs(); const rawFiles = [...args["--"] || [], ...resultArgs]; let releaseFromArgs; if (rawFiles.length > 0) { const firstArg = rawFiles[0]; if (firstArg === "prompt" || isReleaseType(firstArg) || isValid(firstArg)) { releaseFromArgs = firstArg; rawFiles.shift(); } } const parsedArgs = { help: args.help, version: args.version, quiet: args.quiet, options: await loadBumpConfig({ preid: args.preid, commit: args.commit, tag: args.tag, sign: args.sign, push: args.push, all: args.all, noGitCheck: args.gitCheck === void 0 ? void 0 : !args.gitCheck, confirm: args.yes === void 0 ? void 0 : !args.yes, noVerify: args.verify === void 0 ? void 0 : !args.verify, install: args.install, files: rawFiles.length ? rawFiles : void 0, ignoreScripts: args.ignoreScripts, currentVersion: args.currentVersion, execute: args.execute, printCommits: args.printCommits, recursive: args.recursive, release: args.release ?? releaseFromArgs, configFilePath: args.configFilePath }) }; if (parsedArgs.options.recursive && parsedArgs.options.files?.length) console.log(styleText("yellow", "The --recursive option is ignored when files are specified")); return parsedArgs; } catch (error) { return errorHandler$1(error); } } function loadCliArgs(argv = process.argv) { const cli = cac("bumpp"); cli.version(version).usage("[...files]").option("--preid <preid>", "ID for prerelease").option("-a, --all", `Include all files (default: ${bumpConfigDefaults.all})`).option("--git-check", `Run git check (default: ${!bumpConfigDefaults.noGitCheck})`).option("-c, --commit [msg]", `Commit message (default: ${bumpConfigDefaults.commit})`).option("-t, --tag [tag]", `Tag name (default: ${bumpConfigDefaults.tag})`).option("--sign", "Sign commit and tag").option("--install", `Run 'npm install' after bumping version (default: ${bumpConfigDefaults.install})`).option("-p, --push", `Push to remote (default: ${bumpConfigDefaults.push})`).option("-y, --yes", `Skip confirmation (default: ${!bumpConfigDefaults.confirm})`).option("-r, --recursive", `Bump package.json files recursively (default: ${bumpConfigDefaults.recursive})`).option("--verify", `Run git verification (default: ${!bumpConfigDefaults.noVerify})`).option("--ignore-scripts", `Ignore scripts (default: ${bumpConfigDefaults.ignoreScripts})`).option("-q, --quiet", "Quiet mode").option("--current-version <version>", "Current version").option("--print-commits", "Print recent commits").option("-x, --execute <command>", "Commands to execute after version bumps").option("--release <release>", `Release type or version number (e.g. 'major', 'minor', 'patch', 'prerelease', etc. default: ${bumpConfigDefaults.release})`).option("--configFilePath <configFilePath>", `Path to custom build.config file`).help(); const result = cli.parse(argv); return { args: result.options, resultArgs: result.args }; } function errorHandler$1(error) { console.error(error.message); return process.exit(9); } //#endregion //#region src/cli/index.ts /** * The main entry point of the CLI */ async function main() { try { process.on("uncaughtException", errorHandler); process.on("unhandledRejection", errorHandler); const { help, version, quiet, options } = await parseArgs(); if (help || version) process.exit(0); else { if (!options.all && !options.noGitCheck) await checkGitStatus(); if (!quiet) options.progress = options.progress ? options.progress : progress; await versionBump(options); } } catch (error) { errorHandler(error); } } async function checkGitStatus() { const { stdout } = await x("git", ["status", "--porcelain"]); if (stdout.trim()) throw new Error(`Git working tree is not clean:\n${stdout}`); } function progress({ event, script, updatedFiles, skippedFiles, newVersion }) { switch (event) { case "file updated": console.log(symbols.success, `Updated ${updatedFiles.pop()} to ${newVersion}`); break; case "file skipped": console.log(symbols.info, `${skippedFiles.pop()} did not need to be updated`); break; case "git commit": console.log(symbols.success, "Git commit"); break; case "git tag": console.log(symbols.success, "Git tag"); break; case "git push": console.log(symbols.success, "Git push"); break; case "npm script": console.log(symbols.success, `Npm run ${script}`); break; } } function errorHandler(error) { let message = error.message || String(error); if (error instanceof NonZeroExitError) message += `\n\n${error.output?.stderr || ""}`; if (process.env.DEBUG || process.env.NODE_ENV === "development") message += `\n\n${error.stack || ""}`; console.error(message); process.exit(1); } //#endregion export { checkGitStatus, main };