diff --git a/.gitignore b/.gitignore index 82f68ab..faa1f4e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,3 @@ /application/target/ /common/target/classes/META-INF/ /common/target/ -/target/ diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 2327e81..0000000 --- a/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM openjdk:8-jdk-alpine -ENV LANG=C.UTF-8 -RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories -RUN apk update && apk add git curl maven -COPY settings.xml /root/.m2/ -ENV TZ=Asia/Shanghai -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -VOLUME /tmp -ARG JAR_FILE=target/code-diff-*.jar -COPY ${JAR_FILE} app.jar -COPY run.sh . -RUN chmod 777 run.sh -ENV JAVA_OPTS="-server -Xms512m -Xmx1g -Dsping.profiles.active=docker" -RUN ls -l -ENTRYPOINT ["sh","/run.sh"] \ No newline at end of file diff --git a/README.md b/README.md index e6ec8c0..990a583 100644 --- a/README.md +++ b/README.md @@ -1,150 +1,299 @@ # code-diff -基于git或svn的差异代码获取 +基於git的差异代码获取 ### 简介 -+ 本项目主要是用于基于jacoco的增量代码统计,增量代码的统计核心问题是如何获得增量代码,网络上关于增量代码的获取相关资料比较少,而且代码注释也没有,阅读起来相对困难,我这边参考了几个项目后根据实际需求,进行了整理,请配合[jacoco二开](https://gitee.com/Dray/jacoco.git)一起使用 ++ 本项目主要是用于基于jacoco的增量代码统计,增量代码的统计核心问题是如何获得增量代码,网络上关于增量代码的获取相关资料比较少,而且代码注释也没有,阅读起来相对困难,我这边参考了几个项目后根据实际需求,进行了整理,整个项目工程,只有application的部分代码为核心代码,其他都是辅助 -具体实现方案请参考[博客](https://blog.csdn.net/tushuping/article/details/112613528) -## 划重点本项目基于JDK1.8,直接使用master分支即可 -### 功能介绍 -![img.png](img.png) -如上图所示,code-diff最开始只是用于差异代码的获取,后来随着网友们的需求和扩展,目前已经支持以下功能: -* 支持基于git的差异方法获取 - > 1. 验证支持账号密码和秘钥 - > 2. git支持基于分支对比,基于commitId对比,以及基于tag对比 -* 支持基于svn的差异方法获取 - > 1. svn支持基于同分支不同reversion,不同分支同一reversion,不同分支不同reversion -* 支持jacoco全量代码覆盖率报告生成 -* 支持jacoco增量代码覆盖率报告生成 -* 支持基于git的方法的静态调用链 -* 支持基于git的变更代码影响接口(支持基于mybatis的sql变更影响的接口) -* 支持基于svn的静态调用链 -* 支持基于svn的变更代码影响接口 -* 影响接口支持http,dubbo以及自定义起始类,自定义起始方法的代码调用链 -jacoco二开有部分代码开源,部分未开源,但是提供了jar包,在本工程的lib目录下(lib/org.jacoco.cli-0.8.7-SNAPSHOT-nodeps.jar) -![img_3.png](img_3.png) -如上图所示: -* jacoco-cli.jar:差异代码覆盖率(已开源) -* jacoco-cli.jar:按包名或class文件排除类(未开源) -* jacoco-cli.jar:代码变更行展示(未开源) -* jacoco-cli.jar:变更class文件覆盖率合并(未开源,未提供使用,可参考[博客](https://blog.csdn.net/tushuping/article/details/131640959?spm=1001.2014.3001.5501)) ### 使用方法 -* 源码方式使用 - #### 1、修改application.yml - -```agsl - #基于git - git: - userName: admin - password: 123456 - local: - base: - dir: D:\git-test - git支持ssh(目前支持分支)配置 - git: - ssh: - priKey: C:\Users\mylocl/.ssh/id_rsa. - ##基于svn - svn: - userName: admin - password: 123456 - local: - base: - dir: D:\svn-test - maven: - home: E:/Program Files/apache-maven-3.6.3 #maven的安装目录,此配置主要用于代码编译,用于静态代码分析功能,如果只差异分析,可以不配置 - root: - code: - path: src/main/java/ #代码的根目录,非标准maven项目需要自定义 - jacoco: - root: - path: H:/jacoco/root/ #jacoco报告的根目录 -``` - 如果启动报日志错误,可以修改日志路径,当然也可以启动时修改jvm参数-Dlog.path=xxx -![img_1.png](img_1.png) - - #### 2、运行项目,访问http://127.0.0.1:8085/doc.html -* docker方式使用 - -1、拉取镜像(以amd64为例,如果是arm64请拉取arm64的镜像,地址为https://hub.docker.com/repository/docker/rayduan/code-diff/general) -```angular2html -docker pull rayduan/code-diff:v1.1-amd64 -``` -2、运行镜像 -```angular2html -docker run -d -p 8085:8085 --name code-diff rayduan/code-diff:v1.1-amd64 -``` -就是这么简单什么也不用配置,当然如果maven有私服,只用修改~/.m2/settings.xml即可 - -## 使用示例 - -![git差异代码获取](https://images.gitee.com/uploads/images/2021/0408/122939_6cf6505d_1007820.png "屏幕截图.png") -![svn差异代码获取](https://images.gitee.com/uploads/images/2021/0408/123039_5cb136f9_1007820.png "屏幕截图.png") +#### 1、修改application.yml + git: + userName: rayduan #git账号 + password: FDsfret334 #git密码 +#### 2、运行项目,访问http://127.0.0.1:8085/doc.html 2.1 输入git地址,填写差异分支的旧版本,新版本,执行,就可以获取差异信息 + 2.2 { + "code": 10000, + "msg": "业务处理成功", + "data": [ + { + "classFile": "com/dr/application/InstallCert", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/Calculable", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/JenkinsPluginController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/LoginController", + "methodInfos": [ + { + "methodName": "captcha", + "parameters": "HttpServletRequest&HttpServletResponse" + }, + { + "methodName": "login", + "parameters": "LoginUserParam&HttpServletRequest" + }, + { + "methodName": "testInt", + "parameters": "int&char" + }, + { + "methodName": "testInt", + "parameters": "String&int" + }, + { + "methodName": "testInt", + "parameters": "short&int" + }, + { + "methodName": "testInt", + "parameters": "int[]" + }, + { + "methodName": "testInt", + "parameters": "T[]" + }, + { + "methodName": "testInt", + "parameters": "Calculable&int&int" + }, + { + "methodName": "testInt", + "parameters": "Map&List&Set" + }, + { + "methodName": "display", + "parameters": "" + }, + { + "methodName": "a", + "parameters": "InnerClass" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/application/app/controller/RoleController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/controller/TestController", + "methodInfos": [ + { + "methodName": "test", + "parameters": "" + }, + { + "methodName": "getPom", + "parameters": "HttpServletResponse" + }, + { + "methodName": "getDeList", + "parameters": "" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/application/app/controller/view/RoleViewController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/param/AddRoleParam", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/vo/DependencyVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/vo/JenkinsPluginsVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/app/vo/RoleVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/config/ExceptionAdvice", + "methodInfos": [ + { + "methodName": "handleException", + "parameters": "Exception" + }, + { + "methodName": "handleMissingServletRequestParameterException", + "parameters": "MissingServletRequestParameterException" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/application/config/GitConfig", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/config/JenkinsConfig", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/ddd/StaticTest", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/ddd/Test", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/application/util/GitAdapter", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/common/errorcode/BizCode", + "methodInfos": [ + { + "methodName": "getCode", + "parameters": "" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/common/response/ApiResponse", + "methodInfos": [ + { + "methodName": "success", + "parameters": "" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/jenkins/JenkinsApplication", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/config/JenkinsConfigure", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/controller/JenkinsController", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/controller/TestApi", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/dto/JobAddDto", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/service/JenkinsService", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/service/impl/JenkinsServiceImpl", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/util/GenerateUniqueIdUtil", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/vo/DeviceVo", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/vo/GoodsVO", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/jenkins/vo/JobAddVo", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/repository/user/dto/query/RoleQueryDto", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/repository/user/dto/result/RoleResultDto", + "methodInfos": null, + "type": "ADD" + }, + { + "classFile": "com/dr/user/service/impl/PermissionServiceImpl", + "methodInfos": [ + { + "methodName": "getPermissionByRoles", + "parameters": "List" + }, + { + "methodName": "buildMenuTree", + "parameters": "List" + }, + { + "methodName": "getSubMenus", + "parameters": "Long&Map>" + } + ], + "type": "MODIFY" + }, + { + "classFile": "com/dr/user/service/impl/RoleServiceImpl", + "methodInfos": [ + { + "methodName": "getByUserId", + "parameters": "Long" + }, + { + "methodName": "getListByPage", + "parameters": "RoleQueryDto" + } + ], + "type": "MODIFY" + } + ], + "uniqueData": "[{\"classFile\":\"com/dr/application/InstallCert\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/Calculable\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/JenkinsPluginController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/LoginController\",\"methodInfos\":[{\"methodName\":\"captcha\",\"parameters\":\"HttpServletRequest&HttpServletResponse\"},{\"methodName\":\"login\",\"parameters\":\"LoginUserParam&HttpServletRequest\"},{\"methodName\":\"testInt\",\"parameters\":\"int&char\"},{\"methodName\":\"testInt\",\"parameters\":\"String&int\"},{\"methodName\":\"testInt\",\"parameters\":\"short&int\"},{\"methodName\":\"testInt\",\"parameters\":\"int[]\"},{\"methodName\":\"testInt\",\"parameters\":\"T[]\"},{\"methodName\":\"testInt\",\"parameters\":\"Calculable&int&int\"},{\"methodName\":\"testInt\",\"parameters\":\"Map&List&Set\"},{\"methodName\":\"display\",\"parameters\":\"\"},{\"methodName\":\"a\",\"parameters\":\"InnerClass\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/app/controller/RoleController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/controller/TestController\",\"methodInfos\":[{\"methodName\":\"test\",\"parameters\":\"\"},{\"methodName\":\"getPom\",\"parameters\":\"HttpServletResponse\"},{\"methodName\":\"getDeList\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/app/controller/view/RoleViewController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/param/AddRoleParam\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/DependencyVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/JenkinsPluginsVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/app/vo/RoleVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/config/ExceptionAdvice\",\"methodInfos\":[{\"methodName\":\"handleException\",\"parameters\":\"Exception\"},{\"methodName\":\"handleMissingServletRequestParameterException\",\"parameters\":\"MissingServletRequestParameterException\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/application/config/GitConfig\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/config/JenkinsConfig\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/ddd/StaticTest\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/ddd/Test\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/application/util/GitAdapter\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/common/errorcode/BizCode\",\"methodInfos\":[{\"methodName\":\"getCode\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/common/response/ApiResponse\",\"methodInfos\":[{\"methodName\":\"success\",\"parameters\":\"\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/jenkins/JenkinsApplication\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/config/JenkinsConfigure\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/controller/JenkinsController\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/controller/TestApi\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/dto/JobAddDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/service/JenkinsService\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/service/impl/JenkinsServiceImpl\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/util/GenerateUniqueIdUtil\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/DeviceVo\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/GoodsVO\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/jenkins/vo/JobAddVo\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/repository/user/dto/query/RoleQueryDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/repository/user/dto/result/RoleResultDto\",\"methodInfos\":[],\"type\":\"ADD\"},{\"classFile\":\"com/dr/user/service/impl/PermissionServiceImpl\",\"methodInfos\":[{\"methodName\":\"getPermissionByRoles\",\"parameters\":\"List\"},{\"methodName\":\"buildMenuTree\",\"parameters\":\"List\"},{\"methodName\":\"getSubMenus\",\"parameters\":\"Long&Map>\"}],\"type\":\"MODIFY\"},{\"classFile\":\"com/dr/user/service/impl/RoleServiceImpl\",\"methodInfos\":[{\"methodName\":\"getByUserId\",\"parameters\":\"Long\"},{\"methodName\":\"getListByPage\",\"parameters\":\"RoleQueryDto\"}],\"type\":\"MODIFY\"}]" + } + -## 其他 在linux系统部署时请注意修改代码的基础路径和日志路径,如: ```angular2html java -jar -Dlog.path=/app/data2/devops/code-diff/logs -Dgit.local.base.dir=/app/data2/devops/code-diff/ application-1.0.0-SNAPSHOT.jar ``` - -如有疑问,请加群主入群 - -![输入图片说明](https://images.gitee.com/uploads/images/2021/0414/163539_9ff67f82_1007820.png "屏幕截图.png") - - -##问题点: -如果ssh方式出现 -invalid privatekey: [B@6553d80f 则是ssh的版本太高,通过指定旧版本的方式重新生成即可 -``` -ssh-keygen -m PEM -t rsa -``` ---- -[add] -### 新增: -* 1.支持差异对比mapper xml获取变更的mapper类中的方法 -* 2.支持获取项目的静态调用链 -* 3.支持通过差异代码和静态调用链推导变更http接口和dubbo接口 -### 修复: -* 1.方法中的注释 // 应该不做代码差异 -* 2.缺失构造方法的diff -* 3.根据包名对调用链进行降噪 -#### 注意,因为需要编译代码,所以要配置maven,另外本项目运行和编译的代码均采用jdk1.8 -```agsl -maven: - home: /usr/local/app/apache-maven-3.8.3 -``` ---- -【add】 -### 修复: -* 1.修复循环引用问题 -* 2.优化lambda表达式调用链问题 - -【modify】 2023-04-05 -### 变更: -1. 为了降低使用门槛合并代码结构为单模块 -2. 增加了dockerfile,在工程目录下只需执行以下命令就可以构建镜像 - ``` - mvn clean package -Dmaven.test.skip=true - docker build -t code-diff . - ``` - 当然我已经构建了一个通用[镜像](https://hub.docker.com/layers/rayduan/code-diff/v1/images/sha256-eefb21263cef421866ff68b193b4311a877e29e20a5acb2ef5745de1aefd396f?context=repo) - 获取镜像后只需运行 - - ``` - - docker run -d -p 8085:8085 --restart=always -e JAVA_OPTS="-Xms512m -Xmx1g -Dspring.profiles.active=docker" --name code-diff rayduan/code-diff:v1 - - ``` - - 镜像中内置了git和maven,maven settings使用了阿里云镜像,如果需要私服可以手动修改镜像内的文件,或者重新自己构建镜像,另外私钥地址可以运行时指定卷映射出去(-v root/.ssh/id_rsa:root/.ssh/id_rsa),然后通过jvm参数指定,具体涉及到docker相关姿势请手动上网,一般情况下运行上述命令即可,无需做任何改动 - 运行时参数可以通过修改JAVA_OPTS指定,如git的账号密码: - ``` - JAVA_OPTS="-Dgit.userName=zs -Dgit.password=123456 -Dgit.ssh.priKey=/root/.ssh/id_rsa" - ``` - -【modify】2023-04-16 -支持jacoco报告生成,操作步骤参考[这里](https://gitee.com/Dray/code-diff/wikis/%E4%BD%BF%E7%94%A8jacoco%E5%91%BD%E4%BB%A4%E7%94%9F%E6%88%90jacoco%E6%8A%A5%E5%91%8A?sort_id=8001440) \ No newline at end of file +#近期github不稳定,请访问https://gitee.com/Dray/code-diff.git diff --git a/application/pom.xml b/application/pom.xml new file mode 100644 index 0000000..0c686d7 --- /dev/null +++ b/application/pom.xml @@ -0,0 +1,125 @@ + + + + code-diff-parent + com.dr + 1.0.0-SNAPSHOT + + 4.0.0 + + application + + + + org.springframework.boot + spring-boot-starter-web + + + com.dr + common + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + org.springframework.boot + spring-boot-starter-logging + + + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + com.spring4all + swagger-spring-boot-starter + + + com.github.xiaoymin + swagger-bootstrap-ui + + + org.projectlombok + lombok + + + + org.springframework.boot + spring-boot-starter-test + test + + + + cn.afterturn + easypoi-spring-boot-starter + + + + + org.eclipse.jgit + org.eclipse.jgit + + + + org.tmatesoft.svnkit + svnkit + + + + + com.github.javaparser + javaparser-core + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + true + + + + + repackage + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/dr/code/diff/CodeDiffApplication.java b/application/src/main/java/com/dr/code/diff/CodeDiffApplication.java similarity index 74% rename from src/main/java/com/dr/code/diff/CodeDiffApplication.java rename to application/src/main/java/com/dr/code/diff/CodeDiffApplication.java index 5b1018e..40459bc 100644 --- a/src/main/java/com/dr/code/diff/CodeDiffApplication.java +++ b/application/src/main/java/com/dr/code/diff/CodeDiffApplication.java @@ -1,5 +1,7 @@ package com.dr.code.diff; +import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI; +import com.spring4all.swagger.EnableSwagger2Doc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; @@ -12,6 +14,8 @@ * */ @SpringBootApplication +@EnableSwagger2Doc +@EnableSwaggerBootstrapUI @ComponentScan(value = "com.dr.**") public class CodeDiffApplication { diff --git a/src/main/java/com/dr/code/diff/config/CustomizeConfig.java b/application/src/main/java/com/dr/code/diff/config/CustomizeConfig.java similarity index 66% rename from src/main/java/com/dr/code/diff/config/CustomizeConfig.java rename to application/src/main/java/com/dr/code/diff/config/CustomizeConfig.java index 26dd30b..9c9cf7c 100644 --- a/src/main/java/com/dr/code/diff/config/CustomizeConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/CustomizeConfig.java @@ -53,33 +53,4 @@ public class CustomizeConfig { */ @Value(value = "${svn.local.base.dir}") private String svnLocalBaseRepoDir; - - @Value(value = "${git.ssh.priKey}") - private String gitSshPrivateKey; - - /** - * maven的地址 - */ - @Value(value = "${maven.home}") - private String mavenHome; - - /** - * 根代码路径 - */ - @Value(value = "${root.code.path}") - private String rootCodePath; - - /** - * jacoco exec路径 - */ - @Value(value = "${jacoco.root.path}") - private String jacocoRootPath; - - - @Value(value = "${custom.link.type:1}") - private Integer linkType; - - - @Value(value = "${custom.dubbo.xml.path}") - private String dubboXmlPath; } diff --git a/src/main/java/com/dr/code/diff/config/ExceptionAdvice.java b/application/src/main/java/com/dr/code/diff/config/ExceptionAdvice.java similarity index 93% rename from src/main/java/com/dr/code/diff/config/ExceptionAdvice.java rename to application/src/main/java/com/dr/code/diff/config/ExceptionAdvice.java index 15b38f4..9574d3c 100644 --- a/src/main/java/com/dr/code/diff/config/ExceptionAdvice.java +++ b/application/src/main/java/com/dr/code/diff/config/ExceptionAdvice.java @@ -1,9 +1,9 @@ package com.dr.code.diff.config; -import com.dr.code.diff.common.errorcode.BaseCode; -import com.dr.code.diff.common.exception.BizException; -import com.dr.code.diff.common.log.LoggerUtil; -import com.dr.code.diff.common.response.ApiResponse; +import com.dr.common.errorcode.BaseCode; +import com.dr.common.exception.BizException; +import com.dr.common.log.LoggerUtil; +import com.dr.common.response.ApiResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.validation.BindException; diff --git a/src/main/java/com/dr/code/diff/config/ExecutorConfig.java b/application/src/main/java/com/dr/code/diff/config/ExecutorConfig.java similarity index 96% rename from src/main/java/com/dr/code/diff/config/ExecutorConfig.java rename to application/src/main/java/com/dr/code/diff/config/ExecutorConfig.java index 4871de9..014d070 100644 --- a/src/main/java/com/dr/code/diff/config/ExecutorConfig.java +++ b/application/src/main/java/com/dr/code/diff/config/ExecutorConfig.java @@ -1,7 +1,7 @@ package com.dr.code.diff.config; -import com.dr.code.diff.common.log.LoggerUtil; +import com.dr.common.log.LoggerUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java new file mode 100644 index 0000000..799c74f --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/controller/CodeDiffController.java @@ -0,0 +1,81 @@ +package com.dr.code.diff.controller; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.dr.code.diff.dto.ClassInfoResult; +import com.dr.code.diff.dto.DiffMethodParams; +import com.dr.code.diff.enums.CodeManageTypeEnum; +import com.dr.code.diff.service.CodeDiffService; +import com.dr.code.diff.vo.result.CodeDiffResultVO; +import com.dr.common.response.UniqueApoResponse; +import com.dr.common.utils.mapper.OrikaMapperUtils; +import com.fasterxml.jackson.core.JsonProcessingException; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * @author rui.duan + * @version 1.0 + * @className UserController + * @description 用户管理 + * @date 2019/11/20 6:25 下午 + */ +@RestController +@Api(value = "/api/code/diff", tags = "差异代码模块") +@RequestMapping("/api/code/diff") +public class CodeDiffController { + + @Autowired + private CodeDiffService codeDiffService; + + @ApiOperation("git获取差异代码") + @RequestMapping(value = "git/list", method = RequestMethod.GET) + public UniqueApoResponse> getGitList( + @ApiParam(required = true, name = "gitUrl", value = "git远程仓库地址") + @RequestParam(value = "gitUrl") String gitUrl, + @ApiParam(required = true, name = "baseVersion", value = "git原始分支或tag") + @RequestParam(value = "baseVersion") String baseVersion, + @ApiParam(required = true, name = "nowVersion", value = "git现分支或tag") + @RequestParam(value = "nowVersion") String nowVersion) { + DiffMethodParams diffMethodParams = DiffMethodParams.builder() + .repoUrl(gitUrl) + .baseVersion(baseVersion) + .nowVersion(nowVersion) + .codeManageTypeEnum(CodeManageTypeEnum.GIT) + .build(); + List diffCodeList = codeDiffService.getDiffCode(diffMethodParams); + List codeDiffResultVOS = OrikaMapperUtils.mapList(diffCodeList, ClassInfoResult.class, CodeDiffResultVO.class); + return new UniqueApoResponse>().success(codeDiffResultVOS, JSON.toJSONString(codeDiffResultVOS,SerializerFeature.WriteNullListAsEmpty)); + } + + + @ApiOperation("svn获取差异代码") + @RequestMapping(value = "svn/list", method = RequestMethod.GET) + public UniqueApoResponse> getSvnList( + @ApiParam(required = true, name = "svnUrl", value = "svn远程仓库地址,如svn:192.168.0.1:3690/svn") + @RequestParam(value = "svnUrl") String svnUrl, + @ApiParam(required = true, name = "baseVersion", value = "svn原始分支,如:1") + @RequestParam(value = "baseVersion") String baseVersion, + @ApiParam(required = true, name = "nowVersion", value = "svn现分支,如:2") + @RequestParam(value = "nowVersion") String nowVersion) { + DiffMethodParams diffMethodParams = DiffMethodParams.builder() + .repoUrl(svnUrl) + .baseVersion(baseVersion) + .nowVersion(nowVersion) + .codeManageTypeEnum(CodeManageTypeEnum.SVN) + .build(); + List diffCodeList = codeDiffService.getDiffCode(diffMethodParams); + List codeDiffResultVOS = OrikaMapperUtils.mapList(diffCodeList, ClassInfoResult.class, CodeDiffResultVO.class); + return new UniqueApoResponse>().success(codeDiffResultVOS, JSON.toJSONString(codeDiffResultVOS,SerializerFeature.WriteNullListAsEmpty)); + } + + +} diff --git a/src/main/java/com/dr/code/diff/dto/DiffClassInfoResult.java b/application/src/main/java/com/dr/code/diff/dto/ClassInfoResult.java similarity index 88% rename from src/main/java/com/dr/code/diff/dto/DiffClassInfoResult.java rename to application/src/main/java/com/dr/code/diff/dto/ClassInfoResult.java index c085cb2..e22cb4f 100644 --- a/src/main/java/com/dr/code/diff/dto/DiffClassInfoResult.java +++ b/application/src/main/java/com/dr/code/diff/dto/ClassInfoResult.java @@ -21,7 +21,7 @@ */ @Builder @Data -public class DiffClassInfoResult { +public class ClassInfoResult { /** * java文件 */ @@ -35,28 +35,24 @@ public class DiffClassInfoResult { */ private String packages; - - /** - * 模块名称 - */ - private String moduleName; - /** * 类中的方法 */ private List methodInfos; - /** - * 修改类型 + * 新增的行数 */ - private String type; - + private List addLines; + /** + * 删除的行数 + */ + private List delLines; /** - * 变更行 + * 修改类型 */ - private List lines; + private String type; } diff --git a/src/main/java/com/dr/code/diff/dto/DiffEntryDto.java b/application/src/main/java/com/dr/code/diff/dto/DiffEntryDto.java similarity index 84% rename from src/main/java/com/dr/code/diff/dto/DiffEntryDto.java rename to application/src/main/java/com/dr/code/diff/dto/DiffEntryDto.java index 8dec1a0..b111663 100644 --- a/src/main/java/com/dr/code/diff/dto/DiffEntryDto.java +++ b/application/src/main/java/com/dr/code/diff/dto/DiffEntryDto.java @@ -3,8 +3,6 @@ import lombok.Data; import org.eclipse.jgit.diff.DiffEntry; -import java.util.List; - /** * @ProjectName: code-diff-parent * @Package: com.dr.code.diff.dto @@ -28,10 +26,4 @@ public class DiffEntryDto { * 文件变更类型 */ private DiffEntry.ChangeType changeType; - - - /** - * 变更行 - */ - private List lines; } diff --git a/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java b/application/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java similarity index 71% rename from src/main/java/com/dr/code/diff/dto/DiffMethodParams.java rename to application/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java index ff79c0e..9efe09a 100644 --- a/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java +++ b/application/src/main/java/com/dr/code/diff/dto/DiffMethodParams.java @@ -1,12 +1,9 @@ package com.dr.code.diff.dto; import com.dr.code.diff.enums.CodeManageTypeEnum; -import com.dr.code.diff.enums.GitUrlTypeEnum; import lombok.Builder; import lombok.Data; -import java.util.List; - /** * @ProjectName: base-service * @Package: com.dr.jenkins.jenkins.dto @@ -30,25 +27,18 @@ public class DiffMethodParams { /** * git原始分支或tag */ - private String baseVersion = ""; + private String baseVersion; /** * git现分支或tag */ - private String nowVersion = ""; + private String nowVersion; - /** - * 专用于svn新分支 - */ - private String svnRepoUrl; - /** * 版本控制类型 */ private CodeManageTypeEnum codeManageTypeEnum; - private List excludeFiles; - } diff --git a/src/main/java/com/dr/code/diff/dto/MethodInfoResult.java b/application/src/main/java/com/dr/code/diff/dto/MethodInfoResult.java similarity index 58% rename from src/main/java/com/dr/code/diff/dto/MethodInfoResult.java rename to application/src/main/java/com/dr/code/diff/dto/MethodInfoResult.java index 5d5b450..d6af651 100644 --- a/src/main/java/com/dr/code/diff/dto/MethodInfoResult.java +++ b/application/src/main/java/com/dr/code/diff/dto/MethodInfoResult.java @@ -3,8 +3,6 @@ import lombok.Builder; import lombok.Data; -import java.util.List; - /** * @author dr */ @@ -22,17 +20,6 @@ public class MethodInfoResult { /** * 方法参数 */ - public List parameters; - - public String methodSign; + public String parameters; - /** - * 开始行 - */ - private Integer startLine; - - /** - * 结束行 - */ - private Integer endLine; } diff --git a/src/main/java/com/dr/code/diff/dto/VersionControlDto.java b/application/src/main/java/com/dr/code/diff/dto/VersionControlDto.java similarity index 73% rename from src/main/java/com/dr/code/diff/dto/VersionControlDto.java rename to application/src/main/java/com/dr/code/diff/dto/VersionControlDto.java index 8372145..c3069dc 100644 --- a/src/main/java/com/dr/code/diff/dto/VersionControlDto.java +++ b/application/src/main/java/com/dr/code/diff/dto/VersionControlDto.java @@ -1,7 +1,6 @@ package com.dr.code.diff.dto; import com.dr.code.diff.enums.CodeManageTypeEnum; -import com.dr.code.diff.enums.GitUrlTypeEnum; import lombok.Builder; import lombok.Data; import org.eclipse.jgit.diff.DiffEntry; @@ -37,22 +36,6 @@ public class VersionControlDto { private String nowVersion; - /** - * 专用于svn新分支 - */ - private String svnRepoUrl; - - - /** - * 本地旧文件基础地址 - */ - private String oldLocalBasePath; - - /** - * 本地新文件基础地址 - */ - private String newLocalBasePath; - /** * 版本控制类型 */ @@ -61,5 +44,4 @@ public class VersionControlDto { private List diffClasses; - } diff --git a/src/main/java/com/dr/code/diff/enums/CodeManageTypeEnum.java b/application/src/main/java/com/dr/code/diff/enums/CodeManageTypeEnum.java similarity index 100% rename from src/main/java/com/dr/code/diff/enums/CodeManageTypeEnum.java rename to application/src/main/java/com/dr/code/diff/enums/CodeManageTypeEnum.java diff --git a/src/main/java/com/dr/code/diff/service/CodeDiffService.java b/application/src/main/java/com/dr/code/diff/service/CodeDiffService.java similarity index 54% rename from src/main/java/com/dr/code/diff/service/CodeDiffService.java rename to application/src/main/java/com/dr/code/diff/service/CodeDiffService.java index 035bb34..14578b4 100644 --- a/src/main/java/com/dr/code/diff/service/CodeDiffService.java +++ b/application/src/main/java/com/dr/code/diff/service/CodeDiffService.java @@ -1,10 +1,9 @@ package com.dr.code.diff.service; -import com.dr.code.diff.analyze.bean.MethodInfo; -import com.dr.code.diff.dto.*; +import com.dr.code.diff.dto.ClassInfoResult; +import com.dr.code.diff.dto.DiffMethodParams; import java.util.List; -import java.util.Map; /** * @ProjectName: base-service @@ -25,17 +24,7 @@ public interface CodeDiffService { * @author:Administrator * @description: 获取差异代码 */ - DiffInfo getDiffCode(DiffMethodParams diffMethodParams); - - - - /** - * 得到静态方法调用 - * - * @param methodInvokeParam 方法调用参数 - * @return {@link ApiModify} - */ - Map> getStaticMethodInvoke(MethodInvokeParam methodInvokeParam); + List getDiffCode(DiffMethodParams diffMethodParams); } diff --git a/application/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java b/application/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java new file mode 100644 index 0000000..e4e0b7d --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java @@ -0,0 +1,43 @@ +package com.dr.code.diff.service.impl; + +import com.dr.code.diff.dto.ClassInfoResult; +import com.dr.code.diff.dto.DiffMethodParams; +import com.dr.code.diff.dto.VersionControlDto; +import com.dr.code.diff.service.CodeDiffService; +import com.dr.code.diff.vercontrol.VersionControlHandlerFactory; +import com.dr.code.diff.vercontrol.git.GitVersionControl; +import com.dr.code.diff.vercontrol.svn.SvnVersionControl; +import com.dr.common.utils.mapper.OrikaMapperUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @ProjectName: base-service + * @Package: com.dr.jenkins.jenkins.service.impl + * @Description: 获取差异代码 + * @Author: duanrui + * @CreateDate: 2020/6/20 21:39 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2020 + */ +@Service +@Slf4j +public class CodeDiffServiceImpl implements CodeDiffService { + + /** + * @param diffMethodParams + * @date:2021/1/9 + * @className:CodeDiffService + * @author:Administrator + * @description: 获取差异代码 + */ + @Override + public List getDiffCode(DiffMethodParams diffMethodParams) { + VersionControlDto dto = OrikaMapperUtils.map(diffMethodParams, VersionControlDto.class); + return VersionControlHandlerFactory.processHandler(dto); + } +} diff --git a/application/src/main/java/com/dr/code/diff/util/GitRepoUtil.java b/application/src/main/java/com/dr/code/diff/util/GitRepoUtil.java new file mode 100644 index 0000000..3a97b03 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/util/GitRepoUtil.java @@ -0,0 +1,169 @@ +package com.dr.code.diff.util; + +import com.dr.common.errorcode.BizCode; +import com.dr.common.exception.BizException; +import com.dr.common.log.LoggerUtil; +import com.dr.common.utils.file.FileUtil; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectReader; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.jgit.treewalk.AbstractTreeIterator; +import org.eclipse.jgit.treewalk.CanonicalTreeParser; + +import java.io.File; +import java.io.IOException; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.util + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/4/5 11:16 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2021 + */ +@Slf4j +public class GitRepoUtil { + + + /** + * 克隆代码到本地 + * + * @param gitUrl + * @param codePath + * @param commitId + * @return + * @throws GitAPIException + * @throws IOException + */ + public static Git cloneRepository(String gitUrl, String codePath, String commitId,String gitUserName,String gitPassWord) { + Git git = null; + try { + if (!checkGitWorkSpace(gitUrl, codePath)) { + LoggerUtil.info(log, "本地代码不存在,clone", gitUrl, codePath); + git = Git.cloneRepository() + .setURI(gitUrl) + .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)) + .setDirectory(new File(codePath)) + .setBranch(commitId) + .call(); + // 下载指定commitId/branch + git.checkout().setName(commitId).call(); + } else { + LoggerUtil.info(log, "本地代码存在,直接使用", gitUrl, codePath); + git = Git.open(new File(codePath)); + git.getRepository().getFullBranch(); + //判断是分支还是commitId,分支做更新,commitId无法改变用原有的 + if (git.getRepository().exactRef(Constants.HEAD).isSymbolic()) { + //更新代码 + git.pull().setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)).call(); + } + } + } catch (IOException | GitAPIException e) { + e.printStackTrace(); + throw new BizException(BizCode.GIT_OPERATED_FAIlED); + } + return git; + } + + + /** + * 将代码转成树状 + * + * @param repository + * @param branchName + * @return + */ + public static AbstractTreeIterator prepareTreeParser(Repository repository, String branchName) { + try { + RevWalk walk = new RevWalk(repository); + RevTree tree; + tree = walk.parseTree(repository.resolve(branchName)); + CanonicalTreeParser TreeParser = new CanonicalTreeParser(); + try (ObjectReader reader = repository.newObjectReader()) { + TreeParser.reset(reader, tree.getId()); + } + walk.dispose(); + return TreeParser; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 取远程代码本地存储路径 + * + * @param gitUrl + * @param localBaseRepoDir + * @param version + * @return + */ + public static String getLocalDir(String gitUrl, String localBaseRepoDir, String version) { + StringBuilder localDir = new StringBuilder(localBaseRepoDir); + if (Strings.isNullOrEmpty(gitUrl)) { + return ""; + } + localDir.append("/"); + String repoName = Splitter.on("/") + .splitToStream(gitUrl).reduce((first, second) -> second) + .map(e -> Splitter.on(".").splitToStream(e).findFirst().get()).get(); + localDir.append(repoName); + localDir.append("/"); + localDir.append(version); + return localDir.toString(); + } + + + + /** + * 判断工作目录是否存在,本来可以每次拉去代码时删除再拉取,但是这样代码多的化IO比较大,所以就代码可以复用 + * + * @param codePath + * @return + */ + public static Boolean checkGitWorkSpace(String gitUrl, String codePath) throws IOException { + Boolean isExist = Boolean.FALSE; + File RepoGitDir = new File(codePath + "/.git"); + if (!RepoGitDir.exists()) { + return false; + } + Git git = Git.open(new File(codePath)); + if (null == git) { + return isExist; + } + Repository repository = git.getRepository(); + //解析本地代码,获取远程uri,是否是我们需要的git远程仓库 + String repoUrl = repository.getConfig().getString("remote", "origin", "url"); + if (gitUrl.equals(repoUrl)) { + isExist = Boolean.TRUE; + } else { + LoggerUtil.info(log, "本地存在其他仓的代码,先删除"); + FileUtil.removeDir(new File(codePath)); + } + return isExist; + } + + /** + * 获取class文件的地址 + * + * @param git + * @param classPackage + * @return + */ + public String getClassFile(Git git, String classPackage) { + StringBuilder builder = new StringBuilder(git.getRepository().getDirectory().getParent()); + return builder.append("/") + .append(classPackage).toString(); + } + +} diff --git a/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java new file mode 100644 index 0000000..67a69a6 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/util/MethodParserUtils.java @@ -0,0 +1,90 @@ +package com.dr.code.diff.util; + +import com.dr.code.diff.dto.MethodInfoResult; +import com.dr.common.utils.security.Md5Util; +import com.github.javaparser.StaticJavaParser; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.NodeList; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.Parameter; +import com.github.javaparser.ast.visitor.VoidVisitorAdapter; +import com.google.common.base.Splitter; +import org.springframework.util.CollectionUtils; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; + +/** + * @ProjectName: base-service + * @Package: com.dr.codediff.util + * @Description: 解析获取类的方法 + * @Author: duanrui + * @CreateDate: 2021/1/8 21:06 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2021 + */ +public class MethodParserUtils { + + + /** + * 解析类获取类的所有方法 + * + * @param classFile + * @return + */ + public static List parseMethods(String classFile) { + try { + List list = new ArrayList<>(); + FileInputStream in = new FileInputStream(classFile); + CompilationUnit cu = StaticJavaParser.parse(in); + //由于jacoco不会统计接口覆盖率,没比较计算接口的方法,此处排除接口类 + final List types = cu.getTypes(); + boolean isInterface = types.stream().filter(t -> t instanceof ClassOrInterfaceDeclaration).anyMatch(t -> ((ClassOrInterfaceDeclaration) t).isInterface()); + if (isInterface) { + return list; + } + cu.accept(new MethodVisitor(), list); + return list; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + /** + * javaparser工具类核心方法,主要通过这个类遍历class文件的方法,此方法主要是获取出代码的所有方法,然后再去对比方法是否存在差异 + */ + private static class MethodVisitor extends VoidVisitorAdapter> { + @Override + public void visit(MethodDeclaration n, List list) { + //删除注释 + n.removeComment(); + //计算方法体的hash值,疑问,空格,特殊转义字符会影响结果,导致相同匹配为差异?建议提交代码时统一工具格式化 + String md5 = Md5Util.encode(n.toString()); + //参数处理 + StringBuilder params = new StringBuilder(); + NodeList parameters = n.getParameters(); + if(!CollectionUtils.isEmpty(parameters)){ + for (int i = 0; i < parameters.size(); i++) { + String param = parameters.get(i).getType().toString(); + params.append(param.replaceAll(" ", "")); + if(i != parameters.size() -1){ + params.append("&"); + } + } + } + MethodInfoResult result = MethodInfoResult.builder() + .md5(md5) + .methodName(n.getNameAsString()) + .parameters(params.toString()) + .build(); + list.add(result); + super.visit(n, list); + } + + } +} diff --git a/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java b/application/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java similarity index 60% rename from src/main/java/com/dr/code/diff/util/SvnRepoUtil.java rename to application/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java index 40c9878..7fa81f6 100644 --- a/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java +++ b/application/src/main/java/com/dr/code/diff/util/SvnRepoUtil.java @@ -1,16 +1,27 @@ package com.dr.code.diff.util; +import com.dr.code.diff.vercontrol.svn.MySVNEditor; +import com.dr.common.errorcode.BizCode; +import com.dr.common.exception.BizException; +import com.dr.common.log.LoggerUtil; import com.google.common.base.Splitter; import com.google.common.base.Strings; -import org.springframework.util.StringUtils; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions; +import org.tmatesoft.svn.core.io.ISVNEditor; +import org.tmatesoft.svn.core.io.SVNRepository; +import org.tmatesoft.svn.core.io.SVNRepositoryFactory; import org.tmatesoft.svn.core.wc.*; import java.io.File; -import java.util.UUID; +import java.io.IOException; /** * @ProjectName: code-diff-parent @@ -30,47 +41,35 @@ public class SvnRepoUtil { * @author:Administrator * @description: 获取svn代码仓 */ - public static void cloneRepository(String repoUrl, String codePath, SVNRevision svnRevision, String userName, String password) { + public static void cloneRepository(String repoUrl, String codePath, String commitId, String userName, String password) { try { ISVNOptions options = SVNWCUtil.createDefaultOptions(true); SVNUpdateClient updateClient = SVNClientManager.newInstance((DefaultSVNOptions) options, userName, password).getUpdateClient(); - updateClient.doCheckout(SVNURL.parseURIEncoded(repoUrl), new File(codePath), svnRevision,svnRevision, SVNDepth.INFINITY, false); + updateClient.doCheckout(SVNURL.parseURIEncoded(repoUrl), new File(codePath), SVNRevision.create(Long.parseLong(commitId)), SVNRevision.create(Long.parseLong(commitId)), SVNDepth.INFINITY, false); } catch (SVNException e) { e.printStackTrace(); } } - public static SVNDiffClient getSvnDiffClient(String userName, String password) { + public static SVNDiffClient getSVNDiffClient(String userName, String password) { ISVNOptions options = SVNWCUtil.createDefaultOptions(true); //实例化客户端管理类 return SVNClientManager.newInstance((DefaultSVNOptions) options, userName, password).getDiffClient(); } - /** - * 取远程代码本地存储路径 - * - * @param repoUrl - * @param localBaseRepoDir - * @param version - * @return - */ - public static String getSvnLocalDir(String repoUrl, String localBaseRepoDir, String version) { + + public static String getLocalDir(String gitUrl, String localBaseRepoDir, String version) { StringBuilder localDir = new StringBuilder(localBaseRepoDir); - if (Strings.isNullOrEmpty(repoUrl)) { + if (Strings.isNullOrEmpty(gitUrl)) { return ""; } - localDir.append("/"); String repoName = Splitter.on("/") - .splitToStream(repoUrl).reduce((first, second) -> second).orElse(""); + .splitToStream(gitUrl).reduce((first, second) -> second).get(); + localDir.append("/"); localDir.append(repoName); - if(!StringUtils.isEmpty(version)){ - localDir.append("/"); - localDir.append(version); - } - //加入uuid防止重复 localDir.append("/"); - localDir.append(UUID.randomUUID()); + localDir.append(version); return localDir.toString(); } diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/VersionControl.java b/application/src/main/java/com/dr/code/diff/vercontrol/VersionControl.java new file mode 100644 index 0000000..b3c5f7e --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vercontrol/VersionControl.java @@ -0,0 +1,142 @@ +package com.dr.code.diff.vercontrol; + +import com.dr.code.diff.dto.ClassInfoResult; +import com.dr.code.diff.dto.DiffEntryDto; +import com.dr.code.diff.dto.MethodInfoResult; +import com.dr.code.diff.dto.VersionControlDto; +import com.dr.code.diff.enums.CodeManageTypeEnum; +import com.dr.code.diff.util.MethodParserUtils; +import lombok.Data; +import org.eclipse.jgit.diff.DiffEntry; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.stream.Collectors; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.vercontrol + * @Description: 代码差异获取流程类定义 + * @Author: duanrui + * @CreateDate: 2021/4/5 9:56 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2021 + */ +@Data +public abstract class VersionControl { + + protected VersionControlDto versionControlDto; + + + @Resource(name = "asyncExecutor") + private Executor executor; + + + /** + * 执行handler + * @return + */ + public List handler(VersionControlDto versionControlDto) { + this.versionControlDto = versionControlDto; + getDiffCodeClasses(); + return getDiffCodeMethods(); + } + + public abstract String getBaseDir(); + + /** + * @date:2021/4/5 + * @className:VersionControl + * @author:Administrator + * @description: 获取差异类 + */ + public abstract void getDiffCodeClasses(); + + /** + * 获取操作类型 + */ + public abstract CodeManageTypeEnum getType(); + + /** + * @date:2021/4/5 + * @className:VersionControl + * @author:Administrator + * @description: 获取差异方法 + */ + public List getDiffCodeMethods() { + List> priceFuture = versionControlDto.getDiffClasses().stream() + .map(item -> getClassMethods(getClassFilePath(getBaseDir(), versionControlDto.getBaseVersion(), item.getNewPath()), getClassFilePath(getBaseDir(), versionControlDto.getNowVersion(), item.getNewPath()), item)) + .collect(Collectors.toList()); + return priceFuture.stream().map(CompletableFuture::join).filter(Objects::nonNull).collect(Collectors.toList()); + } + + /** + * @date:2021/4/5 + * @className:VersionControl + * @author:Administrator + * @description: 获取类本地地址 + * + */ + private String getClassFilePath(String baseDir, String version, String classPath) { + StringBuilder builder = new StringBuilder(baseDir); + builder.append(version); + builder.append("/"); + builder.append(classPath); + return builder.toString(); + + } + + /** + * 获取类的增量方法 + * + * @param oldClassFile 旧类的本地地址 + * @param mewClassFile 新类的本地地址 + * @param diffEntry 差异类 + * @return + */ + private CompletableFuture getClassMethods(String oldClassFile, String mewClassFile, DiffEntryDto diffEntry) { + //多线程获取差异方法,此处只要考虑增量代码太多的情况下,每个类都需要遍历所有方法,采用多线程方式加快速度 + return CompletableFuture.supplyAsync(() -> { + String className = diffEntry.getNewPath().split("\\.")[0].split("src/main/java/")[1]; + //新增类直接标记,不用计算方法 + if (DiffEntry.ChangeType.ADD.equals(diffEntry.getChangeType())) { + return ClassInfoResult.builder() + .classFile(className) + .type(DiffEntry.ChangeType.ADD.name()) + .build(); + } + List diffMethods; + //获取新类的所有方法 + List newMethodInfoResults = MethodParserUtils.parseMethods(mewClassFile); + //如果新类为空,没必要比较 + if (CollectionUtils.isEmpty(newMethodInfoResults)) { + return null; + } + //获取旧类的所有方法 + List oldMethodInfoResults = MethodParserUtils.parseMethods(oldClassFile); + //如果旧类为空,新类的方法所有为增量 + if (CollectionUtils.isEmpty(oldMethodInfoResults)) { + diffMethods = newMethodInfoResults; + } else { //否则,计算增量方法 + List md5s = oldMethodInfoResults.stream().map(MethodInfoResult::getMd5).collect(Collectors.toList()); + diffMethods = newMethodInfoResults.stream().filter(m -> !md5s.contains(m.getMd5())).collect(Collectors.toList()); + } + //没有增量方法,过滤掉 + if (CollectionUtils.isEmpty(diffMethods)) { + return null; + } + return ClassInfoResult.builder() + .classFile(className) + .methodInfos(diffMethods) + .type(DiffEntry.ChangeType.MODIFY.name()) + .build(); + }, executor); + } + + +} diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/VersionControlHandlerFactory.java b/application/src/main/java/com/dr/code/diff/vercontrol/VersionControlHandlerFactory.java new file mode 100644 index 0000000..0f55264 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vercontrol/VersionControlHandlerFactory.java @@ -0,0 +1,65 @@ +package com.dr.code.diff.vercontrol; + +import com.dr.code.diff.dto.ClassInfoResult; +import com.dr.code.diff.dto.VersionControlDto; +import com.dr.code.diff.enums.CodeManageTypeEnum; +import com.google.common.collect.Lists; +import org.springframework.beans.BeansException; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; + +/** + * @ProjectName: cmdb + * @Package: com.dr.cmdb.application.filedcheck + * @Description: java类作用描述 + * @Author: duanrui + * @CreateDate: 2021/3/30 10:10 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2021 + */ +@Component +public class VersionControlHandlerFactory implements CommandLineRunner, ApplicationContextAware { + private volatile ApplicationContext applicationContext; + + + private static List handlers; + + + /** + * 拼接变种责任链 + * @param args + */ + @Override + public void run(String... args) { + Collection checkHandlers = this.applicationContext.getBeansOfType(VersionControl.class).values(); + handlers = Lists.newArrayList(checkHandlers); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + /** + * 执行方法校验 + * @param versionControlDto + */ + public static List processHandler(VersionControlDto versionControlDto) { + List result = null; + for (int i = 0; i < handlers.size(); i++) { + if(versionControlDto.getCodeManageTypeEnum().equals(handlers.get(i).getType())){ + result = handlers.get(i).handler(versionControlDto); + } + } + return result; + + } + + +} diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/git/GitVersionControl.java b/application/src/main/java/com/dr/code/diff/vercontrol/git/GitVersionControl.java new file mode 100644 index 0000000..8a7fb53 --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vercontrol/git/GitVersionControl.java @@ -0,0 +1,82 @@ +package com.dr.code.diff.vercontrol.git; + +import com.dr.code.diff.config.CustomizeConfig; +import com.dr.code.diff.dto.DiffEntryDto; +import com.dr.code.diff.enums.CodeManageTypeEnum; +import com.dr.code.diff.util.GitRepoUtil; +import com.dr.code.diff.vercontrol.VersionControl; +import com.dr.common.utils.mapper.OrikaMapperUtils; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.diff.DiffEntry; +import org.eclipse.jgit.treewalk.AbstractTreeIterator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.vercontrol + * @Description: 代码差异获取流程类定义 + * @Author: duanrui + * @CreateDate: 2021/4/5 9:56 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2021 + */ +@Component +public class GitVersionControl extends VersionControl { + + @Autowired + private CustomizeConfig customizeConfig; + + + /** + * 获取操作类型 + */ + @Override + public CodeManageTypeEnum getType() { + return CodeManageTypeEnum.GIT; + } + + @Override + public void getDiffCodeClasses() { + try { + String localBaseRepoDir = GitRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getGitLocalBaseRepoDir(), super.versionControlDto.getBaseVersion()); + String localNowRepoDir = GitRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getGitLocalBaseRepoDir(), super.versionControlDto.getNowVersion()); + //原有代码git对象 + Git baseGit = GitRepoUtil.cloneRepository(super.versionControlDto.getRepoUrl(), localBaseRepoDir, super.versionControlDto.getBaseVersion(), customizeConfig.getGitUserName(), customizeConfig.getGitPassWord()); + //现有代码git对象 + Git nowGit = GitRepoUtil.cloneRepository(super.versionControlDto.getRepoUrl(), localNowRepoDir, super.versionControlDto.getNowVersion(), customizeConfig.getGitUserName(), customizeConfig.getGitPassWord()); + AbstractTreeIterator baseTree = GitRepoUtil.prepareTreeParser(baseGit.getRepository(), super.versionControlDto.getBaseVersion()); + AbstractTreeIterator nowTree = GitRepoUtil.prepareTreeParser(nowGit.getRepository(), super.versionControlDto.getNowVersion()); + //获取两个版本之间的差异代码 + List diff = null; + diff = nowGit.diff().setOldTree(baseTree).setNewTree(nowTree).setShowNameAndStatusOnly(true).call(); + //过滤出有效的差异代码 + Collection validDiffList = diff.stream() + //只计算java文件 + .filter(e -> e.getNewPath().endsWith(".java")) + //排除测试文件 + .filter(e -> e.getNewPath().contains("src/main/java")) + //只计算新增和变更文件 + .filter(e -> DiffEntry.ChangeType.ADD.equals(e.getChangeType()) || DiffEntry.ChangeType.MODIFY.equals(e.getChangeType())) + .collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(validDiffList)) { + List diffEntrys = OrikaMapperUtils.mapList(validDiffList, DiffEntry.class, DiffEntryDto.class); + super.versionControlDto.setDiffClasses(diffEntrys); + } + } catch (GitAPIException e) { + e.printStackTrace(); + } + } + + @Override + public String getBaseDir() { + return GitRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getGitLocalBaseRepoDir(),""); + } +} diff --git a/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNDiffStatusHandler.java b/application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNDiffStatusHandler.java similarity index 85% rename from src/main/java/com/dr/code/diff/vercontrol/svn/MySVNDiffStatusHandler.java rename to application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNDiffStatusHandler.java index a59fa1b..4a4e327 100644 --- a/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNDiffStatusHandler.java +++ b/application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNDiffStatusHandler.java @@ -1,7 +1,6 @@ package com.dr.code.diff.vercontrol.svn; import com.dr.code.diff.dto.DiffEntryDto; -import lombok.Data; import org.eclipse.jgit.diff.DiffEntry; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.wc.ISVNDiffStatusHandler; @@ -22,16 +21,10 @@ *

