OCLint 工具的使用与规则配置

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容