还在人工代码review?reviewdog和PMD了解一下

news2024/9/21 18:42:01

前言

代码reivew作为团队协同开发时确保代码质量的手段之一,在软件开发团队中非常常见。特别是对于刚入门不久的团队成员,通过代码review也可一定程度上避免一些低级错误,提升整个部分的代码健壮性。

一般来讲,通过代码review可发现的问题主要有以下几类:

  1. 代码规范,如常量名应使用大写驼峰命名、一个方法代码量不超过300行、static变量应该使用final修饰……
  2. 代码漏洞,如代码空指针、方法加锁后未主动释放锁、多线程下使用了线程不安全的集合……
  3. 业务代码缺陷,如用户登录成功后应提示“登录成功”实际代码为“登录失败”、解析VRRP协议号时应为112代码写成了113、端口9200应识别为elasticsearch的默认端口识别成了mysql的默认端口……

对于上述中的代码规范问题代码基础漏洞这类问题一般与业务无法,可由代码分析工具识别出来(一种可选的实现方案可使用antlr进行抽象语法树解析,此部分可参考笔者以前的文章:《使用antlr快速解析SQL》)。
诸如checkstyle、PMD、阿里巴巴规范p3c、findbugs、spotbugs这些常见的工具都是对这一类问题的实际运用。

而对于业务代码缺陷这类的问题,则往往需要对编码的具体业务有一定了解,此类问题的识别则需要具体的业务专家或业务测试用例来判别,如由共同开发同一模块的其他同学(结对编程)进行代码交叉review,或使用预定的业务单元测试进行用例覆盖等。

本文将介绍一种代码merge request提交后自动进行代码review的方案。通过既定的规则扫描,实现对增量代码的代码自动review与评论,为项目中的代码review提个速。

reviewdog介绍