* Copyright: Copyright (c) 2021 */ -@Data public class MySVNDiffStatusHandler implements ISVNDiffStatusHandler { - public final static List list = Collections.synchronizedList(new ArrayList()); + public final static List list = Collections.synchronizedList(new ArrayList());; - private String rootCodePath; - - public MySVNDiffStatusHandler(String rootCodePath) { - this.rootCodePath = rootCodePath; - } @Override public void handleDiffStatus(SVNDiffStatus svnDiffStatus) throws SVNException { @@ -40,7 +33,7 @@ public void handleDiffStatus(SVNDiffStatus svnDiffStatus) throws SVNException { return; } //过滤测试文件 - if(!svnDiffStatus.getPath().contains(rootCodePath)){ + if(!svnDiffStatus.getPath().contains("src/main/java")){ return; } DiffEntryDto entry = new DiffEntryDto(); diff --git a/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNEditor.java b/application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNEditor.java similarity index 100% rename from src/main/java/com/dr/code/diff/vercontrol/svn/MySVNEditor.java rename to application/src/main/java/com/dr/code/diff/vercontrol/svn/MySVNEditor.java diff --git a/application/src/main/java/com/dr/code/diff/vercontrol/svn/SvnVersionControl.java b/application/src/main/java/com/dr/code/diff/vercontrol/svn/SvnVersionControl.java new file mode 100644 index 0000000..e7f5a2b --- /dev/null +++ b/application/src/main/java/com/dr/code/diff/vercontrol/svn/SvnVersionControl.java @@ -0,0 +1,61 @@ +package com.dr.code.diff.vercontrol.svn; + +import com.dr.code.diff.config.CustomizeConfig; +import com.dr.code.diff.enums.CodeManageTypeEnum; +import com.dr.code.diff.util.SvnRepoUtil; +import com.dr.code.diff.vercontrol.VersionControl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.SVNDiffClient; +import org.tmatesoft.svn.core.wc.SVNRevision; + +/** + * @ProjectName: code-diff-parent + * @Package: com.dr.code.diff.vercontrol + * @Description: svn差异代码获取 + * @Author: duanrui + * @CreateDate: 2021/4/5 9:56 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2021 + */ +@Component +public class SvnVersionControl extends VersionControl { + + @Autowired + private CustomizeConfig customizeConfig; + + + /** + * 获取操作类型 + */ + @Override + public CodeManageTypeEnum getType() { + return CodeManageTypeEnum.SVN; + } + + @Override + public void getDiffCodeClasses() { + try { + MySVNDiffStatusHandler.list.clear(); + String localBaseRepoDir = SvnRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getSvnLocalBaseRepoDir(), super.versionControlDto.getBaseVersion()); + String localNowRepoDir = SvnRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getSvnLocalBaseRepoDir(), super.versionControlDto.getNowVersion()); + SvnRepoUtil.cloneRepository(super.versionControlDto.getRepoUrl(), localBaseRepoDir, super.versionControlDto.getBaseVersion(), customizeConfig.getSvnUserName(), customizeConfig.getSvnPassWord()); + SvnRepoUtil.cloneRepository(super.versionControlDto.getRepoUrl(), localNowRepoDir, super.versionControlDto.getNowVersion(), customizeConfig.getSvnUserName(), customizeConfig.getSvnPassWord()); + SVNDiffClient svnDiffClient = SvnRepoUtil.getSVNDiffClient(customizeConfig.getSvnUserName(), customizeConfig.getSvnPassWord()); + svnDiffClient.doDiffStatus(SVNURL.parseURIEncoded(super.versionControlDto.getRepoUrl()), SVNRevision.create(Long.parseLong(super.versionControlDto.getBaseVersion())), SVNURL.parseURIEncoded(super.versionControlDto.getRepoUrl()), SVNRevision.create(Long.parseLong(super.versionControlDto.getNowVersion())), SVNDepth.INFINITY, true, new MySVNDiffStatusHandler()); + //将差异代码设置进集合 + super.versionControlDto.setDiffClasses(MySVNDiffStatusHandler.list); + } catch (SVNException e) { + e.printStackTrace(); + } + } + + @Override + public String getBaseDir() { + return SvnRepoUtil.getLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getSvnLocalBaseRepoDir(),""); + } +} diff --git a/src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java b/application/src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java similarity index 100% rename from src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java rename to application/src/main/java/com/dr/code/diff/vo/param/CodeDiffParamVO.java diff --git a/src/main/java/com/dr/code/diff/vo/result/CodeDiffResultVO.java b/application/src/main/java/com/dr/code/diff/vo/result/CodeDiffResultVO.java similarity index 70% rename from src/main/java/com/dr/code/diff/vo/result/CodeDiffResultVO.java rename to application/src/main/java/com/dr/code/diff/vo/result/CodeDiffResultVO.java index 1c1c517..f1672b0 100644 --- a/src/main/java/com/dr/code/diff/vo/result/CodeDiffResultVO.java +++ b/application/src/main/java/com/dr/code/diff/vo/result/CodeDiffResultVO.java @@ -17,13 +17,6 @@ public class CodeDiffResultVO { - - /** - * 模块名称 - */ - @ApiModelProperty(name = "moduleName", value = "模块名,请把模块名和目录保持一致", dataType = "String", example = "com/dr/code/diff/common") - private String moduleName; - /** * java文件 */ @@ -43,10 +36,4 @@ public class CodeDiffResultVO { @ApiModelProperty(name = "type", value = "修改类型", dataType = "String", example = "ADD") private String type; - /** - * 变更行 - */ - @ApiModelProperty(name = "lines", value = "变更行信息") - private List lines; - } diff --git a/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java b/application/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java similarity index 66% rename from src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java rename to application/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java index c29e744..5914cb5 100644 --- a/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java +++ b/application/src/main/java/com/dr/code/diff/vo/result/MethodInfoResultVO.java @@ -4,8 +4,6 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import java.util.List; - /** * @date:2021/1/9 * @className:MethodInfoResultVO @@ -25,24 +23,13 @@ public class MethodInfoResultVO { /** * 方法名 */ - @ApiModelProperty(name = "methodName", value = "方法名", dataType = "string", example = "getAll", position = 1) + @ApiModelProperty(name = "methodName", value = "方法名", dataType = "string", example = "getAll") public String methodName; /** * 方法参数 */ - @ApiModelProperty(name = "parameters", value = "parameters", dataType = "string", position = 2) - public List parameters; - - /** - * 开始行 - */ - @ApiModelProperty(value = "开始行", position = 3) - private Integer startLine; + @ApiModelProperty(name = "parameters", value = "parameters", dataType = "string") + public String parameters; - /** - * - */ - @ApiModelProperty(value = "结束行", position = 4) - private Integer endLine; } diff --git a/src/main/resources/application-docker.yml b/application/src/main/resources/application.yml similarity index 59% rename from src/main/resources/application-docker.yml rename to application/src/main/resources/application.yml index 39c5c22..bf70065 100644 --- a/src/main/resources/application-docker.yml +++ b/application/src/main/resources/application.yml @@ -1,4 +1,7 @@ spring: + profiles: + #激活开发环境 + active: dev messages: basename: i18n/Messages,i18n/Pages # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 @@ -10,13 +13,9 @@ spring: time-zone: GMT+8 logging: config: classpath:log4j2.yml -springfox: - documentation: - enabled: true swagger: + enabled: true base-package: com.dr.code.diff.controller - authorization: - type: None ##日志配置 #logging: # config: classpath:log4j2.yml @@ -27,33 +26,17 @@ swagger: # sessionManager: # sessionIdUrlRewritingEnabled: false git: - userName: ray + userName: rayduan password: 123456 local: base: - dir: /home/git-test - ssh: - priKey: ~/.ssh/id_rsa. + dir: D:\git-test svn: userName: admin password: 123456 local: base: - dir: /home/svn-test -maven: - home: /usr/share/java/maven-3 -root: - code: - path: src/main/java/ - -custom: - link: - start: - classNameList: - - com/dr/common/utils/mapper/OrikaMapperUtils - methodSignList: - - com/dr/code/diff/service/CodeDiffService#getDiffCode#DiffMethodParams - - com/dr/code/diff/analyze/bean/ClassInfo#getSuperClassName# + dir: D:\svn-test server: port: 8085 servlet: @@ -63,7 +46,8 @@ server: # url: http://192.168.80.128:8081 # userName: admin # password: 1 - dubbo: - xml: - path: "" - +--- +server: + port: 8084 +spring: + profiles: test diff --git a/src/main/resources/log4j2.yml b/application/src/main/resources/log4j2.yml similarity index 83% rename from src/main/resources/log4j2.yml rename to application/src/main/resources/log4j2.yml index f3eaf2e..2c04d1b 100644 --- a/src/main/resources/log4j2.yml +++ b/application/src/main/resources/log4j2.yml @@ -12,7 +12,7 @@ Configuration: - name: log.sql.level value: trace - name: log.path - value: /home/logs + value: D://logs Appenders: Console: #输出到控制台 name: CONSOLE @@ -26,8 +26,8 @@ Configuration: RollingFile: # 输出到文件,超过128MB归档 - name: info ignoreExceptions: false - fileName: ${sys:log.path}/${date:yyyy-MM}/${date:yyyy-MM-dd}/info.log - filePattern: "${sys:log.path}/${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz" + fileName: ${log.path}/${date:yyyy-MM}/${date:yyyy-MM-dd}/info.log + filePattern: "${log.path}/${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz" ThresholdFilter: level: info onMatch: ACCEPT @@ -41,8 +41,8 @@ Configuration: max: 1000 - name: debug ignoreExceptions: false - fileName: ${sys:log.path}/${date:yyyy-MM}/${date:yyyy-MM-dd}/debug.log - filePattern: "${sys:log.path}/$${date:yyyy-MM}/debug-%d{yyyy-MM-dd}-%i.log.gz" + fileName: ${log.path}/${date:yyyy-MM}/${date:yyyy-MM-dd}/debug.log + filePattern: "${log.path}/$${date:yyyy-MM}/debug-%d{yyyy-MM-dd}-%i.log.gz" ThresholdFilter: level: debug onMatch: ACCEPT @@ -56,8 +56,8 @@ Configuration: max: 1000 - name: error ignoreExceptions: false - fileName: ${sys:log.path}/${date:yyyy-MM}/${date:yyyy-MM-dd}/error.log - filePattern: "${sys:log.path}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz" + fileName: ${log.path}/${date:yyyy-MM}/${date:yyyy-MM-dd}/error.log + filePattern: "${log.path}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz" ThresholdFilter: level: error onMatch: ACCEPT diff --git a/src/test/java/com/dr/code/diff/CodeDiffApplicationTest.java b/application/src/test/java/com/dr/code/diff/CodeDiffApplicationTest.java similarity index 100% rename from src/test/java/com/dr/code/diff/CodeDiffApplicationTest.java rename to application/src/test/java/com/dr/code/diff/CodeDiffApplicationTest.java diff --git a/src/test/java/com/dr/code/diff/config/GitConfigTest.java b/application/src/test/java/com/dr/code/diff/config/GitConfigTest.java similarity index 100% rename from src/test/java/com/dr/code/diff/config/GitConfigTest.java rename to application/src/test/java/com/dr/code/diff/config/GitConfigTest.java diff --git a/src/test/java/com/dr/code/diff/util/MethodParserUtilsTest.java b/application/src/test/java/com/dr/code/diff/util/MethodParserUtilsTest.java similarity index 92% rename from src/test/java/com/dr/code/diff/util/MethodParserUtilsTest.java rename to application/src/test/java/com/dr/code/diff/util/MethodParserUtilsTest.java index 30b246f..4cf40f4 100644 --- a/src/test/java/com/dr/code/diff/util/MethodParserUtilsTest.java +++ b/application/src/test/java/com/dr/code/diff/util/MethodParserUtilsTest.java @@ -18,12 +18,7 @@ class MethodParserUtilsTest extends CodeDiffApplicationTest { @Test void parseMethods() { MethodParserUtils methodParserUtils = new MethodParserUtils(); - methodParserUtils.parseMethods("D:\\git-test\\43c9a993fbbb35bbe3221dfc20cf07fedb0bb3a2\\collector\\src\\main\\java\\com\\geely\\collector\\mvc\\APIResponse.java","src/main/java"); + methodParserUtils.parseMethods("D:\\git-test\\43c9a993fbbb35bbe3221dfc20cf07fedb0bb3a2\\collector\\src\\main\\java\\com\\geely\\collector\\mvc\\APIResponse.java"); // methodParser.parseMethods("D:\\git-test\\43c9a993fbbb35bbe3221dfc20cf07fedb0bb3a2\\third-sdk\\src\\main\\java\\com\\geely\\gitlab\\service\\GitlabService.java"); } - - - - - } \ No newline at end of file diff --git a/src/test/java/com/dr/code/diff/vercontrol/SvnAbstractVersionControlTest.java b/application/src/test/java/com/dr/code/diff/vercontrol/SvnVersionControlTest.java similarity index 79% rename from src/test/java/com/dr/code/diff/vercontrol/SvnAbstractVersionControlTest.java rename to application/src/test/java/com/dr/code/diff/vercontrol/SvnVersionControlTest.java index 23392fd..fac10b2 100644 --- a/src/test/java/com/dr/code/diff/vercontrol/SvnAbstractVersionControlTest.java +++ b/application/src/test/java/com/dr/code/diff/vercontrol/SvnVersionControlTest.java @@ -1,7 +1,8 @@ package com.dr.code.diff.vercontrol; import com.dr.code.diff.CodeDiffApplicationTest; -import com.dr.code.diff.vercontrol.svn.SvnAbstractVersionControl; +import com.dr.code.diff.dto.VersionControlDto; +import com.dr.code.diff.vercontrol.svn.SvnVersionControl; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -15,10 +16,10 @@ *

* Copyright: Copyright (c) 2021 */ -class SvnAbstractVersionControlTest extends CodeDiffApplicationTest { +class SvnVersionControlTest extends CodeDiffApplicationTest { @Autowired - private SvnAbstractVersionControl svnVersionControl; + private SvnVersionControl svnVersionControl; @Test void getDiffCodeClasses() { diff --git a/code-diff.exec b/code-diff.exec deleted file mode 100644 index ffc3c8b..0000000 Binary files a/code-diff.exec and /dev/null differ diff --git a/common/pom.xml b/common/pom.xml new file mode 100644 index 0000000..4fc70b6 --- /dev/null +++ b/common/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + com.dr + code-diff-parent + 1.0.0-SNAPSHOT + + common + 1.0.0-SNAPSHOT + common + Demo project for Spring Boot + + + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.apache.httpcomponents + httpclient + + + org.springframework.boot + spring-boot-starter-aop + + + ma.glasnost.orika + orika-core + + + cn.afterturn + easypoi-spring-boot-starter + + + org.projectlombok + lombok + + + com.alibaba + fastjson + + + com.github.whvcse + easy-captcha + + + + com.google.guava + guava + + + org.aspectj + aspectjweaver + + + + + + diff --git a/src/main/java/com/dr/code/diff/common/annotation/IdempotentCheck.java b/common/src/main/java/com/dr/common/annotation/IdempotentCheck.java similarity index 86% rename from src/main/java/com/dr/code/diff/common/annotation/IdempotentCheck.java rename to common/src/main/java/com/dr/common/annotation/IdempotentCheck.java index dcbfc10..50c9f16 100644 --- a/src/main/java/com/dr/code/diff/common/annotation/IdempotentCheck.java +++ b/common/src/main/java/com/dr/common/annotation/IdempotentCheck.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.annotation; +package com.dr.common.annotation; import java.lang.annotation.*; diff --git a/src/main/java/com/dr/code/diff/common/aop/IdempotentAspect.java b/common/src/main/java/com/dr/common/aop/IdempotentAspect.java similarity index 95% rename from src/main/java/com/dr/code/diff/common/aop/IdempotentAspect.java rename to common/src/main/java/com/dr/common/aop/IdempotentAspect.java index 2a67711..cb31910 100644 --- a/src/main/java/com/dr/code/diff/common/aop/IdempotentAspect.java +++ b/common/src/main/java/com/dr/common/aop/IdempotentAspect.java @@ -1,7 +1,7 @@ -package com.dr.code.diff.common.aop; +package com.dr.common.aop; -import com.dr.code.diff.common.annotation.IdempotentCheck; +import com.dr.common.annotation.IdempotentCheck; import javassist.*; import javassist.bytecode.CodeAttribute; import javassist.bytecode.LocalVariableAttribute; @@ -31,7 +31,7 @@ public class IdempotentAspect { // private IUcsCache ucsCache; - @Pointcut("@annotation(com.dr.code.diff.common.annotation.IdempotentCheck)") + @Pointcut("@annotation(com.dr.common.annotation.IdempotentCheck)") public void idempotentCheck() {} @Before("idempotentCheck()") diff --git a/src/main/java/com/dr/code/diff/common/config/BaseConfiguration.java b/common/src/main/java/com/dr/common/config/BaseConfiguration.java similarity index 97% rename from src/main/java/com/dr/code/diff/common/config/BaseConfiguration.java rename to common/src/main/java/com/dr/common/config/BaseConfiguration.java index f36ab35..14640bb 100644 --- a/src/main/java/com/dr/code/diff/common/config/BaseConfiguration.java +++ b/common/src/main/java/com/dr/common/config/BaseConfiguration.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.config; +package com.dr.common.config; import lombok.Data; import org.springframework.beans.factory.annotation.Value; diff --git a/src/main/java/com/dr/code/diff/common/constant/AuthConstant.java b/common/src/main/java/com/dr/common/constant/AuthConstant.java similarity index 96% rename from src/main/java/com/dr/code/diff/common/constant/AuthConstant.java rename to common/src/main/java/com/dr/common/constant/AuthConstant.java index 6b92e93..e09fec7 100644 --- a/src/main/java/com/dr/code/diff/common/constant/AuthConstant.java +++ b/common/src/main/java/com/dr/common/constant/AuthConstant.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.constant; +package com.dr.common.constant; /** * @author ylw diff --git a/src/main/java/com/dr/code/diff/common/constant/Constant.java b/common/src/main/java/com/dr/common/constant/Constant.java similarity index 97% rename from src/main/java/com/dr/code/diff/common/constant/Constant.java rename to common/src/main/java/com/dr/common/constant/Constant.java index ad6b3da..c38388c 100644 --- a/src/main/java/com/dr/code/diff/common/constant/Constant.java +++ b/common/src/main/java/com/dr/common/constant/Constant.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.constant; +package com.dr.common.constant; /** * @author rui.duan @@ -16,7 +16,7 @@ public class Constant { /** * 最大导出条数 */ - public final static int LIMIT_EXPORT_COUNT = 5000; + public final static int LIMIT_EXPORT_COUNT = 10000; /** * 云秀供应商商品ID diff --git a/src/main/java/com/dr/code/diff/common/enums/AdminTypeEnum.java b/common/src/main/java/com/dr/common/enums/AdminTypeEnum.java similarity index 96% rename from src/main/java/com/dr/code/diff/common/enums/AdminTypeEnum.java rename to common/src/main/java/com/dr/common/enums/AdminTypeEnum.java index ca02ada..e52016c 100644 --- a/src/main/java/com/dr/code/diff/common/enums/AdminTypeEnum.java +++ b/common/src/main/java/com/dr/common/enums/AdminTypeEnum.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.enums; +package com.dr.common.enums; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/com/dr/code/diff/common/enums/PermissionTypeEnum.java b/common/src/main/java/com/dr/common/enums/PermissionTypeEnum.java similarity index 97% rename from src/main/java/com/dr/code/diff/common/enums/PermissionTypeEnum.java rename to common/src/main/java/com/dr/common/enums/PermissionTypeEnum.java index 6a1aad0..545580e 100644 --- a/src/main/java/com/dr/code/diff/common/enums/PermissionTypeEnum.java +++ b/common/src/main/java/com/dr/common/enums/PermissionTypeEnum.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.enums; +package com.dr.common.enums; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/dr/code/diff/common/errorcode/BaseCode.java b/common/src/main/java/com/dr/common/errorcode/BaseCode.java similarity index 99% rename from src/main/java/com/dr/code/diff/common/errorcode/BaseCode.java rename to common/src/main/java/com/dr/common/errorcode/BaseCode.java index a25c10b..a5d296a 100644 --- a/src/main/java/com/dr/code/diff/common/errorcode/BaseCode.java +++ b/common/src/main/java/com/dr/common/errorcode/BaseCode.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.errorcode; +package com.dr.common.errorcode; /** * @Author : Max. diff --git a/common/src/main/java/com/dr/common/errorcode/BizCode.java b/common/src/main/java/com/dr/common/errorcode/BizCode.java new file mode 100644 index 0000000..d980693 --- /dev/null +++ b/common/src/main/java/com/dr/common/errorcode/BizCode.java @@ -0,0 +1,71 @@ +package com.dr.common.errorcode; + +/** + * + */ +public enum BizCode implements Code { + + /**************************计费模块错误码******************************/ + GIT_OPERATED_FAIlED(20000, "git拉取代码失败", "请检查git参数配置"), + CHARGE_PKG_SKU_INVALID(20001, "包裹商品数据不存在", "请检查包裹商品信息是否存在"), + CREATE_JOB_FAIL(20002, "创建job失败", "请联系管理员"), + + + + ; + + private final int code; + private final String info; + private final String fixTips; + + BizCode(int code, String info, String fixTips) { + this.code = code; + this.info = info; + this.fixTips = fixTips; + } + + /** + * 错误码 + * eg: 200xx gateway + * 300xx user + * 400xx order + * 500xx core + * 600xx operator + * 700xx admin + *

+ * universal: + * 10000 ~ 19999 + * 10000 success + * 10001 system error + * 10002 timed out + * 10003 params error + * 10004 rpc timeout + * 10005 rpc invoke error + * + * @return + */ + @Override + public int getCode() { + return this.code; + } + + /** + * 错误码说明(内部日志,统计,查看使用) + * + * @return + */ + @Override + public String getInfo() { + return this.info; + } + + /** + * 错误码描述,对外输出 + * + * @return + */ + @Override + public String getFixTips() { + return this.fixTips; + } +} diff --git a/src/main/java/com/dr/code/diff/common/errorcode/Code.java b/common/src/main/java/com/dr/common/errorcode/Code.java similarity index 68% rename from src/main/java/com/dr/code/diff/common/errorcode/Code.java rename to common/src/main/java/com/dr/common/errorcode/Code.java index ca9de71..cfde5b3 100644 --- a/src/main/java/com/dr/code/diff/common/errorcode/Code.java +++ b/common/src/main/java/com/dr/common/errorcode/Code.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.errorcode; +package com.dr.common.errorcode; public interface Code { int getCode(); diff --git a/src/main/java/com/dr/code/diff/common/exception/BaseException.java b/common/src/main/java/com/dr/common/exception/BaseException.java similarity index 91% rename from src/main/java/com/dr/code/diff/common/exception/BaseException.java rename to common/src/main/java/com/dr/common/exception/BaseException.java index 06af5d3..ad391a3 100644 --- a/src/main/java/com/dr/code/diff/common/exception/BaseException.java +++ b/common/src/main/java/com/dr/common/exception/BaseException.java @@ -1,7 +1,7 @@ -package com.dr.code.diff.common.exception; +package com.dr.common.exception; -import com.dr.code.diff.common.errorcode.Code; +import com.dr.common.errorcode.Code; public class BaseException extends RuntimeException { diff --git a/src/main/java/com/dr/code/diff/common/exception/BizException.java b/common/src/main/java/com/dr/common/exception/BizException.java similarity index 81% rename from src/main/java/com/dr/code/diff/common/exception/BizException.java rename to common/src/main/java/com/dr/common/exception/BizException.java index 1c94ca8..e55b0c6 100644 --- a/src/main/java/com/dr/code/diff/common/exception/BizException.java +++ b/common/src/main/java/com/dr/common/exception/BizException.java @@ -1,7 +1,7 @@ -package com.dr.code.diff.common.exception; +package com.dr.common.exception; -import com.dr.code.diff.common.errorcode.Code; +import com.dr.common.errorcode.Code; /** * diff --git a/src/main/java/com/dr/code/diff/common/httpclient/HttpClientUtil.java b/common/src/main/java/com/dr/common/httpclient/HttpClientUtil.java similarity index 99% rename from src/main/java/com/dr/code/diff/common/httpclient/HttpClientUtil.java rename to common/src/main/java/com/dr/common/httpclient/HttpClientUtil.java index ad8d34c..3e54232 100644 --- a/src/main/java/com/dr/code/diff/common/httpclient/HttpClientUtil.java +++ b/common/src/main/java/com/dr/common/httpclient/HttpClientUtil.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.httpclient; +package com.dr.common.httpclient; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/com/dr/code/diff/common/httpclient/HttpRequestResult.java b/common/src/main/java/com/dr/common/httpclient/HttpRequestResult.java similarity index 86% rename from src/main/java/com/dr/code/diff/common/httpclient/HttpRequestResult.java rename to common/src/main/java/com/dr/common/httpclient/HttpRequestResult.java index b9315e3..870faeb 100644 --- a/src/main/java/com/dr/code/diff/common/httpclient/HttpRequestResult.java +++ b/common/src/main/java/com/dr/common/httpclient/HttpRequestResult.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.httpclient; +package com.dr.common.httpclient; import lombok.Data; diff --git a/src/main/java/com/dr/code/diff/common/log/LoggerUtil.java b/common/src/main/java/com/dr/common/log/LoggerUtil.java similarity index 98% rename from src/main/java/com/dr/code/diff/common/log/LoggerUtil.java rename to common/src/main/java/com/dr/common/log/LoggerUtil.java index bb45397..d92a574 100644 --- a/src/main/java/com/dr/code/diff/common/log/LoggerUtil.java +++ b/common/src/main/java/com/dr/common/log/LoggerUtil.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.log; +package com.dr.common.log; import com.alibaba.fastjson.JSON; import org.apache.commons.lang3.StringUtils; diff --git a/src/main/java/com/dr/code/diff/common/page/PageParam.java b/common/src/main/java/com/dr/common/page/PageParam.java similarity index 94% rename from src/main/java/com/dr/code/diff/common/page/PageParam.java rename to common/src/main/java/com/dr/common/page/PageParam.java index e133217..48c60e5 100644 --- a/src/main/java/com/dr/code/diff/common/page/PageParam.java +++ b/common/src/main/java/com/dr/common/page/PageParam.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.page; +package com.dr.common.page; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/com/dr/code/diff/common/page/PageResult.java b/common/src/main/java/com/dr/common/page/PageResult.java similarity index 97% rename from src/main/java/com/dr/code/diff/common/page/PageResult.java rename to common/src/main/java/com/dr/common/page/PageResult.java index 8d558c4..08ccf74 100644 --- a/src/main/java/com/dr/code/diff/common/page/PageResult.java +++ b/common/src/main/java/com/dr/common/page/PageResult.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.page; +package com.dr.common.page; import lombok.Data; diff --git a/src/main/java/com/dr/code/diff/common/response/ApiResponse.java b/common/src/main/java/com/dr/common/response/ApiResponse.java similarity index 88% rename from src/main/java/com/dr/code/diff/common/response/ApiResponse.java rename to common/src/main/java/com/dr/common/response/ApiResponse.java index cc0ef81..06abd5d 100644 --- a/src/main/java/com/dr/code/diff/common/response/ApiResponse.java +++ b/common/src/main/java/com/dr/common/response/ApiResponse.java @@ -1,9 +1,9 @@ -package com.dr.code.diff.common.response; +package com.dr.common.response; -import com.dr.code.diff.common.errorcode.BaseCode; -import com.dr.code.diff.common.errorcode.Code; -import com.dr.code.diff.common.exception.BaseException; +import com.dr.common.errorcode.BaseCode; +import com.dr.common.errorcode.Code; +import com.dr.common.exception.BaseException; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/src/main/java/com/dr/code/diff/common/response/UniqueApoResponse.java b/common/src/main/java/com/dr/common/response/UniqueApoResponse.java similarity index 85% rename from src/main/java/com/dr/code/diff/common/response/UniqueApoResponse.java rename to common/src/main/java/com/dr/common/response/UniqueApoResponse.java index 9fe3b3e..f91a305 100644 --- a/src/main/java/com/dr/code/diff/common/response/UniqueApoResponse.java +++ b/common/src/main/java/com/dr/common/response/UniqueApoResponse.java @@ -1,9 +1,10 @@ -package com.dr.code.diff.common.response; +package com.dr.common.response; -import com.dr.code.diff.common.errorcode.BaseCode; +import com.dr.common.errorcode.BaseCode; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.apache.poi.ss.formula.functions.T; /** * @ProjectName: code-diff-parent diff --git a/src/main/java/com/dr/code/diff/common/utils/auth/MD5Util.java b/common/src/main/java/com/dr/common/utils/auth/MD5Util.java similarity index 84% rename from src/main/java/com/dr/code/diff/common/utils/auth/MD5Util.java rename to common/src/main/java/com/dr/common/utils/auth/MD5Util.java index f96ef49..e6a72df 100644 --- a/src/main/java/com/dr/code/diff/common/utils/auth/MD5Util.java +++ b/common/src/main/java/com/dr/common/utils/auth/MD5Util.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.auth; +package com.dr.common.utils.auth; import com.google.common.io.ByteSource; import org.apache.commons.lang3.StringUtils; @@ -10,17 +10,15 @@ public class MD5Util { private static String byteArrayToHexString(byte b[]) { StringBuffer resultSb = new StringBuffer(); - for (int i = 0; i < b.length; i++) { + for (int i = 0; i < b.length; i++) resultSb.append(byteToHexString(b[i])); - } return resultSb.toString(); } private static String byteToHexString(byte b) { int n = b; - if (n < 0) { + if (n < 0) n += 256; - } int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; @@ -31,13 +29,12 @@ public static String MD5Encode(String origin, String charsetname) { try { resultString = new String(origin); MessageDigest md = MessageDigest.getInstance("MD5"); - if (charsetname == null || "".equals(charsetname)) { + if (charsetname == null || "".equals(charsetname)) resultString = byteArrayToHexString(md.digest(resultString .getBytes())); - } else { + else resultString = byteArrayToHexString(md.digest(resultString .getBytes(charsetname))); - } } catch (Exception exception) { exception.printStackTrace(); } diff --git a/src/main/java/com/dr/code/diff/common/utils/captcha/CaptchaUtil.java b/common/src/main/java/com/dr/common/utils/captcha/CaptchaUtil.java similarity index 98% rename from src/main/java/com/dr/code/diff/common/utils/captcha/CaptchaUtil.java rename to common/src/main/java/com/dr/common/utils/captcha/CaptchaUtil.java index 32172ce..731d1bb 100644 --- a/src/main/java/com/dr/code/diff/common/utils/captcha/CaptchaUtil.java +++ b/common/src/main/java/com/dr/common/utils/captcha/CaptchaUtil.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.captcha; +package com.dr.common.utils.captcha; import com.wf.captcha.GifCaptcha; diff --git a/src/main/java/com/dr/code/diff/common/utils/date/DateUtil.java b/common/src/main/java/com/dr/common/utils/date/DateUtil.java similarity index 99% rename from src/main/java/com/dr/code/diff/common/utils/date/DateUtil.java rename to common/src/main/java/com/dr/common/utils/date/DateUtil.java index 8ac0f23..e91b037 100644 --- a/src/main/java/com/dr/code/diff/common/utils/date/DateUtil.java +++ b/common/src/main/java/com/dr/common/utils/date/DateUtil.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.date; +package com.dr.common.utils.date; import com.google.common.collect.Lists; diff --git a/src/main/java/com/dr/code/diff/common/utils/date/JDKDateTimeUtil.java b/common/src/main/java/com/dr/common/utils/date/JDKDateTimeUtil.java similarity index 98% rename from src/main/java/com/dr/code/diff/common/utils/date/JDKDateTimeUtil.java rename to common/src/main/java/com/dr/common/utils/date/JDKDateTimeUtil.java index c43dc99..799f7e9 100644 --- a/src/main/java/com/dr/code/diff/common/utils/date/JDKDateTimeUtil.java +++ b/common/src/main/java/com/dr/common/utils/date/JDKDateTimeUtil.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.date; +package com.dr.common.utils.date; import java.text.SimpleDateFormat; import java.time.*; diff --git a/src/main/java/com/dr/code/diff/common/utils/date/JDKDateUtil.java b/common/src/main/java/com/dr/common/utils/date/JDKDateUtil.java similarity index 99% rename from src/main/java/com/dr/code/diff/common/utils/date/JDKDateUtil.java rename to common/src/main/java/com/dr/common/utils/date/JDKDateUtil.java index e2b2b30..fa561ac 100644 --- a/src/main/java/com/dr/code/diff/common/utils/date/JDKDateUtil.java +++ b/common/src/main/java/com/dr/common/utils/date/JDKDateUtil.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.date; +package com.dr.common.utils.date; import java.text.SimpleDateFormat; import java.time.*; diff --git a/src/main/java/com/dr/code/diff/common/utils/excel/ExcelUtil.java b/common/src/main/java/com/dr/common/utils/excel/ExcelUtil.java similarity index 96% rename from src/main/java/com/dr/code/diff/common/utils/excel/ExcelUtil.java rename to common/src/main/java/com/dr/common/utils/excel/ExcelUtil.java index 59f757a..714e909 100644 --- a/src/main/java/com/dr/code/diff/common/utils/excel/ExcelUtil.java +++ b/common/src/main/java/com/dr/common/utils/excel/ExcelUtil.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.excel; +package com.dr.common.utils.excel; import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.ExcelImportUtil; @@ -8,10 +8,10 @@ import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult; import cn.afterturn.easypoi.excel.imports.ExcelImportService; import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler; -import com.dr.code.diff.common.constant.Constant; -import com.dr.code.diff.common.errorcode.BaseCode; -import com.dr.code.diff.common.exception.BizException; -import com.dr.code.diff.common.log.LoggerUtil; +import com.dr.common.constant.Constant; +import com.dr.common.errorcode.BaseCode; +import com.dr.common.exception.BizException; +import com.dr.common.log.LoggerUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.Workbook; diff --git a/common/src/main/java/com/dr/common/utils/file/FileUtil.java b/common/src/main/java/com/dr/common/utils/file/FileUtil.java new file mode 100644 index 0000000..9da12af --- /dev/null +++ b/common/src/main/java/com/dr/common/utils/file/FileUtil.java @@ -0,0 +1,39 @@ +package com.dr.common.utils.file; + +import com.dr.common.log.LoggerUtil; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; + +/** + * @ProjectName: code-diff + * @Package: com.dr.common.utils.file + * @Description: 文件处理类 + * @Author: duanrui + * @CreateDate: 2021/1/9 22:56 + * @Version: 1.0 + *

+ * Copyright: Copyright (c) 2021 + */ +@Slf4j +public class FileUtil { + /** + * 删除目录下所有文件 + * + * @param dir + */ + public static void removeDir(File dir) { + if (null == dir) { + return; + } + File[] files = dir.listFiles(); + for (File file : files) { + if (file.isDirectory()) { + removeDir(file); + } else { + System.out.println(file + ":" + file.delete()); + } + } + LoggerUtil.info(log,dir + ":" + dir.delete()); + } +} diff --git a/src/main/java/com/dr/code/diff/common/utils/list/ListUtils.java b/common/src/main/java/com/dr/common/utils/list/ListUtils.java similarity index 92% rename from src/main/java/com/dr/code/diff/common/utils/list/ListUtils.java rename to common/src/main/java/com/dr/common/utils/list/ListUtils.java index 68ca562..490ebf4 100644 --- a/src/main/java/com/dr/code/diff/common/utils/list/ListUtils.java +++ b/common/src/main/java/com/dr/common/utils/list/ListUtils.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.list; +package com.dr.common.utils.list; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/src/main/java/com/dr/code/diff/common/utils/mapper/OrikaMapperUtils.java b/common/src/main/java/com/dr/common/utils/mapper/OrikaMapperUtils.java similarity index 98% rename from src/main/java/com/dr/code/diff/common/utils/mapper/OrikaMapperUtils.java rename to common/src/main/java/com/dr/common/utils/mapper/OrikaMapperUtils.java index 7f33512..b6d41c7 100644 --- a/src/main/java/com/dr/code/diff/common/utils/mapper/OrikaMapperUtils.java +++ b/common/src/main/java/com/dr/common/utils/mapper/OrikaMapperUtils.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.mapper; +package com.dr.common.utils.mapper; import ma.glasnost.orika.MapperFacade; import ma.glasnost.orika.MapperFactory; diff --git a/src/main/java/com/dr/code/diff/common/utils/security/AESUtils.java b/common/src/main/java/com/dr/common/utils/security/AESUtils.java similarity index 98% rename from src/main/java/com/dr/code/diff/common/utils/security/AESUtils.java rename to common/src/main/java/com/dr/common/utils/security/AESUtils.java index 8dcb1ba..573640e 100644 --- a/src/main/java/com/dr/code/diff/common/utils/security/AESUtils.java +++ b/common/src/main/java/com/dr/common/utils/security/AESUtils.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.security; +package com.dr.common.utils.security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; diff --git a/src/main/java/com/dr/code/diff/common/utils/security/Md5Util.java b/common/src/main/java/com/dr/common/utils/security/Md5Util.java similarity index 94% rename from src/main/java/com/dr/code/diff/common/utils/security/Md5Util.java rename to common/src/main/java/com/dr/common/utils/security/Md5Util.java index 4ce11be..8035797 100644 --- a/src/main/java/com/dr/code/diff/common/utils/security/Md5Util.java +++ b/common/src/main/java/com/dr/common/utils/security/Md5Util.java @@ -1,6 +1,6 @@ -package com.dr.code.diff.common.utils.security; +package com.dr.common.utils.security; -import com.dr.code.diff.common.log.LoggerUtil; +import com.dr.common.log.LoggerUtil; import lombok.extern.slf4j.Slf4j; import java.security.MessageDigest; diff --git a/src/main/java/com/dr/code/diff/common/utils/security/SaltUtil.java b/common/src/main/java/com/dr/common/utils/security/SaltUtil.java similarity index 93% rename from src/main/java/com/dr/code/diff/common/utils/security/SaltUtil.java rename to common/src/main/java/com/dr/common/utils/security/SaltUtil.java index c9cad95..5423cbc 100644 --- a/src/main/java/com/dr/code/diff/common/utils/security/SaltUtil.java +++ b/common/src/main/java/com/dr/common/utils/security/SaltUtil.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.security; +package com.dr.common.utils.security; import java.util.Random; diff --git a/src/main/java/com/dr/code/diff/common/utils/spring/SpringBeanRegisterUtils.java b/common/src/main/java/com/dr/common/utils/spring/SpringBeanRegisterUtils.java similarity index 98% rename from src/main/java/com/dr/code/diff/common/utils/spring/SpringBeanRegisterUtils.java rename to common/src/main/java/com/dr/common/utils/spring/SpringBeanRegisterUtils.java index 4998900..f1883ec 100644 --- a/src/main/java/com/dr/code/diff/common/utils/spring/SpringBeanRegisterUtils.java +++ b/common/src/main/java/com/dr/common/utils/spring/SpringBeanRegisterUtils.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.spring; +package com.dr.common.utils.spring; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; diff --git a/src/main/java/com/dr/code/diff/common/utils/spring/SpringCtxUtils.java b/common/src/main/java/com/dr/common/utils/spring/SpringCtxUtils.java similarity index 98% rename from src/main/java/com/dr/code/diff/common/utils/spring/SpringCtxUtils.java rename to common/src/main/java/com/dr/common/utils/spring/SpringCtxUtils.java index 1d416e1..025de37 100644 --- a/src/main/java/com/dr/code/diff/common/utils/spring/SpringCtxUtils.java +++ b/common/src/main/java/com/dr/common/utils/spring/SpringCtxUtils.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.spring; +package com.dr.common.utils.spring; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeansException; diff --git a/src/main/java/com/dr/code/diff/common/utils/string/BaseStringUtil.java b/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java similarity index 97% rename from src/main/java/com/dr/code/diff/common/utils/string/BaseStringUtil.java rename to common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java index 1352fa0..e3a1453 100644 --- a/src/main/java/com/dr/code/diff/common/utils/string/BaseStringUtil.java +++ b/common/src/main/java/com/dr/common/utils/string/BaseStringUtil.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.string; +package com.dr.common.utils.string; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/com/dr/code/diff/common/utils/string/PhoneUtils.java b/common/src/main/java/com/dr/common/utils/string/PhoneUtils.java similarity index 96% rename from src/main/java/com/dr/code/diff/common/utils/string/PhoneUtils.java rename to common/src/main/java/com/dr/common/utils/string/PhoneUtils.java index cb54dd0..f6aa884 100644 --- a/src/main/java/com/dr/code/diff/common/utils/string/PhoneUtils.java +++ b/common/src/main/java/com/dr/common/utils/string/PhoneUtils.java @@ -1,4 +1,4 @@ -package com.dr.code.diff.common.utils.string; +package com.dr.common.utils.string; import org.apache.commons.lang3.StringUtils; diff --git a/img.png b/img.png deleted file mode 100644 index 70a2087..0000000 Binary files a/img.png and /dev/null differ diff --git a/img_1.png b/img_1.png deleted file mode 100644 index b6d919a..0000000 Binary files a/img_1.png and /dev/null differ diff --git a/img_2.png b/img_2.png deleted file mode 100644 index 6423966..0000000 Binary files a/img_2.png and /dev/null differ diff --git a/img_3.png b/img_3.png deleted file mode 100644 index d985ca2..0000000 Binary files a/img_3.png and /dev/null differ diff --git a/lib/org.jacoco.cli-0.8.11-SNAPSHOT-nodeps.jar b/lib/org.jacoco.cli-0.8.11-SNAPSHOT-nodeps.jar deleted file mode 100644 index 68ba7d8..0000000 Binary files a/lib/org.jacoco.cli-0.8.11-SNAPSHOT-nodeps.jar and /dev/null differ diff --git a/lib/org.jacoco.cli-0.8.7-SNAPSHOT-nodeps.jar b/lib/org.jacoco.cli-0.8.7-SNAPSHOT-nodeps.jar deleted file mode 100644 index 379d072..0000000 Binary files a/lib/org.jacoco.cli-0.8.7-SNAPSHOT-nodeps.jar and /dev/null differ diff --git a/pom.xml b/pom.xml index 29bf1a5..847f5d5 100644 --- a/pom.xml +++ b/pom.xml @@ -8,17 +8,19 @@ 2.2.8.RELEASE com.dr - code-diff + code-diff-parent 1.0.0-SNAPSHOT code-diff-parent - jar + pom Demo project for Spring Boot + + common + application + 1.8 - 2.0.2.RELEASE + 1.9.0.RELEASE 1.9.6 - 3.0.3 - 3.0.3 1.2.62 1.5.4 1.1.20 @@ -28,256 +30,147 @@ 1.4.2 1.6.2 0.3.8 - 2.0.8 + + + + + + + + com.dr + common + ${project.version} + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis.version} + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pageHelper.version} + + + + cn.afterturn + easypoi-spring-boot-starter + ${easypoi.version} + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + com.alibaba + fastjson + ${fastjson.version} + + + ma.glasnost.orika + orika-core + ${orika-core.version} + + + + com.spring4all + swagger-spring-boot-starter + ${swagger.version} + + + com.github.xiaoymin + swagger-bootstrap-ui + ${swagger.ui.version} + + + + org.apache.shiro + shiro-spring-boot-web-starter + ${shiro.version} + + + + com.github.whvcse + easy-captcha + ${captcha.version} + + + + + com.google.guava + guava + 28.2-jre + + + + + com.offbytwo.jenkins + jenkins-client + ${jenkins.api.version} + + + + org.flywaydb + flyway-core + 5.2.4 + + + + com.github.javaparser + javaparser-core + 3.18.0 + + + + + + org.eclipse.jgit + org.eclipse.jgit + 5.10.0.202012080955-r + + + + + org.tmatesoft.svnkit + svnkit + 1.10.1 + + + + + + + + + + scm:git:https://github.com/rayduan/base-service.git + - - - - org.springframework.boot - spring-boot-starter-web - - - - - - - - - org.springframework.boot - spring-boot-starter-logging - - - - - - - - org.springframework.boot - spring-boot-starter-log4j2 - - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - - - org.projectlombok - lombok - - - cn.afterturn - easypoi-spring-boot-starter - ${easypoi.version} - - - - com.alibaba - fastjson - ${fastjson.version} - - - ma.glasnost.orika - orika-core - ${orika-core.version} - - - - com.spring4all - swagger-spring-boot-starter - ${swagger.version} - - - - - - - - com.github.xiaoymin - knife4j-spring-ui - ${knife4j.ui.version} - - - - - - - - - - - com.github.whvcse - easy-captcha - ${captcha.version} - - - - - com.google.guava - guava - 28.2-jre - - - - - - - - - - - - com.github.javaparser - javaparser-core - 3.25.4 - - - - - org.eclipse.jgit - org.eclipse.jgit - 5.13.1.202206130422-r - - - - - - - - - org.eclipse.jgit - org.eclipse.jgit.ssh.jsch - 5.13.1.202206130422-r - - - com.jcraft - jsch - - - - - com.github.mwiede - jsch - 0.2.8 - - - - - org.tmatesoft.svnkit - svnkit - 1.10.1 - - - cn.hutool - hutool-all - 5.6.3 - - - - - com.jayway.jsonpath - json-path - 2.6.0 - - - - org.apache.maven.shared - maven-invoker - 3.2.0 - - - org.xmlunit - xmlunit-core - 2.9.1 - - - org.springframework.boot - spring-boot-starter-aop - - - org.apache.maven - maven-model - 3.8.1 - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.vintage - junit-vintage-engine - - - - - - org.apache.httpcomponents - httpclient - - - - com.org - jacoco-cli - 1.0.0 - system - ${project.basedir}/lib/org.jacoco.cli-0.8.7-SNAPSHOT-nodeps.jar - - - - org.springframework.boot - spring-boot-maven-plugin - 2.3.5.RELEASE - - - true - true - - - - - - repackage - - - - - org.apache.maven.plugins - maven-compiler-plugin + maven-release-plugin - 1.8 - 1.8 - UTF-8 - - - ${java.home}/lib/rt.jar${path.separator}${java.home}/lib/jce.jar - - lib - + true + v@{project.version} + false + -DskipTests - - - org.apache.maven.plugins - maven-source-plugin - - true - - - - verify - - jar-no-fork - - - - + + + + maven-deploy-plugin + 2.8.2 + + + - diff --git a/run.sh b/run.sh deleted file mode 100644 index f3fa29d..0000000 --- a/run.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /app.jar \ No newline at end of file diff --git a/settings.xml b/settings.xml deleted file mode 100644 index 6065c4c..0000000 --- a/settings.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - /app/maven - - - aliyun - * - 阿里云公共仓库 - https://maven.aliyun.com/repository/public - - - \ No newline at end of file diff --git a/src/main/java/com/dr/code/diff/analyze/DeduceApiService.java b/src/main/java/com/dr/code/diff/analyze/DeduceApiService.java deleted file mode 100644 index bc55ad7..0000000 --- a/src/main/java/com/dr/code/diff/analyze/DeduceApiService.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.dr.code.diff.analyze; - -import com.alibaba.fastjson.JSON; -import com.dr.code.diff.analyze.bean.MethodInfo; -import com.dr.code.diff.dto.*; -import com.dr.code.diff.enums.MethodNodeTypeEnum; -import com.dr.code.diff.service.CodeDiffService; -import com.dr.code.diff.util.FileUtils; -import com.dr.code.diff.util.StringUtil; -import com.dr.code.diff.common.log.LoggerUtil; -import com.dr.code.diff.common.utils.mapper.OrikaMapperUtils; -import com.google.common.collect.Lists; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import javax.annotation.Resource; -import java.io.File; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -/** - * @Package: com.dr.code.diff.analyze - * @Description: 推导变更接口 - * @Author: rayduan - * @CreateDate: 2023/2/27 21:12 - * @Version: 1.0 - *

- */ -@Service -@Slf4j -public class DeduceApiService { - - @Autowired - private CodeDiffService codeDiffService; - - @Autowired - private MavenCmdInvokeService mavenCmdInvokeService; - - @Autowired - private InvokeLinkBuildService invokeLinkBuildService; - - @Resource(name = "asyncExecutor") - private Executor executor; - - /** - * 推断api - * - * @param diffMethodParams diff方法参数 - * @return {@link ApiModify} - */ - public ApiModify deduceApi(DiffMethodParams diffMethodParams) { - ApiModify apiModify = ApiModify.builder().httpApiModifies(new HashSet<>()).dubboApiModifies(new HashSet<>()).customClassModifies(new HashSet<>()).customMethodSignModifies(new HashSet<>()).build(); - //先获取源码,获取差异代码 - DiffInfo diffCode = codeDiffService.getDiffCode(diffMethodParams); - //然后编译源码 - String pomPath = StringUtil.connectPath(diffCode.getNewProjectPath(), "pom.xml"); - LoggerUtil.info(log, "开始编译项目", pomPath); - //这里存在风险,如果代码是分支,且有更新,这里必须要重新编译,先不考虑这个 - boolean compileFlag = FileUtils.searchFile(new File(diffCode.getNewProjectPath()), ".class"); - if (compileFlag) { - log.info("代码已经编译,直接使用"); - } else { - //编译代码 - mavenCmdInvokeService.compileCode(pomPath); - } - LoggerUtil.info(log, "项目编译完成"); - //获取静态调用链 - LoggerUtil.info(log, "开始获取静态调用链"); - Map> methodsInvokeLink = invokeLinkBuildService.getMethodsInvokeLink(Lists.newArrayList(diffCode.getNewProjectPath()), diffMethodParams.getExcludeFiles()); - LoggerUtil.info(log, "获取静态调用链完成"); - if (CollectionUtils.isEmpty(methodsInvokeLink)) { - return apiModify; - } - if (CollectionUtils.isEmpty(diffCode.getDiffClasses())) { - return apiModify; - } -// List httpMethodInfoList = methodsInvokeLink.get(MethodNodeTypeEnum.HTTP); -// List dubboMethodInfoList = methodsInvokeLink.get(MethodNodeTypeEnum.DUBBO); - Map> typeMap = diffCode.getDiffClasses().stream().collect(Collectors.groupingBy(DiffClassInfoResult::getType)); - List addMethods = typeMap.get("ADD"); - List modifyMethods = typeMap.get("MODIFY"); - //变更方法签名集合 - List modifyMethodSigns = new ArrayList(); - //新增类集合 - List addClassNames = new ArrayList(); - List modifyList = new ArrayList<>(); - if (!CollectionUtils.isEmpty(addMethods)) { - addClassNames = addMethods.stream().map(DiffClassInfoResult::getClassFile).collect(Collectors.toList()); - } - if (!CollectionUtils.isEmpty(modifyMethods)) { - modifyMethodSigns = modifyMethods.stream().map(DiffClassInfoResult::getMethodInfos).flatMap(Collection::stream).filter(Objects::nonNull).map(MethodInfoResult::getMethodSign).collect(Collectors.toList()); - } - modifyList.addAll(addClassNames); - modifyList.addAll(modifyMethodSigns); - getDiffApi(methodsInvokeLink, modifyList, apiModify); - return apiModify; - } - - /** - * 得到diff api - * - * @param keys 变更类的键值 - * @param apiModify api修改 - * @param methodsInvokeLink 方法调用链接 - */ - private void getDiffApi(Map> methodsInvokeLink, List keys, ApiModify apiModify) { - if (!CollectionUtils.isEmpty(keys)) { - //并发获取每个方法的调用方法 - CompletableFuture.allOf(keys.stream() - .map(item -> CompletableFuture.runAsync(() -> { - methodsInvokeLink.forEach( - (k, v) -> { - if (CollectionUtils.isEmpty(v)) { - return; - } - if (MethodNodeTypeEnum.HTTP.equals(k)) { - //计算http接口变更 - List httpModify = v.stream().filter(h -> JSON.toJSONString(h).contains(item)).collect(Collectors.toList()); - List httpApiModifies = OrikaMapperUtils.mapList(httpModify, MethodInfo.class, HttpApiModify.class); - apiModify.getHttpApiModifies().addAll(httpApiModifies); - } else { - List modifies = v.stream().filter(h -> JSON.toJSONString(h).contains(item)).collect(Collectors.toList()); - List apiModifies = OrikaMapperUtils.mapList(modifies, MethodInfo.class, ApiMethodModify.class); - if (MethodNodeTypeEnum.DUBBO.equals(k)) { - apiModify.getDubboApiModifies().addAll(apiModifies); - } else if (MethodNodeTypeEnum.CUSTOM_CLASS.equals(k)) { - apiModify.getCustomClassModifies().addAll(apiModifies); - } else if (MethodNodeTypeEnum.CUSTOM_METHOD.equals(k)) { - apiModify.getCustomMethodSignModifies().addAll(apiModifies); - } - } - } - ); - - }, executor)).toArray(CompletableFuture[]::new)).join(); - } - } - - -} - diff --git a/src/main/java/com/dr/code/diff/analyze/InvokeLinkBuildService.java b/src/main/java/com/dr/code/diff/analyze/InvokeLinkBuildService.java deleted file mode 100644 index a6d040a..0000000 --- a/src/main/java/com/dr/code/diff/analyze/InvokeLinkBuildService.java +++ /dev/null @@ -1,380 +0,0 @@ -package com.dr.code.diff.analyze; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.io.FileUtil; -import com.alibaba.fastjson.JSON; -import com.dr.code.diff.analyze.bean.AdapterContext; -import com.dr.code.diff.analyze.bean.MethodInfo; -import com.dr.code.diff.analyze.constant.SysConstant; -import com.dr.code.diff.analyze.link.CallChainClassVisitor; -import com.dr.code.diff.analyze.strategy.MethodFilterContext; -import com.dr.code.diff.config.CustomizeConfig; -import com.dr.code.diff.config.CustomizeLinkStartConfig; -import com.dr.code.diff.enums.LinkScopeTypeEnum; -import com.dr.code.diff.enums.MethodNodeTypeEnum; -import com.dr.code.diff.util.StringUtil; -import com.dr.code.diff.common.errorcode.BizCode; -import com.dr.code.diff.common.exception.BizException; -import com.dr.code.diff.common.log.LoggerUtil; -import com.dr.code.diff.common.utils.mapper.OrikaMapperUtils; -import com.dr.code.diff.util.XmlDubboUtil; -import com.google.common.collect.Lists; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassWriter; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.apache.maven.model.Model; -import org.apache.maven.model.io.xpp3.MavenXpp3Reader; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.CollectionUtils; - -import javax.annotation.Resource; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.nio.file.Files; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * @Package: com.dr.code.diff.analyze - * @Description: 基于ASM获取调用链 - * @Author: rayduan - * @CreateDate: 2023/2/24 15:55 - * @Version: 1.0 - *

- */ -@Service -@Slf4j -public class InvokeLinkBuildService { - - - /** - * ant路径匹配器 - */ - private static final AntPathMatcher antPathMatcher = new AntPathMatcher(); - private static final String URL_PREFIX = "/"; - - - @Resource(name = "asyncExecutor") - private Executor executor; - - - @Autowired - private CustomizeLinkStartConfig customizeLinkStartConfig; - - - @Autowired - private CustomizeConfig customizeConfig; - - /** - * get方法调用链接 - * - * @param classesDir 类的目录 - * @param excludeClasses 排除类 - * @return {@link List}<{@link MethodInfo}> - */ - public Map> getMethodsInvokeLink(List classesDir, List excludeClasses) { - LoggerUtil.info(log, "开始获取调用链"); - if (CollectionUtils.isEmpty(classesDir)) { - LoggerUtil.info(log, "请正确填写class文件地址"); - return Collections.emptyMap(); - } - List allMethods = new ArrayList<>(); - classesDir.forEach( - e -> { - try { - //获取项目的groupId用于调用链降噪 - String pomPath = StringUtil.connectPath(e, "pom.xml"); - MavenXpp3Reader reader = new MavenXpp3Reader(); - String groupId = ""; - try { - Model model = reader.read(new FileReader(pomPath)); - groupId = model.getGroupId(); - if (!StringUtils.isEmpty(groupId)) { - groupId = groupId.replace(".", "/"); - } - } catch (FileNotFoundException fileNotFoundException) { - LoggerUtil.error(log, "非maven项目或者获取pom路径有误!"); - } - AdapterContext.AdapterContextBuilder builder = AdapterContext.builder(); - MethodFilterContext.MethodFilterContextBuilder methodFilterContextBuilder = MethodFilterContext.builder(); - if (LinkScopeTypeEnum.EXCLUDE_JDK_TYPE.getCode().equals(customizeConfig.getLinkType())) { - methodFilterContextBuilder.baseClassName("java"); - methodFilterContextBuilder.linKScopeTypeEnum(LinkScopeTypeEnum.EXCLUDE_JDK_TYPE); - } else if (LinkScopeTypeEnum.GROUP_ONLY_TYPE.getCode().equals(customizeConfig.getLinkType())) { - methodFilterContextBuilder.baseClassName(groupId); - methodFilterContextBuilder.linKScopeTypeEnum(LinkScopeTypeEnum.GROUP_ONLY_TYPE); - } else if (LinkScopeTypeEnum.ALL_TYPE.getCode().equals(customizeConfig.getLinkType())) { - methodFilterContextBuilder.baseClassName(""); - methodFilterContextBuilder.linKScopeTypeEnum(LinkScopeTypeEnum.ALL_TYPE); - } - builder.methodFilterContext(methodFilterContextBuilder.build()); - //获取dubbo xml的配置 - List dubboService = XmlDubboUtil.scanDubboService(e); - builder.dubboClasses(dubboService); - //获取一个目录下的所有class文件 - List files = FileUtil.loopFiles(new File(e), pathname -> pathname.getName().endsWith(".class") && pathname.getAbsolutePath().contains("classes")); - if (CollectionUtils.isEmpty(files)) { - return; - } - AdapterContext adapterContext = builder.build(); - //并发获取每个方法的调用方法 - List>> priceFuture = files.stream() - .map(item -> CompletableFuture.supplyAsync(() -> getSingleClassMethodsInvoke(item, excludeClasses, adapterContext), executor)) - .collect(Collectors.toList()); - CompletableFuture.allOf(priceFuture.toArray(new CompletableFuture[0])).join(); - List list = priceFuture.stream().map(CompletableFuture::join).flatMap(Collection::stream).filter(Objects::nonNull).collect(Collectors.toList()); -// List list = files.stream().map(item -> getSingleClassMethodsInvoke(item, excludeClasses, adapterContext)).flatMap(Collection::stream).filter(Objects::nonNull).collect(Collectors.toList()); - allMethods.addAll(list); - } catch (Exception ex) { - throw new BizException(BizCode.GET_METHOD_INVOKE_LINK_FAIL); - } - } - ); - LoggerUtil.info(log, "调用链获取完成"); - return buildMethodLink(allMethods); - } - - - /** - * 单个类的方法调用 - * - * @param file 文件 - * @return {@link List}<{@link MethodInfo}> - */ - public List getSingleClassMethodsInvoke(File file, List excludeClasses, AdapterContext adapterContext) { - if (!CollectionUtils.isEmpty(excludeClasses)) { - boolean excludeFlag = excludeClasses.stream().allMatch(e -> antPathMatcher.match(e, file.getPath())); - if (excludeFlag) { - return Collections.emptyList(); - } - } - List list = new ArrayList<>(); - try { - ClassReader cr = new ClassReader(Files.newInputStream(file.toPath())); - CallChainClassVisitor cv = new CallChainClassVisitor(null, list, adapterContext); - cr.accept(cv, ClassReader.SKIP_FRAMES); - } catch (Exception e) { - LoggerUtil.error(log, "获取调用链失败", e.getMessage()); - return Collections.emptyList(); - } - return list; - - } - - - /** - * 构建方法链接tree - * - * @param allMethods 所有方法 - * @return {@link List}<{@link MethodInfo}> - */ - public Map> buildMethodLink(List allMethods) { - //判断allMethods是否为空 - if (CollectionUtils.isEmpty(allMethods)) { - return Collections.emptyMap(); - } - Map> map = new HashMap<>(); - Map> methodCallMap = allMethods.stream().collect(Collectors.toMap(MethodInfo::getMethodSign, MethodInfo::getCallerMethods, (v1, v2) -> v2)); - //按照抽象方法的类名和其实现方法分组 - Map> abstractSubMethodMap = allMethods.stream().filter(e -> StringUtils.isNotBlank(e.getClassInfo().getSuperClassName())).collect(Collectors.groupingBy(e -> e.getClassInfo().getSuperClassName())); - List allInterFaceList = new ArrayList<>(); - List interFaceList = allMethods.stream().filter(e -> !CollectionUtils.isEmpty((e.getClassInfo().getInterfacesClassNames()))).collect(Collectors.toList()); - interFaceList.forEach( - e -> { - List interfacesClassNames = e.getClassInfo().getInterfacesClassNames(); - interfacesClassNames.forEach( - i -> { - MethodInfo m = OrikaMapperUtils.map(e, MethodInfo.class); - m.getClassInfo().setInterfacesClassNames(Lists.newArrayList(i)); - allInterFaceList.add(m); - } - ); - } - ); - Map> interFaceMethodMap = allInterFaceList.stream().collect(Collectors.groupingBy(e -> e.getClassInfo().getInterfacesClassNames().get(0))); - //将抽象类和接口的实现合并 - abstractSubMethodMap.putAll(interFaceMethodMap); - //获取所有的抽象或者接口方法 - List abstractMethod = allMethods.stream().filter(MethodInfo::getAbstractFlag).map(MethodInfo::getMethodSign).collect(Collectors.toList()); - buildLinkStartMap(allMethods, map); - if (CollectionUtils.isEmpty(map)) { - return map; - } - map.values().forEach(e -> loadChildren(methodCallMap, e, abstractSubMethodMap, abstractMethod)); - return map; - } - - - /** - * 建立链接起始Map - * - * @param allMethods 所有方法 - * @param startMap 起始Map - */ - private void buildLinkStartMap(List allMethods, Map> startMap) { - if (CollectionUtils.isEmpty(allMethods)) { - return; - } - //先找出起点方法 - Map> methodTypeMap = allMethods.stream().filter(e -> null != e.getMethodNodeTypeEnum()).collect(Collectors.groupingBy(MethodInfo::getMethodNodeTypeEnum)); - //1.http接口方法 - List httpMethodInfoList = methodTypeMap.get(MethodNodeTypeEnum.HTTP); - if (!CollectionUtils.isEmpty(httpMethodInfoList)) { - //这里为了避免多个起始节点相互影响 - httpMethodInfoList = OrikaMapperUtils.mapList(httpMethodInfoList, MethodInfo.class, MethodInfo.class); - Map feignMap = allMethods.stream().filter(e -> e.getClassInfo().getFeignFlag()).collect(Collectors.toMap(e -> e.getClassInfo().getClassName() + SysConstant.SPILT_CHAR + e.getMethodName() + SysConstant.SPILT_CHAR + String.join(",", e.getMethodParams()), Function.identity())); - //初始化子节点 - httpMethodInfoList.forEach(e -> { - //重置调用节点,避免循环引用 - e.setCallerMethods(null); - //这里只考虑Controller有一个实现类 - MethodInfo feignMethodInfo = null; - if (!CollectionUtils.isEmpty(feignMap) && !CollectionUtils.isEmpty(e.getClassInfo().getInterfacesClassNames()) && feignMap.containsKey(e.getClassInfo().getInterfacesClassNames().get(0))) { - feignMethodInfo = feignMap.get(e.getClassInfo().getInterfacesClassNames().get(0)); - } - String controllerMappingUrl = e.getClassInfo().getRequestUrl(); - String methodMappingUrl = e.getMappingUrl(); - //这里处理了一下feign,如果controller没有url,则使用feign的url - if (null != feignMethodInfo && StringUtils.isBlank(controllerMappingUrl)) { - controllerMappingUrl = feignMethodInfo.getClassInfo().getRequestUrl(); - } - if (null != feignMethodInfo && StringUtils.isBlank(methodMappingUrl)) { - methodMappingUrl = feignMethodInfo.getMappingUrl(); - } - if (StringUtils.isBlank(controllerMappingUrl)) { - controllerMappingUrl = ""; - } - if (StringUtils.isBlank(methodMappingUrl)) { - methodMappingUrl = ""; - } - String methodUrl = StringUtil.connectPath(controllerMappingUrl, methodMappingUrl); - e.setMappingUrl(methodUrl); - e.setVisitedMethods(Lists.newArrayList(e.getMethodSign())); - }); - startMap.put(MethodNodeTypeEnum.HTTP, httpMethodInfoList); - } - //2.dubbo方法 - List dubboMethodInfoList = methodTypeMap.get(MethodNodeTypeEnum.DUBBO); - if (!CollectionUtils.isEmpty(dubboMethodInfoList)) { - //这里为了避免多个起始节点相互影响 - dubboMethodInfoList = OrikaMapperUtils.mapList(dubboMethodInfoList, MethodInfo.class, MethodInfo.class); - //初始化子节点 - dubboMethodInfoList.forEach(e -> { - e.setCallerMethods(null); - e.setVisitedMethods(Lists.newArrayList(e.getMethodSign())); - }); - startMap.put(MethodNodeTypeEnum.DUBBO, dubboMethodInfoList); - } - //自定义类 - List customLinkStartClassName = customizeLinkStartConfig.getClassNameList(); - if (!CollectionUtils.isEmpty(customLinkStartClassName)) { - List customClassList = allMethods.stream().filter(e -> customLinkStartClassName.contains(e.getClassInfo().getClassName())).collect(Collectors.toList()); - //这里为了避免多个起始节点相互影响 - customClassList = OrikaMapperUtils.mapList(customClassList, MethodInfo.class, MethodInfo.class); - customClassList.forEach(e -> { - e.setCallerMethods(null); - e.setVisitedMethods(Lists.newArrayList(e.getMethodSign())); - }); - startMap.put(MethodNodeTypeEnum.CUSTOM_CLASS, customClassList); - } - - // 遍历集合,执行异步操作 -// List> futures = new ArrayList<>(); -// k8sCmdParam.getPods().forEach(pod -> { -// CompletableFuture future = CompletableFuture.runAsync(() -> { -// // 异步操作 -// podExec(pod, k8sCmdParam.getCmd(), k8sCmdParam.getNamespace(), client); -// getFile(pod, k8sCmdParam.getNamespace(), client, k8sCmdParam.getWorkspace()); -// }, k8sCmdParam.getExecutor()); -// futures.add(future); -// }); - - //自定义方法 - List customLinkStartMethodSign = customizeLinkStartConfig.getMethodSignList(); - if (!CollectionUtils.isEmpty(customLinkStartMethodSign)) { - List customMethodSignList = allMethods.stream().filter(e -> customLinkStartMethodSign.contains(e.getMethodSign())).collect(Collectors.toList()); - customMethodSignList = OrikaMapperUtils.mapList(customMethodSignList, MethodInfo.class, MethodInfo.class); - customMethodSignList.forEach(e -> { - e.setCallerMethods(null); - e.setVisitedMethods(Lists.newArrayList(e.getMethodSign())); - }); - startMap.put(MethodNodeTypeEnum.CUSTOM_METHOD, customMethodSignList); - } - } - - - /** - * 构建父子节点 - * - * @param map 所有方法调用map - * @param parentList 父列表 - * @param abstractSubMethodMap 抽象子映射方法 - */ - private void loadChildren(Map> map, List parentList, Map> abstractSubMethodMap, List abstractMethod) { - if (CollectionUtils.isEmpty(parentList) || CollectionUtils.isEmpty(map)) { - return; - } - parentList.forEach( - e -> { - List visitedMethods = e.getVisitedMethods(); - //如果方法是抽象方法,则将其所有子类匹配的方法都加入链路中 - if (abstractMethod.contains(e.getMethodSign())) { - //抽象和接口类处理 - setSubMethod(e, abstractSubMethodMap); - } else { - List subList = map.get(e.getMethodSign()); - if (!CollectionUtils.isEmpty(subList)) { - //校验父节点中是否已经存在的子节点 - List vaildSubList = subList.stream().filter(s -> !e.getVisitedMethods().contains(s.getMethodSign())).collect(Collectors.toList()); - if (!CollectionUtils.isEmpty(vaildSubList)) { - vaildSubList = OrikaMapperUtils.mapList(vaildSubList, MethodInfo.class, MethodInfo.class); - e.setCallerMethods(vaildSubList); - } - } - } - if (CollUtil.isNotEmpty(e.getCallerMethods())) { - //记录链路的方法用于校验循环引用 - e.getCallerMethods().forEach(c -> { - ArrayList visited = new ArrayList<>(visitedMethods); - visited.add(c.getMethodSign()); - c.setVisitedMethods(visited); - } - ); - //清理工作避免内存溢出 - e.setVisitedMethods(null); - // 设置子节点 - loadChildren(map, e.getCallerMethods(), abstractSubMethodMap, abstractMethod); - } - } - ); - } - - - /** - * 设置子方法 - * - * @param methodInfo 方法信息 - * @param abstractSubMethodMap 抽象子映射方法 - */ - private void setSubMethod(MethodInfo methodInfo, Map> abstractSubMethodMap) { - if (!CollectionUtils.isEmpty(abstractSubMethodMap) && abstractSubMethodMap.containsKey(methodInfo.getClassInfo().getClassName())) { - List methodInfoList = abstractSubMethodMap.get(methodInfo.getClassInfo().getClassName()); - if (CollectionUtils.isEmpty(methodInfoList)) { - return; - } - methodInfoList.forEach(e -> e.setCallerMethods(null)); - //过滤出实现类匹配的方法 - methodInfoList = methodInfoList.stream().filter(e -> - e.getMethodName().equals(methodInfo.getMethodName()) && String.join(",", e.getMethodParams()).equals(String.join(",", methodInfo.getMethodParams())) - ).collect(Collectors.toList()); - methodInfo.setCallerMethods((OrikaMapperUtils.mapList(methodInfoList, MethodInfo.class, MethodInfo.class))); - } - } -} diff --git a/src/main/java/com/dr/code/diff/analyze/MavenCmdInvokeService.java b/src/main/java/com/dr/code/diff/analyze/MavenCmdInvokeService.java deleted file mode 100644 index 392451b..0000000 --- a/src/main/java/com/dr/code/diff/analyze/MavenCmdInvokeService.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.dr.code.diff.analyze; - -import cn.hutool.core.io.FileUtil; -import com.dr.code.diff.config.CustomizeConfig; -import com.dr.code.diff.common.errorcode.BizCode; -import com.dr.code.diff.common.exception.BizException; -import com.dr.code.diff.common.log.LoggerUtil; -import lombok.extern.slf4j.Slf4j; -import org.apache.maven.shared.invoker.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.io.File; -import java.util.Collections; - -/** - * @Package: com.dr.code.diff.analyze - * @Description: 使用maven invoker编译目标代码为class文件 - * @Author: rayduan - * @CreateDate: 2023/2/27 20:47 - * @Version: 1.0 - *

- */ -@Service -@Slf4j -public class MavenCmdInvokeService { - - - @Autowired - private CustomizeConfig customizeConfig; - - /** - * 运行maven cmd - * - * @param pomPath 要操控的pom文件的系统路径 如:D:\coding\**\pom.xml - * @param cmd maven命令如:clean - */ - public void operationMavenCmd(String pomPath, String cmd) { - InvocationRequest request = new DefaultInvocationRequest(); - //想要操控的pom文件的位置 - request.setPomFile(new File(pomPath)); - //操控的maven命令 - request.setGoals(Collections.singletonList(cmd)); - InvocationOutputHandler outputHandler = s -> LoggerUtil.info(log, s); - request.setOutputHandler(outputHandler); - Invoker invoker = new DefaultInvoker(); - //maven的位置 - invoker.setMavenHome(new File(customizeConfig.getMavenHome())); - try { - invoker.execute(request); - } catch (MavenInvocationException e) { - LoggerUtil.error(log, "编译项目失败:", pomPath, "失败原因:", e); - throw new BizException(BizCode.COMPILE_CODE_FAIL); - } - } - - - /** - * 编译代码 - * - * @param pomPath pom路径 - */ - public void compileCode(String pomPath) { - LoggerUtil.info(log, "开始编译代码"); - //判断文件是否存在 - boolean exist = FileUtil.exist(pomPath); - if (!exist) { - LoggerUtil.info(log, "pom文件不存在:",pomPath); - throw new BizException(BizCode.POM_NOT_EXIST_FAIL); - } - operationMavenCmd(pomPath, "clean compile -Dmaven.test.skip=true"); - LoggerUtil.info(log, "代码编译完成"); - } -} diff --git a/src/main/java/com/dr/code/diff/analyze/bean/AdapterContext.java b/src/main/java/com/dr/code/diff/analyze/bean/AdapterContext.java deleted file mode 100644 index e8872ba..0000000 --- a/src/main/java/com/dr/code/diff/analyze/bean/AdapterContext.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.dr.code.diff.analyze.bean; - -import com.dr.code.diff.analyze.strategy.MethodFilterContext; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -/** - * 适配器上下文 - * - * @author rayduan - * @Package: com.dr.code.diff.analyze.bean - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/3/8 17:25 - * @Version: 1.0 - *

- * @date 2023/03/08 - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class AdapterContext { - - /** - * 调用链过滤上下文 - */ - private MethodFilterContext methodFilterContext; - - /** - * dubbo xml指定的类 - */ - private List dubboClasses; -} diff --git a/src/main/java/com/dr/code/diff/analyze/bean/ClassInfo.java b/src/main/java/com/dr/code/diff/analyze/bean/ClassInfo.java deleted file mode 100644 index e7da375..0000000 --- a/src/main/java/com/dr/code/diff/analyze/bean/ClassInfo.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.dr.code.diff.analyze.bean; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -/** - * @Package: com.dr.code.diff.analyze.bean - * @Description: 类信息 - * @Author: rayduan - * @CreateDate: 2023/2/23 20:26 - * @Version: 1.0 - *

- */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ClassInfo { - - /** - * 类名 - */ - private String className; - - - /** - * 超类名字 - */ - private String superClassName; - - - /** - * 接口类名 - */ - private List interfacesClassNames; - - - /** - * 抽象标志 - */ - private Boolean abstractFlag = Boolean.FALSE; - - /** - * 接口标志 - */ - private Boolean interfaceFlag = Boolean.FALSE; - - - /** - * 控制器标志 - */ - private Boolean controllerFlag = Boolean.FALSE; - - - /** - * feign标识 - */ - private Boolean feignFlag = Boolean.FALSE; - /** - * dubbo标志 - */ - private Boolean dubboFlag = Boolean.FALSE; - - /** - * 请求url - */ - private String requestUrl; - -} diff --git a/src/main/java/com/dr/code/diff/analyze/bean/MethodInfo.java b/src/main/java/com/dr/code/diff/analyze/bean/MethodInfo.java deleted file mode 100644 index 227ec96..0000000 --- a/src/main/java/com/dr/code/diff/analyze/bean/MethodInfo.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.dr.code.diff.analyze.bean; - -import com.dr.code.diff.enums.MethodNodeTypeEnum; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.web.bind.annotation.RequestMethod; - -import java.util.List; - -/** - * @Package: com.dr.code.diff.dto - * @Description: 方法信息 - * @Author: rayduan - * @CreateDate: 2023/2/20 16:39 - * @Version: 1.0 - *

- */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class MethodInfo { - - /** - * 类信息 - */ - private ClassInfo classInfo; - - - /** - * 抽象标志 - */ - private Boolean abstractFlag; - - - /** - * 方法名称 - */ - private String methodName; - - - /** - * 方法参数 - */ - private List methodParams; - - /** - * 参数名称列表 - */ - private List methodParamNameList; - /** - * 方法签名,com/dr/code/diff/controller/CodeDiffController#getSvnList#String, String, String - */ - private String methodSign; - - - /** - * url映射,如/api/res/1 - */ - private String mappingUrl; - - - /** - * 映射方法,如get,put - */ - private RequestMethod mappingMethod; - - - /** - * 方法节点类型枚举 - */ - private MethodNodeTypeEnum methodNodeTypeEnum; - /** - * 调用的方法 - */ - private List callerMethods; - - - private List visitedMethods; -} diff --git a/src/main/java/com/dr/code/diff/analyze/bean/RequestInfo.java b/src/main/java/com/dr/code/diff/analyze/bean/RequestInfo.java deleted file mode 100644 index 677858d..0000000 --- a/src/main/java/com/dr/code/diff/analyze/bean/RequestInfo.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.dr.code.diff.analyze.bean; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * @Package: com.dr.code.diff.analyze.bean - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/2/24 15:39 - * @Version: 1.0 - *

- */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class RequestInfo { - private String requestUrl; - private RequestMethod mappingMethod; -} diff --git a/src/main/java/com/dr/code/diff/analyze/constant/AnnotationConstant.java b/src/main/java/com/dr/code/diff/analyze/constant/AnnotationConstant.java deleted file mode 100644 index 1120804..0000000 --- a/src/main/java/com/dr/code/diff/analyze/constant/AnnotationConstant.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.dr.code.diff.analyze.constant; - -import org.springframework.web.bind.annotation.RequestMethod; - -import java.util.HashMap; -import java.util.Map; - -/** - * @Package: com.dr.code.diff.analyze.constant - * @Description: 注解常量类 - * @Author: rayduan - * @CreateDate: 2023/2/23 21:08 - * @Version: 1.0 - *

- */ -public class AnnotationConstant { - - // Request的注解 - public static final String[] requestAnnotation = { - "Lorg/springframework/web/bind/annotation/RequestMapping;", - "Lorg/springframework/web/bind/annotation/GetMapping;", - "Lorg/springframework/web/bind/annotation/PostMapping;", - "Lorg/springframework/web/bind/annotation/DeleteMapping;", - "Lorg/springframework/web/bind/annotation/PatchMapping;", - "Lorg/springframework/web/bind/annotation/PutMapping;", - "Lorg/springframework/web/bind/annotation/MessageMapping;", - "Lorg/springframework/web/bind/annotation/SubscribeMapping;"}; - - - /** - * 请求注释映射 - */ - public static final Map requestAnnotationMap; - static { - requestAnnotationMap = new HashMap(); - requestAnnotationMap.put("Lorg/springframework/web/bind/annotation/GetMapping;", RequestMethod.GET); - requestAnnotationMap.put("Lorg/springframework/web/bind/annotation/PostMapping;", RequestMethod.POST); - requestAnnotationMap.put("Lorg/springframework/web/bind/annotation/DeleteMapping;", RequestMethod.DELETE); - requestAnnotationMap.put("Lorg/springframework/web/bind/annotation/PatchMapping;", RequestMethod.PATCH); - requestAnnotationMap.put("Lorg/springframework/web/bind/annotation/PutMapping;", RequestMethod.PUT); - - } - - - //dubbo注解 - public static final String[] dubboAnnotation = { - "Lorg/apache/dubbo/config/annotation/DubboService;", - "Lcom/alibaba/dubbo/config/annotation/Service;", - "Lorg/apache/dubbo/config/annotation/Service;", - }; - - //Controller 的注解 - public static final String[] controllerAnnotation = { - "Lorg/springframework/web/bind/annotation/RestController;", - "Lorg/springframework/stereotype/Controller;", - }; - - public static final String[] mybatisTagName = { - "insert", - "delete", - "update", - "select", - }; - public static final String[] feignAnnotation = { - "Lorg/springframework/cloud/openfeign/FeignClient;" - }; - -} - diff --git a/src/main/java/com/dr/code/diff/analyze/constant/SysConstant.java b/src/main/java/com/dr/code/diff/analyze/constant/SysConstant.java deleted file mode 100644 index cd00877..0000000 --- a/src/main/java/com/dr/code/diff/analyze/constant/SysConstant.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.dr.code.diff.analyze.constant; - -/** - * @Package: com.dr.code.diff.analyze.constant - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/5/8 19:29 - * @Version: 1.0 - *

- */ -public class SysConstant { - /** - * 连接字符 - */ - public static final String SPILT_CHAR = "#"; -} diff --git a/src/main/java/com/dr/code/diff/analyze/link/CallChainAnnotationVisitor.java b/src/main/java/com/dr/code/diff/analyze/link/CallChainAnnotationVisitor.java deleted file mode 100644 index 65840c0..0000000 --- a/src/main/java/com/dr/code/diff/analyze/link/CallChainAnnotationVisitor.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.dr.code.diff.analyze.link; - -import com.dr.code.diff.analyze.bean.RequestInfo; -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * @Package: com.dr.code.diff.analyze.link - * @Description: 注解访问 - * @Author: rayduan - * @CreateDate: 2023/2/23 21:21 - * @Version: 1.0 - *

- */ -public class CallChainAnnotationVisitor extends AnnotationVisitor { - - private final RequestInfo requestInfo; - - public CallChainAnnotationVisitor(AnnotationVisitor annotationVisitor, RequestInfo requestInfo) { - super(Opcodes.ASM5, annotationVisitor); - this.requestInfo = requestInfo; - } - - - /** - * 访问数组,这里先访问注解里面的key值 - * - * @param name 名字 - * @return {@link AnnotationVisitor} - */ - @Override - public AnnotationVisitor visitArray(String name) { - // 主要获取requestMapping的信息 - if (name.equals("value") || name.equals("method")) { - return new CallChainAnnotationVisitor(super.visitArray(name), this.requestInfo); - } - return super.visitArray(name); - } - - /** - * 再访问数组里的value - * - * @param name 名字 - * @param value 值 - */ - @Override - public void visit(String name, Object value) { - // 这里是url - this.requestInfo.setRequestUrl(null == value ? "" : (String) value); - super.visit(name, value); - } - - /** - * 如果注解里面的值是枚举类型从这里访问 - * - * @param name 名字 - * @param descriptor 描述符 - * @param value 价值 - */ - public void visitEnum(final String name, final String descriptor, final String value) { - //这里是请求方法 - this.requestInfo.setMappingMethod(RequestMethod.valueOf(value)); - if (av != null) { - av.visitEnum(name, descriptor, value); - } - } - - -} diff --git a/src/main/java/com/dr/code/diff/analyze/link/CallChainClassVisitor.java b/src/main/java/com/dr/code/diff/analyze/link/CallChainClassVisitor.java deleted file mode 100644 index 26333b1..0000000 --- a/src/main/java/com/dr/code/diff/analyze/link/CallChainClassVisitor.java +++ /dev/null @@ -1,192 +0,0 @@ -package com.dr.code.diff.analyze.link; - -import com.dr.code.diff.analyze.bean.AdapterContext; -import com.dr.code.diff.analyze.bean.ClassInfo; -import com.dr.code.diff.analyze.bean.MethodInfo; -import com.dr.code.diff.analyze.bean.RequestInfo; -import com.dr.code.diff.analyze.constant.AnnotationConstant; -import com.dr.code.diff.analyze.constant.SysConstant; -import com.dr.code.diff.enums.MethodNodeTypeEnum; -import com.dr.code.diff.util.StringUtil; -import jdk.internal.org.objectweb.asm.*; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -/** - * @Package: com.dr.code.diff.analyze.link - * @Description: 遍历class文件 - * @Author: rayduan - * @CreateDate: 2023/2/20 17:11 - * @Version: 1.0 - *

- */ -public class CallChainClassVisitor extends ClassVisitor { - - - public static final String JAVA_LANG_OBJECT = "java/lang/Object"; - - /** - * 类信息 - */ - private ClassInfo classInfo; - - /** - * 类中的方法 - */ - private final List methods; - - - /** - * 请求信息 - */ - private RequestInfo requestInfo; - - - /** - * 适配器上下文 - */ - private final AdapterContext adapterContext; - - - /** - * 调用链访问者构造函数 - * - * @param cv 类访问者 - */ - public CallChainClassVisitor(ClassVisitor cv, List list, AdapterContext adapterContext) { - super(Opcodes.ASM5, cv); - this.methods = list; - this.adapterContext = adapterContext; - } - - /** - * 访问类 - * - * @param version 版本 - * @param access 访问 - * @param name 类全限定名 - * @param signature 签名 - * @param superName 超类 - * @param interfaces 接口 - */ - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - ClassInfo.ClassInfoBuilder classInfoBuilder = ClassInfo.builder() - .className(name) - .controllerFlag(Boolean.FALSE) - .abstractFlag(Boolean.FALSE) - .interfaceFlag(Boolean.FALSE) - .feignFlag(Boolean.FALSE) - .dubboFlag(Boolean.FALSE); - // 如果是interface - if ((access & Opcodes.ACC_INTERFACE) == Opcodes.ACC_INTERFACE) { - classInfoBuilder.interfaceFlag(Boolean.TRUE); - } - // 如果是abstract类 - if ((access & Opcodes.ACC_ABSTRACT) == Opcodes.ACC_ABSTRACT) { - classInfoBuilder.abstractFlag(Boolean.TRUE); - } - if(!JAVA_LANG_OBJECT.equals(superName)){ - //说明是抽象类的实现类 - classInfoBuilder.superClassName(superName); - } - if (null != interfaces && interfaces.length > 0) { - classInfoBuilder.interfacesClassNames(new ArrayList<>(Arrays.asList(interfaces))); - } - if (null != adapterContext && !CollectionUtils.isEmpty(adapterContext.getDubboClasses())) { - if (adapterContext.getDubboClasses().contains(name)) { - classInfoBuilder.dubboFlag(Boolean.TRUE); - } - } - this.classInfo = classInfoBuilder.build(); - super.visit(version, access, name, signature, superName, interfaces); - - } - - - /** - * 访问方法 - * - * @param access 访问 - * @param name 名字 - * @param descriptor 描述符 - * @param signature 签名 - * @param exceptions 异常 - * @return {@link MethodVisitor} - */ - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, - String signature, String[] exceptions) { - // 跳过初始化方法 - if (name.equals("") || name.equals("")) { - // Ignore constructor and class initializer - return null; - } - Type[] argumentTypes = Type.getArgumentTypes(descriptor); - List params = Arrays.stream(argumentTypes).map(Type::getClassName) - .map(e -> StringUtil.getSplitLast(e, ".")).collect(Collectors.toList()); - String methodSign = classInfo.getClassName() + SysConstant.SPILT_CHAR + name + SysConstant.SPILT_CHAR + String.join(",", params); - MethodInfo.MethodInfoBuilder builder = MethodInfo - .builder() - .methodName(name) - .methodParams(params) - .methodSign(methodSign) - .classInfo(this.classInfo) - .abstractFlag(Boolean.FALSE); - // 如果是interface,这里也标记方法为无法直接调用的方法 - if ((access & Opcodes.ACC_INTERFACE) == Opcodes.ACC_INTERFACE) { - builder.abstractFlag(Boolean.TRUE); - } - // 如果是abstract类 - if ((access & Opcodes.ACC_ABSTRACT) == Opcodes.ACC_ABSTRACT) { - builder.abstractFlag(Boolean.TRUE); - } - //如果是dubbo的接口类 - if (this.classInfo.getDubboFlag()) { - builder.methodNodeTypeEnum(MethodNodeTypeEnum.DUBBO); - } - MethodInfo currentMethod = builder.build(); - List callerMethods = new ArrayList<>(); - this.methods.add(currentMethod); - return new CallChainMethodVisitor(super.visitMethod(access, name, descriptor, signature, exceptions), currentMethod, callerMethods, adapterContext); - } - - - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - //说明是controller层 - if (Arrays.asList(AnnotationConstant.controllerAnnotation).contains(descriptor)) { - this.classInfo.setControllerFlag(Boolean.TRUE); - } - if (Arrays.asList(AnnotationConstant.feignAnnotation).contains(descriptor)) { - this.classInfo.setFeignFlag(Boolean.TRUE); - } - if (Arrays.asList(AnnotationConstant.dubboAnnotation).contains(descriptor)) { - this.classInfo.setDubboFlag(Boolean.TRUE); - } - //只有controller的注解才能生效 - if (this.classInfo.getControllerFlag() || this.classInfo.getFeignFlag()) { - if (Arrays.asList(AnnotationConstant.requestAnnotation).contains(descriptor)) { - this.requestInfo = new RequestInfo(); - // 这里去获取类的 requestMappingValue - return new CallChainAnnotationVisitor(super.visitAnnotation(descriptor, visible), this.requestInfo); - } - } - - return super.visitAnnotation(descriptor, visible); - } - - @Override - public void visitEnd() { - if (null != this.requestInfo) { - this.classInfo.setRequestUrl(null == this.requestInfo.getRequestUrl() ? "" : this.requestInfo.getRequestUrl()); - } - super.visitEnd(); - } - - -} diff --git a/src/main/java/com/dr/code/diff/analyze/link/CallChainMethodVisitor.java b/src/main/java/com/dr/code/diff/analyze/link/CallChainMethodVisitor.java deleted file mode 100644 index 1004949..0000000 --- a/src/main/java/com/dr/code/diff/analyze/link/CallChainMethodVisitor.java +++ /dev/null @@ -1,193 +0,0 @@ -package com.dr.code.diff.analyze.link; - -import com.dr.code.diff.analyze.bean.AdapterContext; -import com.dr.code.diff.analyze.bean.ClassInfo; -import com.dr.code.diff.analyze.bean.MethodInfo; -import com.dr.code.diff.analyze.bean.RequestInfo; -import com.dr.code.diff.analyze.constant.AnnotationConstant; -import com.dr.code.diff.analyze.strategy.MethodFilterContext; -import com.dr.code.diff.analyze.strategy.MethodInvokeFactory; -import com.dr.code.diff.enums.LinkScopeTypeEnum; -import com.dr.code.diff.enums.MethodNodeTypeEnum; -import com.dr.code.diff.util.StringUtil; -import jdk.internal.org.objectweb.asm.*; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -/** - * @Package: com.dr.code.diff.analyze.link - * @Description: 遍历方法获取其调用关系 - * @Author: rayduan - * @CreateDate: 2023/2/20 17:11 - * @Version: 1.0 - *

- */ -public class CallChainMethodVisitor extends MethodVisitor { - - public static final String JAVA = "java"; - /** - * 调用方法 - */ - private final List callerMethods; - - /** - * 当前方法 - */ - private final MethodInfo currentMethod; - - - /** - * 请求信息 - */ - private RequestInfo requestInfo; - - - /** - * 适配器上下文 - */ - private final AdapterContext adapterContext; - - public CallChainMethodVisitor(MethodVisitor mv, MethodInfo currentMethod, List callerMethods, AdapterContext adapterContext) { - super(Opcodes.ASM5, mv); - this.callerMethods = callerMethods; - this.currentMethod = currentMethod; - this.adapterContext = adapterContext; - } - - public void visitParameter(String name, int access) { - List methodParamNameList = currentMethod.getMethodParamNameList(); - if (CollectionUtils.isEmpty(methodParamNameList)) { - methodParamNameList = new ArrayList<>(); - currentMethod.setMethodParamNameList(methodParamNameList); - } - methodParamNameList.add(name); - super.visitParameter(name, access); - } - - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { - // 跳过初始化方法 - if (name.equals("") || name.equals("")) { - // Ignore constructor and class initializer - return; - } - //非本包调用过滤 - MethodFilterContext methodFilterContext = adapterContext.getMethodFilterContext(); - if (null != methodFilterContext) { - if (LinkScopeTypeEnum.GROUP_ONLY_TYPE.equals(methodFilterContext.getLinKScopeTypeEnum())) { - if (!owner.startsWith(methodFilterContext.getBaseClassName())) { - return; - } - } else if (LinkScopeTypeEnum.EXCLUDE_JDK_TYPE.equals(methodFilterContext.getLinKScopeTypeEnum())) { - if (owner.contains(methodFilterContext.getBaseClassName())) { - return; - } - } - - } - - // 记录被调用方法的信息 - buildInvokeMethod(owner, name, desc); - super.visitMethodInsn(opcode, owner, name, desc, itf); - } - - - public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) { - // 检查 bootstrapMethodHandle 中的 method descriptor 是否包含 "java/lang/invoke/LambdaMetafactory.metafactory", - // 如果是,则说明当前的 invoke dynamic 指令为 Lambda 表达式 - if (bootstrapMethodHandle.getTag() == Opcodes.H_INVOKESTATIC && bootstrapMethodHandle.getOwner().equals("java/lang/invoke/LambdaMetafactory") && bootstrapMethodHandle.getName().equals("metafactory")) { - // 获取 Lambda 表达式所绑定的方法 - Handle methodHandle = (Handle) bootstrapMethodArguments[1]; - String owner = methodHandle.getOwner(); - String methodName = methodHandle.getName(); - String methodDescriptor = methodHandle.getDesc(); - // 记录被调用方法的信息 - buildInvokeMethod(owner, methodName, methodDescriptor); - } - super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments); - - } - - /** - * 构建调用方法 - * - * @param owner 老板 - * @param methodName 方法名称 - * @param methodDescriptor 方法描述符 - */ - private void buildInvokeMethod(String owner, String methodName, String methodDescriptor) { - ClassInfo classInfo = ClassInfo.builder().className(owner).build(); - Type[] argumentTypes = Type.getArgumentTypes(methodDescriptor); - List params = Arrays.stream(argumentTypes).map(Type::getClassName) - .map(e -> StringUtil.getSplitLast(e, ".")).collect(Collectors.toList()); - String methodSign = owner + "#" + methodName + "#" + String.join(",", params); - MethodInfo methodCaller = MethodInfo.builder() - .classInfo(classInfo) - .methodName(methodName) - .methodParams(params) - .methodSign(methodSign) - .abstractFlag(Boolean.FALSE) - .build(); - this.callerMethods.add(methodCaller); - } - - /** - * 访问注释 - * - * @param descriptor 描述符 - * @param visible 有形 - * @return {@link AnnotationVisitor} - */ - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - //说明是request接口方法 - if (Arrays.asList(AnnotationConstant.requestAnnotation).contains(descriptor)) { - //说明方法是http接口方法 - this.currentMethod.setMethodNodeTypeEnum(MethodNodeTypeEnum.HTTP); - // 这里去获取类的 requestMappingValue - this.requestInfo = new RequestInfo(); - if (AnnotationConstant.requestAnnotationMap.containsKey(descriptor)) { - this.requestInfo.setMappingMethod(AnnotationConstant.requestAnnotationMap.get(descriptor)); - } - return new CallChainAnnotationVisitor(super.visitAnnotation(descriptor, visible), requestInfo); - } - return super.visitAnnotation(descriptor, visible); - } - - /** - * 访问结束时调用 - */ - @Override - public void visitEnd() { - if (null != this.requestInfo) { - this.currentMethod.setMappingMethod(this.requestInfo.getMappingMethod()); - this.currentMethod.setMappingUrl(this.requestInfo.getRequestUrl()); - } - //这里记录调用的方法 - this.currentMethod.setCallerMethods(this.callerMethods); - super.visitEnd(); - } - - - /** - * 访问方法调用时抛出异常捕获 - * - * @param a 一个 - * @param b b - */ - @Override - public void visitMaxs(int a, int b) { - try { - super.visitMaxs(a, b); - } catch (Exception e) { - return; - } - } -} diff --git a/src/main/java/com/dr/code/diff/analyze/strategy/ExcludeJdkMethodFilter.java b/src/main/java/com/dr/code/diff/analyze/strategy/ExcludeJdkMethodFilter.java deleted file mode 100644 index 1fe7dd1..0000000 --- a/src/main/java/com/dr/code/diff/analyze/strategy/ExcludeJdkMethodFilter.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.dr.code.diff.analyze.strategy; - -import com.dr.code.diff.enums.LinkScopeTypeEnum; -import org.springframework.stereotype.Component; - -/** - * @Package: com.dr.code.diff.analyze.strategy - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/5/19 10:29 - * @Version: 1.0 - *

- */ -@Component -public class ExcludeJdkMethodFilter implements MethodInvokeFilter { - - @Override - public LinkScopeTypeEnum filterType() { - return LinkScopeTypeEnum.EXCLUDE_JDK_TYPE; - } - - @Override - public Boolean isMatch(MethodFilterContext methodFilterContext) { - if (!methodFilterContext.getClassName().contains(methodFilterContext.getBaseClassName())) { - return Boolean.TRUE; - } - return Boolean.FALSE; - } -} diff --git a/src/main/java/com/dr/code/diff/analyze/strategy/GroupIdMethodFilter.java b/src/main/java/com/dr/code/diff/analyze/strategy/GroupIdMethodFilter.java deleted file mode 100644 index 81d218f..0000000 --- a/src/main/java/com/dr/code/diff/analyze/strategy/GroupIdMethodFilter.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dr.code.diff.analyze.strategy; - -import com.dr.code.diff.enums.LinkScopeTypeEnum; -import org.springframework.stereotype.Component; - -/** - * @Package: com.dr.code.diff.analyze.strategy - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/5/19 10:29 - * @Version: 1.0 - *

- */ -@Component -public class GroupIdMethodFilter implements MethodInvokeFilter { - - @Override - public LinkScopeTypeEnum filterType() { - return LinkScopeTypeEnum.GROUP_ONLY_TYPE; - } - - @Override - public Boolean isMatch(MethodFilterContext methodFilterContext) { - return methodFilterContext.getClassName().startsWith(methodFilterContext.getBaseClassName()); - } -} diff --git a/src/main/java/com/dr/code/diff/analyze/strategy/MethodFilterContext.java b/src/main/java/com/dr/code/diff/analyze/strategy/MethodFilterContext.java deleted file mode 100644 index 9b356a1..0000000 --- a/src/main/java/com/dr/code/diff/analyze/strategy/MethodFilterContext.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.dr.code.diff.analyze.strategy; - -import com.dr.code.diff.enums.LinkScopeTypeEnum; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @Package: com.dr.code.diff.analyze.strategy - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/6/5 13:49 - * @Version: 1.0 - *

- */ -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class MethodFilterContext { - - private LinkScopeTypeEnum linKScopeTypeEnum; - - private String className; - - private String baseClassName; - -} diff --git a/src/main/java/com/dr/code/diff/analyze/strategy/MethodInvokeFactory.java b/src/main/java/com/dr/code/diff/analyze/strategy/MethodInvokeFactory.java deleted file mode 100644 index 885b244..0000000 --- a/src/main/java/com/dr/code/diff/analyze/strategy/MethodInvokeFactory.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.dr.code.diff.analyze.strategy; - -import com.dr.code.diff.enums.LinkScopeTypeEnum; -import org.springframework.beans.BeansException; -import org.springframework.boot.CommandLineRunner; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.stereotype.Component; - -import java.util.Collection; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * @ProjectName: cmdb - * @Package: com.dr.cmdb.application.filedcheck - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2021/3/30 10:10 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -@Component -public class MethodInvokeFactory implements CommandLineRunner, ApplicationContextAware { - private volatile ApplicationContext applicationContext; - - - private static Map handlerMap; - - - /** - * 封装策略 - * - * @param args - */ - @Override - public void run(String... args) { - Collection checkHandlers = this.applicationContext.getBeansOfType(MethodInvokeFilter.class).values(); - setHandlerMap(checkHandlers.stream().collect(Collectors.toMap(e -> e.filterType().getValue(), Function.identity()))); - } - - /** - * 设置应用程序上下文 - * - * @param applicationContext 应用程序上下文 - * @throws BeansException - */ - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - - /** - * 设置处理Map - * - * @param handlerMap - */ - private static void setHandlerMap(Map handlerMap) { - MethodInvokeFactory.handlerMap = handlerMap; - } - - /** - * 执行方法过滤器 - * - * @param methodFilterContext - */ - public static Boolean processHandler(MethodFilterContext methodFilterContext) { - if (null == methodFilterContext) { - return Boolean.FALSE; - } - LinkScopeTypeEnum linKScopeTypeEnum = methodFilterContext.getLinKScopeTypeEnum(); - if (handlerMap.containsKey(linKScopeTypeEnum.getValue())) { - return handlerMap.get(linKScopeTypeEnum.getValue()).isMatch(methodFilterContext); - } - return null; - } - - -} diff --git a/src/main/java/com/dr/code/diff/analyze/strategy/MethodInvokeFilter.java b/src/main/java/com/dr/code/diff/analyze/strategy/MethodInvokeFilter.java deleted file mode 100644 index d6e3865..0000000 --- a/src/main/java/com/dr/code/diff/analyze/strategy/MethodInvokeFilter.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.dr.code.diff.analyze.strategy; - -import com.dr.code.diff.enums.LinkScopeTypeEnum; - -/** - * @Package: com.dr.code.diff.analyze.strategy - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/5/19 10:18 - * @Version: 1.0 - *

- */ -public interface MethodInvokeFilter { - - LinkScopeTypeEnum filterType(); - Boolean isMatch(MethodFilterContext methodFilterContext); -} diff --git a/src/main/java/com/dr/code/diff/common/errorcode/BizCode.java b/src/main/java/com/dr/code/diff/common/errorcode/BizCode.java deleted file mode 100644 index b3a0d52..0000000 --- a/src/main/java/com/dr/code/diff/common/errorcode/BizCode.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.dr.code.diff.common.errorcode; - -/** -* @date:2021/5/1 -* @className:BizCode -* @author:Administrator -* @description: 业务异常类 -* -*/ -public enum BizCode implements Code { - - /**************************计费模块错误码******************************/ - GIT_OPERATED_FAIlED(20000, "git拉取代码失败", "git拉取代码失败"), - GET_DIFF_CLASS_ERROR(20001, "获取差异类失败", "获取差异类失败,请查看日志文件"), - CREATE_JOB_FAIL(20002, "创建job失败", "请联系管理员"), - PARSE_BRANCH_ERROR(20003, "解析分支失败", "请确认分支正常"), - PARSE_JAVA_FILE(20004, "解析java类失败", "请确认类是否有语法错误"), - GIT_AUTH_FAILED(20005, "git认证失败", "git认证失败"), - LOAD_CLASS_FAIL(20006, "读取java类失败", "读取java类失败,请稍后再试"), - UNKNOWN_REPOSITY_URL(20007, "未知仓库地址", "请检查仓库url"), - GET_METHOD_INVOKE_LINK_FAIL(20008, "获取方法调用链失败", "获取方法调用链失败"), - - COMPILE_CODE_FAIL(20009, "编译源码失败", "获取classes文件失败"), - POM_NOT_EXIST_FAIL(20010, "pom文件不存在", "编译源码失败,pom文件不存在"), - JACOCO_EXEC_NOT_EXIST(20011, "exec文件不存在", "exec文件不存在,请检查目录"), - JACOCO_REPORT_FAIL(20012, "生成jacoco报告失败", "生成jacoco报告失败"), - - GET_CODE_FAIL(20013, "获取代码失败", "获取代码失败,请排查日志"), - ; - private final int code; - private final String info; - private final String fixTips; - - BizCode(int code, String info, String fixTips) { - this.code = code; - this.info = info; - this.fixTips = fixTips; - } - - /** - * 错误码 - * eg: 200xx gateway - * 300xx user - * 400xx order - * 500xx core - * 600xx operator - * 700xx admin - *

- * universal: - * 10000 ~ 19999 - * 10000 success - * 10001 system error - * 10002 timed out - * 10003 params error - * 10004 rpc timeout - * 10005 rpc invoke error - * - * @return int - */ - @Override - public int getCode() { - return this.code; - } - - /** - * 错误码说明(内部日志,统计,查看使用) - * - * @return String - */ - @Override - public String getInfo() { - return this.info; - } - - /** - * 错误码描述,对外输出 - * - * @return String - */ - @Override - public String getFixTips() { - return this.fixTips; - } -} diff --git a/src/main/java/com/dr/code/diff/config/CustomizeLinkStartConfig.java b/src/main/java/com/dr/code/diff/config/CustomizeLinkStartConfig.java deleted file mode 100644 index fad720c..0000000 --- a/src/main/java/com/dr/code/diff/config/CustomizeLinkStartConfig.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.dr.code.diff.config; - -import lombok.Data; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; -import org.springframework.stereotype.Component; - -import java.util.List; - -/** - * @ProjectName: cmdb - * @Package: com.dr.cmdb.application.config - * @Description: 自定义参数 - * @Author: duanrui - * @CreateDate: 2021/3/18 9:49 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ - -@Component -@ConfigurationProperties(prefix = "custom.link.start") -@Data -public class CustomizeLinkStartConfig { - - - - /** - * 自定义链接类名 - */ - private List classNameList; - - /** - * 自定义链接方法签名 - */ - private List methodSignList; -} diff --git a/src/main/java/com/dr/code/diff/config/JsonConfig.java b/src/main/java/com/dr/code/diff/config/JsonConfig.java deleted file mode 100644 index 934d220..0000000 --- a/src/main/java/com/dr/code/diff/config/JsonConfig.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.dr.code.diff.config; - -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.alibaba.fastjson.support.config.FastJsonConfig; -import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import java.util.List; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.config - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2021/5/29 11:49 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -@Configuration -public class JsonConfig implements WebMvcConfigurer { - - - /** - * Configure the {@link HttpMessageConverter HttpMessageConverters} to use for reading or writing - * to the body of the request or response. If no converters are added, a - * default list of converters is registered. - *

Note that adding converters to the list, turns off - * default converter registration. To simply add a converter without impacting - * default registration, consider using the method - * {@link #extendMessageConverters(List)} instead. - * - * @param converters initially an empty list of converters - */ - @Override - public void configureMessageConverters(List> converters) { - FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); - FastJsonConfig fastJsonConfig = new FastJsonConfig(); - fastJsonConfig.setSerializerFeatures( - //List字段如果为null,输出为[],而非null - SerializerFeature.WriteNullListAsEmpty, - //是否输出值为null的字段,默认为false - SerializerFeature.WriteMapNullValue, - //字符串null返回空字符串 - SerializerFeature.WriteNullStringAsEmpty, - //空布尔值返回false - SerializerFeature.WriteNullBooleanAsFalse, - //禁止循环引用 - SerializerFeature.DisableCircularReferenceDetect, - //结果是否格式化,默认为false - SerializerFeature.PrettyFormat); - - //格式化日期 - fastJsonConfig.setDateFormat("YYYY-MM-dd HH:mm:ss"); - converter.setFastJsonConfig(fastJsonConfig); - converters.add(0, converter); - } - - -} diff --git a/src/main/java/com/dr/code/diff/controller/CodeDiffController.java b/src/main/java/com/dr/code/diff/controller/CodeDiffController.java deleted file mode 100644 index 8b1e50b..0000000 --- a/src/main/java/com/dr/code/diff/controller/CodeDiffController.java +++ /dev/null @@ -1,236 +0,0 @@ -package com.dr.code.diff.controller; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.dr.code.diff.analyze.DeduceApiService; -import com.dr.code.diff.analyze.bean.MethodInfo; -import com.dr.code.diff.dto.ApiModify; -import com.dr.code.diff.dto.DiffClassInfoResult; -import com.dr.code.diff.dto.DiffMethodParams; -import com.dr.code.diff.dto.MethodInvokeParam; -import com.dr.code.diff.enums.CodeManageTypeEnum; -import com.dr.code.diff.service.CodeDiffService; -import com.dr.code.diff.vo.result.CodeDiffResultVO; -import com.dr.code.diff.vo.result.DeduceApiVO; -import com.dr.code.diff.vo.result.MethodInfoVO; -import com.dr.code.diff.common.response.ApiResponse; -import com.dr.code.diff.common.response.UniqueApoResponse; -import com.dr.code.diff.common.utils.mapper.OrikaMapperUtils; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import javax.validation.constraints.NotEmpty; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author rui.duan - * @version 1.0 - * @className UserController - * @description 用户管理 - * @date 2019/11/20 6:25 下午 - */ -@RestController -@Api(value = "/api/code/diff", tags = "差异代码模块") -@RequestMapping("/api/code/diff") -@Validated -public class CodeDiffController { - - @Autowired - private CodeDiffService codeDiffService; - - @Autowired - protected DeduceApiService deduceApiService; - - @ApiOperation("git获取差异代码") - @RequestMapping(value = "git/list", method = RequestMethod.GET) - public UniqueApoResponse> getGitList( - @ApiParam(required = true, name = "gitUrl", value = "git远程仓库地址") - @NotEmpty - @RequestParam(value = "gitUrl") String gitUrl, - @ApiParam(required = true, name = "baseVersion", value = "git原始分支或tag") - @NotEmpty - @RequestParam(value = "baseVersion") String baseVersion, - @ApiParam(required = true, name = "nowVersion", value = "git现分支或tag") - @NotEmpty - @RequestParam(value = "nowVersion") String nowVersion) { - DiffMethodParams diffMethodParams = DiffMethodParams.builder() - .repoUrl(StringUtils.trim(gitUrl)) - .baseVersion(StringUtils.trim(baseVersion)) - .nowVersion(StringUtils.trim(nowVersion)) - .codeManageTypeEnum(CodeManageTypeEnum.GIT) - .build(); - List diffCodeList = codeDiffService.getDiffCode(diffMethodParams).getDiffClasses(); - List list = OrikaMapperUtils.mapList(diffCodeList, DiffClassInfoResult.class, CodeDiffResultVO.class); - return new UniqueApoResponse>().success(list, JSON.toJSONString(list, SerializerFeature.WriteNullListAsEmpty)); - } - - - @ApiOperation("svn同分支获取差异代码") - @RequestMapping(value = "svn/list", method = RequestMethod.GET) - public UniqueApoResponse> getSvnList( - @NotEmpty - @ApiParam(required = true, name = "svnUrl", value = "svn远程仓库地址,如svn:192.168.0.1:3690/svn") - @RequestParam(value = "svnUrl") String svnUrl, - @NotEmpty - @ApiParam(required = true, name = "baseVersion", value = "svn原始分支,如:1") - @RequestParam(value = "baseVersion") String baseVersion, - @NotEmpty - @ApiParam(required = true, name = "nowVersion", value = "svn现分支,如:2") - @RequestParam(value = "nowVersion") String nowVersion) { - DiffMethodParams diffMethodParams = DiffMethodParams.builder() - .repoUrl(StringUtils.trim(svnUrl)) - .baseVersion(StringUtils.trim(baseVersion)) - .nowVersion(StringUtils.trim(nowVersion)) - .codeManageTypeEnum(CodeManageTypeEnum.SVN) - .build(); - List diffCodeList = codeDiffService.getDiffCode(diffMethodParams).getDiffClasses(); - List list = OrikaMapperUtils.mapList(diffCodeList, DiffClassInfoResult.class, CodeDiffResultVO.class); - return new UniqueApoResponse>().success(list, JSON.toJSONString(list, SerializerFeature.WriteNullListAsEmpty)); - } - - @ApiOperation("svn不同分支获取差异代码") - @RequestMapping(value = "svn/branch/list", method = RequestMethod.GET) - public UniqueApoResponse> getSvnBranchList( - @ApiParam(required = true, name = "baseSvnUrl", value = "svn原始分支远程仓库地址,如svn:192.168.0.1:3690/svn/truck") - @NotEmpty - @RequestParam(value = "baseSvnUrl") String baseSvnUrl, - @ApiParam(required = true, name = "nowSvnUrl", value = "svn现分支远程仓库地址,如svn:192.168.0.1:3690/svn/feature") - @NotEmpty - @RequestParam(value = "nowSvnUrl") String nowSvnUrl - ) { - DiffMethodParams diffMethodParams = DiffMethodParams.builder() - .repoUrl(baseSvnUrl) - .svnRepoUrl(nowSvnUrl) - .codeManageTypeEnum(CodeManageTypeEnum.SVN) - .build(); - List diffCodeList = codeDiffService.getDiffCode(diffMethodParams).getDiffClasses(); - List list = OrikaMapperUtils.mapList(diffCodeList, DiffClassInfoResult.class, CodeDiffResultVO.class); - return new UniqueApoResponse>().success(list, JSON.toJSONString(list, SerializerFeature.WriteNullListAsEmpty)); - } - - - @ApiOperation("svn不同分支不同reversion获取差异代码") - @RequestMapping(value = "svn/branch/reversion/list", method = RequestMethod.GET) - public UniqueApoResponse> getSvnBranchReversionList( - @NotEmpty - @ApiParam(required = true, name = "baseSvnUrl", value = "svn原始分支远程仓库地址,如svn:192.168.0.1:3690/svn/truck") - @RequestParam(value = "baseSvnUrl") String baseSvnUrl, - @ApiParam(required = true, name = "baseVersion", value = "svn原始分支,如:1") - @NotEmpty - @RequestParam(value = "baseVersion") String baseVersion, - @ApiParam(required = true, name = "nowSvnUrl", value = "svn现分支远程仓库地址,如svn:192.168.0.1:3690/svn/feature") - @NotEmpty - @RequestParam(value = "nowSvnUrl") String nowSvnUrl, - @ApiParam(required = true, name = "nowVersion", value = "svn现分支,如:2") - @NotEmpty - @RequestParam(value = "nowVersion") String nowVersion - ) { - DiffMethodParams diffMethodParams = DiffMethodParams.builder() - .repoUrl(baseSvnUrl) - .svnRepoUrl(nowSvnUrl) - .baseVersion(baseVersion) - .nowVersion(nowVersion) - .codeManageTypeEnum(CodeManageTypeEnum.SVN) - .build(); - List diffCodeList = codeDiffService.getDiffCode(diffMethodParams).getDiffClasses(); - List list = OrikaMapperUtils.mapList(diffCodeList, DiffClassInfoResult.class, CodeDiffResultVO.class); - return new UniqueApoResponse>().success(list, JSON.toJSONString(list, SerializerFeature.WriteNullListAsEmpty)); - } - - - @ApiOperation("git获取影响接口") - @RequestMapping(value = "git/deduce/api", method = RequestMethod.GET) - public ApiResponse getGitDeduceApiList( - @ApiParam(required = true, name = "gitUrl", value = "git远程仓库地址") - @NotEmpty - @RequestParam(value = "gitUrl") String gitUrl, - @ApiParam(required = true, name = "baseVersion", value = "git原始分支或tag") - @NotEmpty - @RequestParam(value = "baseVersion") String baseVersion, - @ApiParam(required = true, name = "nowVersion", value = "git现分支或tag") - @NotEmpty - @RequestParam(value = "nowVersion") String nowVersion) { - DiffMethodParams diffMethodParams = DiffMethodParams.builder() - .repoUrl(StringUtils.trim(gitUrl)) - .baseVersion(StringUtils.trim(baseVersion)) - .nowVersion(StringUtils.trim(nowVersion)) - .codeManageTypeEnum(CodeManageTypeEnum.GIT) - .build(); - ApiModify apiModify = deduceApiService.deduceApi(diffMethodParams); - DeduceApiVO deduceApiVO = OrikaMapperUtils.map(apiModify, DeduceApiVO.class); - return new ApiResponse().success(deduceApiVO); - } - - - @ApiOperation("svn获取影响接口") - @RequestMapping(value = "svn/deduce/api", method = RequestMethod.GET) - public ApiResponse getSvnDeduceApiList( - @NotEmpty - @ApiParam(required = true, name = "svnUrl", value = "svn远程仓库地址,如svn:192.168.0.1:3690/svn") - @RequestParam(value = "svnUrl") String svnUrl, - @NotEmpty - @ApiParam(required = true, name = "baseVersion", value = "svn原始分支,如:1") - @RequestParam(value = "baseVersion") String baseVersion, - @NotEmpty - @ApiParam(required = true, name = "nowVersion", value = "svn现分支,如:2") - @RequestParam(value = "nowVersion") String nowVersion) { - DiffMethodParams diffMethodParams = DiffMethodParams.builder() - .repoUrl(StringUtils.trim(svnUrl)) - .baseVersion(StringUtils.trim(baseVersion)) - .nowVersion(StringUtils.trim(nowVersion)) - .codeManageTypeEnum(CodeManageTypeEnum.SVN) - .build(); - ApiModify apiModify = deduceApiService.deduceApi(diffMethodParams); - DeduceApiVO deduceApiVO = OrikaMapperUtils.map(apiModify, DeduceApiVO.class); - return new ApiResponse().success(deduceApiVO); - } - - @ApiOperation("获取git调用链") - @RequestMapping(value = "git/method/link", method = RequestMethod.GET) - public ApiResponse>> getGitMethodLink( - @ApiParam(required = true, name = "gitUrl", value = "git远程仓库地址") - @NotEmpty - @RequestParam(value = "gitUrl") String gitUrl, - @ApiParam(required = true, name = "branchName", value = "git分支或tag") - @NotEmpty - @RequestParam(value = "branchName") String branchName) { - MethodInvokeParam methodInvokeParam = MethodInvokeParam.builder().repoUrl(gitUrl).branchName(branchName).codeManageTypeEnum(CodeManageTypeEnum.GIT).build(); - Map> staticMethodInvoke = codeDiffService.getStaticMethodInvoke(methodInvokeParam); - Map> map = new HashMap<>(); - staticMethodInvoke.forEach((k, v) -> { - map.put(k, OrikaMapperUtils.mapList(v, MethodInfo.class, MethodInfoVO.class)); - }); - return new ApiResponse>>().success(map); - } - - - @ApiOperation("获取svn调用链") - @RequestMapping(value = "svn/method/link", method = RequestMethod.GET) - public ApiResponse>> getSVNMethodLink( - @ApiParam(required = true, name = "repoUrl", value = "svn远程仓库地址") - @NotEmpty - @RequestParam(value = "repoUrl") String repoUrl, - @ApiParam(required = true, name = "branchName", value = "svn版本") - @NotEmpty - @RequestParam(value = "branchName") String branchName) { - MethodInvokeParam methodInvokeParam = MethodInvokeParam.builder().repoUrl(repoUrl).branchName(branchName).codeManageTypeEnum(CodeManageTypeEnum.SVN).build(); - Map> staticMethodInvoke = codeDiffService.getStaticMethodInvoke(methodInvokeParam); - Map> map = new HashMap<>(); - staticMethodInvoke.forEach((k, v) -> { - map.put(k, OrikaMapperUtils.mapList(v, MethodInfo.class, MethodInfoVO.class)); - }); - return new ApiResponse>>().success(map); - } - - -} diff --git a/src/main/java/com/dr/code/diff/controller/ReportController.java b/src/main/java/com/dr/code/diff/controller/ReportController.java deleted file mode 100644 index a80e889..0000000 --- a/src/main/java/com/dr/code/diff/controller/ReportController.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.dr.code.diff.controller; - -import cn.hutool.core.io.FileUtil; -import cn.hutool.json.JSONUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.dr.code.diff.analyze.DeduceApiService; -import com.dr.code.diff.analyze.bean.MethodInfo; -import com.dr.code.diff.common.response.ApiResponse; -import com.dr.code.diff.common.response.UniqueApoResponse; -import com.dr.code.diff.common.utils.mapper.OrikaMapperUtils; -import com.dr.code.diff.config.CustomizeConfig; -import com.dr.code.diff.dto.ApiModify; -import com.dr.code.diff.dto.DiffClassInfoResult; -import com.dr.code.diff.dto.DiffMethodParams; -import com.dr.code.diff.dto.MethodInvokeParam; -import com.dr.code.diff.enums.CodeManageTypeEnum; -import com.dr.code.diff.jacoco.bean.RemoteJacocoServer; -import com.dr.code.diff.jacoco.bean.ReportJacocoParam; -import com.dr.code.diff.jacoco.dump.DumpAction; -import com.dr.code.diff.jacoco.report.ReportAction; -import com.dr.code.diff.service.CodeDiffService; -import com.dr.code.diff.vo.param.RemoteJacocoServerParamVO; -import com.dr.code.diff.vo.param.ReportJacocoParamVO; -import com.dr.code.diff.vo.result.CodeDiffResultVO; -import com.dr.code.diff.vo.result.DeduceApiVO; -import com.dr.code.diff.vo.result.MethodInfoVO; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.CollectionUtils; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.validation.constraints.NotEmpty; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author rui.duan - * @version 1.0 - * @className UserController - * @description 用户管理 - * @date 2019/11/20 6:25 下午 - */ -@RestController -@Api(value = "/api/jacoco/action", tags = "jacoco报告服务") -@RequestMapping("/api/jacoco/action") -@Validated -public class ReportController { - - @Autowired - private CodeDiffService codeDiffService; - - - @Autowired - private DumpAction dumpAction; - - - @Autowired - private ReportAction reportAction; - - @Autowired - private CustomizeConfig customizeConfig; - - @ApiOperation("git获取差异代码生成json文件") - @RequestMapping(value = "diff", method = RequestMethod.GET) - public ApiResponse getGitListToFile( - @ApiParam(required = true, name = "gitUrl", value = "git远程仓库地址") - @NotEmpty - @RequestParam(value = "gitUrl") String gitUrl, - @ApiParam(required = true, name = "baseVersion", value = "git原始分支或tag") - @NotEmpty - @RequestParam(value = "baseVersion") String baseVersion, - @ApiParam(required = true, name = "nowVersion", value = "git现分支或tag") - @NotEmpty - @RequestParam(value = "nowVersion") String nowVersion, - @ApiParam(required = true, name = "diffName", value = "生成差异代码名称a.json") - @NotEmpty - @RequestParam(value = "diffName") String diffName) { - DiffMethodParams diffMethodParams = DiffMethodParams.builder() - .repoUrl(StringUtils.trim(gitUrl)) - .baseVersion(StringUtils.trim(baseVersion)) - .nowVersion(StringUtils.trim(nowVersion)) - .codeManageTypeEnum(CodeManageTypeEnum.GIT) - .build(); - List diffCodeList = codeDiffService.getDiffCode(diffMethodParams).getDiffClasses(); - List list = OrikaMapperUtils.mapList(diffCodeList, DiffClassInfoResult.class, CodeDiffResultVO.class); - String diffCodePath = customizeConfig.getJacocoRootPath() + "/diff/" + diffName; - if (!CollectionUtils.isEmpty(list)) { - FileUtil.writeUtf8String(JSONUtil.toJsonStr(list), diffCodePath); - } - return new ApiResponse().success(diffCodePath); - } - - - @ApiOperation("dump生成exec文件") - @RequestMapping(value = "dump", method = RequestMethod.POST) - public ApiResponse> dump( - @ApiParam(value = "远程服务器信息", required = true) - @RequestBody List list) { - List remoteJacocoServers = OrikaMapperUtils.mapList(list, RemoteJacocoServerParamVO.class, RemoteJacocoServer.class); - List execs = dumpAction.dumpExecs(remoteJacocoServers); - return new ApiResponse>().success(execs); - } - - @ApiOperation("report生成html文件") - @RequestMapping(value = "report", method = RequestMethod.POST) - public ApiResponse response( - @ApiParam(value = "生成报告参数", required = true) - @RequestBody ReportJacocoParamVO reportJacocoParamVO) { - ReportJacocoParam reportJacocoParam = OrikaMapperUtils.map(reportJacocoParamVO, ReportJacocoParam.class); - reportAction.reportJacoco(reportJacocoParam); - return new ApiResponse<>().success(); - } - - -} diff --git a/src/main/java/com/dr/code/diff/dto/ApiMethodModify.java b/src/main/java/com/dr/code/diff/dto/ApiMethodModify.java deleted file mode 100644 index bd3f02f..0000000 --- a/src/main/java/com/dr/code/diff/dto/ApiMethodModify.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.dr.code.diff.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -/** - * @Package: com.dr.code.diff.dto - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/2/27 21:17 - * @Version: 1.0 - *

- */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class ApiMethodModify { - - - /** - * 方法签名,com/dr/code/diff/controller/CodeDiffController.getSvnList(String, String, String) - */ - private String methodSign; - - /** - * 类名 - */ - private String className; - - - /** - * 方法名称 - */ - private String methodName; - - - /** - * 方法参数 - */ - private List methodParams; - - -} diff --git a/src/main/java/com/dr/code/diff/dto/ApiModify.java b/src/main/java/com/dr/code/diff/dto/ApiModify.java deleted file mode 100644 index 2eba9f1..0000000 --- a/src/main/java/com/dr/code/diff/dto/ApiModify.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.dr.code.diff.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.Set; - -/** - * @Package: com.dr.code.diff.dto - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/2/27 21:17 - * @Version: 1.0 - *

- */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class ApiModify { - - - /** - * http api修改 - */ - private Set httpApiModifies; - - /** - * dubbo api修改 - */ - private Set dubboApiModifies; - - - - - private Set customClassModifies; - - - - - private Set customMethodSignModifies; - -} diff --git a/src/main/java/com/dr/code/diff/dto/ChangeLine.java b/src/main/java/com/dr/code/diff/dto/ChangeLine.java deleted file mode 100644 index 0f9625d..0000000 --- a/src/main/java/com/dr/code/diff/dto/ChangeLine.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.dr.code.diff.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.dto - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2021/6/24 21:11 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class ChangeLine { - - /** - * 变更类型 - */ - private String type; - - private Integer startLineNum; - - private Integer endLineNum; - -} diff --git a/src/main/java/com/dr/code/diff/dto/DiffInfo.java b/src/main/java/com/dr/code/diff/dto/DiffInfo.java deleted file mode 100644 index 4e680b0..0000000 --- a/src/main/java/com/dr/code/diff/dto/DiffInfo.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.dr.code.diff.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.ArrayList; -import java.util.List; - -/** - * @Package: com.dr.code.diff.dto - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/2/27 21:28 - * @Version: 1.0 - *

- */ -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class DiffInfo { - - - /** - * 老项目路径 - */ - private String oldProjectPath; - /** - * 新项目路径 - */ - private String newProjectPath; - - /** - * diff类 - */ - private List diffClasses; -} diff --git a/src/main/java/com/dr/code/diff/dto/GitInfoDto.java b/src/main/java/com/dr/code/diff/dto/GitInfoDto.java deleted file mode 100644 index 201a131..0000000 --- a/src/main/java/com/dr/code/diff/dto/GitInfoDto.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.dr.code.diff.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.eclipse.jgit.api.Git; - -/** - * @Package: com.dr.code.diff.dto - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/3/28 18:30 - * @Version: 1.0 - *

- */ -@Builder -@Data -@AllArgsConstructor -@NoArgsConstructor -public class GitInfoDto { - /** - * git - */ - private Git git; - - - /** - * 本地代码基础路径 - */ - private String localBaseRepoDir; - -} diff --git a/src/main/java/com/dr/code/diff/dto/HttpApiModify.java b/src/main/java/com/dr/code/diff/dto/HttpApiModify.java deleted file mode 100644 index 2b365e6..0000000 --- a/src/main/java/com/dr/code/diff/dto/HttpApiModify.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.dr.code.diff.dto; - -import com.dr.code.diff.enums.MethodNodeTypeEnum; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * @Package: com.dr.code.diff.dto - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/2/27 21:15 - * @Version: 1.0 - *

- */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class HttpApiModify { - - - /** - * 方法签名,com/dr/code/diff/controller/CodeDiffController.getSvnList(String, String, String) - */ - private String methodSign; - - - /** - * url映射,如/api/res/1 - */ - private String mappingUrl; - - - - /** - * 映射方法,如get,put - */ - private RequestMethod mappingMethod; - - -} diff --git a/src/main/java/com/dr/code/diff/dto/MethodInvokeDto.java b/src/main/java/com/dr/code/diff/dto/MethodInvokeDto.java deleted file mode 100644 index 786d681..0000000 --- a/src/main/java/com/dr/code/diff/dto/MethodInvokeDto.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.dr.code.diff.dto; - -import com.dr.code.diff.enums.CodeManageTypeEnum; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @Package: com.dr.code.diff.dto - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/3/8 21:22 - * @Version: 1.0 - *

- */ -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class MethodInvokeDto { - - /** - * 远程仓库地址 - */ - private String repoUrl; - - /** - * 分支或tag - */ - private String branchName = ""; - - - - /** - * 版本控制类型 - */ - private CodeManageTypeEnum codeManageTypeEnum; - -} diff --git a/src/main/java/com/dr/code/diff/dto/MethodInvokeParam.java b/src/main/java/com/dr/code/diff/dto/MethodInvokeParam.java deleted file mode 100644 index 195fade..0000000 --- a/src/main/java/com/dr/code/diff/dto/MethodInvokeParam.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.dr.code.diff.dto; - -import com.dr.code.diff.enums.CodeManageTypeEnum; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @Package: com.dr.code.diff.dto - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/3/8 21:22 - * @Version: 1.0 - *

- */ -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class MethodInvokeParam { - - /** - * 远程仓库地址 - */ - private String repoUrl; - - /** - * 分支或tag - */ - private String branchName = ""; - - - - /** - * 版本控制类型 - */ - private CodeManageTypeEnum codeManageTypeEnum; - -} diff --git a/src/main/java/com/dr/code/diff/enums/GitUrlTypeEnum.java b/src/main/java/com/dr/code/diff/enums/GitUrlTypeEnum.java deleted file mode 100644 index 357f2f2..0000000 --- a/src/main/java/com/dr/code/diff/enums/GitUrlTypeEnum.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.dr.code.diff.enums; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * @author rui.duan - * @version 1.0 - * @className WarehousingReceiptStatusEnum - * @description 代码管理工具枚举 - * @date 2019-06-10 11:39 - */ -@Getter -@AllArgsConstructor -public enum GitUrlTypeEnum { - //http - HTTP(1,"http"), - - SSH(2,"ssh"),; - - private Integer code; - private String value; - - - /** - * 根据code获取值 - * @param code - * @return - */ - public static String getValueByCode(Integer code) { - GitUrlTypeEnum[] values = GitUrlTypeEnum.values(); - for (GitUrlTypeEnum type : values) { - if (type.code.equals(code)) { - return type.value; - } - } - return null; - } - - /** - * 根据code获取值 - * @param code - * @returngetTypeEnumByCode - */ - public static GitUrlTypeEnum getTypeEnumByCode(Integer code) { - GitUrlTypeEnum[] values = GitUrlTypeEnum.values(); - for (GitUrlTypeEnum type : values) { - if (type.code.equals(code)) { - return type; - } - } - return null; - } - - /** - * 根据value获取code - * @param value - * @return - */ - public static Integer getCodeByValue(String value) { - GitUrlTypeEnum[] values = GitUrlTypeEnum.values(); - for (GitUrlTypeEnum type : values) { - if (type.value.equalsIgnoreCase(value)) { - return type.code; - } - } - return null; - } -} diff --git a/src/main/java/com/dr/code/diff/enums/LinkScopeTypeEnum.java b/src/main/java/com/dr/code/diff/enums/LinkScopeTypeEnum.java deleted file mode 100644 index f9aafa6..0000000 --- a/src/main/java/com/dr/code/diff/enums/LinkScopeTypeEnum.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.dr.code.diff.enums; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * @author rui.duan - * @version 1.0 - * @className WarehousingReceiptStatusEnum - * @description 代码管理工具枚举 - * @date 2019-06-10 11:39 - */ -@Getter -@AllArgsConstructor -public enum LinkScopeTypeEnum { - //排除jdk方法 - EXCLUDE_JDK_TYPE(1, "exclude_jdk"), - //只包本工程groupId的方法 - GROUP_ONLY_TYPE(2, "group_only"), - //全部调用链 - ALL_TYPE(3, "all"), - ; - - private Integer code; - private String value; - - - /** - * 根据code获取值 - * - * @param code - * @return - */ - public static String getValueByCode(Integer code) { - LinkScopeTypeEnum[] values = LinkScopeTypeEnum.values(); - for (LinkScopeTypeEnum type : values) { - if (type.code.equals(code)) { - return type.value; - } - } - return null; - } - - /** - * 根据value获取code - * - * @param value - * @return - */ - public static Integer getCodeByValue(String value) { - LinkScopeTypeEnum[] values = LinkScopeTypeEnum.values(); - for (LinkScopeTypeEnum type : values) { - if (type.value.equalsIgnoreCase(value)) { - return type.code; - } - } - return null; - } -} diff --git a/src/main/java/com/dr/code/diff/enums/MethodNodeTypeEnum.java b/src/main/java/com/dr/code/diff/enums/MethodNodeTypeEnum.java deleted file mode 100644 index 8dd3f56..0000000 --- a/src/main/java/com/dr/code/diff/enums/MethodNodeTypeEnum.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.dr.code.diff.enums; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * @author rui.duan - * @version 1.0 - * @className WarehousingReceiptStatusEnum - * @description 代码管理工具枚举 - * @date 2019-06-10 11:39 - */ -@Getter -@AllArgsConstructor -public enum MethodNodeTypeEnum { - //普通方法 - //http方法 - HTTP(1, "http"), - //dubbo方法 - DUBBO(2, "dubbo"), - - //自定义 - CUSTOM_CLASS(3, "custom_class"), - CUSTOM_METHOD(4, "custom_method"), - ; - - private Integer code; - private String value; - - - /** - * 根据code获取值 - * - * @param code - * @return - */ - public static String getValueByCode(Integer code) { - MethodNodeTypeEnum[] values = MethodNodeTypeEnum.values(); - for (MethodNodeTypeEnum type : values) { - if (type.code.equals(code)) { - return type.value; - } - } - return null; - } - - /** - * 根据value获取code - * - * @param value - * @return - */ - public static Integer getCodeByValue(String value) { - MethodNodeTypeEnum[] values = MethodNodeTypeEnum.values(); - for (MethodNodeTypeEnum type : values) { - if (type.value.equalsIgnoreCase(value)) { - return type.code; - } - } - return null; - } -} diff --git a/src/main/java/com/dr/code/diff/jacoco/bean/RemoteJacocoServer.java b/src/main/java/com/dr/code/diff/jacoco/bean/RemoteJacocoServer.java deleted file mode 100644 index d5b5d8d..0000000 --- a/src/main/java/com/dr/code/diff/jacoco/bean/RemoteJacocoServer.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.dr.code.diff.jacoco.bean; - -import lombok.Data; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.analyze.bean - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2023/4/16 16:38 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2023 - */ - -@Data -public class RemoteJacocoServer { - - /** - * 主机 - */ - private String host; - - - /** - * 端口 - */ - private Integer port; - - - /** - * exec文件名称 - */ - private String execFileName; - - -} diff --git a/src/main/java/com/dr/code/diff/jacoco/bean/ReportJacocoParam.java b/src/main/java/com/dr/code/diff/jacoco/bean/ReportJacocoParam.java deleted file mode 100644 index 8ca05a2..0000000 --- a/src/main/java/com/dr/code/diff/jacoco/bean/ReportJacocoParam.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.dr.code.diff.jacoco.bean; - -import lombok.Data; - -import java.util.List; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.jacoco.bean - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2023/4/16 17:08 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2023 - */ -@Data -public class ReportJacocoParam { - - /** - * 类目录 - */ - private List classesDirectory; - /** - * 源码目录 - */ - private List sourceDirectory; - /** - * exec文件目录 - * 0 - */ - private List executionDataFile; - - - /** - * 排除类目录 - */ - private String excludedClassesDirectory; - - /** - * 0 - * 报告生成目录 - */ - private String reportDirectory; - - - /** - * diff代码文件 - */ - private String diffCodeFile; - - - /** - * 报告名称 - */ - private String reportName; - -} diff --git a/src/main/java/com/dr/code/diff/jacoco/dump/DumpAction.java b/src/main/java/com/dr/code/diff/jacoco/dump/DumpAction.java deleted file mode 100644 index 3c5710c..0000000 --- a/src/main/java/com/dr/code/diff/jacoco/dump/DumpAction.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.dr.code.diff.jacoco.dump; - -import com.dr.code.diff.config.CustomizeConfig; -import com.dr.code.diff.jacoco.bean.RemoteJacocoServer; -import org.jacoco.cli.internal.core.data.ExecutionDataWriter; -import org.jacoco.cli.internal.core.runtime.RemoteControlReader; -import org.jacoco.cli.internal.core.runtime.RemoteControlWriter; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import javax.annotation.Resource; -import java.io.*; -import java.net.InetAddress; -import java.net.Socket; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.jacoco.dump - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2023/4/15 19:25 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2023 - */ -@Service -public class DumpAction { - - @Resource(name = "asyncExecutor") - private Executor executor; - - - @Autowired - private CustomizeConfig customizeConfig; - - - /** - * 批量dump - * - * @param serverList 服务器列表 - * @return {@link List}<{@link String}> - */ - public List dumpExecs(List serverList) { - if (CollectionUtils.isEmpty(serverList)) { - return null; - } - List> priceFuture = serverList.stream() - .map(item -> CompletableFuture.supplyAsync(() -> dumpExecData(item), - executor - )) - .collect(Collectors.toList()); - CompletableFuture.allOf(priceFuture.toArray(new CompletableFuture[0])).join(); - return priceFuture.stream().map(CompletableFuture::join).filter(Objects::nonNull).collect(Collectors.toList()); - } - - - /** - * 转储执行数据 - * - * @param server 服务器 - */ - public String dumpExecData(RemoteJacocoServer server) { - if (null == server) { - return null; - } - final FileOutputStream localFile; - Socket socket = null; - String execFile = customizeConfig.getJacocoRootPath() + server.getExecFileName(); - try { - localFile = new FileOutputStream(execFile); - final ExecutionDataWriter localWriter = new ExecutionDataWriter( - localFile); - - // Open a socket to the coverage agent: - socket = new Socket(InetAddress.getByName(server.getHost()), server.getPort()); - final RemoteControlWriter writer = new RemoteControlWriter( - socket.getOutputStream()); - final RemoteControlReader reader = new RemoteControlReader( - socket.getInputStream()); - reader.setSessionInfoVisitor(localWriter); - reader.setExecutionDataVisitor(localWriter); - - // Send a dump command and read the response: - writer.visitDumpCommand(true, false); - if (!reader.read()) { - throw new IOException("Socket closed unexpectedly."); - } - socket.close(); - localFile.close(); - return execFile; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - -} diff --git a/src/main/java/com/dr/code/diff/jacoco/report/ReportAction.java b/src/main/java/com/dr/code/diff/jacoco/report/ReportAction.java deleted file mode 100644 index 248e0ab..0000000 --- a/src/main/java/com/dr/code/diff/jacoco/report/ReportAction.java +++ /dev/null @@ -1,155 +0,0 @@ -package com.dr.code.diff.jacoco.report; - -import com.dr.code.diff.common.errorcode.BizCode; -import com.dr.code.diff.common.exception.BizException; -import com.dr.code.diff.common.log.LoggerUtil; -import com.dr.code.diff.jacoco.bean.ReportJacocoParam; -import lombok.extern.slf4j.Slf4j; -import org.jacoco.cli.internal.core.analysis.Analyzer; -import org.jacoco.cli.internal.core.analysis.CoverageBuilder; -import org.jacoco.cli.internal.core.analysis.IBundleCoverage; -import org.jacoco.cli.internal.core.internal.diff.JsonReadUtil; -import org.jacoco.cli.internal.core.tools.ExecFileLoader; -import org.jacoco.cli.internal.report.*; -import org.jacoco.cli.internal.report.html.HTMLFormatter; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.jacoco.report - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2023/4/15 19:57 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2023 - */ -@Service -@Slf4j -public class ReportAction { - - public void reportJacoco(ReportJacocoParam reportJacocoParam) { - //解析exec - ExecFileLoader execFileLoader = loadExecutionData(reportJacocoParam.getExecutionDataFile()); - if (null == execFileLoader) { - throw new BizException(BizCode.JACOCO_REPORT_FAIL); - } - //对比exec和class类,生成覆盖数据 - IBundleCoverage bundleCoverage = analyzeStructure(reportJacocoParam, execFileLoader); - if (null == bundleCoverage) { - throw new BizException(BizCode.JACOCO_REPORT_FAIL); - } - //生成报告 - createReport(bundleCoverage, execFileLoader, reportJacocoParam); - } - - - /** - * 第一步解析exec文件 - */ - public ExecFileLoader loadExecutionData(List executionDataFile) { - if (CollectionUtils.isEmpty(executionDataFile)) { - throw new BizException(BizCode.JACOCO_EXEC_NOT_EXIST); - } - // 解析exec - ExecFileLoader execFileLoader = new ExecFileLoader(); - executionDataFile.forEach(e -> { - try { - execFileLoader.load(new File(e)); - } catch (IOException ex) { - throw new BizException(BizCode.JACOCO_REPORT_FAIL.getCode(), ex.getMessage()); - } - }); - return execFileLoader; - } - - - /** - * 分析结构 - * - * @param reportJacocoParam 报告jacoco参数 - * @param execFileLoader exec文件加载器 - * @return {@link IBundleCoverage} - */ - public IBundleCoverage analyzeStructure(ReportJacocoParam reportJacocoParam, ExecFileLoader execFileLoader) { - try { - - CoverageBuilder builder; - // 如果有增量参数将其设置进去 - if (null != reportJacocoParam.getDiffCodeFile()) { - builder = new CoverageBuilder( - JsonReadUtil.readJsonToString(reportJacocoParam.getDiffCodeFile()), reportJacocoParam.getExcludedClassesDirectory()); - } else { - builder = new CoverageBuilder(reportJacocoParam.getExcludedClassesDirectory()); - } - final Analyzer analyzer = new Analyzer(execFileLoader.getExecutionDataStore(), builder); - List classesDirectory = reportJacocoParam.getClassesDirectory(); - // class类用于类方法的比较,源码只用于最后的着色 - for (String f : classesDirectory) { - File file = new File(f); - analyzer.analyzeAll(file); - } - return builder.getBundle(reportJacocoParam.getReportName()); - - } catch (Exception e) { - LoggerUtil.error(log, "解析class失败", e); - } - return null; - } - - /** - * 创建报告 - * - * @param bundleCoverage 包覆盖 - * @param execFileLoader exec文件加载器 - * @param reportJacocoParam 报告jacoco参数 - * @throws IOException ioexception - */ - public void createReport(final IBundleCoverage bundleCoverage, ExecFileLoader execFileLoader, ReportJacocoParam reportJacocoParam) { - try { - // Create a concrete report visitor based on some supplied - // configuration. In this case we use the defaults - final HTMLFormatter htmlFormatter = new HTMLFormatter(); - final IReportVisitor visitor = htmlFormatter.createVisitor(new FileMultiReportOutput(new File(reportJacocoParam.getReportDirectory()))); - - // Initialize the report with all of the execution and session - // information. At this point the report doesn't know about the - // structure of the report being created - visitor.visitInfo(execFileLoader.getSessionInfoStore().getInfos(), execFileLoader.getExecutionDataStore().getContents()); - - // Populate the report structure with the bundle coverage information. - // Call visitGroup if you need groups in your report. - visitor.visitBundle(bundleCoverage, getSourceLocator(reportJacocoParam.getSourceDirectory())); - - visitor.visitEnd(); - } catch (Exception e) { - LoggerUtil.error(log, "创建html报告失败", e); - throw new BizException(BizCode.JACOCO_REPORT_FAIL.getCode(), e.getMessage()); - } - - } - - - /** - * 得到源代码资源 - * - * @param sourceList 源列表 - * @return {@link ISourceFileLocator} - */ - private ISourceFileLocator getSourceLocator(List sourceList) { - final MultiSourceFileLocator multi = new MultiSourceFileLocator( - 4); - for (String f : sourceList) { - File file = new File(f); - multi.add(new DirectorySourceFileLocator(file, "utf-8", 4)); - } - return multi; - } - - -} diff --git a/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java b/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java deleted file mode 100644 index 1003423..0000000 --- a/src/main/java/com/dr/code/diff/service/impl/CodeDiffServiceImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.dr.code.diff.service.impl; - -import com.dr.code.diff.analyze.InvokeLinkBuildService; -import com.dr.code.diff.analyze.MavenCmdInvokeService; -import com.dr.code.diff.analyze.bean.MethodInfo; -import com.dr.code.diff.common.errorcode.BizCode; -import com.dr.code.diff.common.exception.BizException; -import com.dr.code.diff.dto.*; -import com.dr.code.diff.enums.MethodNodeTypeEnum; -import com.dr.code.diff.service.CodeDiffService; -import com.dr.code.diff.util.FileUtils; -import com.dr.code.diff.vercontrol.VersionControlHandlerFactory; -import com.dr.code.diff.common.utils.mapper.OrikaMapperUtils; -import com.google.common.collect.Lists; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import java.io.File; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @ProjectName: base-service - * @Package: com.dr.jenkins.jenkins.service.impl - * @Description: 获取差异代码 - * @Author: duanrui - * @CreateDate: 2020/6/20 21:39 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2020 - */ -@Service -@Slf4j -public class CodeDiffServiceImpl implements CodeDiffService { - - @Autowired - private MavenCmdInvokeService mavenCmdInvokeService; - - @Autowired - private InvokeLinkBuildService invokeLinkBuildService; - - /** - * @param diffMethodParams - * @date:2021/1/9 - * @className:CodeDiffService - * @author:Administrator - * @description: 获取差异代码 - */ - @Override - public DiffInfo getDiffCode(DiffMethodParams diffMethodParams) { - VersionControlDto dto = OrikaMapperUtils.map(diffMethodParams, VersionControlDto.class); - return VersionControlHandlerFactory.processHandler(dto); - } - - - /** - * 得到静态方法调用 - * - * @param methodInvokeParam 方法调用参数 - * @return methodInvokeParam - */ - @Override - public Map> getStaticMethodInvoke(MethodInvokeParam methodInvokeParam) { - MethodInvokeDto dto = OrikaMapperUtils.map(methodInvokeParam, MethodInvokeDto.class); - //下载代码 - String path = VersionControlHandlerFactory.downloadCode(dto); - if (StringUtils.isBlank(path)) { - throw new BizException(BizCode.GIT_OPERATED_FAIlED); - } - //这里存在风险,如果代码是分支,且有更新,这里必须要重新编译,先不考虑这个 - boolean compileFlag = FileUtils.searchFile(new File(path), ".class"); - if (compileFlag) { - log.info("代码已经编译,直接使用"); - } else { - //编译代码 - mavenCmdInvokeService.compileCode(path); - } - //获取调用链 - Map> methodsInvokeLink = invokeLinkBuildService.getMethodsInvokeLink(Lists.newArrayList(path), null); - if (CollectionUtils.isEmpty(methodsInvokeLink)) { - return Collections.emptyMap(); - } - Map> linksMap = new HashMap<>(); - methodsInvokeLink.forEach((k, v) -> linksMap.put(k.getValue(), v)); - return linksMap; - } -} diff --git a/src/main/java/com/dr/code/diff/util/FileUtils.java b/src/main/java/com/dr/code/diff/util/FileUtils.java deleted file mode 100644 index 12f4f26..0000000 --- a/src/main/java/com/dr/code/diff/util/FileUtils.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.dr.code.diff.util; - -import java.io.File; - -/** - * @Package: com.netease.precisiontesting.common.utils.file - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/4/19 13:57 - * @Version: 1.0 - *

- */ -public class FileUtils { - /** - * 搜索文件是否存在对应后缀的文件 - * - * @param directory 目录 - * @param suffix 后缀 - * @return boolean - */ - public static boolean searchFile(File directory,String suffix) { - if (directory == null || !directory.isDirectory()) { - return false; - } - File[] files = directory.listFiles(); - if (files == null) { - return false; - } - for (File file : files) { - if (file.isDirectory()) { - if (searchFile(file,suffix)) { - return true; - } - } else if (file.getName().endsWith(suffix)) { - return true; - } - } - return false; - } -} diff --git a/src/main/java/com/dr/code/diff/util/GitRepoUtil.java b/src/main/java/com/dr/code/diff/util/GitRepoUtil.java deleted file mode 100644 index ed8ca81..0000000 --- a/src/main/java/com/dr/code/diff/util/GitRepoUtil.java +++ /dev/null @@ -1,288 +0,0 @@ -package com.dr.code.diff.util; - -import com.dr.code.diff.common.errorcode.BizCode; -import com.dr.code.diff.common.exception.BizException; -import com.dr.code.diff.common.log.LoggerUtil; -import com.dr.code.diff.enums.GitUrlTypeEnum; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.jcraft.jsch.JSch; -import com.jcraft.jsch.JSchException; -import com.jcraft.jsch.Session; -import lombok.extern.slf4j.Slf4j; -import org.eclipse.jgit.api.CloneCommand; -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.errors.GitAPIException; -import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.lib.ObjectReader; -import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.revwalk.RevTree; -import org.eclipse.jgit.revwalk.RevWalk; -import org.eclipse.jgit.transport.*; -import org.eclipse.jgit.treewalk.AbstractTreeIterator; -import org.eclipse.jgit.treewalk.CanonicalTreeParser; -import org.eclipse.jgit.util.FS; -import org.eclipse.jgit.util.FileUtils; -import org.springframework.util.StringUtils; - -import java.io.File; -import java.io.IOException; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.util - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2021/4/5 11:16 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -@Slf4j -public class GitRepoUtil { - - - private static final Integer COMMIT_ID_LENGTH = 40; - - public static Git instanceHttpGit(String gitUrl, String codePath, String commitId, Git git, String gitUserName, String gitPassWord) throws GitAPIException { - if (null != git) { - git.pull().setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)).call(); - return git; - } - CloneCommand cloneCommand = Git.cloneRepository() - .setURI(gitUrl) - .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassWord)) - .setDirectory(new File(codePath)); - //说明不是commit_id - if(COMMIT_ID_LENGTH != commitId.length()){ - cloneCommand.setBranch(commitId); - } - return cloneCommand.call(); - } - - - public static Git instanceSshGit(String gitUrl, String codePath, String commitId, Git git, String privateKey) throws GitAPIException { - SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() { - @Override - protected JSch createDefaultJSch(FS fs) throws JSchException { - JSch defaultJSch = super.createDefaultJSch(fs); - defaultJSch.addIdentity(privateKey); - return defaultJSch; - } - - @Override - public void configure(OpenSshConfig.Host hc, Session session) { - session.setConfig("StrictHostKeyChecking", "no"); - } - }; - - if (null != git) { - git.pull().setTransportConfigCallback(transport -> { - SshTransport sshTransport = (SshTransport) transport; - sshTransport.setSshSessionFactory(sshSessionFactory); - }).call(); - return git; - } - CloneCommand cloneCommand = Git.cloneRepository() - .setURI(gitUrl) - .setTransportConfigCallback(transport -> { - SshTransport sshTransport = (SshTransport) transport; - sshTransport.setSshSessionFactory(sshSessionFactory); - }) - .setDirectory(new File(codePath)); - //说明不是commit_id - if(COMMIT_ID_LENGTH != commitId.length()){ - cloneCommand.setBranch(commitId); - } - return cloneCommand.call(); - } - - /** - * 克隆代码到本地,http/s方式拉取代码 - * - * @param gitUrl git url - * @param codePath 代码路径 - * @param branchName 分支名称 - * @param gitUserName git用户名 - * @param gitPassWord git密码 - * @return {@link Git} - */ - public static Git httpCloneRepository(String gitUrl, String codePath, String branchName, String gitUserName, String gitPassWord) { - Git git = null; - try { - if (!checkGitWorkSpace(gitUrl, codePath)) { - LoggerUtil.info(log, "本地代码不存在,clone", gitUrl, codePath); - git = instanceHttpGit(gitUrl, codePath, branchName, null, gitUserName, gitPassWord); - // 下载指定分支,如果是commitId在上一步已经下载了 - if (git.getRepository().exactRef(Constants.HEAD).isSymbolic()){ - git.checkout().setName(branchName).call(); - } - } else { - LoggerUtil.info(log, "本地代码存在,直接使用", gitUrl, codePath); - git = Git.open(new File(codePath)); - git.getRepository().getFullBranch(); - //判断是分支还是commitId,分支做更新,commitId无法改变用原有的 - if (git.getRepository().exactRef(Constants.HEAD).isSymbolic()) { - //更新分支代码 - instanceHttpGit(gitUrl, codePath, branchName, git, gitUserName, gitPassWord); - } - } - } catch (IOException | GitAPIException e) { - if (e instanceof GitAPIException) { - throw new BizException(BizCode.GIT_AUTH_FAILED.getCode(), e.getMessage()); - } - e.printStackTrace(); - throw new BizException(BizCode.GIT_OPERATED_FAIlED); - } - return git; - } - - /** - * ssh克隆存储库 - * - * @param gitUrl git url - * @param codePath 代码路径 - * @param branchName 分支名称 - * @param privateKey 私钥 - * @return {@link Git} - * @date:2021/9/8 - * @className:GitRepoUtil - * @author:Administrator - * @description: ssh方式拉取代码 - */ - public static Git sshCloneRepository(String gitUrl, String codePath, String branchName, String privateKey) { - Git git = null; - try { - if (!checkGitWorkSpace(gitUrl, codePath)) { - LoggerUtil.info(log, "本地代码不存在,clone", gitUrl, codePath); - //为了区分ssh路径和http/s这里ssh多加了一层目录 - git = instanceSshGit(gitUrl, codePath, branchName, null, privateKey); - // 下载指定branch - if (git.getRepository().exactRef(Constants.HEAD).isSymbolic()){ - git.checkout().setName(branchName).call(); - } - } else { - LoggerUtil.info(log, "本地代码存在,直接使用", gitUrl, codePath); - git = Git.open(new File(codePath)); - git.getRepository().getFullBranch(); - //判断是分支还是commitId,分支做更新,commitId无法改变用原有的 - if (git.getRepository().exactRef(Constants.HEAD).isSymbolic()) { - //更新代码 - instanceSshGit(gitUrl, codePath, branchName, git, privateKey); - } - } - - } catch (GitAPIException | - IOException e) { - if (e instanceof GitAPIException) { - throw new BizException(BizCode.GIT_AUTH_FAILED.getCode(), e.getMessage()); - } - e.printStackTrace(); - throw new BizException(BizCode.GIT_OPERATED_FAIlED); - } - return git; - } - - /** - * 将代码转成树状 - * - * @param repository - * @param branchName - * @return - */ - public static AbstractTreeIterator prepareTreeParser(Repository repository, String branchName) { - try { - RevWalk walk = new RevWalk(repository); - RevTree tree; - if (null == repository.resolve(branchName)) { - throw new BizException(BizCode.PARSE_BRANCH_ERROR); - } - tree = walk.parseTree(repository.resolve(branchName)); - CanonicalTreeParser treeParser = new CanonicalTreeParser(); - try (ObjectReader reader = repository.newObjectReader()) { - treeParser.reset(reader, tree.getId()); - } - walk.dispose(); - return treeParser; - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - - /** - * 判断工作目录是否存在,本来可以每次拉去代码时删除再拉取,但是这样代码多的化IO比较大,所以就代码可以复用 - * - * @param codePath - * @return - */ - public static Boolean checkGitWorkSpace(String gitUrl, String codePath) throws IOException { - Boolean isExist = Boolean.FALSE; - File repoGitDir = new File(codePath + "/.git"); - if (!repoGitDir.exists()) { - return isExist; - } - Git git = Git.open(new File(codePath)); - if (null == git) { - return isExist; - } - Repository repository = git.getRepository(); - //解析本地代码,获取远程uri,是否是我们需要的git远程仓库 - String repoUrl = repository.getConfig().getString("remote", "origin", "url"); - if (gitUrl.equals(repoUrl)) { - isExist = Boolean.TRUE; - } else { - LoggerUtil.info(log, "本地存在其他仓的代码,先删除"); - git.close(); - FileUtils.delete(new File(codePath)); - } - return isExist; - } - - - /** - * 获取url类型 - * - * @param url - * @return - */ - public static GitUrlTypeEnum judgeUrlType(String url) { - if (StringUtils.isEmpty(url)) { - return null; - } - if (url.toLowerCase().startsWith("http")) { - return GitUrlTypeEnum.HTTP; - } else if (url.toLowerCase().startsWith("git@")) { - return GitUrlTypeEnum.SSH; - } - return null; - } - - /** - * 取远程代码本地存储路径 - * - * @param repoUrl - * @param localBaseRepoDir - * @param version - * @return - */ - public static String getLocalDir(String repoUrl, String localBaseRepoDir, String version) { - StringBuilder localDir = new StringBuilder(localBaseRepoDir); - if (Strings.isNullOrEmpty(repoUrl)) { - return ""; - } - localDir.append("/"); - String repoName = Splitter.on("/") - .splitToStream(repoUrl).reduce((first, second) -> second) - .map(e -> Splitter.on(".").splitToStream(e).findFirst().get()).get(); - localDir.append(repoName); - if (!StringUtils.isEmpty(version)) { - localDir.append("/"); - localDir.append(version); - } - localDir.append("/"); - return localDir.toString(); - } - -} diff --git a/src/main/java/com/dr/code/diff/util/JsonUtils.java b/src/main/java/com/dr/code/diff/util/JsonUtils.java deleted file mode 100644 index c48ef46..0000000 --- a/src/main/java/com/dr/code/diff/util/JsonUtils.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.dr.code.diff.util; - -import com.jayway.jsonpath.*; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.util - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2021/10/29 20:55 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -@Slf4j -public class JsonUtils { - - public static void main(String[] args) { - String jsonStr1 = " {\n" + - " \"a\": [1,2,3],\n" + - " \"b\": 2,\n" + - " \"c\": [\n" + - " {\n" + - " \"m\": 3,\n" + - " \"n\": 4\n" + - " },\n" + - " {\n" + - " \"d\": 1,\n" + - " \"f\": 2\n" + - " }\n" + - " ]\n" + - "}"; - String jsonStr2 = "\n" + - "{\n" + - " \"a\": [1,3],\n" + - " \"b\": 2,\n" + - " \"c\": [\n" + - " {\n" + - " \"m\": 3,\n" + - " \"n\": 4\n" + - " }\n" + - " ]\n" + - "}"; - Boolean subJson = isSubJson(jsonStr1, jsonStr2); - System.out.println(subJson); - } - - /** - * 判断第二个json串是不是第一个json串的子集 - * - * @param actualJson - * @param expectJson - * @return - */ - public static Boolean isSubJson(String actualJson, String expectJson) { - try { - Configuration conf = Configuration.builder() - .options(Option.AS_PATH_LIST).build(); - ReadContext ctx = JsonPath.using(conf).parse(expectJson); - //获取期望json的全目录 - List jsonPaths = ctx.read("$..*"); - if (CollectionUtils.isEmpty(jsonPaths)) { - return Boolean.FALSE; - } - //排除非叶子结点 - List leafPaths = getPathList(jsonPaths); - ReadContext actualJsonCtx = JsonPath.parse(actualJson); - ReadContext expectJsonCtx = JsonPath.parse(expectJson); - //遍历子集,判断子集的value是否等于父集的 - for (String path : leafPaths) { - Object actualVal = actualJsonCtx.read(path); - Object expectVal = expectJsonCtx.read(path); - if (!expectVal.equals(actualVal)) { - return Boolean.FALSE; - } - } - return Boolean.TRUE; - } catch (Exception e) { - log.error("比较json子集失败:{}", e.getMessage()); - return Boolean.FALSE; - } - - } - - /** - * 排除非叶子节点 - * - * @param list - * @return - */ - private static List getPathList(List list) { - List removeList = new ArrayList<>(list.size()); - for (int i = 0; i < list.size(); i++) { - for (String s : list) { - if (s.startsWith(list.get(i)) && list.get(i).length() < s.length()) { - removeList.add(list.get(i)); - } - } - } - list.removeAll(removeList); - return list; - } -} diff --git a/src/main/java/com/dr/code/diff/util/MethodParserUtils.java b/src/main/java/com/dr/code/diff/util/MethodParserUtils.java deleted file mode 100644 index 3b76adc..0000000 --- a/src/main/java/com/dr/code/diff/util/MethodParserUtils.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.dr.code.diff.util; - -import cn.hutool.crypto.SecureUtil; -import com.dr.code.diff.common.errorcode.BizCode; -import com.dr.code.diff.common.exception.BizException; -import com.dr.code.diff.common.log.LoggerUtil; -import com.dr.code.diff.dto.MethodInfoResult; -import com.github.javaparser.JavaParser; -import com.github.javaparser.Range; -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.NodeList; -import com.github.javaparser.ast.body.CallableDeclaration; -import com.github.javaparser.ast.body.ConstructorDeclaration; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.comments.Comment; -import com.github.javaparser.ast.expr.LambdaExpr; -import com.github.javaparser.ast.visitor.VoidVisitorAdapter; -import lombok.extern.slf4j.Slf4j; - -import java.io.FileInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -/** - * @ProjectName: base-service - * @Package: com.dr.codediff.util - * @Description: 解析获取类的方法 - * @Author: duanrui - * @CreateDate: 2021/1/8 21:06 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -@Slf4j -public class MethodParserUtils { - - /** - * 解析类获取类的所有方法 - * - * @param classFile - * @return - */ - public static List parseMethods(String classFile, String rootCodePath) { - List list = new ArrayList<>(); - try (FileInputStream in = new FileInputStream(classFile)) { - JavaParser javaParser = new JavaParser(); - CompilationUnit cu = javaParser.parse(in).getResult().orElseThrow(() -> new BizException(BizCode.PARSE_JAVA_FILE)); - //由于jacoco不会统计接口覆盖率,没比较计算接口的方法,此处排除接口类 TODO 这样会排除mapper层 -// final List types = cu.getTypes(); -// boolean isInterface = types.stream().filter(t -> t instanceof ClassOrInterfaceDeclaration).anyMatch(t -> ((ClassOrInterfaceDeclaration) t).isInterface()); -// if (isInterface) { -// return list; -// } - cu.accept(new MethodVisitor(), list); - return list; - } catch (IOException e) { - LoggerUtil.error(log, "读取class类失败", e); - throw new BizException(BizCode.PARSE_JAVA_FILE); - } - - } - - /** - * javaparser工具类核心方法,主要通过这个类遍历class文件的方法,此方法主要是获取出代码的所有方法,然后再去对比方法是否存在差异 - */ - private static class MethodVisitor extends VoidVisitorAdapter> { - - - /** - * 构造函数变更 - * - * @param n - * @param list - */ - @Override - public void visit(final ConstructorDeclaration n, List list) { - buildMethod(n, list); - super.visit(n, list); - } - - @Override - public void visit(MethodDeclaration m, List list) { - buildMethod(m, list); - super.visit(m, list); - } - - @Override - public void visit(final LambdaExpr n, List list) { - super.visit(n, list); - } - private void buildMethod(CallableDeclaration m, List list) { - //删除外部注释 - m.removeComment(); - //删除方法内行注释 - List comments = m.getAllContainedComments(); - for (Comment comment : comments) { - comment.remove(); - } - //计算方法体的hash值,疑问,空格,特殊转义字符会影响结果,导致相同匹配为差异?建议提交代码时统一工具格式化 - String md5 = SecureUtil.md5(m.toString()); - NodeList parameters = m.getParameters(); - List params = parameters.stream().map(e -> { - if (e.getType().isClassOrInterfaceType()) { - return e.getType().asClassOrInterfaceType().getNameAsString(); - } - return e.getType().toString().trim(); - - }).collect(Collectors.toList()); - int startLine = 0; - int endLine = 0; - Range range = m.getRange().orElse(null); - if (null != range) { - startLine = range.begin.line; - endLine = range.end.line; - } - MethodInfoResult result = MethodInfoResult.builder() - .md5(md5) - .methodName(m.getNameAsString()) - .parameters(params) - .startLine(startLine) - .endLine(endLine) - .build(); - list.add(result); - } - - - } -} diff --git a/src/main/java/com/dr/code/diff/util/PathUtils.java b/src/main/java/com/dr/code/diff/util/PathUtils.java deleted file mode 100644 index 7df609f..0000000 --- a/src/main/java/com/dr/code/diff/util/PathUtils.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.dr.code.diff.util; - -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import org.springframework.util.StringUtils; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.util - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2021/4/24 21:17 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -public class PathUtils { - - /** - * @date:2021/4/5 - * @className:VersionControl - * @author:Administrator - * @description: 获取类本地地址 - */ - public static String getClassFilePath(String baseDir, String classPath) { - StringBuilder builder = new StringBuilder(baseDir); - builder.append("/"); - builder.append(classPath); - return builder.toString(); - } - - -} diff --git a/src/main/java/com/dr/code/diff/util/StringUtil.java b/src/main/java/com/dr/code/diff/util/StringUtil.java deleted file mode 100644 index 674447b..0000000 --- a/src/main/java/com/dr/code/diff/util/StringUtil.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.dr.code.diff.util; - -import com.google.common.base.Splitter; -import org.apache.commons.lang3.StringUtils; -import org.springframework.util.CollectionUtils; - -import java.util.List; - -/** - * @Package: com.dr.code.diff.util - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/2/23 20:56 - * @Version: 1.0 - *

- */ -public class StringUtil { - - public static final String PREFIX = "/"; - /** - * 获取分割后的最后元素 - * - * @param str str - * @return {@link String} - */ - public static String getSplitLast(String str, String separator) { - if (StringUtils.isBlank(str)) { - return str; - } - List strings = Splitter.on(separator).omitEmptyStrings().trimResults().splitToList(str); - if (CollectionUtils.isEmpty(strings)) { - return str; - } - return strings.get(strings.size() - 1); - } - - - /** - * 连接路径 - * - * @param path 路径 - * @param filename 文件名 - * @return {@link String} - */ - public static String connectPath(String path, String filename) { - if (StringUtils.isBlank(path)) { - return filename; - } - if (path.endsWith(PREFIX)) { - if (filename.startsWith(PREFIX)) { - return path + filename.substring(1); - } - return path + filename; - } else { - if (filename.startsWith(PREFIX)) { - return path + filename; - } - return path + PREFIX + filename; - } - } - - -} diff --git a/src/main/java/com/dr/code/diff/util/XmlDiffUtils.java b/src/main/java/com/dr/code/diff/util/XmlDiffUtils.java deleted file mode 100644 index 82bb390..0000000 --- a/src/main/java/com/dr/code/diff/util/XmlDiffUtils.java +++ /dev/null @@ -1,182 +0,0 @@ -package com.dr.code.diff.util; - - -import com.dr.code.diff.common.log.LoggerUtil; -import com.dr.code.diff.dto.MethodInfoResult; -import com.google.common.base.Splitter; -import com.google.common.collect.Lists; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xmlunit.builder.DiffBuilder; -import org.xmlunit.builder.Input; -import org.xmlunit.diff.DefaultNodeMatcher; -import org.xmlunit.diff.Diff; -import org.xmlunit.diff.Difference; -import org.xmlunit.diff.ElementSelectors; -import org.xmlunit.xpath.JAXPXPathEngine; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Source; -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.util.List; -import java.util.Set; - - -/** - * @Package: com.dr.code.diff.util - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/3/1 15:37 - * @Version: 1.0 - *

- */ -@Slf4j -public class XmlDiffUtils { - - private static JAXPXPathEngine xpathEngine = new JAXPXPathEngine(); - private static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - - - /** - * xml diff - * xml diff - * - * @param oldXmlPath 老xml路径 - * @param newXmlPath 新xml路径 - * @param list 列表 - */ - public static void getXmlDiffMethod(String oldXmlPath, String newXmlPath, Set list) { - try { - Source source = Input.fromFile(oldXmlPath).build(); - Source target = Input.fromFile(newXmlPath).build(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(false); - dbf.setFeature("http://xml.org/sax/features/validation", false); - dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); - dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); - Diff diff = DiffBuilder.compare(source) - .withTest(target) - .checkForSimilar() - .ignoreWhitespace() - .ignoreComments() - .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndAllAttributes)) - .withDocumentBuilderFactory(dbf) - .build(); - //先获取对比差异 - Iterable differences = diff.getDifferences(); - if (!differences.iterator().hasNext()) { - return; - } - differences.forEach( - e -> { - String xPath = e.getComparison().getControlDetails().getXPath(); - String pathValid = getPathValid(xPath); - if (StringUtils.isBlank(pathValid)) { - return; - } - try { - DocumentBuilder builder = factory.newDocumentBuilder(); - builder.setEntityResolver((publicId, systemId) -> { - System.out.println("Ignoring " + publicId + ", " + systemId); - return new InputSource(new StringReader("")); - }); - Document document = builder.parse(new File(newXmlPath)); - Iterable methodNode = xpathEngine.selectNodes(pathValid, document.getDocumentElement()); - if (!methodNode.iterator().hasNext()) { - return; - } - Node targetNode = methodNode.iterator().next(); - if (null == targetNode) { - return; - } - if (!targetNode.hasAttributes()) { - return; - } - NamedNodeMap attributes = targetNode.getAttributes(); - //获取方法名 - String methodName = attributes.getNamedItem("id").getNodeValue(); - //获取方法参数 - String paramType = ""; - Node parameterTypeNode = attributes.getNamedItem("parameterType"); - if (null != parameterTypeNode) { - String parameterType = parameterTypeNode.getNodeValue(); - if (!StringUtils.isBlank(parameterType)) { - paramType = StringUtil.getSplitLast(parameterType, "."); - } - } - MethodInfoResult methodInfoResult = MethodInfoResult.builder().methodName(methodName).parameters(Lists.newArrayList(paramType)).build(); - list.add(methodInfoResult); - } catch (SAXException | IOException | ParserConfigurationException ex) { - LoggerUtil.error(log, "获取xml信息失败", ex.getMessage()); - } - } - ); - } catch (Exception e) { - LoggerUtil.error(log, "xml对比失败", e.getMessage()); - } - } - - - /** - * xml diff类名 - * - * @param newXmlPath 新xml路径 - * @return {@link String} - */ - public static String getXmlDiffClassName(String newXmlPath) { - String namespace = ""; - try { - DocumentBuilder builder = factory.newDocumentBuilder(); - builder.setEntityResolver((publicId, systemId) -> { - System.out.println("Ignoring " + publicId + ", " + systemId); - return new InputSource(new StringReader("")); - }); - Document document = builder.parse(new File(newXmlPath)); - //先获取对比差异 - Iterable mapperMatches = xpathEngine.selectNodes("/mapper", document.getDocumentElement()); - if (!mapperMatches.iterator().hasNext()) { - return StringUtils.EMPTY; - } else { - Node mapper = mapperMatches.iterator().next(); - //获取mapper的namespace - namespace = mapper.getAttributes().getNamedItem("namespace").getNodeValue(); - namespace = namespace.replace(".", "/"); - } - return namespace; - } catch (IOException | SAXException | ParserConfigurationException e) { - LoggerUtil.error(log, "非mybatis xml文件", e.getMessage()); - return ""; - } - } - - - /** - * 获取路径有效,因为xml的格式一般为/mapper[1]/insert[1]/trim[1]格式,我们截取前两个就好了 - * - * @param xPath x路径 - * @return {@link Boolean} - */ - public static String getPathValid(String xPath) { - try { - if (StringUtils.isBlank(xPath)) { - return StringUtils.EMPTY; - } - List paths = Splitter.on("/").omitEmptyStrings().splitToList(xPath); - List subList = paths.subList(0, 2); - return "/" + String.join("/", subList); - } catch (Exception e) { - LoggerUtil.error(log, "非sql变更,忽略"); - return StringUtils.EMPTY; - } - } - -} diff --git a/src/main/java/com/dr/code/diff/util/XmlDubboUtil.java b/src/main/java/com/dr/code/diff/util/XmlDubboUtil.java deleted file mode 100644 index 57f2204..0000000 --- a/src/main/java/com/dr/code/diff/util/XmlDubboUtil.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.dr.code.diff.util; - -import cn.hutool.core.io.FileUtil; -import com.dr.code.diff.common.log.LoggerUtil; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xmlunit.xpath.JAXPXPathEngine; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.util - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2023/5/2 17:45 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2023 - */ -@Slf4j -public class XmlDubboUtil { - private static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - - public static List getDubboService(File inputStream) { - List classNames = new ArrayList<>(); - try { - DocumentBuilder builder = factory.newDocumentBuilder(); - builder.setEntityResolver((publicId, systemId) -> { -// System.out.println("Ignoring " + publicId + ", " + systemId); - return new InputSource(new StringReader("")); - }); - Document document = builder.parse(inputStream); - //获取dubbo的service - NodeList serviceList = document.getElementsByTagName("dubbo:service"); - for (int i = 0; i < serviceList.getLength(); i++) { - Element serviceElement = (Element) serviceList.item(i); - String className = serviceElement.getAttribute("interface"); - className = className.replace(".", "/"); - classNames.add(className); - } - return classNames; - } catch (IOException | SAXException | ParserConfigurationException e) { - LoggerUtil.error(log, "非dubbo xml文件", e.getMessage()); - return null; - } - } - - - /** - * 扫描dubbo xml - * - * @param resourcePath 资源路径 - * @return {@link List}<{@link String}> - */ - public static List scanDubboService(String resourcePath) { - List xmlFiles = FileUtil.loopFiles(new File(resourcePath), pathname -> pathname.getName().endsWith(".xml")); - List dubboServices = new ArrayList(); - xmlFiles.forEach(file -> { - List dubboService = getDubboService(file); - dubboServices.addAll(dubboService); - }); - return dubboServices; - } - - -} diff --git a/src/main/java/com/dr/code/diff/vercontrol/AbstractVersionControl.java b/src/main/java/com/dr/code/diff/vercontrol/AbstractVersionControl.java deleted file mode 100644 index 545e5fe..0000000 --- a/src/main/java/com/dr/code/diff/vercontrol/AbstractVersionControl.java +++ /dev/null @@ -1,221 +0,0 @@ -package com.dr.code.diff.vercontrol; - -import cn.hutool.core.io.FileUtil; -import com.dr.code.diff.config.CustomizeConfig; -import com.dr.code.diff.dto.*; -import com.dr.code.diff.enums.CodeManageTypeEnum; -import com.dr.code.diff.util.MethodParserUtils; -import com.dr.code.diff.util.XmlDiffUtils; -import com.dr.code.diff.common.log.LoggerUtil; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.eclipse.jgit.diff.DiffEntry; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.CollectionUtils; - -import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.vercontrol - * @Description: 代码差异获取流程类定义 - * @Author: duanrui - * @CreateDate: 2021/4/5 9:56 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -@Data -@Slf4j -public abstract class AbstractVersionControl { - - protected VersionControlDto versionControlDto; - - - @Resource(name = "asyncExecutor") - private Executor executor; - - - @Autowired - private CustomizeConfig customizeConfig; - - /** - * 执行handler - * - * @return - */ - public DiffInfo handler(VersionControlDto versionControlDto) { - this.versionControlDto = versionControlDto; - getDiffCodeClasses(); - List diffCodeMethods = getDiffCodeMethods(); - return DiffInfo.builder() - .newProjectPath(versionControlDto.getNewLocalBasePath()) - .oldProjectPath(versionControlDto.getOldLocalBasePath()) - .diffClasses(diffCodeMethods) - .build(); - } - - - /** - * 下载代码 - * - * @param methodInvokeDto 方法调用dto - * @return {@link String} - */ - public abstract String downloadCode(MethodInvokeDto methodInvokeDto); - - - /** - * @date:2021/4/5 - * @className:VersionControl - * @author:Administrator - * @description: 获取差异类 - */ - public abstract void getDiffCodeClasses(); - - /** - * 获取操作类型 - */ - public abstract CodeManageTypeEnum getType(); - - - /** - * @date:2021/4/24 - * @className:VersionControl - * @author:Administrator - * @description: 获取旧版本文件本地路径 - */ - public abstract String getLocalNewPath(String filePackage); - - - /** - * @date:2021/4/24 - * @className:VersionControl - * @author:Administrator - * @description: 获取新版本文件本地路径 - */ - public abstract String getLocalOldPath(String filePackage); - - /** - * @date:2021/4/5 - * @className:VersionControl - * @author:Administrator - * @description: 获取差异方法 - */ - public List getDiffCodeMethods() { - if (CollectionUtils.isEmpty(versionControlDto.getDiffClasses())) { - return null; - } - LoggerUtil.info(log, "需要对比的差异类数", versionControlDto.getDiffClasses().size()); - List> priceFuture = versionControlDto.getDiffClasses().stream() - .map(item -> getClassMethods(getLocalOldPath(item.getNewPath()), getLocalNewPath(item.getNewPath()), item)) - .collect(Collectors.toList()); - CompletableFuture.allOf(priceFuture.toArray(new CompletableFuture[0])).join(); - List list = priceFuture.stream().map(CompletableFuture::join).filter(Objects::nonNull).collect(Collectors.toList()); - if (!CollectionUtils.isEmpty(list)) { - LoggerUtil.info(log, "计算出最终差异类数", list.size()); - } - return list; - } - - - /** - * 获取类的增量方法 - * - * @param oldClassFile 旧类的本地地址 - * @param mewClassFile 新类的本地地址 - * @param diffEntry 差异类 - * @return - */ - private CompletableFuture getClassMethods(String oldClassFile, String mewClassFile, DiffEntryDto diffEntry) { - //多线程获取差异方法,此处只要考虑增量代码太多的情况下,每个类都需要遍历所有方法,采用多线程方式加快速度 - return CompletableFuture.supplyAsync(() -> { - String moduleName = diffEntry.getNewPath().split("/")[0]; - if ("src".equals(moduleName)) { - moduleName = ""; - } - //mybatis的xml变更 - if (mewClassFile.endsWith(".xml")) { - String xmlDiffClassName = XmlDiffUtils.getXmlDiffClassName(mewClassFile); - if (StringUtils.isBlank(xmlDiffClassName)) { - return null; - } - HashSet methodSet = new HashSet<>(); - //如果旧的mapper不存在,说明是新增的,java mapper会识别到,这里不用对比 - if (StringUtils.isBlank(oldClassFile) || !FileUtil.exist(oldClassFile)) { - return null; - } - XmlDiffUtils.getXmlDiffMethod(oldClassFile, mewClassFile, methodSet); - if (CollectionUtils.isEmpty(methodSet)) { - return null; - } - methodSet.forEach(e -> - e.setMethodSign(xmlDiffClassName + "#" + e.getMethodName() + "#" + String.join(",", e.getParameters()))); - return DiffClassInfoResult.builder() - .classFile(xmlDiffClassName) - .methodInfos(new ArrayList<>(methodSet)) - .type(DiffEntry.ChangeType.MODIFY.name()) - .moduleName(moduleName) - .build(); - } - String className; - if (diffEntry.getNewPath().contains(customizeConfig.getRootCodePath())) { - className = diffEntry.getNewPath().split(customizeConfig.getRootCodePath())[1].split("\\.")[0]; - } else { - className = ""; - } - //新增类直接标记,不用计算方法 -// if (DiffEntry.ChangeType.ADD.equals(diffEntry.getChangeType())) { -// return DiffClassInfoResult.builder() -// .classFile(className) -// .type(DiffEntry.ChangeType.ADD.name()) -// .moduleName(moduleName) -// .lines(diffEntry.getLines()) -// .build(); -// } - List diffMethods; - //获取新类的所有方法 - List newMethodInfoResults = MethodParserUtils.parseMethods(mewClassFile, customizeConfig.getRootCodePath()); - //如果新类为空,没必要比较 - if (CollectionUtils.isEmpty(newMethodInfoResults)) { - return null; - } - //获取旧类的所有方法 - List oldMethodInfoResults = null; - if (DiffEntry.ChangeType.MODIFY.equals(diffEntry.getChangeType())) { - oldMethodInfoResults = MethodParserUtils.parseMethods(oldClassFile, customizeConfig.getRootCodePath()); - } - //如果旧类为空,新类的方法所有为增量 - if (CollectionUtils.isEmpty(oldMethodInfoResults)) { - diffMethods = newMethodInfoResults; - } else { //否则,计算增量方法 - List md5s = oldMethodInfoResults.stream().map(MethodInfoResult::getMd5).collect(Collectors.toList()); - diffMethods = newMethodInfoResults.stream().filter(m -> !md5s.contains(m.getMd5())).collect(Collectors.toList()); - } - //没有增量方法,过滤掉 - if (CollectionUtils.isEmpty(diffMethods)) { - return null; - } - diffMethods.forEach(e -> - e.setMethodSign(className + "#" + e.getMethodName() + "#" + String.join(",", e.getParameters())) - ); - return DiffClassInfoResult.builder() - .classFile(className) - .methodInfos(diffMethods) - .type(diffEntry.getChangeType().name()) - .moduleName(moduleName) - .lines(diffEntry.getLines()) - .build(); - }, executor); - } - - -} diff --git a/src/main/java/com/dr/code/diff/vercontrol/VersionControlHandlerFactory.java b/src/main/java/com/dr/code/diff/vercontrol/VersionControlHandlerFactory.java deleted file mode 100644 index b7f58e6..0000000 --- a/src/main/java/com/dr/code/diff/vercontrol/VersionControlHandlerFactory.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.dr.code.diff.vercontrol; - -import com.dr.code.diff.dto.DiffClassInfoResult; -import com.dr.code.diff.dto.DiffInfo; -import com.dr.code.diff.dto.MethodInvokeDto; -import com.dr.code.diff.dto.VersionControlDto; -import com.dr.code.diff.enums.CodeManageTypeEnum; -import org.springframework.beans.BeansException; -import org.springframework.boot.CommandLineRunner; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.stereotype.Component; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * @ProjectName: cmdb - * @Package: com.dr.cmdb.application.filedcheck - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2021/3/30 10:10 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -@Component -public class VersionControlHandlerFactory implements CommandLineRunner, ApplicationContextAware { - private volatile ApplicationContext applicationContext; - - - private static Map handlerMap; - - - /** - * 封装策略 - * - * @param args - */ - @Override - public void run(String... args) { - Collection checkHandlers = this.applicationContext.getBeansOfType(AbstractVersionControl.class).values(); - setHandlerMap(checkHandlers.stream().collect(Collectors.toMap(e -> e.getType().getValue(), Function.identity()))); - } - - /** - * 设置应用程序上下文 - * - * @param applicationContext 应用程序上下文 - * @throws BeansException - */ - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - - /** - * 设置处理Map - * - * @param handlerMap - */ - private static void setHandlerMap(Map handlerMap) { - VersionControlHandlerFactory.handlerMap = handlerMap; - } - - /** - * 执行方法校验 - * - * @param versionControlDto - */ - public static DiffInfo processHandler(VersionControlDto versionControlDto) { - CodeManageTypeEnum codeManageTypeEnum = versionControlDto.getCodeManageTypeEnum(); - if (handlerMap.containsKey(codeManageTypeEnum.getValue())) { - return handlerMap.get(codeManageTypeEnum.getValue()).handler(versionControlDto); - } - return null; - } - - - public static String downloadCode(MethodInvokeDto methodInvokeDto) { - CodeManageTypeEnum codeManageTypeEnum = methodInvokeDto.getCodeManageTypeEnum(); - if (handlerMap.containsKey(codeManageTypeEnum.getValue())) { - return handlerMap.get(codeManageTypeEnum.getValue()).downloadCode(methodInvokeDto); - } - return null; - } -} diff --git a/src/main/java/com/dr/code/diff/vercontrol/git/GitAbstractVersionControl.java b/src/main/java/com/dr/code/diff/vercontrol/git/GitAbstractVersionControl.java deleted file mode 100644 index 2200bb3..0000000 --- a/src/main/java/com/dr/code/diff/vercontrol/git/GitAbstractVersionControl.java +++ /dev/null @@ -1,204 +0,0 @@ -package com.dr.code.diff.vercontrol.git; - -import com.alibaba.fastjson.JSON; -import com.dr.code.diff.config.CustomizeConfig; -import com.dr.code.diff.dto.ChangeLine; -import com.dr.code.diff.dto.DiffEntryDto; -import com.dr.code.diff.dto.GitInfoDto; -import com.dr.code.diff.dto.MethodInvokeDto; -import com.dr.code.diff.enums.CodeManageTypeEnum; -import com.dr.code.diff.enums.GitUrlTypeEnum; -import com.dr.code.diff.util.GitRepoUtil; -import com.dr.code.diff.util.PathUtils; -import com.dr.code.diff.vercontrol.AbstractVersionControl; -import com.dr.code.diff.common.errorcode.BizCode; -import com.dr.code.diff.common.exception.BizException; -import com.dr.code.diff.common.log.LoggerUtil; -import com.dr.code.diff.common.utils.mapper.OrikaMapperUtils; -import lombok.extern.slf4j.Slf4j; -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.errors.GitAPIException; -import org.eclipse.jgit.diff.DiffEntry; -import org.eclipse.jgit.diff.DiffFormatter; -import org.eclipse.jgit.diff.Edit; -import org.eclipse.jgit.diff.EditList; -import org.eclipse.jgit.treewalk.AbstractTreeIterator; -import org.eclipse.jgit.util.io.DisabledOutputStream; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.io.IOException; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.vercontrol - * @Description: 代码差异获取流程类定义 - * @Author: duanrui - * @CreateDate: 2021/4/5 9:56 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -@Component -@Slf4j -public class GitAbstractVersionControl extends AbstractVersionControl { - - @Autowired - private CustomizeConfig customizeConfig; - - - /** - * 获取操作类型 - */ - @Override - public CodeManageTypeEnum getType() { - return CodeManageTypeEnum.GIT; - } - - @Override - public void getDiffCodeClasses() { - try { - GitInfoDto baseGitInfo = getGitInfo(super.versionControlDto.getRepoUrl(), super.versionControlDto.getBaseVersion()); - Git baseGit = baseGitInfo.getGit(); - GitInfoDto nowGitInfo = getGitInfo(super.versionControlDto.getRepoUrl(), super.versionControlDto.getNowVersion()); - Git nowGit = nowGitInfo.getGit(); - super.versionControlDto.setNewLocalBasePath(nowGitInfo.getLocalBaseRepoDir()); - super.versionControlDto.setOldLocalBasePath(baseGitInfo.getLocalBaseRepoDir()); - AbstractTreeIterator baseTree = GitRepoUtil.prepareTreeParser(baseGit.getRepository(), super.versionControlDto.getBaseVersion()); - AbstractTreeIterator nowTree = GitRepoUtil.prepareTreeParser(nowGit.getRepository(), super.versionControlDto.getNowVersion()); - //获取两个版本之间的差异代码 - List diff = null; - diff = nowGit.diff().setOldTree(baseTree).setNewTree(nowTree).setShowNameAndStatusOnly(true).call(); - //过滤出有效的差异代码 - Collection validDiffList = diff.stream() - //只计算java文件和xml - .filter(e -> e.getNewPath().endsWith(".java") || e.getNewPath().endsWith(".xml")) - //排除测试文件 - .filter(e -> { - if (e.getNewPath().endsWith(".java")) { - return e.getNewPath().contains(customizeConfig.getRootCodePath()); - } - return Boolean.TRUE; - }) - //只计算新增和变更文件 - .filter(e -> DiffEntry.ChangeType.ADD.equals(e.getChangeType()) || DiffEntry.ChangeType.MODIFY.equals(e.getChangeType())) - .collect(Collectors.toList()); - //计算xml变更引起的mapper方法变更 - if (CollectionUtils.isEmpty(validDiffList)) { - LoggerUtil.info(log, "没有需要对比的类"); - return; - } - List diffEntries = OrikaMapperUtils.mapList(validDiffList, DiffEntry.class, DiffEntryDto.class); - - Map diffMap = diffEntries.stream().collect(Collectors.toMap(DiffEntryDto::getNewPath, Function.identity())); - LoggerUtil.info(log, "需要对比的差异类为:", JSON.toJSON(diffEntries)); - DiffFormatter diffFormatter = new DiffFormatter(DisabledOutputStream.INSTANCE); - diffFormatter.setRepository(nowGit.getRepository()); - diffFormatter.setContext(0); - //此处是获取变更行,有群友需求新增行或变更行要在类中打标记,此处忽略删除行 - for (DiffEntry diffClass : validDiffList) { - //获取变更行 - EditList edits = diffFormatter.toFileHeader(diffClass).toEditList(); - if (CollectionUtils.isEmpty(edits)) { - continue; - } - //获取出新增行和变更行 - List list = edits.stream().filter(e -> Edit.Type.INSERT.equals(e.getType()) || Edit.Type.REPLACE.equals(e.getType())).collect(Collectors.toList()); - List lines = new ArrayList<>(list.size()); - list.forEach( - edit -> { - ChangeLine build = ChangeLine.builder().startLineNum(edit.getBeginB()).endLineNum(edit.getEndB()).type(edit.getType().name()).build(); - lines.add(build); - } - ); - if (diffMap.containsKey(diffClass.getNewPath())) { - DiffEntryDto diffEntryDto = diffMap.get(diffClass.getNewPath()); - diffEntryDto.setLines(lines); - } - } - //设置变更行 - super.versionControlDto.setDiffClasses(new ArrayList(diffMap.values())); - } catch (IOException | - GitAPIException e) { - e.printStackTrace(); - throw new BizException(BizCode.GET_DIFF_CLASS_ERROR); - } - - } - - - /** - * 下载代码 - * - * @param methodInvokeDto 方法调用dto - * @return {@link String} - */ - @Override - public String downloadCode(MethodInvokeDto methodInvokeDto) { - GitInfoDto gitInfo = getGitInfo(methodInvokeDto.getRepoUrl(), methodInvokeDto.getBranchName()); - return gitInfo.getLocalBaseRepoDir(); - } - - - /** - * git获取信息 - * - * @param repoUrl 仓库url - * @param branchName 分支机构名称 - * @return {@link GitInfoDto} - */ - public GitInfoDto getGitInfo(String repoUrl, String branchName) { - Git git = null; - String localBaseRepoDir = GitRepoUtil.getLocalDir(repoUrl, customizeConfig.getGitLocalBaseRepoDir(), branchName); - GitUrlTypeEnum gitUrlTypeEnum = GitRepoUtil.judgeUrlType(repoUrl); - if (null == gitUrlTypeEnum) { - throw new BizException(BizCode.UNKNOWN_REPOSITY_URL); - } - switch (Objects.requireNonNull(gitUrlTypeEnum)) { - case HTTP: { - //原有代码git对象 - git = GitRepoUtil.httpCloneRepository(repoUrl, localBaseRepoDir, branchName, customizeConfig.getGitUserName(), customizeConfig.getGitPassWord()); - break; - } - case SSH: { - localBaseRepoDir += GitUrlTypeEnum.SSH.getValue(); - //原有代码git对象 - git = GitRepoUtil.sshCloneRepository(repoUrl, localBaseRepoDir, branchName, customizeConfig.getGitSshPrivateKey()); - break; - } - default: { - LoggerUtil.error(log, "未知类型仓库地址"); - throw new BizException(BizCode.UNKNOWN_REPOSITY_URL); - } - } - return GitInfoDto.builder().git(git).localBaseRepoDir(localBaseRepoDir).build(); - } - - /** - * @param filePackage - * @date:2021/4/24 - * @className:VersionControl - * @author:Administrator - * @description: 获取旧版本文件本地路径 - */ - @Override - public String getLocalNewPath(String filePackage) { - return PathUtils.getClassFilePath(super.versionControlDto.getNewLocalBasePath(), filePackage); - } - - /** - * @param filePackage - * @date:2021/4/24 - * @className:VersionControl - * @author:Administrator - * @description: 获取新版本文件本地路径 - */ - @Override - public String getLocalOldPath(String filePackage) { - return PathUtils.getClassFilePath(super.versionControlDto.getOldLocalBasePath(), filePackage); - } -} diff --git a/src/main/java/com/dr/code/diff/vercontrol/svn/SvnAbstractVersionControl.java b/src/main/java/com/dr/code/diff/vercontrol/svn/SvnAbstractVersionControl.java deleted file mode 100644 index f4a271d..0000000 --- a/src/main/java/com/dr/code/diff/vercontrol/svn/SvnAbstractVersionControl.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.dr.code.diff.vercontrol.svn; - -import com.dr.code.diff.config.CustomizeConfig; -import com.dr.code.diff.dto.MethodInvokeDto; -import com.dr.code.diff.enums.CodeManageTypeEnum; -import com.dr.code.diff.util.PathUtils; -import com.dr.code.diff.util.SvnRepoUtil; -import com.dr.code.diff.vercontrol.AbstractVersionControl; -import com.dr.code.diff.common.log.LoggerUtil; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.tmatesoft.svn.core.SVNDepth; -import org.tmatesoft.svn.core.SVNException; -import org.tmatesoft.svn.core.SVNURL; -import org.tmatesoft.svn.core.wc.SVNDiffClient; -import org.tmatesoft.svn.core.wc.SVNRevision; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.vercontrol - * @Description: svn差异代码获取 - * @Author: duanrui - * @CreateDate: 2021/4/5 9:56 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -@Slf4j -@Component -public class SvnAbstractVersionControl extends AbstractVersionControl { - - @Autowired - private CustomizeConfig customizeConfig; - - - /** - * 获取操作类型 - */ - @Override - public CodeManageTypeEnum getType() { - return CodeManageTypeEnum.SVN; - } - - @Override - public void getDiffCodeClasses() { - try { - MySVNDiffStatusHandler.list.clear(); - String nowSvnUrl = super.versionControlDto.getRepoUrl(); - if(StringUtils.isNotBlank(super.versionControlDto.getSvnRepoUrl())){ - nowSvnUrl = super.versionControlDto.getSvnRepoUrl(); - } - SVNRevision oldVersion = null; - SVNRevision newVersion = null; - //不同reversion的比较和最新reversion的比较 - if (StringUtils.isNotBlank(super.versionControlDto.getNowVersion()) && StringUtils.isNotBlank(super.versionControlDto.getBaseVersion())) { - oldVersion = SVNRevision.create(Long.parseLong(super.versionControlDto.getBaseVersion())); - newVersion = SVNRevision.create(Long.parseLong(super.versionControlDto.getNowVersion())); - } else { - oldVersion = SVNRevision.HEAD; - newVersion = SVNRevision.HEAD; - } - String localBaseRepoDir = SvnRepoUtil.getSvnLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getSvnLocalBaseRepoDir(), oldVersion.toString()); - String localNowRepoDir = SvnRepoUtil.getSvnLocalDir(nowSvnUrl, customizeConfig.getSvnLocalBaseRepoDir(), newVersion.toString()); - LoggerUtil.info(log,"旧版本本地地址",localBaseRepoDir); - LoggerUtil.info(log,"新版本本地地址",localNowRepoDir); - super.versionControlDto.setNewLocalBasePath(localNowRepoDir); - super.versionControlDto.setOldLocalBasePath(localBaseRepoDir); - SvnRepoUtil.cloneRepository(super.versionControlDto.getRepoUrl(), localBaseRepoDir, oldVersion, customizeConfig.getSvnUserName(), customizeConfig.getSvnPassWord()); - SvnRepoUtil.cloneRepository(nowSvnUrl, localNowRepoDir, newVersion, customizeConfig.getSvnUserName(), customizeConfig.getSvnPassWord()); - SVNDiffClient svnDiffClient = SvnRepoUtil.getSvnDiffClient(customizeConfig.getSvnUserName(), customizeConfig.getSvnPassWord()); - svnDiffClient.doDiffStatus(SVNURL.parseURIEncoded(super.versionControlDto.getRepoUrl()), oldVersion, SVNURL.parseURIEncoded(nowSvnUrl), newVersion, SVNDepth.INFINITY, true, new MySVNDiffStatusHandler(customizeConfig.getRootCodePath())); - //将差异代码设置进集合 - super.versionControlDto.setDiffClasses(MySVNDiffStatusHandler.list); - } catch (SVNException e) { - e.printStackTrace(); - } - } - - - /** - * @param filePackage - * @date:2021/4/24 - * @className:VersionControl - * @author:Administrator - * @description: 获取旧版本文件本地路径 - */ - @Override - public String getLocalNewPath(String filePackage) { - return PathUtils.getClassFilePath(super.versionControlDto.getNewLocalBasePath(), filePackage); - } - - /** - * @param filePackage - * @date:2021/4/24 - * @className:VersionControl - * @author:Administrator - * @description: 获取新版本文件本地路径 - */ - @Override - public String getLocalOldPath(String filePackage) { - String localDir = SvnRepoUtil.getSvnLocalDir(super.versionControlDto.getRepoUrl(), customizeConfig.getSvnLocalBaseRepoDir(), ""); - return PathUtils.getClassFilePath(super.versionControlDto.getOldLocalBasePath(), filePackage); - } - - /** - * 下载代码 - * - * @param methodInvokeDto 方法调用dto - * @return {@link String} - */ - @Override - public String downloadCode(MethodInvokeDto methodInvokeDto) { - SVNRevision oldVersion = SVNRevision.create(Long.parseLong(methodInvokeDto.getBranchName())); - String localBaseRepoDir = SvnRepoUtil.getSvnLocalDir(methodInvokeDto.getRepoUrl(), customizeConfig.getSvnLocalBaseRepoDir(), oldVersion.toString()); - SvnRepoUtil.cloneRepository(methodInvokeDto.getRepoUrl(), localBaseRepoDir, oldVersion, customizeConfig.getSvnUserName(), customizeConfig.getSvnPassWord()); - return localBaseRepoDir; - } -} diff --git a/src/main/java/com/dr/code/diff/vo/param/RemoteJacocoServerParamVO.java b/src/main/java/com/dr/code/diff/vo/param/RemoteJacocoServerParamVO.java deleted file mode 100644 index 86476fb..0000000 --- a/src/main/java/com/dr/code/diff/vo/param/RemoteJacocoServerParamVO.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.dr.code.diff.vo.param; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.analyze.bean - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2023/4/16 16:38 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2023 - */ - -@Data -@ApiModel -public class RemoteJacocoServerParamVO { - - /** - * 主机 - */ - @ApiModelProperty( value = "jacoco agent服务地址", example = "127.0.0.1") - private String host; - - - /** - * 端口 - */ - @ApiModelProperty( value = "jacoco agent服务端口", example = "6300") - private Integer port; - - - /** - * exec文件名称 - */ - @ApiModelProperty( value = "生成exec文件的名称", example = "code-diff.exec") - private String execFileName; - - -} diff --git a/src/main/java/com/dr/code/diff/vo/param/ReportJacocoParamVO.java b/src/main/java/com/dr/code/diff/vo/param/ReportJacocoParamVO.java deleted file mode 100644 index 4048f57..0000000 --- a/src/main/java/com/dr/code/diff/vo/param/ReportJacocoParamVO.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.dr.code.diff.vo.param; - -import io.swagger.annotations.ApiModel; -import lombok.Data; - -import java.util.List; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.jacoco.bean - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2023/4/16 17:08 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2023 - */ -@Data -@ApiModel -public class ReportJacocoParamVO { - - /** - * 类目录 - */ - private List classesDirectory; - /** - * 源码目录 - */ - private List sourceDirectory; - /** - * exec文件目录 - * 0 - */ - private List executionDataFile; - - - /** - * 排除类目录 - */ - private String excludedClassesDirectory; - - /** - * 0 - * 报告生成目录 - */ - private String reportDirectory; - - - /** - * diff代码文件 - */ - private String diffCodeFile; - - - /** - * 报告名称 - */ - private String reportName; - -} diff --git a/src/main/java/com/dr/code/diff/vo/result/ApiMethodModifyVO.java b/src/main/java/com/dr/code/diff/vo/result/ApiMethodModifyVO.java deleted file mode 100644 index 225d9f6..0000000 --- a/src/main/java/com/dr/code/diff/vo/result/ApiMethodModifyVO.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.dr.code.diff.vo.result; - -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -/** - * @Package: com.dr.code.diff.dto - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/2/27 21:17 - * @Version: 1.0 - *

- */ - -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class ApiMethodModifyVO { - - - /** - * 方法签名,com/dr/code/diff/controller/CodeDiffController#getSvnList#String, String, String - */ - @ApiModelProperty(value = "方法签名,com/dr/code/diff/controller/CodeDiffController#getSvnList#String, String, String") - private String methodSign; - - /** - * 类名 - */ - @ApiModelProperty(value = "类名") - private String className; - - - /** - * 方法名称 - */ - @ApiModelProperty(value = "方法名称") - private String methodName; - - - /** - * 方法参数 - */ - @ApiModelProperty(value = "方法参数") - private List methodParams; - - -} diff --git a/src/main/java/com/dr/code/diff/vo/result/ChangeLineVO.java b/src/main/java/com/dr/code/diff/vo/result/ChangeLineVO.java deleted file mode 100644 index 3a2f095..0000000 --- a/src/main/java/com/dr/code/diff/vo/result/ChangeLineVO.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.dr.code.diff.vo.result; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -/** - * @ProjectName: code-diff-parent - * @Package: com.dr.code.diff.vo.result - * @Description: java类作用描述 - * @Author: duanrui - * @CreateDate: 2021/6/24 21:32 - * @Version: 1.0 - *

- * Copyright: Copyright (c) 2021 - */ -@Data -@ApiModel("差异代码变更行") -public class ChangeLineVO { - /** - * 变更类型 - */ - @ApiModelProperty(name = "type", value = "变更类型,如insert,replace", dataType = "String") - private String type; - - @ApiModelProperty(name = "startLineNum", value = "变更开始行号") - private Integer startLineNum; - - @ApiModelProperty(name = "endLineNum", value = "变更结束行号") - private Integer endLineNum; -} diff --git a/src/main/java/com/dr/code/diff/vo/result/ClassInfoVO.java b/src/main/java/com/dr/code/diff/vo/result/ClassInfoVO.java deleted file mode 100644 index 9fae209..0000000 --- a/src/main/java/com/dr/code/diff/vo/result/ClassInfoVO.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.dr.code.diff.vo.result; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -/** - * @Package: com.dr.code.diff.analyze.bean - * @Description: 类信息 - * @Author: rayduan - * @CreateDate: 2023/2/23 20:26 - * @Version: 1.0 - *

- */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ClassInfoVO { - - /** - * 类名 - */ - @ApiModelProperty(value = "类名") - private String className; - - - /** - * 超类名字 - */ - @ApiModelProperty(value = "超类名字") - private String superClassName; - - - /** - * 接口类名 - */ - @ApiModelProperty(value = "接口类名") - private List interfacesClassNames; - - - /** - * 抽象标志 - */ - @ApiModelProperty(value = "抽象标志") - private Boolean abstractFlag = Boolean.FALSE; - - /** - * 接口标志 - */ - @ApiModelProperty(value = "接口标志") - private Boolean interfaceFlag = Boolean.FALSE; - - - /** - * 控制器标志 - */ - @ApiModelProperty(value = "控制器标志") - private Boolean controllerFlag = Boolean.FALSE; - - - /** - * feign标识 - */ - @ApiModelProperty(value = "feign标识") - private Boolean feignFlag = Boolean.FALSE; - /** - * dubbo标志 - */ - @ApiModelProperty(value = "dubbo标志") - private Boolean dubboFlag = Boolean.FALSE; - - /** - * 请求url - */ - @ApiModelProperty(value = "请求url") - private String requestUrl; - -} diff --git a/src/main/java/com/dr/code/diff/vo/result/DeduceApiVO.java b/src/main/java/com/dr/code/diff/vo/result/DeduceApiVO.java deleted file mode 100644 index 93f14dd..0000000 --- a/src/main/java/com/dr/code/diff/vo/result/DeduceApiVO.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.dr.code.diff.vo.result; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.Set; - -/** - * @date:2021/1/9 - * @className:CodeDiffResultVO - * @author:Administrator - * @description: 差异代码结果集 - */ -@Data -public class DeduceApiVO { - - - - /** - * http api修改 - */ - @ApiModelProperty(value = "影响的http接口") - private Set httpApiModifies; - - /** - * dubbo api修改 - */ - @ApiModelProperty(value = "影响的dubbo接口") - private Set dubboApiModifies; - - - @ApiModelProperty(value = "影响的自定义类") - private Set customClassModifies; - - - - @ApiModelProperty(value = "影响的自定义方法") - private Set customMethodSignModifies; -} diff --git a/src/main/java/com/dr/code/diff/vo/result/HttpApiModifyVO.java b/src/main/java/com/dr/code/diff/vo/result/HttpApiModifyVO.java deleted file mode 100644 index 15fb18d..0000000 --- a/src/main/java/com/dr/code/diff/vo/result/HttpApiModifyVO.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.dr.code.diff.vo.result; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * @Package: com.dr.code.diff.dto - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/2/27 21:15 - * @Version: 1.0 - *

- */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class HttpApiModifyVO { - - - /** - * 方法签名,com/dr/code/diff/controller/CodeDiffController#getSvnList#String, String, String - */ - @ApiModelProperty(value = "方法签名,com/dr/code/diff/controller/CodeDiffController#getSvnList#String, String, String") - private String methodSign; - - - /** - * url映射,如/api/res/1 - */ - @ApiModelProperty(value = "url映射,如/api/res/1") - private String mappingUrl; - - - - /** - * 映射方法,如get,put - */ - @ApiModelProperty(value = "映射方法,如get,put") - private RequestMethod mappingMethod; - - -} diff --git a/src/main/java/com/dr/code/diff/vo/result/MethodInfoVO.java b/src/main/java/com/dr/code/diff/vo/result/MethodInfoVO.java deleted file mode 100644 index a0a26c5..0000000 --- a/src/main/java/com/dr/code/diff/vo/result/MethodInfoVO.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.dr.code.diff.vo.result; - -import com.dr.code.diff.enums.MethodNodeTypeEnum; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.springframework.web.bind.annotation.RequestMethod; - -import java.util.List; - -/** - * @Package: com.dr.code.diff.dto - * @Description: 方法信息 - * @Author: rayduan - * @CreateDate: 2023/2/20 16:39 - * @Version: 1.0 - *

- */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class MethodInfoVO { - - /** - * 类信息 - */ - @ApiModelProperty(value = "类信息") - private ClassInfoVO classInfo; - - - /** - * 抽象标志 - */ - @ApiModelProperty(value = "抽象标志") - private Boolean abstractFlag; - - - /** - * 方法名称 - */ - @ApiModelProperty(value = "方法名称") - private String methodName; - - - /** - * 方法参数 - */ - @ApiModelProperty(value = "方法参数") - private List methodParams; - - - /** - * 方法签名,com/dr/code/diff/controller/CodeDiffController#getSvnList#String, String, String - */ - @ApiModelProperty(value = "方法签名,com/dr/code/diff/controller/CodeDiffController#getSvnList#String, String, String") - private String methodSign; - - - /** - * url映射,如/api/res/1 - */ - @ApiModelProperty(value = "url映射,如/api/res/1") - private String mappingUrl; - - - /** - * 映射方法,如get,put - */ - @ApiModelProperty(value = "映射方法,如get,put") - private RequestMethod mappingMethod; - - - /** - * 方法节点类型枚举 - */ - @ApiModelProperty(value = "方法节点类型枚举") - private MethodNodeTypeEnum methodNodeTypeEnum; - /** - * 调用的方法 - */ - @ApiModelProperty(value = "调用的方法") - private List callerMethods; -} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml deleted file mode 100644 index 45a4cbd..0000000 --- a/src/main/resources/application-dev.yml +++ /dev/null @@ -1,36 +0,0 @@ -git: - userName: ray1 - password: 12345456 - local: - base: - dir: /Users/test/app/git-test - ssh: - priKey: C:\Users\mylocl/.ssh/id_rsa. -svn: - userName: admin - password: 123456 - local: - base: - dir: D:\svn-test -maven: - home: /Users/rayduan/app/apache-maven-3.8.3 -#代码的根目录,非标准maven项目需要自定义 -root: - code: - path: src/main/java/ -jacoco: - root: - path: /Users/rayduan/jacoco/root/ -custom: - link: - start: - classNameList: -# - com/dr/common/utils/mapper/OrikaMapperUtils - methodSignList: -# - com/dr/code/diff/service/CodeDiffService#getDiffCode#DiffMethodParams -# - com/dr/code/diff/analyze/bean/ClassInfo#getSuperClassName# - type: 2 #此处表示调用链排除jdk本身方法 - dubbo: - xml: - path: "" - diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml deleted file mode 100644 index 88fa7cf..0000000 --- a/src/main/resources/application.yml +++ /dev/null @@ -1,60 +0,0 @@ -spring: - profiles: - #激活开发环境 - active: dev - messages: - basename: i18n/Messages,i18n/Pages - # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 - - main: - allow-bean-definition-overriding: true - jackson: - date-format: yyyy-MM-dd HH:mm:ss - time-zone: GMT+8 -logging: - config: classpath:log4j2.yml -springfox: - documentation: - enabled: true -swagger: - base-package: com.dr.code.diff.controller - authorization: - type: None - -git: - userName: ray1 #git用户名 - password: 12345456 #git密码,这里可以配置token - local: - base: - dir: D:\git-test - ssh: - priKey: C:\Users\mylocl/.ssh/id_rsa. #私钥路径,如果公司内部使用私钥管理,可以使用这种方式,拉取代码时自动判定是http开头还是ssh开头采用不同的方式拉取 -svn: - userName: admin - password: 123456 - local: - base: - dir: D:\svn-test -maven: - home: E:/Program Files/apache-maven-3.6.3 #maven的安装目录,此配置主要用于代码编译,用于静态代码分析功能,如果只差异分析,可以不配置 -root: - code: - path: src/main/java/ #代码的根目录,非标准maven项目需要自定义 -jacoco: - root: - path: H:/jacoco/root/ #jacoco报告的根目录 -custom: - link: - start: - classNameList: - - com/dr/common/utils/mapper/OrikaMapperUtils - methodSignList: - - com/dr/code/diff/service/CodeDiffService#getDiffCode#DiffMethodParams - - com/dr/code/diff/analyze/bean/ClassInfo#getSuperClassName# -server: - port: 8085 - servlet: - session: - timeout: 3600 - - diff --git a/src/main/resources/bootstrap.yml b/src/main/resources/bootstrap.yml deleted file mode 100644 index d37ffb2..0000000 --- a/src/main/resources/bootstrap.yml +++ /dev/null @@ -1,15 +0,0 @@ -server: - port: 8081 -log: - path: /Users/rayduan/logs -management: - endpoint: - shutdown: - enabled: true # 启用shutdown功能 - health: - show-details: always - endpoints: - web: - # base-path: ''/ - exposure: - include: "*" \ No newline at end of file diff --git a/src/test/java/com/dr/code/diff/analyze/DeduceApiServiceTest.java b/src/test/java/com/dr/code/diff/analyze/DeduceApiServiceTest.java deleted file mode 100644 index 75ce5a5..0000000 --- a/src/test/java/com/dr/code/diff/analyze/DeduceApiServiceTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.dr.code.diff.analyze; - -import com.alibaba.fastjson.JSON; -import com.dr.code.diff.CodeDiffApplicationTest; -import com.dr.code.diff.dto.ApiModify; -import com.dr.code.diff.dto.DiffMethodParams; -import com.dr.code.diff.enums.CodeManageTypeEnum; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * @Package: com.dr.code.diff.analyze - * @Description: 接口推导测试类 - * @Author: rayduan - * @CreateDate: 2023/2/27 21:37 - * @Version: 1.0 - *

- */ -class DeduceApiServiceTest extends CodeDiffApplicationTest { - - @Autowired - private DeduceApiService deduceApiService; - - @Test - void deduceApi() { - DiffMethodParams diffMethodParams = DiffMethodParams.builder() - .repoUrl("https://gitee.com/Dray/code-diff.git") - .baseVersion("3b097f2e86fce46066189c740a0157d052682851") - .nowVersion("5eca0308727bded21576c8756e9f93b53fd03109") - .codeManageTypeEnum(CodeManageTypeEnum.GIT) - .build(); - ApiModify apiModify = deduceApiService.deduceApi(diffMethodParams); - System.out.println("变更的接口:"+ JSON.toJSONString(apiModify)); - } -} \ No newline at end of file diff --git a/src/test/java/com/dr/code/diff/analyze/InvokeLinkBuildServiceTest.java b/src/test/java/com/dr/code/diff/analyze/InvokeLinkBuildServiceTest.java deleted file mode 100644 index cf34a3f..0000000 --- a/src/test/java/com/dr/code/diff/analyze/InvokeLinkBuildServiceTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.dr.code.diff.analyze; - -import com.alibaba.fastjson.JSON; -import com.dr.code.diff.CodeDiffApplicationTest; -import com.dr.code.diff.analyze.bean.MethodInfo; -import com.dr.code.diff.enums.MethodNodeTypeEnum; -import com.google.common.collect.Lists; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * @Package: com.dr.code.diff.analyze - * @Description: 获取全量调用链测试类 - * @Author: rayduan - * @CreateDate: 2023/2/24 17:13 - * @Version: 1.0 - *

- */ -class InvokeLinkBuildServiceTest extends CodeDiffApplicationTest { - @Autowired - private InvokeLinkBuildService invokeLinkBuildService; - - @Test - void getMethodsInvokeLink() { - List dirs = new ArrayList(); - dirs.add("D:\\IdeaProjects\\code-diff\\application"); - List excludeFiles = null; - Map> methodsInvokeLink = invokeLinkBuildService.getMethodsInvokeLink(dirs, excludeFiles); - System.out.println(JSON.toJSON(methodsInvokeLink)); - } - - - @Test - void getMethodsInvokeLink2() { - List dirs = new ArrayList(); - dirs.add("/Users/rayduan/app/code-diff/master"); - List excludeFiles = null; - Map> methodsInvokeLink = invokeLinkBuildService.getMethodsInvokeLink(dirs, excludeFiles); - System.out.println(JSON.toJSON(methodsInvokeLink)); - } - - -} \ No newline at end of file diff --git a/src/test/java/com/dr/code/diff/analyze/MavenCmdInvokeServiceTest.java b/src/test/java/com/dr/code/diff/analyze/MavenCmdInvokeServiceTest.java deleted file mode 100644 index d39ab1a..0000000 --- a/src/test/java/com/dr/code/diff/analyze/MavenCmdInvokeServiceTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.dr.code.diff.analyze; - -import com.dr.code.diff.CodeDiffApplicationTest; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * @Package: com.dr.code.diff.analyze - * @Description: maven编译类测试类 - * @Author: rayduan - * @CreateDate: 2023/2/27 21:01 - * @Version: 1.0 - *

- */ -class MavenCmdInvokeServiceTest extends CodeDiffApplicationTest { - - @Autowired - private MavenCmdInvokeService mavenCmdInvoke; - - @Test - void operationMavenCmd() { - mavenCmdInvoke.operationMavenCmd("/Users/xx/app/code-diff/5eca0308727bded21576c8756e9f93b53fd03109","clean install -Dmaven.test.skip=true"); - } - @Test - void compileCode() { - mavenCmdInvoke.compileCode("/Users/rayduan/app/code-diff/5eca0308727bded21576c8756e9f93b53fd03109"); - } -} \ No newline at end of file diff --git a/src/test/java/com/dr/code/diff/analyze/link/CallChainClassVisitorTest.java b/src/test/java/com/dr/code/diff/analyze/link/CallChainClassVisitorTest.java deleted file mode 100644 index ed3e9fc..0000000 --- a/src/test/java/com/dr/code/diff/analyze/link/CallChainClassVisitorTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.dr.code.diff.analyze.link; - -import com.dr.code.diff.CodeDiffApplicationTest; -import com.dr.code.diff.analyze.bean.MethodInfo; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassWriter; -import org.junit.jupiter.api.Test; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; - -/** - * @Package: com.dr.code.diff.analyze.link - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/2/24 14:53 - * @Version: 1.0 - *

- */ -class CallChainClassVisitorTest extends CodeDiffApplicationTest { - - @Test - void visitMethod() throws IOException { - String sourceFilePath = "/Users/rayduan/IdeaProjects/code-diff/application/target/classes/com/dr/code/diff/analyze/InvokeLinkBuildService.class"; - File fileReader = new File(sourceFilePath); - ClassReader cr = new ClassReader(Files.newInputStream(fileReader.toPath())); - List list = new ArrayList<>(); - ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - CallChainClassVisitor cv = new CallChainClassVisitor(cw, list, null); - cr.accept(cv, ClassReader.SKIP_FRAMES); - System.out.println(list); - } - - @Test - void visitMethod2() throws IOException { - String sourceFilePath = "/Users/rayduan/IdeaProjects/code-diff/application/target/classes/com/dr/code/diff/util/MethodParserUtils.class"; - File fileReader = new File(sourceFilePath); - ClassReader cr = new ClassReader(Files.newInputStream(fileReader.toPath())); - List list = new ArrayList<>(); - ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - CallChainClassVisitor cv = new CallChainClassVisitor(cw, list, null); - cr.accept(cv, ClassReader.SKIP_FRAMES); - System.out.println(list); - } - - @Test - void visitMethod3() throws IOException { - String sourceFilePath = "/Users/rayduan/IdeaProjects/relation-demo/target/classes/com/dr/test/MyClass.class"; - File fileReader = new File(sourceFilePath); - ClassReader cr = new ClassReader(Files.newInputStream(fileReader.toPath())); - List list = new ArrayList<>(); - ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - CallChainClassVisitor cv = new CallChainClassVisitor(cw, list, null); - cr.accept(cv, ClassReader.SKIP_FRAMES); - System.out.println(list); - } - -} \ No newline at end of file diff --git a/src/test/java/com/dr/code/diff/util/XmlDiffUtilsTest.java b/src/test/java/com/dr/code/diff/util/XmlDiffUtilsTest.java deleted file mode 100644 index 5173631..0000000 --- a/src/test/java/com/dr/code/diff/util/XmlDiffUtilsTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.dr.code.diff.util; - -import com.dr.code.diff.CodeDiffApplicationTest; -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.HashSet; - -/** - * @Package: com.dr.code.diff.util - * @Description: java类作用描述 - * @Author: rayduan - * @CreateDate: 2023/3/1 15:48 - * @Version: 1.0 - *

- */ -class XmlDiffUtilsTest extends CodeDiffApplicationTest { - - @Test - void getXmlDiff() { - XmlDiffUtils.getXmlDiffMethod("/Users/rayduan/app/cmdb/b20bb96a8ca5be1955f9427ccc1aac521d6cb955/cmdb-core/src/main/resources/com/dr/cmdb/core/mapper/TablesModelMapper.xml","/Users/rayduan/app/cmdb/baacfdb9976fe9462096cda0dd1641d4c91158a9/cmdb-core/src/main/resources/com/dr/cmdb/core/mapper/TablesModelMapper.xml",new HashSet<>()); - } -} \ No newline at end of file