143 lines
5.1 KiB
Java
143 lines
5.1 KiB
Java
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), "(", ")");
|
||
}
|
||
} |