@yzfu/bumpx
Version:
Bump version, base on,bumpp,add new --select option
483 lines (466 loc) • 17.3 kB
JavaScript
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
});