This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user