UNPKG

@yzfu/bumpx

Version:

Bump version, base on,bumpp,add new --select option

405 lines (392 loc) 13.8 kB
import { NPM_LOCK_FILE, PACKAGE_JSON_FILE, PKG_NAME, PNPM_LOCK_FILE, PNPM_WORKSPACE_FILE, ROOT, YARN_LOCK_FILE, __commonJS, __require, __toESM, configDefaults, isReleaseType, loadBumpConfig } from "./chunk-W4Y34Y7K.mjs"; // node_modules/.pnpm/picocolors@1.0.0/node_modules/picocolors/picocolors.js var require_picocolors = __commonJS({ "node_modules/.pnpm/picocolors@1.0.0/node_modules/picocolors/picocolors.js"(exports, module) { var tty = __require("tty"); var isColorSupported = !("NO_COLOR" in process.env || process.argv.includes("--no-color")) && ("FORCE_COLOR" in process.env || process.argv.includes("--color") || process.platform === "win32" || tty.isatty(1) && process.env.TERM !== "dumb" || "CI" in process.env); var formatter = (open, close, replace = open) => (input) => { let string = "" + input; let index = string.indexOf(close, open.length); return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close; }; var replaceClose = (string, close, replace, index) => { let start = string.substring(0, index) + replace; let end = string.substring(index + close.length); let nextIndex = end.indexOf(close); return ~nextIndex ? start + replaceClose(end, close, replace, nextIndex) : start + end; }; var createColors = (enabled = isColorSupported) => ({ isColorSupported: enabled, reset: enabled ? (s) => `\x1B[0m${s}\x1B[0m` : String, bold: enabled ? formatter("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m") : String, dim: enabled ? formatter("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m") : String, italic: enabled ? formatter("\x1B[3m", "\x1B[23m") : String, underline: enabled ? formatter("\x1B[4m", "\x1B[24m") : String, inverse: enabled ? formatter("\x1B[7m", "\x1B[27m") : String, hidden: enabled ? formatter("\x1B[8m", "\x1B[28m") : String, strikethrough: enabled ? formatter("\x1B[9m", "\x1B[29m") : String, black: enabled ? formatter("\x1B[30m", "\x1B[39m") : String, red: enabled ? formatter("\x1B[31m", "\x1B[39m") : String, green: enabled ? formatter("\x1B[32m", "\x1B[39m") : String, yellow: enabled ? formatter("\x1B[33m", "\x1B[39m") : String, blue: enabled ? formatter("\x1B[34m", "\x1B[39m") : String, magenta: enabled ? formatter("\x1B[35m", "\x1B[39m") : String, cyan: enabled ? formatter("\x1B[36m", "\x1B[39m") : String, white: enabled ? formatter("\x1B[37m", "\x1B[39m") : String, gray: enabled ? formatter("\x1B[90m", "\x1B[39m") : String, bgBlack: enabled ? formatter("\x1B[40m", "\x1B[49m") : String, bgRed: enabled ? formatter("\x1B[41m", "\x1B[49m") : String, bgGreen: enabled ? formatter("\x1B[42m", "\x1B[49m") : String, bgYellow: enabled ? formatter("\x1B[43m", "\x1B[49m") : String, bgBlue: enabled ? formatter("\x1B[44m", "\x1B[49m") : String, bgMagenta: enabled ? formatter("\x1B[45m", "\x1B[49m") : String, bgCyan: enabled ? formatter("\x1B[46m", "\x1B[49m") : String, bgWhite: enabled ? formatter("\x1B[47m", "\x1B[49m") : String }); module.exports = createColors(); module.exports.createColors = createColors; } }); // src/cli.ts var import_picocolors2 = __toESM(require_picocolors()); import cac from "cac"; import { versionBump } from "bumpp"; import { valid as isValidVersion } from "semver"; // package.json var version = "1.2.2"; // src/exit-code.ts var import_picocolors = __toESM(require_picocolors()); function errorHandler(error) { console.error(import_picocolors.default.red(error.message)); return process.exit(9 /* InvalidArgument */); } // src/select-pkg.ts import glob from "fast-glob"; import prompts from "prompts"; import { existsSync } from "fs"; import { join } from "path"; // src/fs.ts import fs from "fs"; // node_modules/.pnpm/detect-indent@7.0.1/node_modules/detect-indent/index.js var INDENT_REGEX = /^(?:( )+|\t+)/; var INDENT_TYPE_SPACE = "space"; var INDENT_TYPE_TAB = "tab"; function makeIndentsMap(string, ignoreSingleSpaces) { const indents = /* @__PURE__ */ new Map(); let previousSize = 0; let previousIndentType; let key; for (const line of string.split(/\n/g)) { if (!line) { continue; } let indent; let indentType; let use; let weight; let entry; const matches = line.match(INDENT_REGEX); if (matches === null) { previousSize = 0; previousIndentType = ""; } else { indent = matches[0].length; indentType = matches[1] ? INDENT_TYPE_SPACE : INDENT_TYPE_TAB; if (ignoreSingleSpaces && indentType === INDENT_TYPE_SPACE && indent === 1) { continue; } if (indentType !== previousIndentType) { previousSize = 0; } previousIndentType = indentType; use = 1; weight = 0; const indentDifference = indent - previousSize; previousSize = indent; if (indentDifference === 0) { use = 0; weight = 1; } else { const absoluteIndentDifference = indentDifference > 0 ? indentDifference : -indentDifference; key = encodeIndentsKey(indentType, absoluteIndentDifference); } entry = indents.get(key); entry = entry === void 0 ? [1, 0] : [entry[0] + use, entry[1] + weight]; indents.set(key, entry); } } return indents; } function encodeIndentsKey(indentType, indentAmount) { const typeCharacter = indentType === INDENT_TYPE_SPACE ? "s" : "t"; return typeCharacter + String(indentAmount); } function decodeIndentsKey(indentsKey) { const keyHasTypeSpace = indentsKey[0] === "s"; const type = keyHasTypeSpace ? INDENT_TYPE_SPACE : INDENT_TYPE_TAB; const amount = Number(indentsKey.slice(1)); return { type, amount }; } function getMostUsedKey(indents) { let result; let maxUsed = 0; let maxWeight = 0; for (const [key, [usedCount, weight]] of indents) { if (usedCount > maxUsed || usedCount === maxUsed && weight > maxWeight) { maxUsed = usedCount; maxWeight = weight; result = key; } } return result; } function makeIndentString(type, amount) { const indentCharacter = type === INDENT_TYPE_SPACE ? " " : " "; return indentCharacter.repeat(amount); } function detectIndent(string) { if (typeof string !== "string") { throw new TypeError("Expected a string"); } let indents = makeIndentsMap(string, true); if (indents.size === 0) { indents = makeIndentsMap(string, false); } const keyOfMostUsedIndent = getMostUsedKey(indents); let type; let amount = 0; let indent = ""; if (keyOfMostUsedIndent !== void 0) { ({ type, amount } = decodeIndentsKey(keyOfMostUsedIndent)); indent = makeIndentString(type, amount); } return { amount, type, indent }; } // node_modules/.pnpm/detect-newline@4.0.0/node_modules/detect-newline/index.js function detectNewline(string) { if (typeof string !== "string") { throw new TypeError("Expected a string"); } const newlines = string.match(/(?:\r?\n)/g) || []; if (newlines.length === 0) { return; } const crlf = newlines.filter((newline) => newline === "\r\n").length; const lf = newlines.length - crlf; return crlf > lf ? "\r\n" : "\n"; } // src/fs.ts async function readJsonFile(name) { const file = await readTextFile(name); const data = JSON.parse(file.data); const indent = detectIndent(file.data).indent; const newline = detectNewline(file.data); return { ...file, data, indent, newline }; } function readTextFile(filepath) { return new Promise((resolve, reject) => { fs.readFile(filepath, "utf8", (err, text) => { if (err) { reject(err); } else { resolve({ path: filepath, data: text }); } }); }); } // src/mainfest.ts function isManifest(obj) { return obj && typeof obj === "object" && isOptionalString(obj.name) && isOptionalString(obj.version) && isOptionalString(obj.description); } function isOptionalString(value) { const type = typeof value; return value === null || type === "undefined" || type === "string"; } // src/select-pkg.ts async function filterPkgFiles(options) { let pkgFiles = [], files = []; if (options.files?.length) { files = options.files; pkgFiles = findPkgFile(files); } else { files = [PKG_NAME]; const workFiles = await findWorkspace(files); pkgFiles = findPkgFile(workFiles); } return pkgFiles; } async function findWorkspace(files) { try { if (existsSync(NPM_LOCK_FILE) || existsSync(YARN_LOCK_FILE)) { const { data: manifest } = await readJsonFile(PACKAGE_JSON_FILE); if (isManifest(manifest) && manifest.workspaces) { for (let path of manifest.workspaces) { const filepath = convertPath(join(path, PKG_NAME)); files.push(filepath); } } } else if (existsSync(PNPM_LOCK_FILE)) { const { data } = await readTextFile(PNPM_WORKSPACE_FILE); const regex = /'([^']+)'/g; let match; while (match = regex.exec(data)) { const filepath = convertPath(join(match[1], PKG_NAME)); files.push(filepath); } } } catch (e) { return files; } return files; } function findPkgFile(files) { const result = glob.sync(files, { cwd: ROOT, ignore: [ "**/{.git,node_modules,bower_components,__tests__,fixtures,fixture}/**" ] }); return result; } function convertPath(windowsPath) { return windowsPath.replace(/^\\\\\?\\/, "").replace(/\\/g, "/").replace(/\/\/+/g, "/"); } async function selectFiles(files) { const filepaths = []; files = files.filter((file) => file !== PKG_NAME); for (let file of files) { const filepath = join(ROOT, file); const { data: manifest } = await readJsonFile(filepath); if (isManifest(manifest)) { filepaths.push({ title: `${manifest.name} - ${manifest.version}`, value: file }); } } const { isall } = await prompts([ { type: "confirm", name: "isall", message: "Publish all?", initial: false // Default manual selection } ]); if (isall === void 0) { errorHandler({ name: "publish all", message: "No choice, exit abnormally" }); } if (!isall) { const { upgrade } = await prompts([ { type: "autocompleteMultiselect", name: "upgrade", message: "Select the package that needs to be upgraded", choices: filepaths, hint: "- Space to select. Return to keyboard `Enter`" } ]); if (upgrade === void 0) { errorHandler({ name: "upgrade", message: "No choice, exit abnormally" }); } files = upgrade; } files.unshift(PKG_NAME); return files; } // src/cli.ts async function parseArgs() { try { const cli = cac("bumpx"); cli.version(version).usage("[...files]").option("--preid <preid>", "ID for prerelease").option("--all", `Include all files (default: ${configDefaults.all})`).option("-c, --commit [msg]", `Commit message (default: ${configDefaults.commit})`).option("-t, --tag [tag]", `Tag name (default: ${configDefaults.tag})`).option("-p, --push", `Push to remote (default: ${configDefaults.push})`).option("-y, --yes", `Skip confirmation (default: ${!configDefaults.confirm})`).option("-r, --recursive", `Bump package.json files recursively (default: ${configDefaults.recursive})`).option("--no-verify", "Skip git verification").option("--ignore-scripts", `Ignore scripts (default: ${configDefaults.ignoreScripts})`).option("-q, --quiet", "Quiet mode").option("-v, --version <version>", "Tagert version").option("-x, --execute <command>", "Commands to execute after version bumps").option("-s, --select", `Select the specified package file (default: ${configDefaults.select})`).help(); const result = cli.parse(); const args = result.options; const parsedArgs = { help: args.help, version: args.version, quiet: args.quiet, options: await loadBumpConfig({ select: args.select, preid: args.preid, commit: args.commit, tag: args.tag, push: args.push, all: args.all, confirm: !args.yes, noVerify: !args.verify, files: [...args["--"] || [], ...result.args], ignoreScripts: args.ignoreScripts, execute: args.execute, recursive: !!args.recursive }) }; if (parsedArgs.options.files && parsedArgs.options.files.length > 0) { const firstArg = parsedArgs.options.files[0]; if (firstArg === "prompt" || isReleaseType(firstArg) || isValidVersion(firstArg)) { parsedArgs.options.release = firstArg; parsedArgs.options.files.shift(); } } if (parsedArgs.options.recursive) { if (parsedArgs.options.files?.length) console.log(import_picocolors2.default.yellow("The --recursive option is ignored when files are specified")); else parsedArgs.options.files = []; } return parsedArgs; } catch (error) { return errorHandler(error); } } async function main() { try { process.on("uncaughtException", errorHandler); process.on("unhandledRejection", errorHandler); const { help, version: version2, options } = await parseArgs(); if (help) { process.exit(0 /* Success */); } else if (version2) { process.exit(0 /* Success */); } else { options.files = await filterPkgFiles(options); if (options.select) { options.recursive = false; options.files = await selectFiles(options.files); } await versionBump(options); } } catch (error) { errorHandler(error); } } export { main, parseArgs };