auto-version-tool
Version:
根据git commit历史自动修改版本号并生成changelog的CLI工具 (Automatically bump version & generate changelog based on git commits)
188 lines • 7.37 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VersionService = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const semver_1 = __importDefault(require("semver"));
class VersionService {
constructor(config) {
this.config = config;
}
async getCurrentVersion() {
const packageJsonPath = path.resolve(this.config.files.packageJson);
if (!fs.existsSync(packageJsonPath)) {
throw new Error(`package.json 文件不存在: ${packageJsonPath}`);
}
try {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
return packageJson.version || '0.0.0';
}
catch (error) {
throw new Error(`读取 package.json 失败: ${error}`);
}
}
bumpVersion(currentVersion, type) {
const cleanVersion = semver_1.default.clean(currentVersion);
if (!cleanVersion) {
throw new Error(`无效的版本号: ${currentVersion}`);
}
const newVersion = semver_1.default.inc(cleanVersion, type);
if (!newVersion) {
throw new Error(`无法升级版本: ${currentVersion} -> ${type}`);
}
return newVersion;
}
async updateVersion(newVersion) {
// 更新 package.json
await this.updatePackageJson(newVersion);
// 如果配置了独立的版本文件,也要更新
if (this.config.files.versionFile) {
await this.updateVersionFile(newVersion);
}
}
async updatePackageJson(newVersion) {
const packageJsonPath = path.resolve(this.config.files.packageJson);
try {
const content = fs.readFileSync(packageJsonPath, 'utf-8');
const packageJson = JSON.parse(content);
packageJson.version = newVersion;
// 保持原有的格式化风格
const updatedContent = JSON.stringify(packageJson, null, 2) + '\n';
fs.writeFileSync(packageJsonPath, updatedContent, 'utf-8');
console.log(`✅ 已更新 package.json 版本至 ${newVersion}`);
}
catch (error) {
throw new Error(`更新 package.json 失败: ${error}`);
}
}
async updateVersionFile(newVersion) {
if (!this.config.files.versionFile)
return;
const versionFilePath = path.resolve(this.config.files.versionFile);
try {
// 创建版本文件内容
const versionContent = this.generateVersionFileContent(newVersion);
fs.writeFileSync(versionFilePath, versionContent, 'utf-8');
console.log(`✅ 已更新版本文件 ${this.config.files.versionFile}`);
}
catch (error) {
throw new Error(`更新版本文件失败: ${error}`);
}
}
generateVersionFileContent(version) {
const timestamp = new Date().toISOString();
// 根据文件扩展名生成不同格式的内容
const ext = path.extname(this.config.files.versionFile);
switch (ext) {
case '.json':
return JSON.stringify({
version,
buildTime: timestamp,
buildNumber: this.generateBuildNumber()
}, null, 2);
case '.js':
return `export const VERSION = '${version}';
export const BUILD_TIME = '${timestamp}';
export const BUILD_NUMBER = '${this.generateBuildNumber()}';
`;
case '.ts':
return `export const VERSION = '${version}';
export const BUILD_TIME = '${timestamp}';
export const BUILD_NUMBER = '${this.generateBuildNumber()}';
`;
default:
return `${version}\n`;
}
}
generateBuildNumber() {
// 生成基于时间戳的构建号
return Date.now().toString();
}
isValidVersion(version) {
return semver_1.default.valid(version) !== null;
}
compareVersions(version1, version2) {
return semver_1.default.compare(version1, version2);
}
getNextVersions(currentVersion) {
return {
patch: this.bumpVersion(currentVersion, 'patch'),
minor: this.bumpVersion(currentVersion, 'minor'),
major: this.bumpVersion(currentVersion, 'major')
};
}
async validateVersionBump(currentVersion, targetVersion) {
// 检查目标版本是否有效
if (!this.isValidVersion(targetVersion)) {
return false;
}
// 检查目标版本是否大于当前版本
return this.compareVersions(targetVersion, currentVersion) > 0;
}
async getVersionHistory() {
// 这个方法可以通过读取git标签来获取版本历史
// 暂时返回空数组,在后续可以和GitService配合实现
return [];
}
generatePreReleaseVersion(baseVersion, identifier = 'alpha') {
const prereleaseVersion = semver_1.default.inc(baseVersion, 'prerelease', identifier);
if (!prereleaseVersion) {
throw new Error(`无法生成预发布版本: ${baseVersion}`);
}
return prereleaseVersion;
}
isPreRelease(version) {
const parsed = semver_1.default.parse(version);
return !!(parsed && parsed.prerelease.length > 0);
}
getVersionComponents(version) {
const parsed = semver_1.default.parse(version);
if (!parsed) {
throw new Error(`无效的版本号: ${version}`);
}
return {
major: parsed.major,
minor: parsed.minor,
patch: parsed.patch,
prerelease: parsed.prerelease.length > 0 ? parsed.prerelease : undefined
};
}
}
exports.VersionService = VersionService;
//# sourceMappingURL=VersionService.js.map
;