Files
changelog-generator/src/main/java/top/charles7c/app/App.java
2026-02-25 14:07:37 +08:00

143 lines
5.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package top.charles7c.app;
import cn.hutool.core.util.StrUtil;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* Git Changelog 生成器
*
* @author Charles7c
*/
public class App {
private static final String BASIC_PATH = "D:\\Projects\\charles7c\\";
private static final String PROJECT_NAME = "continew-starter";
// private static final String PROJECT_NAME = "continew-admin";
// private static final String PROJECT_NAME = "continew-admin-ui";
//
private static final String LAST_TAG_NAME = "release: v2.15.0";
// private static final String LAST_TAG_NAME = "release: v4.1.0";
private static final boolean SHOW_MODULE_NAME = true;
public static void main(String[] args) throws IOException, GitAPIException {
FileRepositoryBuilder builder = new FileRepositoryBuilder();
Repository repository = builder.setGitDir(new File(BASIC_PATH + PROJECT_NAME + "\\.git"))
.readEnvironment()
.findGitDir()
.build();
Map<String, List<RevCommit>> commitListMap = new LinkedHashMap<>();
// 根据类型汇总提交记录
try (Git git = new Git(repository)) {
// 倒序遍历所有提交记录
Iterable<RevCommit> logs = git.log().call();
for (RevCommit commit : logs) {
// 直到上次发布标签,停止遍历
if (LAST_TAG_NAME.equals(commit.getShortMessage())) {
break;
}
logChangeCommit(commit, commitListMap);
}
} finally {
repository.close();
}
// 转换为 CHANGELOG Markdown
Set<Map.Entry<String, List<RevCommit>>> entrySet = commitListMap.entrySet();
for (Map.Entry<String, List<RevCommit>> entry : entrySet) {
String changeType = entry.getKey();
System.out.printf("%n%n%s%n", changeType);
printChangelog(entry.getValue());
}
}
/**
* 添加变更记录
*
* @param commit 提交记录
* @param commitListMap 提交记录列表
*/
private static void logChangeCommit(RevCommit commit, Map<String, List<RevCommit>> commitListMap) {
String shortMessage = commit.getShortMessage();
// 忽略合并
if (shortMessage.startsWith("Merge ")) {
return;
}
// e.g. feat(core): ServletUtils 新增 isMultipart、isForm、isStream 方法
String changeType = getChangeType(shortMessage);
String changeTypeName = getChangeTypeName(changeType);
List<RevCommit> commitList = commitListMap.get(changeTypeName);
if (null == commitList) {
commitList = new ArrayList<>();
}
// 正序添加
commitList.add(0, commit);
commitListMap.put(changeTypeName, commitList);
}
/**
* 转换为 CHANGELOG Markdown
*
* @param commitList 提交记录列表
*/
private static void printChangelog(List<RevCommit> commitList) {
for (RevCommit commit : commitList) {
String shortMessage = commit.getShortMessage();
String commitId = commit.getId().getName();
String moduleName = getModuleName(shortMessage);
List<String> changelogTemplateVarList = new ArrayList<>(List.of(StrUtil.subAfter(shortMessage, ": ", false), StrUtil.subPre(commitId, 8), PROJECT_NAME, commitId));
String changelogTemplate = "- ";
if (SHOW_MODULE_NAME && StrUtil.isNotBlank(moduleName)) {
changelogTemplate += "【%s】";
changelogTemplateVarList.add(0, moduleName);
}
changelogTemplate += "%s ([%s](https://github.com/continew-org/%s/commit/%s))%n";
System.out.printf(changelogTemplate, changelogTemplateVarList.toArray());
}
}
/**
* 获取变更类型
*
* @param shortMessage {@link RevCommit#getShortMessage()}
* @return 变更类型
*/
private static String getChangeType(String shortMessage) {
return StrUtil.subBefore(StrUtil.subBefore(shortMessage, ":", false), "(", false);
}
/**
* 获取变更类型名称
*
* @param changeType 变更类型
* @return 变更类型名称
*/
private static String getChangeTypeName(String changeType) {
return switch (changeType) {
case "feat" -> "新特性";
case "fix" -> "问题修复";
case "style", "refactor", "perf", "chore" -> "功能优化";
default -> "其他";
};
}
/**
* 获取模块名称
*
* @param shortMessage {@link RevCommit#getShortMessage()}
* @return 模块名称
*/
private static String getModuleName(String shortMessage) {
return StrUtil.subBetween(StrUtil.subBefore(shortMessage, ":", false), "(", ")");
}
}