美文网首页工程自动化
iOS使用OCLint静态代码分析+jenkins集成

iOS使用OCLint静态代码分析+jenkins集成

作者: 爱吃糖的葫芦娃 | 来源:发表于2018-05-26 21:01 被阅读0次

    最近公司要做静态代码分析,对现在的代码自动化CodeReview来提高代码质量。方式有很多种我们使用OCLint进行代码分析。把集成的步骤记录下来,为以后查看方便,也可以为其他人提供参考。

    OCLint有三个指令

    1. oclint:基础指令。通过这个指令可以指定加载验证规则、编译代码、分析代码和生成报告。
    2. oclint-json-compilation-database:从编译好的compile_commands.json文件中读取配置信息并执行oclint。
    3. oclint-xcodebuild通过这个指令可以从 Xcode 的 xcodebuild.log 文件导出编译选项并保存成 JSON Compilation Database 格式。然后把保存到 compile_commands.json 文件中。

    安装OCLint和其他工具

    如果有权限问题可在命令前面加上"sudo"
    1.安装oclint,使用Homebrew是最简单的。在终端输入下面的命令

    brew tap oclint/formulae 
    brew install oclint
    

    安装完成oclint后可以 终端执行oclint看是否安装成功,如果是下面提示证明安装成功

    oclint: Not enough positional command line arguments specified!
    Must specify at least 1 positional argument: See: oclint -help
    

    2.下面还需要用到xcpretty工具,在终端中输入下面命令安装

    gem install xcpretty
    

    使用OCLint两种方式xcode中使用和jenkins集成使用

    Xcode集成使用

    1.我们在项目中创建一个新的 target,然后选择 Aggregate 作为模板


    target创建

    2.创建完成后在 Build Phases 选项卡中选择 Add Run Script


    add Run Script
    3.执行脚本
    将oclint.sh脚本放入工程根目录下,添加脚本执行路径
    添加脚本路径
    bash ./oclint.sh
    

    下面是脚本内容,将脚本中最下面的xxxx替换自己工程的名字后就可以command+B执行了,可以生成一个html格式的分析报告。也可以根据自己的需求输出到xcode上面更改脚本中参数配置就可以。

    #!/bin/bash
    
    # 指定编码
    export LANG="zh_CN.UTF-8"
    export LC_COLLATE="zh_CN.UTF-8"
    export LC_CTYPE="zh_CN.UTF-8"
    export LC_MESSAGES="zh_CN.UTF-8"
    export LC_MONETARY="zh_CN.UTF-8"
    export LC_NUMERIC="zh_CN.UTF-8"
    export LC_TIME="zh_CN.UTF-8"
    export LC_ALL=
    
    function checkDepend () {
        command -v xcpretty >/dev/null 2>&1 || { 
            echo >&2 "I require xcpretty but it's not installed.  Install:gem install xcpretty"; 
            exit
            }
        command -v oclint-json-compilation-database >/dev/null 2>&1 || { 
            echo >&2 "I require oclint-json-compilation-database but it's not installed.  Install:brew install oclint"; 
            exit
            }
    }
    
    function oclintForProject () {
    
        # 检测依赖
        checkDepend
    
        projectName=$1
        scheme=$2
        reportType=$3
    
        REPORT_PMD="pmd"
        REPORT_XCODE="xcode"
        
        myworkspace=${projectName}
        myscheme=${scheme} 
        echo "myworkspace是:${myworkspace}"
        echo "myscheme是:${myscheme}"
        echo "reportType为:${reportType}"
    
        # 清除上次编译数据
        if [ -d ./build/derivedData ]; then
            echo '-----清除上次编译数据derivedData-----'
            rm -rf ./build/derivedData
        fi
    
        # xcodebuild -workspace $myworkspace -scheme $myscheme clean
        xcodebuild clean
    
        echo '-----开始编译-----'
    
        # 生成编译数据
        xcodebuild -workspace ${myworkspace} -scheme ${myscheme} -sdk iphonesimulator -derivedDataPath ./build/derivedData -configuration Debug COMPILER_INDEX_STORE_ENABLE=NO | xcpretty -r json-compilation-database -o compile_commands.json
        
    
        if [ -f ./compile_commands.json ]
            then
            echo '-----编译数据生成完毕-----'
        else
            echo "-----生成编译数据失败-----"
            return -1
        fi
    
        echo '-----分析中-----'
    
        # 自定义排除警告的目录,将目录字符串加到数组里面
        # 转化为:-e Debug.m -e Port.m -e Test
        exclude_files=("cardloan_js" "Pods")
    
        exclude=""
        for i in ${exclude_files[@]}; do
            exclude=${exclude}"-e "${i}" "
        done
        echo "排除目录:${exclude}"
    
        # 分析reportType =~判断子字符串包含关系
        if [[ ${reportType} =~ ${REPORT_PMD} ]] 
            then
            nowReportType="-report-type html -o pmd.html"
        else    
            nowReportType="-report-type xcode"
        fi
        # 自定义report 如:
        # nowReportType="-report-type html -o oclint_result.html"
    
        # 生成报表
        oclint-json-compilation-database ${exclude} -- \
        ${nowReportType} \
        -rc=LONG_CLASS=1500 \
        -rc=NESTED_BLOCK_DEPTH=5 \
        -rc=LONG_VARIABLE_NAME=80 \
        -rc=LONG_METHOD=200 \
        -rc=LONG_LINE=300 \
        -disable-rule ShortVariableName \
        -disable-rule ObjCAssignIvarOutsideAccessors \
        -disable-rule AssignIvarOutsideAccessors \
        -max-priority-1=100000 \
        -max-priority-2=100000 \
        -max-priority-3=100000
    
        rm compile_commands.json
        if [[ ${reportType} =~ ${REPORT_PMD} ]] && [ ! -f ./pmd.xml ]
        then
            echo "-----分析失败-----"
            return -1
        else
            echo '-----分析完毕-----'
            return 0
        fi
    }
    
    # 替换workspace的名字
    myworkspace="xxxx.xcworkspace"
    # 替换scheme的名字
    myscheme="xxxx"
    # 输出方式 xcode/pmd
    reportType="pmd"
    
    oclintForProject ${myworkspace} ${myscheme} ${reportType}
    

    下面是一些参数选项,可以是规则加载选项、报告形式选项

    1. -disable-rule <规则名> 通过规则名使某些验证规则失效
      -rc <参数>=<值> 修改某些阈值
    名称 描述 默认值
    CYCLOMATIC_COMPLEXITY 循环嵌套数限制 10
    LONG_CLASS 类行数限制 1000
    LONG_LINE 每行的字符限制 100
    LONG_METHOD 方法行数限制 50
    LONG_VARIABLE_NAME 参数名字符限制 20
    MAXIMUM_IF_LENGTH if 的行数限制 15
    MINIMUM_CASES_IN_SWITCH switch case 的最小数目 3
    NPATH_COMPLEXITY 通过该方法的非循环执行路径数量限制 200
    NCSS_METHOD 连续未注释行数限制 30
    NESTED_BLOCK_DEPTH block 嵌套层数限制 5
    SHORT_VARIABLE_NAME 变量名的最小字符数限制 3
    TOO_MANY_FIELDS 类成员限制 20
    TOO_MANY_METHODS 类方法数限制 30
    TOO_MANY_PARAMETERS 参数个数限制 10
    1. -report-type <报告类型>有"text"、“html”、“json”、“pmd”、“xcode”几个类型
    2. -o 指定报告的输出目标。
    3. oclint-json-compilation-database 指令有过滤文件选项
      -i :包含进某些文件
      -e : 过滤掉某些文件

    jenkins集成使用

    jenkins安装

    参考链接:https://www.jianshu.com/p/98541e989202

    jenkins安装时候需要获取初始的管理员密码Permission denied问题

    参考链接:https://www.jianshu.com/p/0d6db1789382

    首先安装两个插件PMD和EmailExtendedPlugin

    1. jenkins集成时候需要将上面脚本输出格式修改:-report-type pmd -o pmd.xml
    2. 修改脚本中路径代码用全路径添加“/usr/local/bin/”
    /usr/local/bin/xcpretty -r json-compilation-database -o compile_commands.json
    /usr/local/bin/oclint-json-compilation-database ${exclude}
    

    一.完成分析后生成报告需要发送邮件,首先需要进行邮件配置。进入系统配置

    Extended E-mail Notification

    我这里用qq邮箱发送。userName邮箱地址和管理员的一致,密码是qq授权码不是邮箱密码。SMTPport用的465(qq配置是465,一般都是是25)在最下方点击“DefaultTriggers”配置触发器选中always。开启qq邮箱的smtp服务参考链接:http://service.mail.qq.com/cgi-bin/help?id=28&no=166&subtype=1

    邮件通知配置

    和上面的配置一致。这里可以发送测试邮件测试配置是否配置成功

    二.创建和配置一个Jenkins项目

    1. 源码管理用的svn
    2. 将上面脚本代码放入到执行shell里面
    3. 构建后操作


      构建后操作
    4. 构建后操作中选中EditableEmailNotification


      项目中邮件配置

      Project Recipient List邮件接收人列表,多个可以换行或者逗号隔开
      Default Subject邮件主题
      Default Content邮件内容

    5. 在高级里面设置邮件触发条件


      邮件触发条件

      6.构建完成后会出现PMD Warnings,点击查看报表


      构建完成查看报表

    参考链接

    https://www.jianshu.com/p/c6cc551e2ca3
    https://segmentfault.com/a/1190000005150573
    http://www.cocoachina.com/ios/20170928/20669.html
    https://www.jianshu.com/p/4d9d33c31edd
    官方文档:http://oclint-docs.readthedocs.io/en/stable/
    邮件配置:https://www.centos.bz/2018/01/jenkins-%E9%82%AE%E4%BB%B6%E9%85%8D%E7%BD%AE/
    https://blog.csdn.net/galen2016/article/details/77975965

    相关文章

      网友评论

        本文标题:iOS使用OCLint静态代码分析+jenkins集成

        本文链接:https://www.haomeiwen.com/subject/fxpmjftx.html