OCLint是一款静态代码分析器,可用于分析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可以点击这里查看,分析完成后会在工程目录下生成一个html类型的报告文件,一个常见的report文件可以在这里查看。需要注意的是-- -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命令大家已经很熟悉了,我之前的文章也或多或少做过相应的介绍,比如这里。
这里我们仍然以我的线上壁纸宝贝项目来说明xcodebuild命令的使用(如果大家对壁纸宝贝不了解,可以通过这里了解。)
切到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可以解决这个问题。
安装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会缓存上次编译结果,为了保证编译结果正确,可以做如下操作:
在之前先执行xcodebuild clean命令。
删除文件夹DerivedData(如下图)。
下面讲解一下xcpretty的参数
不出意外的话,大家可以在项目目录下看到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在前面我们已经做个介绍了,下面主要讲解参数
稍等片刻,大家就能看到生成的report文件oclint_result.html,该文件样式在文章开头已经给出过,这里不重复截图了。
至此,文章开头提出的疑问大家已经完全解决了。
OCLint自定义规则
OCLint强大之处在于不但能用于检测代码中存在的警告、错误,还能自定义规则,目前官网上有60几个规则可用。大家可以参考一下,点击这里跳转
封装成脚本
为了方便自动化用于CI(如果读者对CI还不够了解,可以参看这里),我们一般会把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
解决方案:
如果电脑里面安装了两个Xcode的话可能会报上面错误,删掉其他只剩一个
xcode9以后:
更新到最新的oclint, brew upgrade oclint
去github下载最新的oclint.sh,替换掉旧的
试试手动将 工程=> Build Settings => 搜索COMPILER_INDEX_STORE_ENABLE 该配置设成NO
参考
相关推荐: