feat: V1.1 - 责任人区分
All checks were successful
序列化结构检查 / serialization-schema-check (push) Successful in 2s
All checks were successful
序列化结构检查 / serialization-schema-check (push) Successful in 2s
This commit is contained in:
@@ -199,6 +199,8 @@ jobs:
|
|||||||
|
|
||||||
COMMIT_TIME=$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S' "${NEW_SHA}")
|
COMMIT_TIME=$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S' "${NEW_SHA}")
|
||||||
|
|
||||||
|
# 对比区间仍为 before→after 全量;--responsible-author 只把推送人非 merge 触及的文件作触发集
|
||||||
|
# (他人改动应已在其各自 push 时告警;纯 merge 推送 → 空触发集 → 不告警)
|
||||||
java -jar "/tmp/serialization-schema-checker-${SERIALIZATION_SCHEMA_CHECKER_VERSION}.jar" \
|
java -jar "/tmp/serialization-schema-checker-${SERIALIZATION_SCHEMA_CHECKER_VERSION}.jar" \
|
||||||
--config .gitea/config/serialization-schema-check-config.yaml \
|
--config .gitea/config/serialization-schema-check-config.yaml \
|
||||||
--repo-root . \
|
--repo-root . \
|
||||||
@@ -206,4 +208,5 @@ jobs:
|
|||||||
--new-sha "$NEW_SHA" \
|
--new-sha "$NEW_SHA" \
|
||||||
--branch "${{ gitea.ref_name }}" \
|
--branch "${{ gitea.ref_name }}" \
|
||||||
--modifier "${{ gitea.actor }}" \
|
--modifier "${{ gitea.actor }}" \
|
||||||
|
--responsible-author "${{ gitea.actor }}" \
|
||||||
--modify-time "$COMMIT_TIME"
|
--modify-time "$COMMIT_TIME"
|
||||||
|
|||||||
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@@ -2,6 +2,7 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<annotationProcessing>
|
<annotationProcessing>
|
||||||
|
<profile default="true" name="Default" enabled="true" />
|
||||||
<profile name="Maven default annotation processors profile" enabled="true">
|
<profile name="Maven default annotation processors profile" enabled="true">
|
||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||||
@@ -14,6 +15,7 @@
|
|||||||
<outputRelativeToContentRoot value="true" />
|
<outputRelativeToContentRoot value="true" />
|
||||||
<processorPath useClasspath="false">
|
<processorPath useClasspath="false">
|
||||||
<entry name="$PROJECT_DIR$/../../../my_java/mvn_resp/org/projectlombok/lombok/1.18.34/lombok-1.18.34.jar" />
|
<entry name="$PROJECT_DIR$/../../../my_java/mvn_resp/org/projectlombok/lombok/1.18.34/lombok-1.18.34.jar" />
|
||||||
|
<entry name="$PROJECT_DIR$/../../../my_java/mvn_resp/org/projectlombok/lombok/1.18.34/lombok-1.18.34.jar" />
|
||||||
</processorPath>
|
</processorPath>
|
||||||
<module name="redis-schema-checker-parent" />
|
<module name="redis-schema-checker-parent" />
|
||||||
</profile>
|
</profile>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ mode=block 且含任意结构变更 → exit 1(流水线失败)
|
|||||||
|
|
||||||
一次 push 推了多个 commit 时,只跑 **一次** 检测,覆盖整次 push 的累计代码差,**不会**因为「变更发生在中间 commit、最后一个 commit 没改相关文件」而漏检。
|
一次 push 推了多个 commit 时,只跑 **一次** 检测,覆盖整次 push 的累计代码差,**不会**因为「变更发生在中间 commit、最后一个 commit 没改相关文件」而漏检。
|
||||||
|
|
||||||
不需要全量历史:工作树是当前 tip;`before` 通过 `git fetch --depth 1 <sha>`(或 deepen)取到即可。
|
不需要全量历史:工作树是当前 tip;`before` 通过 `git fetch --depth 1 <sha>`(或 deepen)取到即可。责任人过滤依赖 `git log old..new`,流水线已通过 `ensure_range` deepen,保证区间提交可见。
|
||||||
|
|
||||||
边界:
|
边界:
|
||||||
|
|
||||||
@@ -38,6 +38,28 @@ mode=block 且含任意结构变更 → exit 1(流水线失败)
|
|||||||
- 中间 commit 改坏又被末 commit 改回 → 累计可能无告警(以最终结构为准)
|
- 中间 commit 改坏又被末 commit 改回 → 累计可能无告警(以最终结构为准)
|
||||||
- commit 计数:优先取 `gitea.event.commits` 长度;否则 deepen 到 `before` 为祖先后再 `git rev-list`(浅克隆下直接 `rev-list` 会少算)
|
- commit 计数:优先取 `gitea.event.commits` 长度;否则 deepen 到 `before` 为祖先后再 `git rev-list`(浅克隆下直接 `rev-list` 会少算)
|
||||||
|
|
||||||
|
### 1.2 责任人过滤(合并推送不背锅)
|
||||||
|
|
||||||
|
**前提**:A/B 各自 push 都会跑检测;B 的结构变更已在 B 的 push 告警。合并/代推时不应再让推送人背他人的锅,也不按人拆多条通知。
|
||||||
|
|
||||||
|
| 项 | 行为 |
|
||||||
|
|----|------|
|
||||||
|
| 对比区间 | 仍为整次 push 的 `before → after`(Schema 新旧用全量 diff 回填) |
|
||||||
|
| 触发集 | 仅 **责任人非 merge 提交** 触及的 Java 文件 ∩ 区间 diff |
|
||||||
|
| 责任人参数 | `--responsible-author`(流水线传 `gitea.actor`);`--modifier` 同为 actor,报告抬头「责任人」 |
|
||||||
|
| Author 匹配 | 对 `git log` 的 `%an <%ae>` **不区分大小写包含** actor(中文名/邮箱对不上时可能匹配失败) |
|
||||||
|
| `--no-merges` | 纯 merge 推送 → 触发集为空 → **不告警**(符合前提) |
|
||||||
|
| 责任人无自有 Java 改动 | 空报告、打日志跳过 |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
java -jar serialization-schema-checker-1.0.0.jar \
|
||||||
|
--old-sha "$OLD_SHA" \
|
||||||
|
--new-sha "$NEW_SHA" \
|
||||||
|
--modifier "${{ gitea.actor }}" \
|
||||||
|
--responsible-author "${{ gitea.actor }}" \
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. 前置条件
|
## 2. 前置条件
|
||||||
@@ -83,10 +105,12 @@ git checkout -B "$BRANCH" "$NEW_SHA" # NEW_SHA = gitea.sha
|
|||||||
git fetch --depth 1 origin "$OLD_SHA" # 优先
|
git fetch --depth 1 origin "$OLD_SHA" # 优先
|
||||||
# 或 git fetch --deepen N # 兜底
|
# 或 git fetch --deepen N # 兜底
|
||||||
|
|
||||||
# 4) 执行
|
# 4) 执行(对比区间全量;责任人过滤触发集)
|
||||||
java -jar serialization-schema-checker-1.0.0.jar \
|
java -jar serialization-schema-checker-1.0.0.jar \
|
||||||
--old-sha "$OLD_SHA" \
|
--old-sha "$OLD_SHA" \
|
||||||
--new-sha "$NEW_SHA" \
|
--new-sha "$NEW_SHA" \
|
||||||
|
--modifier "${{ gitea.actor }}" \
|
||||||
|
--responsible-author "${{ gitea.actor }}" \
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -146,6 +170,8 @@ com/codechecker/serialization-schema-checker/1.0.0/
|
|||||||
| commit 数显示为 1(实际多个) | 浅克隆下 `rev-list` 看不到中间提交 | 已修复:优先事件 `commits` 长度;并 deepen 到 before 为祖先 |
|
| commit 数显示为 1(实际多个) | 浅克隆下 `rev-list` 看不到中间提交 | 已修复:优先事件 `commits` 长度;并 deepen 到 before 为祖先 |
|
||||||
| 漏报(模式/模块) | W0x/MQ 未开 / include_modules 过窄 | 确认 W01~W05 与 mq_patterns(含 MQ03~05、MQ-K03/K04);检查 `mq_read_hints_enabled` 与模块过滤 |
|
| 漏报(模式/模块) | W0x/MQ 未开 / include_modules 过窄 | 确认 W01~W05 与 mq_patterns(含 MQ03~05、MQ-K03/K04);检查 `mq_read_hints_enabled` 与模块过滤 |
|
||||||
| 类型展开不完整 | 类型在依赖 jar 中 | 补充 `manual_mappings.value_type` |
|
| 类型展开不完整 | 类型在依赖 jar 中 | 补充 `manual_mappings.value_type` |
|
||||||
|
| 合并推送仍告他人改动 | 未传 `--responsible-author` / jar 过旧 | 同步流水线模板;确认 jar ≥ 含责任人过滤的版本 |
|
||||||
|
| 责任人过滤后漏报自己的改动 | actor 与 `%an <%ae>` 对不上 | 看日志「责任人过滤…」;核对 commit author 是否含 actor 子串 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -157,6 +183,7 @@ com/codechecker/serialization-schema-checker/1.0.0/
|
|||||||
# OLD = 推送前 tip,NEW = 当前 tip(可用 origin/branch@{1} 或显式 sha)
|
# OLD = 推送前 tip,NEW = 当前 tip(可用 origin/branch@{1} 或显式 sha)
|
||||||
OLD_SHA=$(git rev-parse origin/$(git branch --show-current)~3) # 示例:假设 ahead 3
|
OLD_SHA=$(git rev-parse origin/$(git branch --show-current)~3) # 示例:假设 ahead 3
|
||||||
NEW_SHA=$(git rev-parse HEAD)
|
NEW_SHA=$(git rev-parse HEAD)
|
||||||
|
AUTHOR=$(git log -1 --format=%an)
|
||||||
|
|
||||||
java -jar /path/to/serialization-schema-checker-1.0.0.jar \
|
java -jar /path/to/serialization-schema-checker-1.0.0.jar \
|
||||||
--config .gitea/config/serialization-schema-check-config.yaml \
|
--config .gitea/config/serialization-schema-check-config.yaml \
|
||||||
@@ -164,12 +191,13 @@ java -jar /path/to/serialization-schema-checker-1.0.0.jar \
|
|||||||
--old-sha "$OLD_SHA" \
|
--old-sha "$OLD_SHA" \
|
||||||
--new-sha "$NEW_SHA" \
|
--new-sha "$NEW_SHA" \
|
||||||
--branch $(git branch --show-current) \
|
--branch $(git branch --show-current) \
|
||||||
--modifier "$(git log -1 --format=%an)" \
|
--modifier "$AUTHOR" \
|
||||||
|
--responsible-author "$AUTHOR" \
|
||||||
--modify-time "$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S')" \
|
--modify-time "$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S')" \
|
||||||
--dry-run
|
--dry-run
|
||||||
```
|
```
|
||||||
|
|
||||||
单 commit 自测仍可用 `--old-sha HEAD~1 --new-sha HEAD`。
|
单 commit 自测仍可用 `--old-sha HEAD~1 --new-sha HEAD`。未传 `--responsible-author` 时不做作者过滤(全量 diff 触发)。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -56,26 +56,61 @@ public class SchemaCheckAnalyzer {
|
|||||||
* @throws GitException git 命令失败时
|
* @throws GitException git 命令失败时
|
||||||
*/
|
*/
|
||||||
public CheckReport analyze(String oldSha, String newSha) throws GitException {
|
public CheckReport analyze(String oldSha, String newSha) throws GitException {
|
||||||
|
return analyze(oldSha, newSha, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对比两个提交之间的序列化结构变更。
|
||||||
|
*
|
||||||
|
* @param oldSha 基准提交
|
||||||
|
* @param newSha 当前提交
|
||||||
|
* @param responsibleAuthor 责任人过滤(如 Gitea actor);非空时仅将「该作者非 merge 提交触及的文件」
|
||||||
|
* 作为检测触发集(他人已在各自 push 告警过的改动不再挂到合并推送人)
|
||||||
|
* @return 检测报告
|
||||||
|
* @throws GitException git 命令失败时
|
||||||
|
*/
|
||||||
|
public CheckReport analyze(String oldSha, String newSha, String responsibleAuthor) throws GitException {
|
||||||
GitDiffScanner scanner = new GitDiffScanner(repoRoot);
|
GitDiffScanner scanner = new GitDiffScanner(repoRoot);
|
||||||
|
|
||||||
List<String> changedRaw = scanner.changedJavaFiles(oldSha, newSha);
|
List<String> changedRaw = scanner.changedJavaFiles(oldSha, newSha);
|
||||||
Set<String> changedFiles = new LinkedHashSet<>();
|
Set<String> allDiffFiles = new LinkedHashSet<>();
|
||||||
FileScanner fileScanner = new FileScanner(repoRoot, config.getIncludeModules(), config.getExcludeModules());
|
FileScanner fileScanner = new FileScanner(repoRoot, config.getIncludeModules(), config.getExcludeModules());
|
||||||
for (String path : changedRaw) {
|
for (String path : changedRaw) {
|
||||||
if (path.contains("/src/main/java/") && fileScanner.moduleAllowed(path) && !isFileIgnored(path)) {
|
if (path.contains("/src/main/java/") && fileScanner.moduleAllowed(path) && !isFileIgnored(path)) {
|
||||||
changedFiles.add(path);
|
allDiffFiles.add(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> changedFiles = allDiffFiles;
|
||||||
|
String authorFilter = responsibleAuthor == null ? null : responsibleAuthor.trim();
|
||||||
|
if (authorFilter != null && !authorFilter.isEmpty()) {
|
||||||
|
Set<String> authorFiles = scanner.javaFilesTouchedByAuthor(oldSha, newSha, authorFilter);
|
||||||
|
Set<String> scoped = new LinkedHashSet<>();
|
||||||
|
for (String path : allDiffFiles) {
|
||||||
|
if (authorFiles.contains(path)) {
|
||||||
|
scoped.add(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changedFiles = scoped;
|
||||||
|
System.out.println("[serialization-schema-checker] 责任人过滤: " + authorFilter
|
||||||
|
+ ",区间 diff 文件 " + allDiffFiles.size()
|
||||||
|
+ " → 责任人触及 " + changedFiles.size());
|
||||||
|
if (changedFiles.isEmpty()) {
|
||||||
|
System.out.println("[serialization-schema-checker] 责任人无非 merge 自有 Java 改动,"
|
||||||
|
+ "跳过结构告警(相关变更应已在原作者 push 时通知)。");
|
||||||
|
return buildReport(oldSha, newSha, Collections.emptyList(), Collections.emptyMap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前工作树(= newSha 检出)内容
|
// 当前工作树(= newSha 检出)内容
|
||||||
Map<String, String> newContents = fileScanner.scan();
|
Map<String, String> newContents = fileScanner.scan();
|
||||||
|
|
||||||
// 旧版本内容:以工作树为基线,用 old 版本覆盖变更文件
|
// 旧版本内容:必须以「区间全部 diff 文件」回填,避免他人改动的类型在索引中新旧一致导致漏 diff
|
||||||
Map<String, String> oldContents = new LinkedHashMap<>(newContents);
|
Map<String, String> oldContents = new LinkedHashMap<>(newContents);
|
||||||
for (String path : changedFiles) {
|
for (String path : allDiffFiles) {
|
||||||
String oldContent = scanner.fileContentAt(oldSha, path);
|
String oldContent = scanner.fileContentAt(oldSha, path);
|
||||||
if (oldContent == null) {
|
if (oldContent == null) {
|
||||||
oldContents.remove(path); // 新增文件在旧版本不存在
|
oldContents.remove(path);
|
||||||
} else {
|
} else {
|
||||||
oldContents.put(path, oldContent);
|
oldContents.put(path, oldContent);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class SerializationSchemaCheckerMain implements Callable<Integer> {
|
|||||||
@Option(names = "--branch", description = "分支名(用于报告展示)")
|
@Option(names = "--branch", description = "分支名(用于报告展示)")
|
||||||
private String branch;
|
private String branch;
|
||||||
|
|
||||||
@Option(names = "--modifier", description = "提交人")
|
@Option(names = "--modifier", description = "责任人/推送人(报告展示;建议与 --responsible-author 一致)")
|
||||||
private String modifier;
|
private String modifier;
|
||||||
|
|
||||||
@Option(names = "--modify-time", description = "提交时间")
|
@Option(names = "--modify-time", description = "提交时间")
|
||||||
@@ -52,6 +52,10 @@ public class SerializationSchemaCheckerMain implements Callable<Integer> {
|
|||||||
@Option(names = "--dry-run", description = "只输出报告,不发送企微通知")
|
@Option(names = "--dry-run", description = "只输出报告,不发送企微通知")
|
||||||
private boolean dryRun;
|
private boolean dryRun;
|
||||||
|
|
||||||
|
@Option(names = "--responsible-author",
|
||||||
|
description = "责任人过滤:仅检测该作者非 merge 提交触及的 Java 文件(通常传 Gitea actor)")
|
||||||
|
private String responsibleAuthor;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer call() {
|
public Integer call() {
|
||||||
try {
|
try {
|
||||||
@@ -69,10 +73,13 @@ public class SerializationSchemaCheckerMain implements Callable<Integer> {
|
|||||||
|
|
||||||
Path root = repoRoot.toAbsolutePath().normalize();
|
Path root = repoRoot.toAbsolutePath().normalize();
|
||||||
SchemaCheckAnalyzer analyzer = new SchemaCheckAnalyzer(config, root);
|
SchemaCheckAnalyzer analyzer = new SchemaCheckAnalyzer(config, root);
|
||||||
CheckReport report = analyzer.analyze(oldSha, newSha);
|
String author = responsibleAuthor != null && !responsibleAuthor.trim().isEmpty()
|
||||||
|
? responsibleAuthor.trim()
|
||||||
|
: (modifier != null ? modifier.trim() : null);
|
||||||
|
CheckReport report = analyzer.analyze(oldSha, newSha, author);
|
||||||
|
|
||||||
report.setBranch(branch);
|
report.setBranch(branch);
|
||||||
report.setModifier(modifier);
|
report.setModifier(modifier != null ? modifier : author);
|
||||||
report.setModifyTime(modifyTime);
|
report.setModifyTime(modifyTime);
|
||||||
report.setRepository(repository != null ? repository : root.getFileName().toString());
|
report.setRepository(repository != null ? repository : root.getFileName().toString());
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ import java.io.InputStreamReader;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于 git 命令的差异扫描与双版本文件内容读取。
|
* 基于 git 命令的差异扫描与双版本文件内容读取。
|
||||||
@@ -18,6 +21,9 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class GitDiffScanner {
|
public class GitDiffScanner {
|
||||||
|
|
||||||
|
/** {@code git log --pretty} 中标识 commit 头的前缀(解析责任人触及文件时用)。 */
|
||||||
|
static final String COMMIT_HEADER_PREFIX = "COMMIT ";
|
||||||
|
|
||||||
private final Path repoRoot;
|
private final Path repoRoot;
|
||||||
|
|
||||||
public GitDiffScanner(Path repoRoot) {
|
public GitDiffScanner(Path repoRoot) {
|
||||||
@@ -40,6 +46,55 @@ public class GitDiffScanner {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回 old..new 区间内、由责任人<strong>非 merge</strong>提交触及的 Java 文件。
|
||||||
|
* <p>用于「作者 push 已告警、合并推送人不再背锅」:只把责任人自己的改动纳入检测触发集。</p>
|
||||||
|
*
|
||||||
|
* @param authorFilter 责任人过滤串(通常为 Gitea actor);与 author name/email 做不区分大小写的包含匹配
|
||||||
|
* @return 相对路径集合;无匹配时为空
|
||||||
|
*/
|
||||||
|
public Set<String> javaFilesTouchedByAuthor(String oldSha, String newSha, String authorFilter)
|
||||||
|
throws GitException {
|
||||||
|
if (authorFilter == null || authorFilter.trim().isEmpty()) {
|
||||||
|
return new LinkedHashSet<>();
|
||||||
|
}
|
||||||
|
List<String> lines = runLines(
|
||||||
|
"git", "log", "--no-merges", "--name-only",
|
||||||
|
"--pretty=format:" + COMMIT_HEADER_PREFIX + "%an <%ae>",
|
||||||
|
oldSha + ".." + newSha, "--", "*.java");
|
||||||
|
return parseAuthorTouchedJavaFiles(lines, authorFilter.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析 {@link #javaFilesTouchedByAuthor} 的 git log 输出。
|
||||||
|
*/
|
||||||
|
static Set<String> parseAuthorTouchedJavaFiles(List<String> lines, String authorFilter) {
|
||||||
|
Set<String> result = new LinkedHashSet<>();
|
||||||
|
if (lines == null || authorFilter == null || authorFilter.isEmpty()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
String needle = authorFilter.toLowerCase(Locale.ROOT);
|
||||||
|
boolean take = false;
|
||||||
|
for (String raw : lines) {
|
||||||
|
if (raw == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String line = raw.trim();
|
||||||
|
if (line.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.startsWith(COMMIT_HEADER_PREFIX)) {
|
||||||
|
String identity = line.substring(COMMIT_HEADER_PREFIX.length()).toLowerCase(Locale.ROOT);
|
||||||
|
take = identity.contains(needle);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (take && line.endsWith(".java")) {
|
||||||
|
result.add(line.replace('\\', '/'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取某提交下指定文件的内容;文件在该提交不存在时返回 null。
|
* 读取某提交下指定文件的内容;文件在该提交不存在时返回 null。
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class CheckReport {
|
|||||||
private String oldSha;
|
private String oldSha;
|
||||||
/** 当前提交 SHA */
|
/** 当前提交 SHA */
|
||||||
private String newSha;
|
private String newSha;
|
||||||
/** 提交人 */
|
/** 责任人 / 推送人(报告抬头展示;流水线责任人过滤时通常为 Gitea actor) */
|
||||||
private String modifier;
|
private String modifier;
|
||||||
/** 提交时间(展示用字符串) */
|
/** 提交时间(展示用字符串) */
|
||||||
private String modifyTime;
|
private String modifyTime;
|
||||||
|
|||||||
66
src/test/java/com/codechecker/cache/git/GitDiffScannerAuthorFilterTest.java
vendored
Normal file
66
src/test/java/com/codechecker/cache/git/GitDiffScannerAuthorFilterTest.java
vendored
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package com.codechecker.cache.git;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link GitDiffScanner#parseAuthorTouchedJavaFiles} 责任人过滤解析单测。
|
||||||
|
*/
|
||||||
|
class GitDiffScannerAuthorFilterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void takesOnlyMatchingAuthorJavaFiles() {
|
||||||
|
Set<String> files = GitDiffScanner.parseAuthorTouchedJavaFiles(Arrays.asList(
|
||||||
|
"COMMIT Alice <alice@example.com>",
|
||||||
|
"a/src/main/java/A.java",
|
||||||
|
"a/src/main/java/Shared.java",
|
||||||
|
"COMMIT Bob <bob@example.com>",
|
||||||
|
"b/src/main/java/B.java",
|
||||||
|
"a/src/main/java/Shared.java"
|
||||||
|
), "alice");
|
||||||
|
|
||||||
|
assertEquals(Set.of(
|
||||||
|
"a/src/main/java/A.java",
|
||||||
|
"a/src/main/java/Shared.java"
|
||||||
|
), files);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void matchesActorAgainstEmailCaseInsensitive() {
|
||||||
|
Set<String> files = GitDiffScanner.parseAuthorTouchedJavaFiles(Arrays.asList(
|
||||||
|
"COMMIT 张三 <ZhangSan@corp.com>",
|
||||||
|
"pkg/Foo.java",
|
||||||
|
"COMMIT 李四 <lisi@corp.com>",
|
||||||
|
"pkg/Bar.java"
|
||||||
|
), "zhangsan");
|
||||||
|
|
||||||
|
assertEquals(Set.of("pkg/Foo.java"), files);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void skipsNonJavaAndEmptyLines() {
|
||||||
|
Set<String> files = GitDiffScanner.parseAuthorTouchedJavaFiles(Arrays.asList(
|
||||||
|
"COMMIT alice <a@x.com>",
|
||||||
|
"",
|
||||||
|
"README.md",
|
||||||
|
"src/Main.java",
|
||||||
|
"COMMIT other <o@x.com>",
|
||||||
|
"src/Other.java"
|
||||||
|
), "alice");
|
||||||
|
|
||||||
|
assertEquals(Set.of("src/Main.java"), files);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void emptyFilterOrLinesYieldEmpty() {
|
||||||
|
assertTrue(GitDiffScanner.parseAuthorTouchedJavaFiles(Collections.emptyList(), "alice").isEmpty());
|
||||||
|
assertTrue(GitDiffScanner.parseAuthorTouchedJavaFiles(
|
||||||
|
Collections.singletonList("COMMIT alice <a@x.com>"), "").isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user