Android 端接入代码检测简介

达成功能 :

  • 对 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
posted @ 2020-06-05 17:51  wkmcyz  阅读(405)  评论(0编辑  收藏  举报