达成功能 :
- 对 java 和 kotlin 文件都进行检测;
- 检测规则可以配置;
- IDE(Android Studio) 可以实时进行不符合设定的代码报错(但是没有自动纠错)
- 对接 gerrit ,每次提交代码进行检测(现在直播的检测是只对修改的文件进行检测,不是全局扫描),可以在检测未通过时对 commit -2.
- 环境无关,不需要在不同的设备上安装额外的东西(在项目里保留检测工具的 jar 包,直接运行 jar 包进行)
检测工具官方文档
对 java 和 kotlin 分别使用不同的检测工具, 对 java 使用 checkStyle , 对 kotlin 使用的是 detekt . 所以两者的检测规则不是完全一致的(不过一些基本规则,例如每行最大字数限制,会保持一致)
checkStyle :?https://checkstyle.sourceforge.io/checks.html
detekt :?https://detekt.github.io/detekt/index.html
AS 接入实时检测报错
对 checkstyle : 使用 checkstyle 插件,在 Plugin?→ Market 中可以找到, 并且在 Preferences→ Other Settings → CheckStyle 中可以新增配置, 选择项目中的 checkstyle.xml
即可新增规则,并在 CheckStyle 栏(使用 "Action → 搜 checkstyle" 可以呼出)选择相应配置即可。
对 detekt : 使用 detekt 插件,在 Plugin→ Market 中可以找到, 在 Preferences?→ Tools?→ detekt 中可以设置配置文件,并且可以设置其他的一些选项(是否 enable / 是否将报错视为 error 等)
检测规则
具体参见 checkStyle 和 deteky 的官方配置。
其中
checkStyle 推荐使用 google-checkstyle 作为基础进行修改
detekt 推荐使用 detekt 默认规则配置作为基础进行修改
监测脚本 demo 代码 (只对提交修改的文件进行检测):
#!/usr/bin/env python
# coding=utf-8
import subprocess
import sys
def printUsage():
print("""
code check .
对一些文件进行代码检查,java 文件使用 checkStyle 进行检测, kt 文件使用 deteKt 进行检测.
检查的文件包含 : [指定的 A commit 的代码]和[指定的 B commit 的代码]之间不同的文件.
检查规则参见 `config/` 目录.
使用方法 : "sh codeCheck.sh commitA commitB" . commit 可以是有效的 commit id,
也可以是 "HEAD","origin/develop" 等
""")
def exitWithErrorMsg(msg):
alertStr = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
print(alertStr)
print("Error : ", msg)
print(alertStr)
def getDiffFileListBetweenTwoCommits(commitA, commitB):
completeProcess = subprocess.run([‘git‘, ‘diff‘, ‘--name-only‘, commitA, commitB], capture_output=True)
if completeProcess.returncode != 0:
exitWithErrorMsg("`git diff --name-only " + commitA + " " + commitB + "` failed with return code : " + completeProcess.returncode)
outputStr = completeProcess.stdout.decode(‘utf-8‘)
diffFiles = outputStr.splitlines()
return diffFiles
# 返回 [javaFiles, ktFiles]
def sortFilesToJavaAndKt(files):
javaFiles = []
ktFiles = []
for fileName in files:
if fileName.endswith(‘.kt‘):
ktFiles.append(fileName)
elif fileName.endswith(‘.java‘):
javaFiles.append(fileName)
return [javaFiles, ktFiles]
def checkJavaFiles(javaFiles):
if (len(javaFiles) != 0):
subprocess.run([‘java‘, ‘-jar‘, ‘config/checkstyle/checkstyle-8.33-all.jar‘, ‘-c‘, ‘config/checkstyle/checkstyle.xml‘, *javaFiles])
def checkKtFiles(ktFiles):
if (len(ktFiles) != 0):
subprocess.run([‘java‘, ‘-jar‘, ‘config/detekt/detekt-cli-1.9.1-all.jar‘, ‘-c‘, ‘config/detekt/detekt-config.yml‘, ‘-i‘, ‘,‘.join(ktFiles)])
if __name__ == ‘__main__‘:
if len(sys.argv) != 3:
printUsage()
exitWithErrorMsg("error usage!")
diffFiles = getDiffFileListBetweenTwoCommits(sys.argv[1], sys.argv[2])
sortedFilesList = sortFilesToJavaAndKt(diffFiles)
print(sortedFilesList)
checkJavaFiles(sortedFilesList[0])
checkKtFiles(sortedFilesList[1])
文件位置
config
├── checkstyle
│?? ├── checkstyle-8.33-all.jar
│?? └── checkstyle.xml
└── detekt
├── detekt-cli-1.9.1-all.jar
└── detekt-config.yml