UNPKG

auto-version-tool

Version:

根据git commit历史自动修改版本号并生成changelog的CLI工具 (Automatically bump version & generate changelog based on git commits)

199 lines 6.63 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GitService = void 0; const simple_git_1 = __importDefault(require("simple-git")); class GitService { constructor(config) { this.config = config; this.git = (0, simple_git_1.default)(); } async isGitRepository() { try { await this.git.status(); return true; } catch { return false; } } async isWorkingDirectoryClean() { const status = await this.git.status(); return status.files.length === 0; } async checkoutBranch(branch) { const branches = await this.git.branchLocal(); if (branches.all.includes(branch)) { await this.git.checkout(branch); } else { // 尝试检出远程分支 try { await this.git.checkout(["-b", branch, `origin/${branch}`]); } catch { throw new Error(`分支 '${branch}' 不存在`); } } } async getCurrentBranch() { const status = await this.git.status(); return status.current || "unknown"; } async getLatestTag() { try { const tags = await this.git.tags(["--sort=-version:refname"]); const tagList = tags.all.filter((tag) => tag.startsWith(this.config.git.tagPrefix)); return tagList[0] || null; } catch { return null; } } async getCommitsSinceLastTag(branch) { const latestTag = await this.getLatestTag(); try { if (latestTag) { // 获取从最新标签(不含)到当前分支HEAD(含)的提交 const log = await this.git.log({ from: latestTag, to: branch }); return log.all .filter((c) => c.hash !== log.latest?.hash || log.latest?.hash !== latestTag) // 保守过滤 .map((commit) => ({ hash: commit.hash, date: commit.date, message: commit.message, author_name: commit.author_name, author_email: commit.author_email, refs: commit.refs, })); } // 没有标签时,返回除首次提交外的全部提交以避免把初始化提交也当成“待发布” const allLog = await this.git.log(); return allLog.all.map((commit) => ({ hash: commit.hash, date: commit.date, message: commit.message, author_name: commit.author_name, author_email: commit.author_email, refs: commit.refs, })); } catch (error) { console.error("获取提交历史失败:", error); return []; } } async getCommitsBetweenTags(from, to) { try { const log = await this.git.log({ from, to, format: { hash: "%H", date: "%ai", message: "%s", author_name: "%an", author_email: "%ae", }, }); return log.all.map((commit) => ({ hash: commit.hash, date: commit.date, message: commit.message, author_name: commit.author_name, author_email: commit.author_email, })); } catch { return []; } } async getAllTags() { try { const tags = await this.git.tags([ "--sort=-version:refname", "-l", "--format=%(refname:short)|%(objectname)|%(creatordate:iso8601)|%(contents:lines=1)", ]); return tags.all .filter((tag) => tag.startsWith(this.config.git.tagPrefix)) .map((tagInfo) => { const [name, hash, date, message] = tagInfo.split("|"); return { name, hash, date, message: message || undefined, }; }); } catch { return []; } } async commitVersionBump(version) { // 添加更改的文件 await this.git.add([ this.config.files.packageJson, this.config.files.changelogFile, ]); // 提交更改 const commitMessage = `chore(release): bump version to ${version}`; await this.git.commit(commitMessage); } async createTag(version, message) { const tagName = `${this.config.git.tagPrefix}${version}`; const tagMessage = message || `Release version ${version}`; await this.git.addAnnotatedTag(tagName, tagMessage); } async pushChanges(branch, withTags = true) { await this.git.push("origin", branch); if (withTags) { await this.git.pushTags("origin"); } } async getBranches() { const branches = await this.git.branchLocal(); return branches.all.map((name) => ({ name, current: name === branches.current, commit: "", // 可以进一步获取每个分支的最新提交 })); } async getRemoteUrl() { try { const remotes = await this.git.getRemotes(true); const origin = remotes.find((remote) => remote.name === "origin"); return origin?.refs?.fetch || null; } catch { return null; } } async hasUncommittedChanges() { const status = await this.git.status(); return status.files.length > 0 || status.staged.length > 0; } async getLastCommit() { try { const log = await this.git.log({ maxCount: 1 }); const commit = log.latest; if (!commit) return null; return { hash: commit.hash, date: commit.date, message: commit.message, author_name: commit.author_name, author_email: commit.author_email, }; } catch { return null; } } } exports.GitService = GitService; //# sourceMappingURL=GitService.js.map