reviewdog
如reviewdog的github(https://github.com/reviewdog/reviewdog)描述所述,reviewdog是一个由go语言开发的开源项目,它可实现对代码托管平台(如github、gitlab)项目中的代码进行自动提交评论,可与各种linter工具搭配使用,如golint、PMD、checkstyle等。
reviewdog-demo
详细描述与官方示例可移步reviewdog管网查看,此处不再赘述。

reviewdog-desc

对于历史项目,reviewdog支持增量检测,即:仅对某一个MR提交的增量部分进行评论。

以gitlab项目为例,它的一般工作流程大致为:

  1. gitlab提交一个MR
  2. MR通过gitlab CICD触发Lint tool进行代码静态分析
  3. reviewdog读取步骤2静态分析的结果并进行解析,并使用git diff获取出当前MR增量的代码
  4. 对静态分析结果与MR增量代码求交集,得到需要评论的代码,调用gitlab的api接口对代码提交评论

安装与运行

reviewdog的安装仅一个可执行文件,可在reviewdog的github中找到对应版本的release包。https://github.com/reviewdog/reviewdog/releases

以linux的x86系统、reviewdog0.20.1版本为例,在release中安装对应reviewdog文件为:reviewdog_0.20.1_Linux_x86_64.tar.gz

在linux中下载并授权:

#下载指定版本的reviewdog
wget https://github.com/reviewdog/reviewdog/releases/download/v0.20.1/reviewdog_0.20.1_Linux_x86_64.tar.gz
#解压
tar -zxvf reviewdog_0.20.1_Linux_x86_64.tar.gz
#拷贝到/usr/bin目录下
cp ./reviewdog /usr/bin/

验证一下:

reviewdog -version
reviewdog-version

再查看下支持的lint格式

reviewdog -list

root@ubuntu:~# reviewdog -list
rdjson		Reviewdog Diagnostic JSON Format (JSON of DiagnosticResult message)						- https://github.com/reviewdog/reviewdog
rdjsonl		Reviewdog Diagnostic JSONL Format (JSONL of Diagnostic message)							- https://github.com/reviewdog/reviewdog
diff		Unified Diff Format												- https://en.wikipedia.org/wiki/Diff#Unified_format
checkstyle	checkstyle XML format												- http://checkstyle.sourceforge.net/
sarif		SARIF JSON format												- https://sarifweb.azurewebsites.net/
ansible-lint	(ansible-lint -p playbook.yml) Checks playbooks for practices and behaviour that could potentially be improved	- https://github.com/ansible/ansible-lint
bandit		A tool designed to find common security issues in Python code.							- https://github.com/PyCQA/bandit.git
black		A uncompromising Python code formatter										- https://github.com/psf/black
brakeman	(brakeman --quiet --format tabs) A static analysis security vulnerability scanner for Ruby on Rails applications- https://github.com/presidentbeef/brakeman
buf		A new way of working with Protocol Buffers.									- https://github.com/bufbuild/buf
cargo-check	(cargo check -q --message-format=short) Check a local package and all of its dependencies for errors		- https://github.com/rust-lang/cargo
clippy		(cargo clippy -q --message-format=short) A bunch of lints to catch common mistakes and improve your Rust code	- https://github.com/rust-lang/rust-clippy
dotenv-linter	Lightning-fast linter for .env files. Written in Rust								- https://github.com/dotenv-linter/dotenv-linter
dotnet		(dotnet build -clp:NoSummary -p:GenerateFullPaths=true --no-incremental --nologo -v q) .NET Core CLI		- https://docs.microsoft.com/en-us/dotnet/core/tools/
erb-lint	(erblint --format compact) Lint your ERB or HTML files								- https://github.com/Shopify/erb-lint
eslint		(eslint [-f stylish]) A fully pluggable tool for identifying and reporting on patterns in JavaScript		- https://github.com/eslint/eslint
eslint-compact	(eslint -f compact) A fully pluggable tool for identifying and reporting on patterns in JavaScript		- https://github.com/eslint/eslint
fasterer	Speed improvements suggester											- https://github.com/DamirSvrtan/fasterer
flake8		Tool for python style guide enforcement										- https://flake8.pycqa.org/
go-consistent	Source code analyzer that helps you to make your Go programs more consistent					- https://github.com/quasilyte/go-consistent
golangci-lint	(golangci-lint run --out-format=line-number) GolangCI-Lint is a linters aggregator.				- https://github.com/golangci/golangci-lint
golint		linter for Go source code											- https://github.com/golang/lint
gosec		(gosec -fmt=golint) Golang Security Checker									- https://github.com/securego/gosec
govet		Vet examines Go source code and reports suspicious problems							- https://golang.org/cmd/vet/
haml-lint	Tool for writing clean and consistent HAML									- https://github.com/sds/haml-lint
hlint		Linter for Haskell source code											- https://github.com/ndmitchell/hlint
isort		A Python utility / library to sort Python imports								- https://github.com/PyCQA/isort
luacheck	(luacheck --formatter=plain) Lua linter and static analyzer							- https://github.com/luarocks/luacheck
misspell	Correct commonly misspelled English words in source files							- https://github.com/client9/misspell
msbuild		(msbuild /property:GenerateFullPaths=true /nologo /v:q) Microsoft Build Engine					- https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild
mypy		An optional static type checker for Python									- http://mypy-lang.org/
pep8		Python style guide checker											- https://pypi.python.org/pypi/pep8
phpstan		(phpstan --error-format=raw) PHP Static Analysis Tool - discover bugs in your code without running it!		- https://github.com/phpstan/phpstan
protolint	A pluggable linting utility for Protocol Buffer files								- https://github.com/yoheimuta/protolint
psalm		(psalm --output-format=text) Psalm is a static analysis tool for finding errors in PHP				- https://github.com/vimeo/psalm
puppet-lint	Check that your Puppet manifests conform to the style guide							- https://github.com/rodjek/puppet-lint
pydocstyle	A static analysis tool for checking compliance with Python docstring conventions				- https://github.com/PyCQA/pydocstyle
reek		(reek --single-line) Code smell detector for Ruby								- https://github.com/troessner/reek
remark-lint	Tool for writing clean and consistent markdown code								- https://github.com/remarkjs/remark-lint
rubocop		A Ruby static code analyzer, based on the community Ruby style guide						- https://github.com/rubocop-hq/rubocop
sbt		the interactive build tool											- http://www.scala-sbt.org/
sbt-scalastyle	Scalastyle - SBT plugin												- http://www.scalastyle.org/sbt.html
scalac		Scala compiler													- http://www.scala-lang.org/
scalastyle	Scalastyle - Command line											- http://www.scalastyle.org/command-line.html
slim-lint	Tool to help keep your Slim files clean and readable								- https://github.com/sds/slim-lint
sorbet		A fast, powerful type checker designed for Ruby									- https://github.com/sorbet/sorbet
standardjs	(standard) JavaScript style guide, linter, and formatter							- https://github.com/standard/standard
standardrb	(standard) Ruby style guide, linter, and formatter								- https://github.com/testdouble/standard
staticcheck	Golang Static Analysis												- https://staticcheck.io
stylelint	A mighty modern CSS linter											- https://github.com/stylelint/stylelint
tsc		TypeScript compiler												- https://www.typescriptlang.org/
tslint		An extensible linter for the TypeScript language								- https://github.com/palantir/tslint
typos		Source code spell checker											- https://github.com/crate-ci/typos
yamllint	(yamllint -f parsable) A linter for YAML files									- https://github.com/adrienverge/yamllint
root@ubuntu:~# 

SARIF介绍

目前reviewdog实际使用时与go项目整合的案例较多,go项目与reviewdog交互时使用的是golint格式。
在java方面使用reviewdog与java语言整合的案例资料较少,经过笔者的实践验证reviewdog和java项目整合也是可行的。需要用到的一个技术为PMD与reviewdog都支持的一种消息格式:SARIF。

SARIF的全称为:Static Analysis Results Interchange Format,即:静态分析结果交换格式。它是由结构化信息标准促进组织——OASIS(Organization for the Advancement of Structured Information Standards)提出的一种标准格式。

OASIS的官网为:https://www.oasis-open.org/

OASIS组织的成员也在每年持续增加中,部分成员截图如下:
SARIF

关于SARIF的快速介绍可查看此文:《DevSecOps工具与平台交互的桥梁 – SARIF入门》

PMD介绍与安装

pmd,An extensible cross-language static code analyzer.
它是一个开源与编程语言无关的可扩展静态代码分析器。如在JAVA界比流行的阿里巴巴规范插件的实现也是基于PMD进行扩展开发的。
PMD
更多PMD的详细介绍与快速入门可移步它的介绍官网:https://pmd.github.io

本例为了演示,直接使用PMD的java-quickstart规则文件,地址为:https://github.com/pmd/pmd/blob/master/pmd-java/src/main/resources/rulesets/java/quickstart.xml

安装pmd也比较简单,它的发行包可直接在pmd的github中找到:
https://github.com/pmd/pmd/releases

以下载7.4.0版本为例,命令为:

wget https://github.com/pmd/pmd/releases/download/pmd_releases%2F7.4.0/pmd-dist-7.4.0-bin.zip
unzip pmd-dist-7.4.0-bin.zip

得到pmd的运行路径:/usr/local/pmd-bin-7.4.0/bin/pmd

pmd验证:

/usr/local/pmd-bin-7.4.0/bin/pmd -V
PMD-version

注意:pmd的运行依赖于java运行环境。jre安装命令示例:

apt install openjdk-17-jre-headless

gitlab与gitlab runner安装

在进行PMD和reviewdog联合演示前需要确保代码托管平台中的cicd插件已准备就绪。
这里以gitlab为例,对应的cicd插件则为gitlab runner。

如快速体验,gitlab可用docker快速启一个。示例:

docker run --name gitlab -p 9980:80 -p 9443:443 -p 9922:22 \
  --hostname 192.168.68.89 \
  --shm-size 2g\
  -v /gitlab/etc/gitlab:/etc/gitlab \
  -v /gitlab/var/log/gitlab:/var/log/gitlab \
  -v /gitlab/var/opt/gitlab:/var/opt/gitlab \
  -dit gitlab/gitlab-ce:latest

其中hostname填写为docker物理机的实际ip地址。

gitlab的默认密码可在映射的目录查看:

cat /gitlab/etc/gitlab/initial_root_password
GITLAB-PWD

然后登录gitlab,创建项目并为项目设置gitlab-runner。
gitlab-runner

然后根据示例安装好gitlab runner即可。
install-runner

注册时填入的url为gitlab-server对应的ip和端口,token为此对应项目的token

sudo gitlab-runner register --url http://192.168.68.89:9980/ --registration-token GR13489414XKCJ3HPCuoz569yHC4v
register-runner

需要注意的是gitlab-runner中的executor需要根据实际情况来填写,本例中为了演示方便使用的是shell,即在当前节点中运行runner

Enter an executor: shell, ssh, parallels, instance, custom, virtualbox, docker, docker-windows, docker+machine, kubernetes, docker-autoscaler:
shell

可使用gitlab-runner list命令验证是否注册成功

root@ubuntu:~# gitlab-runner list
Runtime platform                                    arch=amd64 os=linux pid=11348 revision=9882d9c7 version=17.2.1
Listing configured runners                          ConfigFile=/etc/gitlab-runner/config.toml
my-runner                                           Executor=shell Token=AU9QpietjBf6_zfx6t9Y URL=http://192.168.68.89:9980/

另外在gitlab的web界面中也可看到:
runner-list

编写cicd脚本

在java项目源码根目录创建.gitlab-ci.yml文件,在内容如下:

variables:
  API_TOKEN: "glpat-CW77u3pMBdxnsnGLgwpp"
review-lint:
  script:
    - env
    - export REVIEWDOG_GITLAB_API_TOKEN=$API_TOKEN
    - export GITLAB_API=$CI_API_V4_URL
    - export CI_REPO_OWNER=$CI_PROJECT_NAMESPACE
    - export CI_REPO_NAME=$CI_PROJECT_NAME
    - export REVIEWDOG_INSECURE_SKIP_VERIFY=true
    - check_dirs=$(find ./ -type d -path '*/src/main/java')
    - /usr/local/pmd-bin-7.4.0/bin/pmd -V
    - /usr/local/pmd-bin-7.4.0/bin/pmd check -f sarif -R pmd/quickstart.xml -d $check_dirs --ignore-list pmd/ignore.txt > lint-report.out || true
    - reviewdog -f sarif -diff="git diff HEAD~ HEAD" -reporter=gitlab-mr-discussion -tee < lint-report.out
  only:
    # 当前job只在执行MR提交时才执行
    - merge_requests

脚本中使用到的内置变量可参考gitlab文档:https://docs.gitlab.com/ee/ci/variables/predefined_variables.html

脚本中的REVIEWDOG_GITLAB_API_TOKEN为对应项目的Project Access Token,如没有则需要手动创建一个。
create-token
创建方式位于Settings的AccessTokens下。
如我这里的token为:glpat-CW77u3pMBdxnsnGLgwpp

验证

配置cicd流水线后,就可以提交一个mr进行验证了。
在mr中提交一个代码,让其不符合PMD中quickstart的规范:UnusedPrivateMethod

之后,在gitlab的MR中就会出现由reviewdog触发的自动评论了,示例截图如下:
cicd-demo

如需自定义PMD规则,可参考阿里的P3C项目中的PMD规则实现。
https://github.com/alibaba/p3c/tree/master/p3c-pmd/src/main/resources/rulesets
p3c-demo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1982812.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LearnOpenGL-入门章节学习笔记

LearnOpenGL-入门章节学习笔记 简介一、核心模式与立即渲染模式二、扩展三、状态机四、对象 创建窗口一、Main函数——实例化窗口二、Callback Function 回调函数三、processInput 函数 创建三角形一、顶点输入二、顶点着色器三、编译着色器四、片段着色器五、着色器程序六、链…

二叉树——1.翻转二叉树

力扣题目链接 翻转一棵二叉树。 输入&#xff1a; 输出&#xff1a; 可以发现&#xff0c;如何翻转一个二叉树&#xff1f;将每个父节点下的子节点互换就行了&#xff0c;4下面2分支树和7分支树互换&#xff0c;2下面1和3互换&#xff0c;7下面6和9互换。在前面可以自学一下关…

55 函数嵌套定义、可调用对象与修饰器

1 函数嵌套定义 Python 允许函数的嵌套定义&#xff0c;在函数内部可以再定义另外一个函数。 def func(iterable, operator, value): # 自定义函数if operator not in -*/:return operator errordef nested(item): # 嵌套定义函数return eval(repr(item) operator repr(v…

陷入复杂度深渊的ModularRAG..

最近又有一篇ModularRAG的论文&#xff0c;虽然没有太让人汗毛竖起的惊艳&#xff0c;但我想文中的几张配图冷不丁的也着实让部分密集恐惧症患者又一次炸毛了一下吧;)...ps&#xff0c;图画的还是十分规整和可读的&#xff0c;逻辑也很是清晰&#xff0c;为作者的用心点赞&…

如何快速上手Linux操作系统

&#x1f41f;作者简介&#xff1a;&#x1fab4; &#x1f421;&#x1f419;个人主页&#x1f947;&#xff1a;Aic山鱼 &#x1f420;WeChat&#xff1a;z7010cyy &#x1f988;系列专栏&#xff1a;&#x1f3de;️ 前端-JS基础专栏✨前端-Vue框架专栏✨✨前端-Vue3速学专…

OLAP知识地图思考(附地图)

OLAP知识地图思考&#xff08;附地图&#xff09; OLAP技术在当今数据驱动的时代具有举足轻重的地位。它的核心技术模块包括数据存储、计算引擎和查询语言等&#xff0c;这些模块的有效协同是实现高效数据分析的基础。然而&#xff0c;OLAP在运维方面面临着诸多挑战&#xff0c…

【驱动篇】龙芯LS2K0300之RTC设备驱动

实验介绍 本次实验是关于pcf8563 RTC模块的驱动移植&#xff0c;大致流程如下&#xff1a; 注册i2c设备驱动编写RTC设备驱动将device和driver驱动部署到开发板并装载&#xff0c;通过hwclock命令来测试 模块连接 VCC接Pin2&#xff0c;GND接Pin1&#xff0c;SCL接Pin16&…

一加Ace3 ColorOS14系统精简列表(免root)

#adb工具 https://www.123pan.com/s/Z3kujv-NHRPA.html 提取码:DZOD 使用&#xff1a; 1. 手机 设置 -- 关于本机 -- 版本信息 -- 版本号 &#xff0c;点5次 2. 设置 -- 其他设置 -- 开发者选项 -- USB调试 -- 无线调试 3.adb工具 -- adb connect 10.0.0.156:37909&#xff…

opencv-霍夫变换

霍夫变换就是一个可以让计算机学会自己找图形的算法。是图形处理领域内从图像中检测几何形状的基本方法之一。经典霍夫变换用来检测图像中的直线&#xff0c;后来霍夫变换经过扩展可以进行任意型状物体的识别&#xff0c;例如圆和椭圆。 霍夫变换运用两个坐标空间之间的变换&a…

CSP-J复赛 模拟题3

1.匿名信&#xff1a; 题目描述 出于对社会现状的担忧&#xff0c;Alice 决定给市长写一封建议信&#xff0c;考虑到市长的暴脾气&#xff0c;Alice 最终还是决定匿名上书&#xff0c;为了保证自己的绝对神秘&#xff0c;她还会从当天的报纸上将一些单词(或字母)裁剪下来并重…

安装glibc+mysql的权限问题

安装glibc glibc mysql 俗称绿色mysql 安装之前删掉mariadb: 数据库初始化时候&#xff0c;会⾃动找my.cnf配置&#xff0c;但是原有的mariadb配 置⽂件&#xff0c;会失败 [rootmysql3 ~]# ls -l /etc/my.cnf -rw-r--r--. 1 root root 570 6月 8 2017 /etc/my.cnf [rootm…

Vue路由入门学习

文章目录 路由的基本使用1.目标2.作用3.说明4.官网5.VueRouter的使用&#xff08;52&#xff09;两个核心步骤 组件的存放目录问题1.组件分类存放目录 路由的封装抽离 Vue中的路由&#xff1a; 路径和组件的 映射关系 路由的基本使用 1.目标 认识插件 VueRouter&#xff0c…

Midjourney仅10分钟搞定⼀套漫画,含MJ提⽰词分享

Midjourney能帮我们画漫画了,你敢信?⼀起来和⽹易设计师学习如何只⽤10分钟,即使你是设计⿇⽠,也能轻轻松松完成⼀张属于你⾃⼰的短⽚⼩漫画!今天就⽤MJ来实战⼀套漫画,包含创作⽤的⼯ 具和提⽰词的应⽤,以前来学习吧! 漫画先看成品图: ▍ Part1你要画个啥? 画漫画当…

复现一下最近学习的漏洞(sqlab 1-10)

第一个问题&#xff1a;为什么不能用#来闭合单引号呢&#xff1f; 在进行URL地址栏传参的时候&#xff0c;是有一套编码规范的。他不会编码英文、数字和某些符号。但是#它会进行编码。也就是%23。&#xff08;先转ascii码&#xff0c;然后再转十六进制&#xff0c;之后加上%就是…

小白暴力学习001---Vue---第一个Vue

做本文主要是采用Vue3的教程&#xff0c;来源于菜鸟教程&#xff0c; https://www.runoob.com/vue3/vue3-tutorial.html 主要记录从小白开始如何使用Vue建立一个笔记本的网站&#xff0c;并用于记录 基础条件&#xff1a; 有明确的目标有兴趣能使用电脑&#xff0c;会百度 视…

前端的学习-CSS(二)-弹性盒子-flex

一&#xff1a;子元素的属性 order&#xff1a;项目的排列顺序&#xff0c;数值越小&#xff0c;排列越靠前&#xff0c;默认为0。 flex-grow&#xff1a;定义项目的放大比例&#xff0c;默认为 0 &#xff0c;即如果存在剩余空间&#xff0c;也不放大。 flex-shrink&#xff1…

【链表OJ】常见面试题 2

文章目录 1.[链表分割](https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId8&&tqId11004&rp2&ru/activity/oj&qru/ta/cracking-the-coding-interview/question-ranking)1.1 题目要求1.2 哨兵位法 2.[链表的回文结构](https://www.…

Spring Boot集成liquibase快速入门Demo

1.什么是liquibase&#xff1f; Liquibase是一个用于跟踪、管理和应用数据库变化的开源的数据库重构工具。它将所有数据库的变化&#xff08;包括结构和数据&#xff09;都保存在 changelog 文件中&#xff0c;便于版本控制&#xff0c;它的目标是提供一种数据库类型无关的解决…

小厂也是厂,3000我也干

2018年6月&#xff0c;大三暑假 那一天&#xff0c;我投递了家里附近的一家公司有响应了&#xff0c;他线上问我什么时候可以去面试&#xff0c;我说什么时候都行。 HR&#xff1a;“要不你下午来吧&#xff1f;” 我&#xff1a;“行&#xff0c;我家里离面试地点不远” 我…

zdpy+vue3+onlyoffice文档系统实战上课笔记 20240805

上次 上次计划 1、最近文档表格完善 2、实现登录功能 3、新建文件&#xff0c;复制文件&#xff0c;删除文件 4、其他 目前任务&#xff1a;最近文档表格完善 1、在名称前面&#xff0c;渲染这个文档的图标 2、大小的基本的单位是kb&#xff0c;超过1024kb则换成mb&#xff0…