verz
Version:
[](https://www.npmjs.com/package/verz)
280 lines (271 loc) • 10.2 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
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);
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/index.ts
var index_exports = {};
module.exports = __toCommonJS(index_exports);
var import_node_fs2 = require("fs");
var import_node_path2 = require("path");
var import_commander = require("commander");
var import_semver = __toESM(require("semver"));
// src/lib/logger.ts
var import_node_util = require("util");
var COLORS = {
reset: "\x1B[0m",
red: "\x1B[31m",
yellow: "\x1B[33m",
blue: "\x1B[34m",
green: "\x1B[32m",
magenta: "\x1B[35m",
gray: "\x1B[90m"
};
var Logger = class {
constructor(_level = "info") {
this._level = _level;
this.COLORS = COLORS;
}
debug(...args) {
if (this.shouldLog("debug")) console.log(`${COLORS.gray}[DEBUG] ${COLORS.reset}`, ...args.map((arg) => typeof arg === "object" ? (0, import_node_util.inspect)(arg) : arg), COLORS.reset);
}
info(...args) {
if (this.shouldLog("info")) console.log(`${COLORS.blue}[INFO] ${COLORS.reset}`, ...args.map((arg) => typeof arg === "object" ? (0, import_node_util.inspect)(arg) : arg), COLORS.reset);
}
warn(...args) {
if (this.shouldLog("warn")) console.warn(`${COLORS.yellow}[WARN] ${COLORS.reset}`, ...args.map((arg) => typeof arg === "object" ? (0, import_node_util.inspect)(arg) : arg), COLORS.reset);
}
error(...args) {
if (this.shouldLog("error")) console.error(`${COLORS.red}[ERROR] ${COLORS.reset}`, ...args.map((arg) => typeof arg === "object" ? (0, import_node_util.inspect)(arg) : arg), COLORS.reset);
}
level(level) {
this._level = level;
}
shouldLog(level) {
const levels = ["error", "warn", "info", "debug"];
return levels.indexOf(this._level) >= levels.indexOf(level);
}
};
var logger_default = new Logger();
// src/lib/exec.ts
var import_node_child_process = require("child_process");
// src/lib/config.ts
var import_node_path = require("path");
var import_node_fs = require("fs");
// src/lib/utils.ts
var deepMerge = (target, source) => {
if (typeof source !== "object" || source === null) return source;
const output = __spreadValues({}, target);
for (const key in source) {
if (source[key] === void 0 || source[key] === null) continue;
if (typeof source[key] === "object" && !Array.isArray(source[key])) {
output[key] = deepMerge(output[key] || {}, source[key]);
} else {
output[key] = source[key];
}
}
return output;
};
// src/lib/config.ts
var defaultConfig = {
commit: {
message: "chore: version %v"
},
tag: {
name: "%v"
},
dryRun: false
};
var Config = class {
constructor() {
this.config = defaultConfig;
}
fileLoad() {
return __async(this, null, function* () {
const configFiles = ["verz.config.json", "verz.config.js", "verz.config.mjs"];
for (const file of configFiles) {
const configPath = (0, import_node_path.join)(process.cwd(), file);
if ((0, import_node_fs.existsSync)(configPath)) {
logger_default.debug(`Loading config from ${file}`);
try {
if (file.endsWith(".json")) {
return JSON.parse((0, import_node_fs.readFileSync)(configPath, "utf-8"));
} else if (file.endsWith(".mjs")) {
const module2 = yield import(configPath);
return module2.default;
} else {
return require(configPath);
}
} catch (error) {
logger_default.warn(`Failed to load config from ${file}:`, error);
}
}
}
return {};
});
}
load() {
return __async(this, arguments, function* (override = {}) {
const fileConfig = yield this.fileLoad();
this.config = deepMerge(deepMerge(this.config, fileConfig), override);
return this.config;
});
}
get() {
return this.config;
}
};
var config_default = new Config();
// src/lib/exec.ts
var exec = (command, args, options) => {
var _a, _b;
const config = config_default.get();
logger_default.debug(`Running command${logger_default.COLORS.gray}`, command, args);
if (config.dryRun) return "";
const p = (0, import_node_child_process.spawnSync)(command, args.map(String), {
stdio: "pipe"
});
if (!(options == null ? void 0 : options.ignoreReturnCode)) {
if (p.error) {
throw p.error;
}
if (p.status !== 0) {
throw new Error(`Command failed with exit code ${p.status}`);
}
}
const stdout = (_b = (_a = p.stdout) == null ? void 0 : _a.toString()) != null ? _b : "";
if (stdout) {
}
return stdout;
};
var exec_default = exec;
// src/index.ts
function bumpVersion(type) {
var _a;
const config = config_default.get();
const packagePath = (0, import_node_path2.join)(process.cwd(), "package.json");
const packageContent = (0, import_node_fs2.readFileSync)(packagePath, "utf-8");
const packageJson = JSON.parse(packageContent);
const newVersion = import_semver.default.inc(packageJson.version, type);
if (!newVersion) {
throw new Error(`Failed to bump version: ${packageJson.version}`);
}
const packageJsonStatus = exec_default("git", ["status", "--porcelain", "package.json"], {
ignoreReturnCode: true
});
if (packageJsonStatus.length > 0) {
throw new Error("package.json has uncommitted changes. Please commit or stash them first.");
}
const hasChanges = exec_default("git", ["diff", "HEAD"], {
ignoreReturnCode: true
}).length > 0;
if (hasChanges) {
exec_default("git", ["stash", "push", "--keep-index"]);
}
packageJson.version = newVersion;
logger_default.debug(`Updating ${logger_default.COLORS.gray}package.json`);
const match = packageContent.match(/^(?:( +)|\t+)/m);
const indent = (_a = match == null ? void 0 : match[0]) != null ? _a : " ";
if (!config.dryRun) (0, import_node_fs2.writeFileSync)(packagePath, JSON.stringify(packageJson, null, indent) + "\n");
try {
exec_default("git", ["add", "package.json"]);
const commitMessage = config.commit.message.replace("%v", newVersion);
logger_default.info(`Committing changes with message${logger_default.COLORS.magenta}`, commitMessage);
exec_default("git", ["commit", "-m", commitMessage]);
const tagName = config.tag.name.replace("%v", newVersion);
logger_default.info(`Creating tag${logger_default.COLORS.magenta}`, tagName);
exec_default("git", ["tag", tagName]);
} catch (e) {
logger_default.error("Failed to commit and tag:", e);
} finally {
if (hasChanges) {
exec_default("git", ["stash", "pop"]);
}
}
return newVersion;
}
function main() {
return __async(this, null, function* () {
const program = new import_commander.Command();
program.name("verz").description("Version bumping tool").option("--patch", "bump patch version").option("--minor", "bump minor version").option("--major", "bump major version").option("--commit.message <message>", "custom commit message").option("-v, --verbose", "enable verbose logging").option("--dry-run", "dry run").action((options) => __async(null, null, function* () {
if (options.verbose) {
logger_default.level("debug");
}
try {
const type = options.major ? "major" : options.minor ? "minor" : options.patch ? "patch" : void 0;
if (!type) {
logger_default.error("Please specify one of: --patch, --minor, or --major");
process.exit(1);
}
const cliConfig = {
commit: {
message: options["commit.message"]
},
dryRun: options["dryRun"]
};
yield config_default.load(cliConfig);
const newVersion = bumpVersion(type);
logger_default.info(`Version bumped to${logger_default.COLORS.magenta}`, newVersion);
} catch (error) {
logger_default.error("Error:", error);
process.exit(1);
}
}));
program.parse();
});
}
main();