OCLint在Xcode中的使用

作者: 凤栖林 | 来源:发表于2018-01-31 15:20 被阅读137次

    OCLint是一个强大的静态代码分析工具,可以用来提高代码质量,查找潜在的bug,主要针对c,c++和Objective-c的静态分析,功能非常强大。

    一、安装OCLint

    OCLint是一个开源的项目,你可以通过下载压缩包安装,需要设置对应的环境变量,也可以使用Homebrew进行安装。

    1.通过下载安装包:

    从OCLint的github项目链接中下载安装包:oclint-0.13-x86_64-darwin-16.7.0.tar.gz(这是我当前的最新版本,以后读者打开可能就是更新的版本了);
    下载完毕后解压,目录结构是这样的:

    1517380701542.jpg
    然后获取oclint-0.13的本地路径,例如我的是 /Users/zyw/Downloads/oclint-0.13
    然后打开终端,在终端里面输入命令:
      vi ~/.bash_profile 
    
    1517380970250.jpg

    回车,进入.bash_profile的vi编辑器里面,在末尾加上

    OCLINT_HOME= /Users/zyw/Downloads/oclint-0.13
    export PATH=$OCLINT_HOME/bin:$PATH
    

    其中/Users/zyw/Downloads/oclint-0.13就是上面我提到的oclint-0.13在你电脑上的本地路径,之后就是保存(按Esc,shift+:,wq),环境变量即配置完毕。

    2.通过Homebrew进行安装

    2.1如果电脑上未安装Homebrew,输入下面命令安装:
    ruby -e "$(curl --insecure -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    

    安装成功会显示:Installation successful!

    2.2安装xcpretty (xcpretty只是其中一种,本文只介绍这一种使用)

    xcpretty是OCLint的命令执行器,安装方式:
    mac终端输入:

    sudo gem install -n /usr/local/bin  xcpretty,
    

    终端打印 2 gem installed,即安装成功

    2.3安装OCLint

    终端输入:

    brew tap oclint/formulae
    brew install oclint
    

    展示以下内容即为安装成功:

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

    至此,OCLint的安装工作算是完成;

    二、OCLint在xcode中的使用

    1.建立一个工程,在新建的工程里面添加一个新的目标target,并选择Aggregate为模板.

    1517382420032.jpg
    2.输入名字:OCLint
    1517382484835.jpg
    3.创建一个script
    1517382714259.jpg
    4.写入自定义的规则脚本
    下面输入一个最基本的脚本(该脚本没有做任何自定义的规则,OCLint本身有默认的规则,该脚本用途是让xcode和OCLint关):
    使用OCLint与xcpretty
    4.1如果没有cocoapods
    source ~/.bash_profile
    cd ${SRCROOT}
    xcodebuild clean
    xcodebuild | tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json
    oclint-json-compilation-database oclint_args -- -report-type xcode
    
    1517382863415.jpg
    4.2如果项目中使用了cocoapods

    可以添加 -e Pods过滤
    代码如下:

    source ~/.bash_profile
    cd ${SRCROOT}
    xcodebuild clean
    xcodebuild | tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json
    oclint-json-compilation-database -e Pods oclints_args  -- -report-type xcode
    

    规则如下:

    source ~/.bash_profile
    cd ${SRCROOT}
    xcodebuild clean
    xcodebuild  -workspace demo.xcworkspace -scheme demo | xcpretty -r json-compilation-database --output compile_commands.json
    oclint-json-compilation-database -v \
    -e Pods \
    -e MGLivenessDetection \
    -e MGBaseKit \
    -e MGIDCard \
    oclint_args -- -report-type xcode \
    -disable-rule ObjCAssignIvarOutsideAccessors \
    -disable-rule ShortVariableName \
    -rc=MINIMUM_CASES_IN_SWITCH=3 \
    -rc=CYCLOMATIC_COMPLEXITY=10 \
    -rc=LONG_CLASS=700 \
    -rc=LONG_LINE=200 \
    -rc=NCSS_METHOD=40 \
    -rc=NESTED_BLOCK_DEPTH=5 \
    -rc=TOO_MANY_FIELDS=20 \
    -rc=TOO_MANY_METHODS=30 \
    -rc=TOO_MANY_PARAMETERS=6
    exit
    

    知识拓展:
    这是一段结合shell的脚本语言

    xcodebuild | tee xcodebuild.log | xcpretty -r json-compilation-database -o >compile_commands.json  
    

    这段脚本执行会在项目的根目录生成一个xcodebuild.log和compile_commands.json文件
    xcodebuild.log会记录你编译过程中的信息,如编译错误信息等;

    compile_commands.json文件则是记录了自定义规则代码不匹配的信息,里面是一个个字典,字典有三个键值对,command,file,directionary

    oclint-json-compilation-database oclint_args -- -report-type xcode
    

    这段脚本是把compile_commands.json里面的内容解析然后显示的xcode上面,所以xcode上面会根据这个文件显示出警告


    1517385349152.jpg

    5、随便写一个方法用来测试

    -(NSString *)getValueForKey:(NSString *)key
    {
        NSData *valueData = nil;
        if(valueData != nil)
        {
            NSString *value = [[NSString alloc] initWithData:valueData encoding:NSUTF8StringEncoding];
            return value;
        }
        else
        {
            return nil;
        }
    }
    
    1517382983646.jpg

    6、运行
    按command+B编译成功,会看到编译警告,如图:


    1517383186511.jpg
    7、报错

    7.1如果报这个错误:

    tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
    

    在终端中输入这个脚本:

    sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer/
    

    /Applications/Xcode.app/Contents/Developer/是我电脑的路径,换成你自己的即可

    7.2如果是这个错误:
    oclint: error: violations exceed threshold
    P1=0[0] P2=1637[10] P3=53904[20]
    修改脚本如下:

    source ~/.bash_profile
    cd ${SRCROOT}
    xcodebuild clean
    xcodebuild | tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json
    oclint-json-compilation-database -e Pods oclints_args  -- -report-type xcode -max-priority-1=9999 -max-priority-2=9999 -max-priority-3=9999
    

    末尾加上 -max-priority-1=9999 -max-priority-2=9999 -max-priority-3=9999
    7.3出现出现了code sign错误
    第一种方法:在xcodebuild后面加上参数 CODE_SIGN_IDENTITY就行了。
    第二种方法,找到项目所在target,选择一个证书即可
    7.4xcodebuild和xcpretty编译报错:

    20160118104708120.png
    在终端上打印编码格式
    locale
    
    1518083195554.jpg

    在Edit Scheme下面添加环境变量:


    555.gif

    如图:name添加LC_ALL
    Value添加zh_CN.UTF-8

    8、其他原因

    以上的都配置过了,xcode还是会报错,例如compile_commands.json不存在,或者编译显示success了,但是xcode仍然报红不消失(这是因为xcode对脚本的支持不够全面,中间产生的某些文件没有生成)

    我的解决方案:在桌面上创建一个文件夹,取名为shell,打开终端,然后cd ./user/DeskTop/shell(这个shell文件夹的路径,直接拖到终端就会生成路径),vi xcode.sh,终端会进入到vi编辑器里面;同时会在shell文件夹里面生成一个xcode.sh文件,把xcode里面那段脚本

    source ~/.bash_profile
    cd ${SRCROOT}
    xcodebuild clean
    xcodebuild | tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json
    oclint-json-compilation-database oclint_args -- -report-type xcode
    

    粘贴到刚才终端的vi编辑器里面
    同时把cd ${SRCROOT}改为 cd /Users/zyw/Desktop/OCLint-Demo
    /Users/zyw/Desktop/OCLint-Demo为我xcode工程的根目录,换成你的根目录即可
    ,之后保存退出(esc shift+: wq),终端运行刚才的文件

    ./xcode.sh
    

    可能会报权限不够,这时候需要加上

    chmod +x ./xcode.sh
    

    然后在运行

    ./xcode.sh
    

    下面就是清理xcode工程,多编译几次就OK了

    三、OCLint的规则

    OCLint默认有71条规则,查看OCLint规则索引
    可以在xocde的脚本里面写代码过滤不想要的规则
    下面可以看官方给的第一个规则,点击查看地址

    1.BitwiseOperatorInConditional:条件运算符中的位运算符

    意思:检查条件中的按位运算。虽然在一些罕见的情况下有意编写,但按位操作被认为太“聪明”了。智能代码不容易理解。
    此规则由以下类定义:oclint-rules / rules / basic / BitwiseOperatorInConditionalRule.cpp

    1517387769033.jpg

    代码放入我们的工程中,command+B出现警告


    1517388296727.jpg

    修改为如下即可


    1517388458253.jpg
    2. BrokenNilCheck:破零检查

    在某些情况下,Objective-C中的无效检查返回正好相反的结果。

    该规则由以下类定义:oclint-rules / rules / basic / BrokenNullCheckRule.cpp

    1517389587791.jpg

    代码放入我们的工程中,command+B出现警告


    1517389802358.jpg

    修改为如下即可


    1517390138341.jpg

    其他的规则可以一个一个运行看看

    四、如何在xcode中忽略某条规则

    1、把在xcode中写的这句脚本

    oclint-json-compilation-database oclint_args -- -report-type xcode
    

    改为

    oclint-json-compilation-database oclint_args "disable-rule=LONG_CLASS -rc LONG_VARIABLE_NAME=1200" -- -report-type xcode
    

    双引号里面的disable-rule便是忽略某条规则,后面写上对应规则的阀值,多条的话可以在后面拼接
    如:
    "-disable-rule=UnusedMethodParameter -disable-rule=LongLine -disable-rule=LongMethod -disable-rule=NcssMethodCount -disable-rule=ObjCObjectSubscripting -disable-rule=LongClass -disable-rule=NcssMethodCount -disable-rule=NPathComplexity -disable-rule=NPathComplexity -rc LONG_VARIABLE_NAME=1200"

    2、阀值是什么
    上面的规则索引文档中

    1517466318084.jpg 1517466342488.jpg

    规则的下方会有该规则的阀值
    (基本规则没有阀值)

    最后

    这些规则是有c++编写,大家想研究下可以看源码
    目录如下:

    ├── README.md
    ├── oclint-core
    ├── oclint-driver
    ├── oclint-metrics
    ├── oclint-reporters
    ├── oclint-rules
    └── oclint-scripts
    

    oclint-rules/rules/basic/里面便是c++源码

    相关文章

      网友评论

        本文标题:OCLint在Xcode中的使用

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