源码update
All checks were successful
CodeChecker 变更检测 / code-check (push) Successful in 20s

This commit is contained in:
2026-06-09 15:43:04 +08:00
parent c8840e2af0
commit f94c24a0ab
10 changed files with 540 additions and 24 deletions

View File

@@ -3,20 +3,28 @@ package com.codechecker;
import com.codechecker.analyzer.ClassChangeAnalyzer;
import com.codechecker.analyzer.EndpointIndexBuilder;
import com.codechecker.api.analyzer.ApiChangeAnalyzer;
import com.codechecker.api.analyzer.DtoImpactedApiAnalyzer;
import com.codechecker.api.model.ApiChangeKind;
import com.codechecker.api.model.EndpointChangeReport;
import com.codechecker.api.notify.ApiChangeNotifier;
import com.codechecker.api.scanner.ApiFileChangeScanner;
import com.codechecker.config.AppConfig;
import com.codechecker.git.GitChangeScanner;
import com.codechecker.model.ApiEndpoint;
import com.codechecker.model.ClassChangeReport;
import com.codechecker.notify.OverlapNotificationFilter;
import com.codechecker.notify.WeComNotifier;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
/**
@@ -49,7 +57,7 @@ public class CodeCheckMain implements Callable<Integer> {
System.exit(exitCode);
}
/** 主流程:类变更与 API 变更独立检测、分条通知 */
/** 主流程:类变更与 API 变更检测,支持 Dto 跟进与重叠通知策略 */
@Override
public Integer call() throws Exception {
AppConfig appConfig = AppConfig.load(config.toAbsolutePath());
@@ -59,27 +67,34 @@ public class CodeCheckMain implements Callable<Integer> {
}
GitChangeScanner gitScanner = new GitChangeScanner(repoRoot.toAbsolutePath());
int totalSent = 0;
List<ClassChangeReport> classReports = List.of();
List<EndpointChangeReport> apiReports = List.of();
if (appConfig.isClassCheckEnabled()) {
totalSent += executeClassCheck(appConfig, gitScanner);
classReports = analyzeClassChanges(appConfig, gitScanner);
} else {
System.out.println("类变更检测已关闭class_check.enabled=false");
}
if (appConfig.isApiCheckEnabled()) {
totalSent += executeApiCheck(appConfig, gitScanner);
apiReports = analyzeApiChanges(appConfig, gitScanner, classReports);
} else {
System.out.println("API 变更检测已关闭api_check.enabled=false");
}
OverlapNotificationFilter.FilterResult filtered = OverlapNotificationFilter.apply(
classReports, apiReports, appConfig.getDtoOverlapMode());
int totalSent = sendClassNotifications(appConfig, filtered.classReports())
+ sendApiNotifications(appConfig, filtered.apiReports());
if (totalSent == 0 && appConfig.isOnlyOnChange()) {
System.out.println("无变更,静默退出");
}
return 0;
}
private int executeClassCheck(AppConfig appConfig, GitChangeScanner gitScanner) throws Exception {
private List<ClassChangeReport> analyzeClassChanges(AppConfig appConfig, GitChangeScanner gitScanner)
throws Exception {
System.out.println("=== 类变更检测 ===");
EndpointIndexBuilder indexBuilder = new EndpointIndexBuilder();
Map<String, ApiEndpoint> endpointIndex = indexBuilder.buildIndex(repoRoot.toAbsolutePath(), appConfig);
@@ -89,6 +104,55 @@ public class CodeCheckMain implements Callable<Integer> {
List<ClassChangeReport> reports = analyzer.analyze(
repoRoot.toAbsolutePath(), appConfig, oldSha, newSha, endpointIndex);
System.out.println("检测到需通知的类变更数量: " + reports.size());
return reports;
}
private List<EndpointChangeReport> analyzeApiChanges(AppConfig appConfig, GitChangeScanner gitScanner,
List<ClassChangeReport> classReports) throws Exception {
System.out.println("=== API 变更检测 ===");
ApiFileChangeScanner fileScanner = new ApiFileChangeScanner(gitScanner);
Set<String> changedApiFiles = new LinkedHashSet<>(fileScanner.scanChangedFiles(
repoRoot.toAbsolutePath(), appConfig.getAllApiScanDirs(), oldSha, newSha));
ApiChangeAnalyzer analyzer = new ApiChangeAnalyzer(gitScanner);
List<EndpointChangeReport> reports = new ArrayList<>();
if (!changedApiFiles.isEmpty()) {
reports.addAll(analyzer.analyze(repoRoot.toAbsolutePath(), appConfig, oldSha, newSha));
}
if (appConfig.isDtoApiFollowUpEnabled() && !classReports.isEmpty()) {
DtoImpactedApiAnalyzer dtoAnalyzer = new DtoImpactedApiAnalyzer(gitScanner);
List<EndpointChangeReport> followUpReports = dtoAnalyzer.analyze(
repoRoot.toAbsolutePath(), appConfig, oldSha, newSha, classReports, changedApiFiles);
if (!followUpReports.isEmpty()) {
System.out.println("Dto 跟进检测到 API 参数变更数量: " + followUpReports.size());
reports.addAll(followUpReports);
}
}
reports = dedupeApiReports(reports);
System.out.println("检测到需通知的 API 变更数量: " + reports.size());
return reports;
}
private List<EndpointChangeReport> dedupeApiReports(List<EndpointChangeReport> reports) {
Map<String, EndpointChangeReport> merged = new LinkedHashMap<>();
for (EndpointChangeReport report : reports) {
String key = report.getChangeKind() + "|" + report.getHttpMethod() + "|" + report.getUri();
EndpointChangeReport existing = merged.get(key);
if (existing == null) {
merged.put(key, report);
continue;
}
if (report.getChangeKind() == ApiChangeKind.PARAM_CHANGED
&& existing.getChangeKind() == ApiChangeKind.PARAM_CHANGED) {
report.getParameterChanges().forEach(existing::addParameterChange);
}
}
return new ArrayList<>(merged.values());
}
private int sendClassNotifications(AppConfig appConfig, List<ClassChangeReport> reports) {
if (reports.isEmpty()) {
return 0;
}
@@ -100,12 +164,7 @@ public class CodeCheckMain implements Callable<Integer> {
return reports.size();
}
private int executeApiCheck(AppConfig appConfig, GitChangeScanner gitScanner) throws Exception {
System.out.println("=== API 变更检测 ===");
ApiChangeAnalyzer analyzer = new ApiChangeAnalyzer(gitScanner);
List<EndpointChangeReport> reports = analyzer.analyze(
repoRoot.toAbsolutePath(), appConfig, oldSha, newSha);
System.out.println("检测到需通知的 API 变更数量: " + reports.size());
private int sendApiNotifications(AppConfig appConfig, List<EndpointChangeReport> reports) {
if (reports.isEmpty()) {
return 0;
}