作者 kyson老师 2018.04.25 18:05:00 iOS自动化代码审查工具之OCLint 评论:1 [OCLint](http://oclint.org/)是一款静态代码分析器,可用于分析C, C++ 和 Objective-C代码中隐含的问题: - 可能出现的 bug:if/else/try/catch 等条件语句空的声明 - 未使用的代码: 未使用的局部变量以及参数 - 复杂的代码逻辑:高循环复杂度、NP 复杂度、 高 NCSS - 冗余代码:冗余的条件表达式以及无效的括号 - 代码嗅觉:方法代码行过长或者参数过多 - 不好的代码习惯:颠倒的逻辑和参数的错误分配 … 静态代码分析工具是侦测编译器不可见的潜在缺陷的关键技术。OCLint 具有以下先进的代码检验特性: - 依靠源码的抽象语法树来提高分析的精确度以及效率,误报率低 - 动态规则 - 灵活可扩展的配置,确保用户可以自定义分析行为 - 命令行式的调用使持续集成成为可能 ### 安装 依次执行命令 ``` brew tap oclint/formulae brew install oclint ``` 第一句的意思是设置第三方仓库,第二句是安装。 一个常见的oclint命令为: ``` oclint-json-compilation-database -- -report-type html -o oclint.html ``` 意思是使用`oclint-json-compilation-database`命令,将`compile_commands.json`文件中标明的有问题的OC代码通过html的方式展示出来。其中一个常见的`compile_commands.json`可以[点击这里](http://images.kyson.cn/clint/compile_commands.json)查看,分析完成后会在工程目录下生成一个html类型的报告文件,一个常见的report文件可以在[这里](http://images.kyson.cn/clint/oclint.html)查看。需要注意的是`-- -report`并不是笔误,这个后面做解释。 通过json 解析工具可以看到,`compile_commands.json`文件的组成是个数组,数组中是一个个字典,包含了三个字段: - command - file - directory 说到这里,大家肯定一头雾水: - `oclint-json-compilation-database`是什么 - `compile_commands.json`文件是什么文件 - command,file,directory这三个字段各有什么意思 下面听我详细解释: ### OCLint组成 `OCLint`工具集有三个命令: - `oclint` - `oclint-json-compilation-database` - `oclint-xcodebuild` 其功能可以简单概括为: - `oclint` 是 OCLint 工具集最主要的指令,主要作用是规则加载、编译分析选项以及生成分析报告 - `oclint-json-compilation-database` 的作用是在 JSON Compilation Database format 类型的编译文件 `compile_commands.json` 中提取必要的信息。 - `oclint-xcodebuild` 用于将 xcodebuild 生成的 log 文件 xcodebuild.log 转换为 JSON Compilation Database format 类型 这里再对上面的解释做个进一步描述: - `compile_commands.json` 文件是编译完成后提取并生成的信息文件。需要了解这个文件的生成,就需要使用命令`xcodebuild`以及`oclint-xcodebuild`。 - 由于`oclint-xcodebuild`已经不再维护,一般我们使用`xcpretty`代替。 - `-- -report`中的双横线`--`就是分割线,表示后面跟的是`oclint`的参数。也就是文章开头的命令中已经在后台调用了`oclint`命令。 ###xcodebuild `xcodebuild`命令大家已经很熟悉了,我之前的文章也或多或少做过相应的介绍,比如[这里](http://kyson.cn/index.php/archives/34/)。 这里我们仍然以我的线上[壁纸宝贝](https://itunes.apple.com/cn/app/id1334013423)项目来说明xcodebuild命令的使用(如果大家对壁纸宝贝不了解,可以通过[这里](http://kyson.cn/index.php/archives/97/)了解。) 切到`feature/oclint`分支。执行以下命令: ``` xcodebuild -workspace Wallpaper.xcworkspace -scheme Wallpaper -configuration Debug ``` 即可编译项目,如果你没有开发者证书,可以带上`-sdk iphonesimulator`参数: ``` xcodebuild -workspace Wallpaper.xcworkspace -scheme Wallpaper -sdk iphonesimulator -configuration Debug ``` 等待片刻,直到看到成功提示:  蓝色文字部分表示编译成功后的包地址,我们打开对应的文件夹看一下:  ### xcpretty 细心的读者可能会发现,当我们在执行`xcodebuild`命令的时候控制台输出的内容可读性不强,而[xcpretty](https://github.com/supermarin/xcpretty)可以解决这个问题。 #### 安装xcpretty ``` gem install xcpretty ``` 稍等片刻,可以看到安装成功。 #### 小试牛刀 我们可以通过管道,将xcodebuild的输出直接传递给xcpretty,也就是将上述命令改进为: ``` xcodebuild -workspace Wallpaper.xcworkspace -scheme Wallpaper -sdk iphonesimulator -configuration Debug | xcpretty -r json-compilation-database -o compile_commands.json ``` 稍等片刻可以看到,输出的可读性大大增强:  #### 注意点 由于xcodebuild会缓存上次编译结果,为了保证编译结果正确,可以做如下操作: 1. 在之前先执行`xcodebuild clean`命令。 2. 删除文件夹DerivedData(如下图)。  下面讲解一下xcpretty的参数 | 短参数 | 长参数 | 说明 | | ------------ | ------------ | ------------ | | -r | --report | 输出格式,可以是:junit、html、json-compilation-database | | -o | --output | 输出路径 | 不出意外的话,大家可以在项目目录下看到`compile_commands.json`文件了(如下图)。  ### OCLint命令详解 有了`compile_commands.json`文件,我们就可以分析了,一个常见的分析命令如下: ``` oclint-json-compilation-database -v \ -e Pods \ -- -report-type html -o oclint_result.html \ -rc LONG_LINE=200 \ -rc=NCSS_METHOD=100 \ -max-priority-1=100000 \ -max-priority-2=100000 \ -max-priority-3=100000; \ ``` 上面的命令中,"\"用于表示后面的代码追加在本行,这样避免了一行命令过长的情况,其中`oclint-json-compilation-database`在前面我们已经做个介绍了,下面主要讲解参数 |参数 | 含义 | | ------------ | ------------ | | -e | 忽略某个文件/目录 | | -report-type | 输出类型,支持HTML,XML等类型 | | -rc | 表示某个规则,可以在后面具体指定 | 稍等片刻,大家就能看到生成的report文件`oclint_result.html`,该文件样式在文章开头已经给出过,这里不重复截图了。 至此,文章开头提出的疑问大家已经完全解决了。 ### OCLint自定义规则 OCLint强大之处在于不但能用于检测代码中存在的警告、错误,还能自定义规则,目前官网上有60几个规则可用。大家可以参考一下,[点击这里跳转](http://oclint-docs.readthedocs.io/en/latest/rules/) ### 封装成脚本 为了方便自动化用于CI(如果读者对CI还不够了解,可以参看[这里](http://kyson.cn/index.php/archives/34/)),我们一般会把OCLint自动化codereview的过程写成脚本,一个常见的脚本如下: ``` #! /bin/sh #source ~/.bash_profile export LC_ALL=en_US.UTF-8 source /etc/profile if which oclint 2>/dev/null; then echo 'oclint exist' else brew tap oclint/formulae brew install oclint fi if which xcpretty 2>/dev/null; then echo 'xcpretty exist' else gem install xcpretty fi rm compile_commands.json; xcodebuild clean xcodebuild -workspace shop.xcworkspace -scheme dadaShop \ -configuration Debug \ | xcpretty -r json-compilation-database -o compile_commands.json oclint-json-compilation-database -v \ -e Pods \ -- -report-type html -o oclint_result.html \ -rc LONG_LINE=200 \ -rc=NCSS_METHOD=100 \ -max-priority-1=100000 \ -max-priority-2=100000 \ -max-priority-3=100000; \ ``` 脚本的大部分大家应该都能看懂了。开头增加的部分功能在于判断本地是否已经安装OCLint以及xcpretty,如果没安装则安装。至此本教程告一段落了。 ### 问题 在安装以及运行OCLint时遇到如下问题,通过查找资料解决了,这里做个整理: - invalid byte sequence in US-ASCII (ArgumentError) 解决方案: 在调用的Shell脚本中最前面加上:export LC_ALL=en_US.UTF-8 - oclint: error: one compiler command contains multiple jobs 解决方案: 1. 如果电脑里面安装了两个Xcode的话可能会报上面错误,删掉其他只剩一个 xcode9以后: 1. 更新到最新的oclint, brew upgrade oclint 2. 去github下载最新的oclint.sh,替换掉旧的 3. 试试手动将 工程=> Build Settings => 搜索COMPILER_INDEX_STORE_ENABLE 该配置设成NO  ### 参考 [OCLint 静态代码分析](https://manajay.com/2017/06/oclint/) [让XCode自动CodeReview你的代码-OCLint使用](https://juejin.im/post/59cc62a3f265da06700afa95) [OClint 初探](http://blog.hellormy.com/2017/05/15/OClint-%E5%88%9D%E6%8E%A2/) [OClint实现代码静态分析(IOS)](https://www.jianshu.com/p/4d9d33c31edd) [iOS使用OCLint做静态代码分析](https://www.jianshu.com/p/4f505e92d557) [【FAQ】Jenkins上,xcpretty编译报错:invalid byte sequence in US-ASCII (ArgumentError)](https://blog.csdn.net/cuiaamay/article/details/50535272) [OCLint 安装与使用](https://segmentfault.com/a/1190000005150573) [OCLint 规则与结果分析](https://segmentfault.com/a/1190000005155260) >本文地址:http://kyson.cn/index.php/archives/114/ 转载请保留出处 赏 标签:xcodebuildiosoclintcodereviewxcpretty代码审查静态分析
写得不错,五一抽空试一下