diff --git a/README.md b/README.md
index 1f66157..d4b2175 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,30 @@
# code-diff
-**用于java代码的code-dif && 覆盖数据收集**
-
+**用于java代码的code-diff && 覆盖数据合并收集**
+
+* 支持git仓库获取代码code-diff
+* 支持多个实例服务合并收集
+* 支持同分支不同commit代码覆盖率合并收集
+* 支持页面配置管理实例服务:配置jacoco端口;配置includes/excludes表达式
+* 支持实时生成查看报告:报告生成支持使用includes && excldes表达式过滤
+* 支持提供api配合jenkins pipeline集成使用
+* 支持收集函数调用链
+
+## linux部署
+> 需要部署server && web 2个服务
+> FBI warning!!!
+> 这2个服务都需要和jenkins部署在同一台linux上
+### server部署
+- 先执行sql文件:[ code-diff/sql/coverage.sql](https://github.com/alwans/code-diff/blob/main/sql/coverage.sql)
+- 修改数据库配置:[diff-services/src/main/resources/application.properties](https://github.com/alwans/code-diff/blob/main/diff-services/src/main/resources/application.properties)
+- 构建jar:mvn clean install -Dmaven.test.skip=true
+- 启动jar服务:java -jar diff-services-1.0.0.jar
+### web部署
+- nginx部署web服务,web文件:[code-diff/dist.zip](https://github.com/alwans/code-diff/tree/main/dist)
+- 访问wen站点
## docker部署
+
待更新...
+
## 示图
### 1. 集成到jenkins的pipeline脚本中
diff --git a/diff-common/pom.xml b/diff-common/pom.xml
index 6071ddd..9aa64e4 100644
--- a/diff-common/pom.xml
+++ b/diff-common/pom.xml
@@ -51,6 +51,10 @@
junit
test
+
+ com.alibaba.fastjson2
+ fastjson2
+
diff --git a/diff-common/src/main/java/com/test/diff/common/util/FastJsonUtil.java b/diff-common/src/main/java/com/test/diff/common/util/FastJsonUtil.java
new file mode 100644
index 0000000..180fd6d
--- /dev/null
+++ b/diff-common/src/main/java/com/test/diff/common/util/FastJsonUtil.java
@@ -0,0 +1,19 @@
+package com.test.diff.common.util;
+
+import com.alibaba.fastjson2.JSON;
+
+/**
+ * @author wl
+ * @date 2022/8/2
+ */
+public class FastJsonUtil {
+
+
+ public static String serialize (Object object) {
+ return JSON.toJSONString(object);
+ }
+
+ public static T deserialize (String str, Class type) {
+ return JSON.parseObject(str, type);
+ }
+}
diff --git a/diff-common/src/test/java/com/test/diff/common/JacksonTest.java b/diff-common/src/test/java/com/test/diff/common/JacksonTest.java
index e4e6cfd..3705e03 100644
--- a/diff-common/src/test/java/com/test/diff/common/JacksonTest.java
+++ b/diff-common/src/test/java/com/test/diff/common/JacksonTest.java
@@ -1,5 +1,9 @@
package com.test.diff.common;
+import com.alibaba.fastjson2.JSON;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.test.diff.common.util.JacksonUtil;
+import lombok.Data;
import org.junit.Test;
import java.io.DataOutputStream;
@@ -9,8 +13,43 @@
public class JacksonTest {
+ int deep = 50;
+ int count = 1;
+ Node tailNode = null;
@Test
- public void testOutputStreamSerialize() throws FileNotFoundException {
+ public void testOutputStreamSerialize() throws FileNotFoundException, JsonProcessingException {
+ Node head = new Node();
+ head.setUri("com/icai/common/redis/RedisUtils.setRedisProperties(Lcom/icai/common/redis/RedisProperties;)V--" +count);
+ count++;
+ getNode(head);
+// System.out.println(tailNode);
+// String str = JacksonUtil.serialize(tailNode);
+ String str = JSON.toJSONString(tailNode);
+ System.out.println(str.length());
+ }
+ private void getNode(Node preNode) {
+ Node node = new Node();
+ node.setPreNode(preNode);
+ node.setCalledNode(preNode);
+ node.setUri("com/beitai/common/redis/RedisUtils.setRedisProperties(Lcom/beitai/common/redis/RedisProperties;)V--" +count);
+ count++;
+ if(count<=deep){
+ deep--;
+ getNode(node);
+ }
+ else {
+ tailNode = node;
+ }
}
}
+
+@Data
+class Node {
+
+ private Node preNode;
+
+ private Node calledNode;
+
+ private String uri;
+}
diff --git a/diff-services/src/main/java/com/test/diff/services/controller/FileController.java b/diff-services/src/main/java/com/test/diff/services/controller/FileController.java
index 86dcec0..4cd2a9d 100644
--- a/diff-services/src/main/java/com/test/diff/services/controller/FileController.java
+++ b/diff-services/src/main/java/com/test/diff/services/controller/FileController.java
@@ -5,8 +5,10 @@
import com.test.diff.services.entity.ProjectInfo;
import com.test.diff.services.enums.StatusCode;
import com.test.diff.services.internal.source.SourceFileHandleFactory;
+import com.test.diff.services.params.CloneParamDto;
import com.test.diff.services.params.FileParams;
import com.test.diff.services.service.ProjectInfoService;
+import com.test.diff.services.task.CloneProjectTask;
import com.test.diff.services.utils.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -34,6 +36,9 @@ public class FileController {
@Resource
private FileUtil fileUtil;
+ @Resource
+ private CloneProjectTask cloneProjectTask;
+
@PostMapping(value = "/class/path", produces = "application/json;charset=UTF-8")
public BaseResult getFileClassPath(@RequestBody @Validated FileParams fileParams){
ProjectInfo projectInfo = projectInfoService.getById(fileParams.getId());
@@ -56,6 +61,22 @@ public BaseResult getFileClassPath(@RequestBody @Validated FileParams fileParams
return BaseResult.error(StatusCode.OTHER_ERROR, "class文件不存在");
}
+ /**
+ * 克隆指定工程的指定分支或者指定commit id代码
+ * @param cloneParamDto 克隆参数
+ * @return
+ */
+ @GetMapping("/clone/")
+ public BaseResult cloneProject(@Validated CloneParamDto cloneParamDto){
+ ProjectInfo projectInfo = projectInfoService.getById(cloneParamDto.getId());
+ if (projectInfo == null){
+ return BaseResult.error(StatusCode.OTHER_ERROR, "id="+cloneParamDto.getId().toString()+"的工程不存在, 请检查参数");
+ }
+ cloneProjectTask.checkClone(projectInfo, cloneParamDto.getBranchName(), cloneParamDto.getCommitId());
+ cloneProjectTask.cloneProjectTask(projectInfo, cloneParamDto.getBranchName(), cloneParamDto.getCommitId());
+ return BaseResult.success(null);
+ }
+
@GetMapping( "copy/project")
public BaseResult copyProjectFile(@RequestParam("path") String path,
@RequestParam("branch") String branch,
diff --git a/diff-services/src/main/java/com/test/diff/services/internal/jacoco/JacocoHandle.java b/diff-services/src/main/java/com/test/diff/services/internal/jacoco/JacocoHandle.java
index 9bbc3d4..95cd34f 100644
--- a/diff-services/src/main/java/com/test/diff/services/internal/jacoco/JacocoHandle.java
+++ b/diff-services/src/main/java/com/test/diff/services/internal/jacoco/JacocoHandle.java
@@ -46,7 +46,7 @@ public static ExecFileLoader getLoader(String execFilePath){
* @return
*/
public static String getBranchName(ExecFileLoader loader){
- return loader.getExecutionDataStore().getBranchName();
+ return loader.getBranchName();
}
/**
@@ -55,7 +55,7 @@ public static String getBranchName(ExecFileLoader loader){
* @return
*/
public static String getCommitId(ExecFileLoader loader){
- return loader.getExecutionDataStore().getCommitId();
+ return loader.getCommitId();
}
/**
diff --git a/diff-services/src/main/java/com/test/diff/services/openapi/controller/AppInfoController.java b/diff-services/src/main/java/com/test/diff/services/openapi/controller/AppInfoController.java
index 823ee7f..bc0b001 100644
--- a/diff-services/src/main/java/com/test/diff/services/openapi/controller/AppInfoController.java
+++ b/diff-services/src/main/java/com/test/diff/services/openapi/controller/AppInfoController.java
@@ -40,14 +40,15 @@ public BaseResult getInfo(@RequestParam("groupName") String groupName,
if(CollectionUtils.isEmpty(list)){
return BaseResult.error(StatusCode.PROJECT_INFO_NOT_EXISTS);
}
- ProjectInfo projectInfo = list.get(0);
- List apps = coverageAppService.getListByProjectId(projectInfo.getId());
- if(CollectionUtils.isEmpty(apps)){
- return BaseResult.error(StatusCode.APP_INFO_NOT_EXISTS);
- }
- for(CoverageApp app : apps){
- if(app.getAppName().equalsIgnoreCase(projectName)){
- return BaseResult.success(app);
+ for (ProjectInfo projectInfo : list) {
+ List apps = coverageAppService.getListByProjectId(projectInfo.getId());
+// if(CollectionUtils.isEmpty(apps)){
+// return BaseResult.error(StatusCode.APP_INFO_NOT_EXISTS);
+// }
+ for(CoverageApp app : apps){
+ if(app.getAppName().equalsIgnoreCase(projectName)){
+ return BaseResult.success(app);
+ }
}
}
return BaseResult.error(StatusCode.APP_INFO_NOT_EXISTS);
diff --git a/diff-services/src/main/java/com/test/diff/services/params/CloneParamDto.java b/diff-services/src/main/java/com/test/diff/services/params/CloneParamDto.java
new file mode 100644
index 0000000..20fc598
--- /dev/null
+++ b/diff-services/src/main/java/com/test/diff/services/params/CloneParamDto.java
@@ -0,0 +1,39 @@
+package com.test.diff.services.params;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author wl
+ * @date 2022/10/1
+ * @Description 克隆项目请求参数
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CloneParamDto extends BaseParams {
+
+ @NotNull(message = "工程id不可为空")
+ private Integer id;
+
+ @NotEmpty(message = "分支名不可为空")
+ private String branchName;
+
+ private String commitId;
+
+// @ApiModelProperty(value = "编译命令")
+// private String compileInstruction;
+//
+// /**
+// * {@link BuildToolTypeEnum#getValue()}
+// */
+// @ApiModelProperty(value = "编译工具类型")
+// private Integer buildToolType;
+//
+// @ApiModelProperty("是否需要编译")
+// private Boolean isNeedCompile;
+}
diff --git a/diff-services/src/main/java/com/test/diff/services/params/CompileParamDto.java b/diff-services/src/main/java/com/test/diff/services/params/CompileParamDto.java
new file mode 100644
index 0000000..b0b51fe
--- /dev/null
+++ b/diff-services/src/main/java/com/test/diff/services/params/CompileParamDto.java
@@ -0,0 +1,35 @@
+package com.test.diff.services.params;
+;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author wl
+ * @date 2022/9/30
+ * @Description 编译参数
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CompileParamDto extends BaseParams {
+
+ @NotNull(message = "工程id不可为空")
+ private Integer id;
+
+ @NotEmpty(message = "分支名不可为空")
+ private String branchName;
+
+ private String commitId;
+
+ private String compileInstruction;
+
+
+ private Integer buildToolType;
+
+ private Boolean isRecompile;
+
+}
diff --git a/diff-services/src/main/java/com/test/diff/services/task/CloneProjectTask.java b/diff-services/src/main/java/com/test/diff/services/task/CloneProjectTask.java
new file mode 100644
index 0000000..d12fdb3
--- /dev/null
+++ b/diff-services/src/main/java/com/test/diff/services/task/CloneProjectTask.java
@@ -0,0 +1,213 @@
+package com.test.diff.services.task;
+
+
+import com.sun.prism.impl.BaseResourceFactory;
+import com.test.diff.services.entity.ProjectInfo;
+import com.test.diff.services.entity.RepoInfo;
+import com.test.diff.services.exceptions.BizException;
+import com.test.diff.services.internal.BaseRepository;
+import com.test.diff.services.internal.RepositoryFactory;
+import com.test.diff.services.params.CompileParamDto;
+import com.test.diff.services.service.ProjectInfoService;
+import com.test.diff.services.service.RepoInfoService;
+import com.test.diff.services.utils.CMDUtils;
+import com.test.diff.services.utils.FileUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jgit.api.Git;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StopWatch;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+/**
+ * @author wl
+ * @date 2022/9/30
+ */
+@Slf4j
+@Component
+public class CloneProjectTask {
+
+ /**
+ * clone失败的历史任务
+ */
+ public static final List failedTasks = new ArrayList<>();
+
+ /**
+ * 克隆中的项目
+ */
+ public static final Map taskMap = new ConcurrentHashMap<>();
+
+ /**
+ * 仓库实例
+ */
+ private static final Map repoInstances = new ConcurrentHashMap<>();
+
+ @Resource
+ private RepoInfoService repoInfoService;
+
+
+
+ /**
+ * 异步克隆工程代码
+ * @param projectInfo 覆盖工程信息
+ * @param branch 分支信息
+ */
+ @Async("compileExecutor")
+ public void cloneProjectTask(ProjectInfo projectInfo, String branch){
+ cloneProject(projectInfo, branch, null, true);
+ }
+
+ @Async("compileExecutor")
+ public void cloneProjectTask(ProjectInfo projectInfo, String branch, String commitId){
+ cloneProject(projectInfo, branch, commitId, true);
+ }
+
+ /**
+ * 检查是否可以克隆
+ * @param projectInfo
+ */
+ public void checkClone(ProjectInfo projectInfo,
+ String branch, String commitId){
+ String compileKey = projectInfo.getProjectName() + projectInfo.getEnv()
+ + branch + commitId;
+ if (failedTasks.contains(projectInfo.getProjectName())){
+ new BizException(projectInfo.getProjectName()+"工程克隆异常, 不再继续尝试");
+ }
+ synchronized (this){
+ if (taskMap.get(compileKey) != null){
+ throw new BizException(projectInfo.getProjectName()+"项目正在clone中..., 请稍后再试");
+ }
+ taskMap.put(compileKey, projectInfo.getProjectName());
+ if (repoInstances.get(projectInfo.getRepoId()) == null){
+ RepoInfo repoInfo = repoInfoService.getById(projectInfo.getRepoId());
+ if (repoInfo == null){
+ throw new BizException(projectInfo.getProjectName() + "项目的仓库信息不存在,克隆失败");
+ }
+ repoInstances.put(projectInfo.getRepoId(), repoInfo);
+ }
+ }
+ }
+
+ /**
+ * 克隆工程
+ * @param projectInfo
+ * @param branch
+ * @param commitId
+ * @param isNeedCompile 是否需要编译
+ */
+ public void cloneProject(ProjectInfo projectInfo, String branch, String commitId, Boolean isNeedCompile){
+ // 手动调用clone检查
+// checkClone(coverageProject, branch, commitId);
+ RepoInfo repoDto = repoInstances.get(projectInfo.getRepoId());
+ String new_branch = "";
+ if (StringUtils.isEmpty(commitId)){
+ new_branch = branch;
+ }else {
+ new_branch = fixBranch(branch, commitId);
+ }
+ StopWatch stopWatch = new StopWatch();
+ try {
+ String repoPath = FileUtil.getRepoPath(projectInfo, new_branch);
+ log.info("开始克隆"+projectInfo.getProjectName()+"工程,仓库路径: "+repoPath);
+ stopWatch.start();
+ BaseRepository repository = RepositoryFactory.create(repoDto);
+ Git git = repository.clone(projectInfo.getProjectUrl(), repoPath, branch);
+ git.getRepository().close();
+ git.close();
+ if (StringUtils.isNotEmpty(commitId)){
+ repository.pullByCommitId(repoPath, branch, commitId);
+ }
+ stopWatch.stop();
+ log.info("{}工程clone完成, 耗时: {}秒", projectInfo.getProjectName(), stopWatch.getTotalTimeSeconds());
+ } catch (Exception e) {
+ stopWatch.stop();
+ failedTasks.add(projectInfo.getProjectName());
+ log.error("克隆{}项目异常, 耗时: {}秒, 异常原因: {}", projectInfo.getProjectName(),
+ stopWatch.getTotalTimeSeconds(),
+ e.getMessage());
+ } finally {
+ String compileKey = projectInfo.getProjectName() + projectInfo.getEnv()
+ + branch + commitId;
+ taskMap.remove(compileKey);
+ }
+ if (isNeedCompile){
+ // 克隆完,顺便编译一下
+ CompileParamDto compileParamDto = new CompileParamDto();
+ compileParamDto.setId(projectInfo.getId().intValue());
+ compileParamDto.setBranchName(branch);
+ compileParamDto.setCommitId(commitId);
+ compileSource(projectInfo, compileParamDto);
+ }
+ }
+
+ public void compileSource(ProjectInfo projectInfo, CompileParamDto compileParamDto){
+ // 计时
+ StopWatch stopWatch = new StopWatch();
+ stopWatch.start();
+ String branchPath = compileParamDto.getBranchName();
+ if (StringUtils.isNotEmpty(compileParamDto.getCommitId())){
+ branchPath = fixBranch(compileParamDto.getBranchName(), compileParamDto.getCommitId());
+ }
+ String repoPath = FileUtil.getRepoPath(projectInfo, branchPath);
+ log.info("{}工程开始编译...., 分支: {}, commit id: {}", projectInfo.getProjectName(),
+ compileParamDto.getBranchName(),
+ compileParamDto.getCommitId());
+ // 判断代码是不是存在
+ if (!new File(repoPath).exists()){
+ log.info("{}项目的{}分支代码不存在,开始clone项目...", projectInfo.getProjectName(), repoPath);
+ checkClone(projectInfo, compileParamDto.getBranchName(), compileParamDto.getCommitId());
+ log.info("{}项目的{}克隆结束,开始编译项目...", projectInfo.getProjectName(), repoPath);
+ }
+ try {
+ // 开始编译
+ String execCommand = "cd "+repoPath+" && mvn clean package -Dmaven.test.skip=true";
+ CMDUtils.CmdResult result = CMDUtils.exec(execCommand);
+ if (result.getIsSuccess()) {
+ log.info("{}工程编译成功", projectInfo.getProjectName());
+ } else {
+ log.error("{}工程编译失败, 编译信息: {}", projectInfo.getProjectName(), result.getContext());
+ }
+ stopWatch.stop();
+ log.info("{}工程编译完成, 耗时:{}秒", projectInfo.getProjectName(), stopWatch.getTotalTimeSeconds());
+ }finally {
+ String compileKey = projectInfo.getProjectName() + projectInfo.getEnv()
+ + compileParamDto.getBranchName() + compileParamDto.getCommitId();
+// compileMap.remove(compileKey);
+ }
+
+ }
+
+ @Bean("compileExecutor")
+ public Executor compileExecutor(){
+ return Executors.newFixedThreadPool(2, new ThreadFactory() {
+ @Override
+ public Thread newThread(@NotNull Runnable r) {
+ Thread thread = new Thread(r);
+ thread.setName("compile async thread --" + thread.getId());
+ return thread;
+ }
+ });
+ }
+
+
+ public String fixBranch(String branch, String commitId){
+ if (branch.contains("/")){
+ branch = branch.replaceAll("/", "_" );
+ }
+ return branch + "_" + commitId;
+ }
+
+}
diff --git a/diff-services/src/main/java/com/test/diff/services/utils/CMDUtils.java b/diff-services/src/main/java/com/test/diff/services/utils/CMDUtils.java
new file mode 100644
index 0000000..b9c8c06
--- /dev/null
+++ b/diff-services/src/main/java/com/test/diff/services/utils/CMDUtils.java
@@ -0,0 +1,196 @@
+package com.test.diff.services.utils;
+
+import com.test.diff.services.exceptions.BizException;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * @author wl
+ * @date 2022/8/17
+ */
+@Slf4j
+public class CMDUtils {
+
+ public static CmdResult exec (String cmdCommand) {
+ cmdCommand = fixWinCmd(cmdCommand);
+ StringBuilder stringBuilder = new StringBuilder();
+ Process process = null;
+ try {
+ process = Runtime.getRuntime().exec(getOsCmd() + cmdCommand );
+ BufferedReader bufferedReader = new BufferedReader(
+ new InputStreamReader(process.getInputStream(), "GBK"));
+ String line = null;
+ while((line=bufferedReader.readLine()) != null)
+ {
+ stringBuilder.append(line+"\n");
+ }
+ return CmdResult.builder()
+ .isSuccess(process.exitValue() == 0 ? true : false )
+ .status(process.exitValue())
+ .context(stringBuilder.toString())
+ .build();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static String execShell(String scriptPath, String... params) {
+ String[] cmd = new String[]{scriptPath};
+ cmd = ArrayUtils.addAll(cmd, params);
+ //解决脚本没有执行权限
+ ProcessBuilder builder = new ProcessBuilder("/bin/chmod", "777", scriptPath);
+ Process process = null;
+ int runningStatus = 0;
+ try {
+ process = builder.start();
+ process.waitFor();
+ Process ps = Runtime.getRuntime().exec(cmd);
+ runningStatus = ps.waitFor();
+ BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
+ BufferedReader err = new BufferedReader(new InputStreamReader(ps.getErrorStream()));
+ StringBuffer sb = new StringBuffer();
+ String line;
+ while ((line = br.readLine()) != null) {
+ sb.append(line).append("\n");
+ }
+ while ((line = err.readLine()) != null) {
+ log.error("shell log error...." + line);
+ sb.append(line).append("\n");
+ }
+ if (runningStatus != 0){
+ throw new BizException("exec shell script failed, result: " + sb.toString());
+ }
+ //执行结果
+ return sb.toString();
+ } catch (IOException e) {
+ log.error("Failed to exec {}, sandbox load failed", scriptPath);
+ e.printStackTrace();
+ throw new RuntimeException("shell script exec failed, sandbox load failed");
+ } catch (InterruptedException e) {
+ log.error("Failed to exec {}, sandbox load failed", scriptPath);
+ e.printStackTrace();
+ throw new RuntimeException("shell script exec failed, sandbox load failed");
+ }
+ }
+
+ /**
+ * windows系统,如果指令是cd, 需要先D: ,然后再执行cd D:\home 才能正确进入到home目录下
+ * 所以这里特殊处理下
+ * @param cmdCommand
+ * @return
+ */
+ private static String fixWinCmd(String cmdCommand){
+ if (OsUtils.isWindows() && cmdCommand.contains("cd")){
+ String driveLetter = "";
+ // 1.先把多条指令拆分
+ String[] commands = cmdCommand.split("&&");
+ List commandList = new ArrayList<>();
+ for (int i = 0; i < commands.length; i++) {
+ // 2.找出cd操作的指令
+ if (commands[i].trim().startsWith("cd")){
+ driveLetter = getDriveLetter(commands[i]);
+ if (StringUtils.isNotEmpty(driveLetter)){
+ commandList.add( driveLetter + ":"); // D:
+ }
+
+ }
+ commandList.add(commands[i]);
+ }
+ return String.join(" && ", commandList.toArray(new String[0]));
+ }
+ return cmdCommand;
+ }
+
+ /**
+ * 获取windows系统下,cd命令中的盘符
+ * @param command 指令
+ * @return
+ */
+ private static String getDriveLetter(String command){
+ String driveLetter = "";
+ String[] arr = command.split(" ");
+ for (String s: arr){
+ if (s.trim().contains(":\\")){
+ driveLetter = s.split(":")[0];
+ }
+ }
+ return driveLetter.toUpperCase(Locale.ROOT).trim();
+ }
+
+ /**
+ * 获取根指令信息
+ * @return
+ */
+ private static String getOsCmd(){
+ if (OsUtils.isLinux()){
+ return "/bin/sh -c ";
+ }
+ else if(OsUtils.isWindows()){
+ return "cmd /c ";
+ }
+ throw new BizException("系统不支持");
+ }
+
+ /**
+ * 执行结果
+ */
+ @Data
+ @Builder
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class CmdResult{
+
+ /**
+ * 是否成功
+ */
+ private Boolean isSuccess;
+
+ /**
+ * 执行返回状态码
+ */
+ private Integer status;
+
+ /**
+ * 执行返回内容
+ */
+ private String context;
+
+ }
+
+ class inputStreamThread implements Runnable{
+ private InputStream ins = null;
+ private BufferedReader bfr = null;
+ public inputStreamThread(InputStream ins){
+ this.ins = ins;
+ this.bfr = new BufferedReader(new InputStreamReader(ins));
+ }
+ @Override
+ public void run() {
+ String line = null;
+ byte[] b = new byte[100];
+ int num = 0;
+ try {
+ while((num=ins.read(b))!=-1){
+ System.out.println(new String(b,"gb2312"));
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+}
diff --git a/diff-services/src/main/java/com/test/diff/services/utils/FileUtil.java b/diff-services/src/main/java/com/test/diff/services/utils/FileUtil.java
index 6b0bba9..c57c08c 100644
--- a/diff-services/src/main/java/com/test/diff/services/utils/FileUtil.java
+++ b/diff-services/src/main/java/com/test/diff/services/utils/FileUtil.java
@@ -44,7 +44,7 @@ public void createDir(String path) throws FileException {
* @param subPath
* @return
*/
- public String addPath(String... subPath){
+ public static String addPath(String... subPath){
StringBuilder sb = new StringBuilder();
for(String path: subPath){
if(StringUtils.isBlank(path)){
@@ -59,9 +59,9 @@ public String addPath(String... subPath){
return sb.toString().substring(0, sb.lastIndexOf(File.separator));
}
- public String addPaths(String root, String... sunPath){
+ public String addPaths(String root, String... subPath){
StringBuilder path = new StringBuilder(root);
- for(String p: sunPath){
+ for(String p: subPath){
p = p.replaceAll("/", "_");
path.append(File.separator)
.append(p);
@@ -79,14 +79,14 @@ public String addPaths(String root, String... sunPath){
* @param branch
* @return
*/
- public String getRepoPath(String group, String env, String projectName, String branch){
+ public static String getRepoPath(String group, String env, String projectName, String branch){
if(branch.contains("/")){
branch = branch.replaceAll("/", "_");
}
return addPath(FileConst.DIFF_ROOT_PATH, group, env, projectName, branch);
}
- public String getRepoPath(ProjectInfo projectInfo, String branch){
+ public static String getRepoPath(ProjectInfo projectInfo, String branch){
return getRepoPath(projectInfo.getProjectGroup(), projectInfo.getEnv(),
projectInfo.getProjectName(),
branch);
diff --git a/diff-services/src/main/java/com/test/diff/services/utils/OsUtils.java b/diff-services/src/main/java/com/test/diff/services/utils/OsUtils.java
new file mode 100644
index 0000000..1f23621
--- /dev/null
+++ b/diff-services/src/main/java/com/test/diff/services/utils/OsUtils.java
@@ -0,0 +1,20 @@
+package com.test.diff.services.utils;
+
+/**
+ * @author wl
+ * @date 2022/9/29
+ */
+public class OsUtils {
+
+ public static final String OS_NAME = System.getProperty("os.name").toLowerCase();
+ public static final String WINDOWS_PREFIX = "window";
+ public static final String LINUX_PREFIX = "linux";
+
+ public static Boolean isWindows() {
+ return OS_NAME.contains(WINDOWS_PREFIX);
+ }
+
+ public static Boolean isLinux() {
+ return OS_NAME.contains(LINUX_PREFIX);
+ }
+}
diff --git a/diff-services/src/main/resources/application.properties b/diff-services/src/main/resources/application.properties
index d12bd65..45f5a0d 100644
--- a/diff-services/src/main/resources/application.properties
+++ b/diff-services/src/main/resources/application.properties
@@ -1,8 +1,8 @@
server.port=1990
-spring.datasource.url=jdbc:mysql://192.168.100.158:3306/test_platform?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
+spring.datasource.url=jdbc:mysql://127.0.0.1.158:3306/test_platform?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
-spring.datasource.password=Rl123456
+spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#logging.level.com.test.diff.services=trace
diff --git a/diff-services/src/test/java/com/test/diff/services/CollectionTest.java b/diff-services/src/test/java/com/test/diff/services/CollectionTest.java
index 8f25abd..3740097 100644
--- a/diff-services/src/test/java/com/test/diff/services/CollectionTest.java
+++ b/diff-services/src/test/java/com/test/diff/services/CollectionTest.java
@@ -1,6 +1,5 @@
package com.test.diff.services;
-import org.jacoco.cli.internal.core.data.ChainNode;
import org.junit.Test;
import java.util.*;
@@ -8,17 +7,6 @@
public class CollectionTest {
- @Test
- public void testSetClear(){
- Set sets = new HashSet<>();
- ChainNode node = new ChainNode();
- node.setUri("test");
- sets.add(node);
- System.out.println(sets.size());
- sets.clear();
- System.out.println(sets.size());
- }
-
@Test
public void testSetArrayClear(){
Set[] sets = new Set[10];
@@ -64,8 +52,7 @@ public void testAnyMatch(){
@Test
public void testArraySplit(){
-// String str = "String;String;Integer;";
- String str = "Ljava/lang/String;Lcom/beitai/iot/data/enums/SourceType;";
+ String str = "String;String;Integer;";
String[] arr = str.split(";");
System.out.println(arr);
}
diff --git a/diff-services/src/test/java/com/test/diff/services/FileTest.java b/diff-services/src/test/java/com/test/diff/services/FileTest.java
index 269cb85..ecaa694 100644
--- a/diff-services/src/test/java/com/test/diff/services/FileTest.java
+++ b/diff-services/src/test/java/com/test/diff/services/FileTest.java
@@ -22,6 +22,8 @@
import java.util.concurrent.locks.ReentrantLock;
public class FileTest {
+
+ private static final String USER_HOME = System.getProperty("user.home");
private FileUtil fileUtil;
@@ -75,20 +77,20 @@ public void testFilePathTest(){
@Test
public void testRename(){
- String newPath = "C:\\Users\\wl\\code-diff\\dump.txt";
- String oldPath = "C:\\Users\\wl\\code-diff\\merge.txt";
+ String newPath = USER_HOME + "\\code-diff\\dump.txt";
+ String oldPath = USER_HOME + "\\code-diff\\merge.txt";
fileUtil.reName(newPath, oldPath);
}
@Test
public void testDelDir() throws IOException {
- FileUtils.deleteDirectory(new File("C:\\Users\\wl\\code-diff\\jvmTest\\master_35c27bd393e1f92efb757dfff8d2029bd3163849"));
+ FileUtils.deleteDirectory(new File(USER_HOME + "\\code-diff\\jvmTest\\master_35c27bd393e1f92efb757dfff8d2029bd3163849"));
}
@Test
public void testAsyncWrite() {
ReentrantLock lock = new ReentrantLock();
- File file = new File("C:\\Users\\wl\\code-diff\\12.txt");
+ File file = new File(USER_HOME + "\\code-diff\\12.txt");
Thread t1 = new Thread(){
@SneakyThrows
@Override
@@ -154,7 +156,7 @@ public void testSourcePaths(){
@Test
public void testClassPaths(){
- String branPath = "C:\\Users\\wl\\code-diff\\11\\yami-server";
+ String branPath = USER_HOME + "\\code-diff\\11\\yami-server";
List list = fileUtil.getAllClassFilePathsByProject(branPath);
System.out.println(list.size());
list.stream().forEach(path -> System.out.println(path));
@@ -162,8 +164,8 @@ public void testClassPaths(){
@Test
public void testCopyProject() throws IOException {
- String oriPath = "C:\\Users\\wl\\code-diff\\yami-server";
- String newPath = "C:\\Users\\wl\\code-diff\\122";
+ String oriPath = USER_HOME + "\\code-diff\\yami-server";
+ String newPath = USER_HOME + "\\code-diff\\122";
//拷贝.git目录
String oriGitPath = fileUtil.addPath(oriPath, ".git");
String newGitPath = fileUtil.addPath(newPath, ".git");
@@ -201,7 +203,7 @@ public void testFindSelectedClassFilePath(){
key = key.replace("/", File.separator);
}
System.out.println(key);
- String path = fileUtil.getClassFilePath("G:\\jvm\\github\\code-diff",
+ String path = fileUtil.getClassFilePath(USER_HOME + "\\code-diff",
key);
System.out.println(path);
}
diff --git a/diff-services/src/test/java/com/test/diff/services/GitFileHandleTest.java b/diff-services/src/test/java/com/test/diff/services/GitFileHandleTest.java
index 9fe11f9..276f276 100644
--- a/diff-services/src/test/java/com/test/diff/services/GitFileHandleTest.java
+++ b/diff-services/src/test/java/com/test/diff/services/GitFileHandleTest.java
@@ -14,6 +14,8 @@
@RunWith(SpringRunner.class)
public class GitFileHandleTest {
+ private static final String USER_HOME = System.getProperty("user.home");
+
@Autowired
protected ApplicationContext ctx;
@@ -21,7 +23,7 @@ public class GitFileHandleTest {
public void testCopyProject(){
SpringUtil.setContext(ctx);
ISourceFileHandle handle = SourceFileHandleFactory.build();
- String commitId = handle.copyProjectFile(null, "master", "C:\\Users\\wl\\code-diff\\jvmTest", 1);
+ String commitId = handle.copyProjectFile(null, "master", USER_HOME + "\\code-diff\\jvmTest", 1);
System.out.println(commitId);
}
}
diff --git a/diff-services/src/test/java/com/test/diff/services/GitWorkFlowTest.java b/diff-services/src/test/java/com/test/diff/services/GitWorkFlowTest.java
index 90b1ac5..273dc76 100644
--- a/diff-services/src/test/java/com/test/diff/services/GitWorkFlowTest.java
+++ b/diff-services/src/test/java/com/test/diff/services/GitWorkFlowTest.java
@@ -107,7 +107,7 @@ public void testGetCommitList() throws IOException, GitAPIException {
ProjectInfo projectInfo = projectInfoService.getById(1);
String brandDir = fileUtil.getRepoPath(projectInfo, branch);
// String gitPath = fileUtil.addPath(brandDir, ".git");
- String gitPath = "C:\\Users\\wl\\code-diff\\11\\yami-server\\.git";
+ String gitPath = System.getProperty("user.home")+"\\code-diff\\11\\test-server\\.git";
Repository repo = new FileRepository(gitPath);
Git git = new Git(repo);
RevWalk walk = new RevWalk(repo);
diff --git a/diff-services/src/test/java/com/test/diff/services/JacksonTest.java b/diff-services/src/test/java/com/test/diff/services/JacksonTest.java
deleted file mode 100644
index aba0e12..0000000
--- a/diff-services/src/test/java/com/test/diff/services/JacksonTest.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.test.diff.services;
-
-import com.test.diff.common.util.JacksonUtil;
-import org.jacoco.cli.internal.core.data.ChainNode;
-import org.junit.Test;
-
-import java.io.*;
-import java.nio.charset.StandardCharsets;
-
-public class JacksonTest {
-
- @Test
- public void testStreamSerialize() throws IOException {
- ChainNode node = new ChainNode();
- node.setUri("12dfj");
- String str = JacksonUtil.serialize(node);
- byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
- String ss = new String(bytes, StandardCharsets.UTF_8);
- ChainNode n = JacksonUtil.deserialize(ss, ChainNode.class);
-// ChainNode n = JacksonUtil.deserialize(bytes, ChainNode.class);
-// ChainNode n = JacksonUtil.deserialize(str, ChainNode.class);
- System.out.println(n.toString());
- }
-}
diff --git a/diff-services/src/test/java/com/test/diff/services/JacocoHandleTest.java b/diff-services/src/test/java/com/test/diff/services/JacocoHandleTest.java
index 27193f1..2d8ecab 100644
--- a/diff-services/src/test/java/com/test/diff/services/JacocoHandleTest.java
+++ b/diff-services/src/test/java/com/test/diff/services/JacocoHandleTest.java
@@ -8,7 +8,6 @@
import com.test.diff.services.params.ProjectDiffParams;
import com.test.diff.services.utils.FileUtil;
-import org.jacoco.cli.internal.core.data.ChainNode;
import org.jacoco.cli.internal.core.data.ExecutionData;
import org.jacoco.cli.internal.core.data.ExecutionDataStore;
import org.jacoco.cli.internal.core.tools.ExecFileLoader;
@@ -28,6 +27,8 @@
@RunWith(SpringRunner.class)
public class JacocoHandleTest {
+ private static final String USER_HOME = System.getProperty("user.home");
+
@Resource
private DiffWorkFlow diffWorkFlow;
@@ -37,15 +38,15 @@ public class JacocoHandleTest {
@Test
public void testDump() throws Exception {
File execfile = new File(
- "C:\\Users\\wl\\Desktop\\dump2.exec");
+ USER_HOME+ "\\dump2.exec");
- JacocoHandle.dump("192.168.100.83", "6300", execfile.getAbsolutePath());
+ JacocoHandle.dump("127.0.0.1", "6300", execfile.getAbsolutePath());
}
@Test
public void testMerge() throws Exception {
- String newEexcFilePath = "C:\\Users\\wl\\Desktop\\merge.exec";
- File[] files = new File("C:\\Users\\wl\\Desktop").listFiles(new FileFilter() {
+ String newEexcFilePath = USER_HOME + "\\merge.exec";
+ File[] files = new File("").listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getAbsolutePath().endsWith(".exec");
@@ -54,18 +55,9 @@ public boolean accept(File pathname) {
JacocoHandle.merge(0, port, newEexcFilePath, files);
}
- @Test
- public void testChainNode() throws IOException, ClassNotFoundException {
- File file = new File("C:\\Users\\wl\\Desktop\\obj.txt");
- InputStream is = new FileInputStream(file);
- ObjectInputStream ois = new ObjectInputStream(is);
- ChainNode node =(ChainNode) ois.readObject();
- System.out.println(node);
- }
-
@Test
public void testLoadExecFile(){
- String execFilePath = "C:\\Users\\wl\\Desktop\\dump.exec";
+ String execFilePath = USER_HOME + "\\dump2.exec";
ExecFileLoader loader = JacocoHandle.getLoader(execFilePath);
ExecutionDataStore store = loader.getExecutionDataStore();
Collection data = store.getContents();
@@ -95,9 +87,9 @@ public void testReport() throws Exception {
List classInfos = diffWorkFlow.diff(params);
- String execFilePath = "C:\\Users\\wl\\Desktop\\dump.exec";
- String projectDir = "C:\\Users\\wl\\Desktop\\feature_v1.1.1_17602254b3c491c2f4c3dcc693db6f41ec5af8e7";
- String reportPath = "C:\\Users\\wl\\Desktop\\report";
+ String execFilePath = USER_HOME + "\\dump.exec";
+ String projectDir = USER_HOME + "\\feature_v1.1.1_17602254b3c491c2f4c3dcc693db6f41ec5af8e7";
+ String reportPath = USER_HOME + "\\report";
FileUtil fileUtil = new FileUtil();
JacocoHandle.report(execFilePath, fileUtil.getAllClassFilePathsByProject(projectDir),
fileUtil.getAllSourcePathsByProject(projectDir),reportPath, JacksonUtil.serialize(classInfos), null);
diff --git a/diff-services/src/test/java/com/test/diff/services/StringTest.java b/diff-services/src/test/java/com/test/diff/services/StringTest.java
index 14b8766..4ef7b1a 100644
--- a/diff-services/src/test/java/com/test/diff/services/StringTest.java
+++ b/diff-services/src/test/java/com/test/diff/services/StringTest.java
@@ -4,14 +4,16 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Queue;
public class StringTest {
@Test
public void testReplace(){
- String str = "/root/code-diff/wuchan/test/scm-server/feature_1.0_f7eb21efa925a7588ae424ea3033d3805936fb23/sc-support/sc-job/src/main/java";
+ String str = "/root/code-diff/test/test/test-server/feature_1.0_f7eb21efa925a7588ae424ea3033d3805936fb23/sc-test/sc-job/src/main/java";
str = str.replaceAll("/", ".");
System.out.println(str);
+
}
@Test
diff --git a/lib/jacoco-cli.jar b/lib/jacoco-cli.jar
index f9fba35..72cda10 100644
Binary files a/lib/jacoco-cli.jar and b/lib/jacoco-cli.jar differ
diff --git a/lib/jacocoagent.jar b/lib/jacocoagent.jar
index 8a74553..c4ee486 100644
Binary files a/lib/jacocoagent.jar and b/lib/jacocoagent.jar differ
diff --git a/pom.xml b/pom.xml
index e0c7ce1..428e535 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,9 +35,10 @@
2.0.2
3.18.0
5.6.3
- 2.12.4
+ 2.13.3
4.9.0
2.8.6
+ 2.0.10
@@ -128,7 +129,11 @@
gson
${gson.version}
-
+
+ com.alibaba.fastjson2
+ fastjson2
+ ${fastjson2.version}
+