UNPKG

@yzfu/bumpx

Version:

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

483 lines (466 loc) 17.3 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // 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, module2) { 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 }); module2.exports = createColors(); module2.exports.createColors = createColors; } }); // src/cli.ts var cli_exports = {}; __export(cli_exports, { main: () => main, parseArgs: () => parseArgs }); module.exports = __toCommonJS(cli_exports); var import_cac = __toESM(require("cac")); var import_picocolors2 = __toESM(require_picocolors()); var import_bumpp2 = require("bumpp"); var import_semver2 = require("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/config.ts var import_c12 = require("c12"); var import_bumpp = require("bumpp"); // src/contant.ts var import_process = __toESM(require("process")); var import_node_fs = require("fs"); var import_node_path = require("path"); var PKG_NAME = "package.json"; var CWD = import_process.default.cwd(); var ROOT = findRootDir(CWD); var PACKAGE_JSON_FILE = (0, import_node_path.join)(ROOT, PKG_NAME); var NPM_LOCK_FILE = (0, import_node_path.join)(ROOT, "package-lock.json"); var PNPM_LOCK_FILE = (0, import_node_path.join)(ROOT, "pnpm-lock.yaml"); var YARN_LOCK_FILE = (0, import_node_path.join)(ROOT, "yarn.lock"); var PNPM_WORKSPACE_FILE = (0, import_node_path.join)(ROOT, "pnpm-workspace.yaml"); function findRootDir(dir) { if ((0, import_node_fs.existsSync)((0, import_node_path.join)(dir, PKG_NAME))) { return dir; } const parentDir = (0, import_node_path.dirname)(dir); if (dir === parentDir) { return dir; } return findRootDir(parentDir); } // src/config.ts var bumpxConfigDefaults = { select: false, push: false }; var configDefaults = { ...import_bumpp.bumpConfigDefaults, ...bumpxConfigDefaults }; async function loadBumpConfig(overrides) { const { config } = await (0, import_c12.loadConfig)({ name: "bumpx", defaults: configDefaults, overrides: { ...overrides }, cwd: ROOT }); return config; } // src/release-type.ts var import_semver = require("semver"); var prereleaseTypes = ["premajor", "preminor", "prepatch", "prerelease"]; var releaseTypes = prereleaseTypes.concat(["major", "minor", "patch"]); function isReleaseType(value) { return releaseTypes.includes(value); } // src/select-pkg.ts var import_fast_glob = __toESM(require("fast-glob")); var import_prompts = __toESM(require("prompts")); var import_node_fs3 = require("fs"); var import_node_path2 = require("path"); // src/fs.ts var import_node_fs2 = __toESM(require("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) => { import_node_fs2.default.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 ((0, import_node_fs3.existsSync)(NPM_LOCK_FILE) || (0, import_node_fs3.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((0, import_node_path2.join)(path, PKG_NAME)); files.push(filepath); } } } else if ((0, import_node_fs3.existsSync)(PNPM_LOCK_FILE)) { const { data } = await readTextFile(PNPM_WORKSPACE_FILE); const regex = /'([^']+)'/g; let match; while (match = regex.exec(data)) { const filepath = convertPath((0, import_node_path2.join)(match[1], PKG_NAME)); files.push(filepath); } } } catch (e) { return files; } return files; } function findPkgFile(files) { const result = import_fast_glob.default.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 = (0, import_node_path2.join)(ROOT, file); const { data: manifest } = await readJsonFile(filepath); if (isManifest(manifest)) { filepaths.push({ title: `${manifest.name} - ${manifest.version}`, value: file }); } } const { isall } = await (0, import_prompts.default)([ { 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 (0, import_prompts.default)([ { 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 = (0, import_cac.default)("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) || (0, import_semver2.valid)(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 (0, import_bumpp2.versionBump)(options); } } catch (error) { errorHandler(error); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { main, parseArgs });