美文网首页性能优化OCLintCI/CD
OCLint 工具的使用与规则配置

OCLint 工具的使用与规则配置

作者: Lojii | 来源:发表于2017-04-25 11:13 被阅读1411次

    OCLint工具介绍

    OCLint是一个静态代码扫描分析工具,可用于提高代码质量和减少潜在的缺陷,目前支持C,C++,Objective-C,它可以扫描出代码中存在的问题,比如:

    • 可能存在的错误 - 比如空的 if/ else / try / catch / finally语句
    • 未使用的代码段 - 比如未使用的局部变量和参数等
    • 过于复杂的代码 - 比如多路径判断等
    • 冗余的代码 - 比如冗余的if语句和无用的括号等
    • 不合理的代码 - 比如超长的方法和超长的参数列表
    • 错误的做法 - 比如反转逻辑,参数的重新分配

    • 该工具配合持续集成,自动打包编译,可以很大程度的提高编码的乐趣以及尽早的修复潜在的问题以降低维护成本

    安装OCLint

    OCLint是运行于Linux和MacOX平台上的开源工具,可以直接下载源码进行编译安装,也可以使用作者发布的release版本进行安装
    针对于MacOS系统,可以直接通过Homebrew进行安装

    1. 设置brew的第三方仓库

    brew tap oclint/formulae
    

    2. 安装

    brew install oclint
    

    3. OCLint升级

    brew update
    brew upgrade oclint
    

    使用OCLint

    命令列表

    oclint -help
    

    1、生成格式化的编译日志文件compile_commands.json

    • 使用 xcodebuild 对工程进行编译
      OCLint需要根据编译日志里的文件信息对工程进行扫描
      xcodebuild -list 可以显示项目相关的信息



      以quidemo为例
      通过以下命令对工程进行编译并将编译的日志信息输出到 xcodebuild.log 文件中

    xcodebuild -target qmuidemo -configuration Debug -scheme qmuidemo| tee xcodebuild.log
    
    • xcpretty 格式化编译日志
      直接使用OCLint对日志信息进行分析
    oclint-xcodebuild xcodebuild.log
    

    得到输出信息为:

    This binary is no longer under maintenance by OCLint team.
    Please consider using xcpretty (https://github.com/supermarin/xcpretty) instead!

    提示需要使用xcpretty来分析日志信息,需要安装xcpretty, xcpretty可对xcodebuild的输出进行格式化。并且可以输出多种格式的日志信息,这里需要安装xcpretty

    gem install xcpretty
    

    注:如果没有权限,则在前面添加sudo,如果提示文件夹操作被禁止Operation not permitted - /usr/bin/rougify,则更改$GEM_HOME的路径到/usr/local/bin使用sudo gem install xcpretty -n /usr/local/bin来安装
    xcpretty安装之后,使用--report json-compilation-database或者-r json-compilation-database可以生成指定格式的数据,当前指定为json格式。
    运行命令:

    xcodebuild | xcpretty -r json-compilation-database -o compile_commands.json
    

    如果没有设置json输出路径,则默认的路径在build/reports中,需要移动并改名为compile_commands.json到根目录
    如果你想获取编译日志,又想获取格式化后的编译日志可以这样:

    xcodebuild [flags] | tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json
    

    2、OCLint根据json格式化后的编译日志信息对代码进行扫描分析

    使用oclint-json-compilation-database命令对上一步生成的json数据进行分析
    将build/reports目录中的compile_commands.json移动到项目根目录,然后运行命令

    oclint-json-compilation-database — -report-type=html -o=report.html
    

    对项目代码进行分析,最终生成report.html文件
    OCLint目前支持输出html,json,xml,pmd,xcode格式文件

    3、OCLint分析脚本

    上面的步骤可以写成脚本:

    #! /bin/sh
    xcodebuild clean
    xcodebuild | xcpretty -r json-compilation-database
    cp build/reports/compilation_db.json compile_commands.json
    oclint-json-compilation-database —-report-type=html -o=report.html
    

    4、OCLint的规则

    1. 可以通过 -e 参数忽略指定的文件,比如忽略Pods文件夹:
    oclint-json-compilation-database -e Pods -- -o=report.html
    
    1. 通过-rc改变检查规则的默认值,比如有一条默认规则:long line [size|P3] Line with 137 characters exceeds limit of 100 ,这表示一个方法里的代码行数不能超过100,可以通过-rc改变默认100行的限制比如改成200行:
    oclint-json-compilation-database -- -rc=LONG_LINE=200 -o=report.html
    

    具体可以操作哪些规则,可以去官网查询

    1. 通过 -disable-rule可以禁止某一规则,比如禁止LongLine长方法检查:
    oclint-json-compilation-database -disable-rule=LongLine
    
    1. 这些命令是可以组合使用,比如:
    oclint-json-compilation-database -e Pods -rc=LONG_LINE=200-- -o=report.html
    
    1. 如果需要更改的规则比较多,可以通过.oclint 文件配置规则
      具体编写规则如下:



      规则默认值:

    Name Description Default
    CYCLOMATIC_COMPLEXITY Cyclomatic complexity of a method 10
    LONG_CLASS Number of lines for a C class or Objective-C interface, category, protocol, and implementation 1000
    LONG_LINE Number of characters for one line of code 100
    LONG_METHOD Number of lines for a method or function 50
    LONG_VARIABLE_NAME Number of characters for a variable name 20
    MAXIMUM_IF_LENGTH Number of lines for the if block that would prefer an early exists 15
    MINIMUM_CASES_IN_SWITCH Count of case statements in a switch statement 3
    NPATH_COMPLEXITY NPath complexity of a method 200
    NCSS_METHOD Number of non-commenting source statements of a method 30
    NESTED_BLOCK_DEPTH Depth of a block or compound statement 5
    SHORT_VARIABLE_NAME Number of characters for a variable name 3
    TOO_MANY_FIELDS Number of fields of a class 20
    TOO_MANY_METHODS Number of methods of a class 30
    TOO_MANY_PARAMETERS Number of parameters of a method 10

    例如:

    disable-rules:
    - LongLine
    rulePaths:
    - /etc/rules
    rule-configurations:
    - key: CYCLOMATIC_COMPLEXITY
    value: 15
    - key: NPATH_COMPLEXITY
    value: 300
    output: oclint.html
    report-type: html
    enable-clang-static-analyzer: false

    在Xcode里使用OCLint

    OCLint是支持在Xcode中直接显示代码分析结果的

    1. 给工程添加一个Aggregate的target


      Aggregate

    2. 选中刚刚创建的Aggregate target,然后点Build Phases,然后点左上角的加号,添加一个Add Run Script

    如果你使用的是xctool ,输入这个脚本:

    source~/.bash_profile
    cd ${SRCROOT}
    /path/to/xctool.sh -reporter json-compilation-database:compile_commands.json clean
    /path/to/xctool.sh -reporter json-compilation-database:compile_commands.json build
    oclint-json-compilation-database|sed's/\(.*\.\m\{1,2\}:[0-9]*:[0-9]*:\)/\1 warning:/'
    

    如果你使用的是自带的xcodebuild,使用这个脚本

    source~/.bash_profile
    cd ${SRCROOT}
    xcodebuild clean
    xcodebuild|xcpretty -r json-compilation-database
    oclint-json-compilation-database -- -report-type xcode
    
    1. 选中该target,点击编译
      如果提示不存在.bash_profile文件,则手动创建该文件,由于该文件是隐藏文件,所有得先执行命令
    defaults write com.apple.finder AppleShowAllFiles TRUE
    

    让Finder显示隐藏文件,然后强制重新启动Finder,然后Command+Shift+G前往文件夹,填写~查看,若无此文件,命令行进入次目录创建一个即可:

    cd ~
    touch .bash_profile
    

    恢复隐藏文件的隐藏

    defaults write com.apple.finder AppleShowAllFiles FALSE
    

    后重新启动Finder
    4、结果


    结果

    控制OCLint的检查

    有的时候,我们在已知一段代码会产生OCLint的警告,但是因为某些原因,我们没法去修改该段代码,或者没有更好的修改方法,这时候,我们可以在代码中控制OCLint忽略对这段代码的检查

    1. 注解

    可以使用注解的方法禁止OCLint的检查,语法是:

    __attribute__((annotate("oclint:suppress[unused method parameter]")))
    

    比如我们知道一个参数没有使用,而又不想产生警告信息就可以这样写,下面这段代码可以忽略对sender的警告但是没法忽略对参数i的警告:

    - (IBAction)turnoverValueChanged: (id) __attribute__((annotate("oclint:suppress[unused method parameter]"))) sender
    {
         int i;// 这个参数不会被忽略,会产生OCLint警告
         [self calculateTurnover];
    }
    

    对于方法的注解可以这样写,下面方法中产生的警告都会被忽略掉:

    bool __attribute__((annotate("oclint:suppress"))) aMethod(int aParameter)
    {
        // 这个方法里所有的警告都会被忽略
        // 比如下面这个空的if警告会被忽略
        if (1) {}
        return true;
    }
    
    2.!OCLint

    也可以通过//!OCLint注释的方式,不让OCLint检查。比如,禁止对未使用的参数unusedLocalVariable进行检查:

    void a() {
    int unusedLocalVariable; //!OCLINT
    }
    

    注释要写在对应的行上面才能禁止对应的检查,比如对于空的if/else禁止检查的注释为:

    if (true) //!OCLint
    {
    // it is empty
    }
    

    END

    相关文章

      网友评论

        本文标题:OCLint 工具的使用与规则配置

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