美文网首页iOS开发心得ios专题电脑相关
iOS使用OCLint做静态代码分析

iOS使用OCLint做静态代码分析

作者: 這Er | 来源:发表于2017-03-29 19:30 被阅读3874次

初识OCLint

OCLint是一个静态代码分析工具,提高质量和减少缺陷通过检查C 、C++ 和Objective-C 代码和寻找潜在的问题,如:

  • 可能的缺陷 - 空的if / else / try / catch / finally语句
  • 未使用的代码 - 未使用的局部变量和参数
  • 复杂的代码 - 很高的圈复杂度,NPath复杂性和太高的NCSS
  • 代码异味 - 长方法和参数列表
  • 长方法和参数列表不好的实践——倒逻辑和参数重新分配

  • 静态代码分析是一个来检测对于编译不可见的缺陷的关键技术。

注:* NPath 复杂度是一个方法中各种可能的执行路径总和 ; NCSS * 有效代码行
以上翻译自OCLint官网

安装

使用第三方的软件会比使用xcodebuild方便些
最新xctool的build方法已经弃用,不能配合OCLint使用,推荐使用xcpretty

// 安装OCLint
brew tap oclint/formulae
brew install oclint
// 安装xcpretty
gem install xcpretty

如果未安装home brew,自行去官网按提示安装

更新

// 以后可能需要更新
brew update
brew upgrade oclint

使用

在终端进入项目目录,然后替换workspace的名字和scheme的名字,将修改好的命令粘贴到终端执行,等待命令执行完毕

myworkspace=haha.xcworkspace # 替换workspace的名字
myscheme=haha # 替换scheme的名字
xcodebuild -workspace $myworkspace -scheme $myscheme clean&&
xcodebuild -workspace $myworkspace -scheme $myscheme \
-configuration Debug \
| xcpretty -r json-compilation-database -o compile_commands.json&&
oclint-json-compilation-database -e Pods -- \
-report-type html -o oclint_result.html \
-rc LONG_LINE=200 \
-max-priority-1=100000 \
-max-priority-2=100000 \
-max-priority-3=100000; \
rm compile_commands.json;
if [ -f ./oclint_result.html ]; then echo '-----分析完毕-----'
else echo "-----分析失败-----"; fi

中间可能会在Build Succeeded后面等待一段时间,这是因为OCLint在分析文件
等待命令执行完成,终端会打印出-----分析完毕-----字样,
打开项目目录,会看到目录下会多出一个** oclint_result.html **的文件

如果没有使用cocoapods,则去掉myworkspace=haha.xcworkspace-workspace $myworkspace-workspace $myworkspace,然后再在终端执行
另外可以自己建一个xx.sh的文件,将上面代码粘贴进去,每次在命令行进入xx.sh所在目录执行bash xx.sh就可以了

查看

双击打开oclint_result.html文件,样式如下
OCLint的分析结果:
优先级的级别是从Priority 1, Priority 2, Priority 3 依次降低的
Total Files 总文件数
Files with Violations 违规文件数
Compiler Warnings 表示项目中的警告⚠️
Compiler Errors 表示编译错误
Location 表示警告的位置
报告中的描述其实非常清晰,一般找到代码位置,结合代码理解下,自己基本都能明白了
可以直接复制路径到Chrome打开查看,右击查看源码就有行号

Paste_Image.png

自定义规则

上面的命令中
-e Pods 表示移除Pods文件夹里代码的分析, 如果有继续-e Debug.m
-report-type html 表示分析后输出的文件类型为HTML,查看其他支持的文件类型
-o oclint_result.html 表示输出到oclint_result.html这个文件中()
-rc LONG_LINE=200 表示每行最大字节长度为200(默认值为100,感觉在OC中100完全不够用啊)

一些常用规则的注释
# --命名
# 变量名字最长字节
#-rc=LONG_VARIABLE_NAME=20 \
# 变量名字最短字节
#-disable-rule ShortVariableName \
# --size
# 圈复杂度
#-re=CYCLOMATIC_COMPLEXITY=10 \
# 每个类最行数
#-rc=LONG_CLASS=700 \
# 每行字节数量
#-rc=LONG_LINE=200 \
# 每个方法行数
#-rc=LONG_METHOD=80 \
# 忽略注释后括号后的有效代码行数
#-rc=NCSS_METHOD=40 \
# 嵌套深度
#-rc=NESTED_BLOCK_DEPTH=5 \
# 字段数量
#-rc=TOO_MANY_FIELDS=20 \
# 方法数量
#-rc=TOO_MANY_METHODS=30 \
# 方法参数
#-rc=TOO_MANY_PARAMETERS=6

oclint-json-compilation-database命令手册
oclint命令手册
OCLint自定义规则介绍
OCLint全部规则介绍
文档里面有每个规则的demo和对应的命令名字,上面没介绍到的大家可以去文档查询

Xcode集成OCLint

这里有官网指导网址,十分简单
http://oclint-docs.readthedocs.io/en/stable/guide/xcode.html
但是有点小坑:可能出现下面错误

in `===': invalid byte sequence in US-ASCII

此时你需要在xcode的脚本的最前面,加上:

# 指定编码
export LANG="zh_CN.UTF-8"
export LC_COLLATE="zh_CN.UTF-8"
export LC_CTYPE="zh_CN.UTF-8"
export LC_MESSAGES="zh_CN.UTF-8"
export LC_MONETARY="zh_CN.UTF-8"
export LC_NUMERIC="zh_CN.UTF-8"
export LC_TIME="zh_CN.UTF-8"
export LC_ALL=

我写了一个简单的脚本文件oclint_xcode大家可以自己下载,可替换的变量,已经在脚本中使用注释标注了出来

创建一个OCLint的Aggregate,将脚本放到项目工程根目录下,在Run Script中加入以下代码,点击运行即可

bash ./oclint.sh

Jenkins集成OCLint

1. 创建一个PMDOclint.sh的文件, 将下述代码拷贝到文件中,并将文件放入到jenkins的根目录下 (例如我的就是/Users/buildWork/.jenkins/PMDOclint.sh) , 我自己使用的脚本放到了仓库中oclint_apply,可以去里面下载apply_jenkins/PMDOclint.sh
2. jenkins需要安装PMD Plugin插件
3. jenkins新建一个项目,Git配置成需要代码分析的代码库
4. 剩下的按照下图配置,(将PMDOclint.sh放到Jenkins的主目录,如果出现问题,涉及到的路径,请注意检查一下)
QQ20170628-170241.png
5. 效果
效果图

Warning❗️

(一). xcodebuild命令不好用的时候,使用com + opt + shift + kcom + shift + k 有80%的可能解决😂
(二). oclint: error: one compiler command contains multiple jobs:
解决方案:

1. 如果电脑里面安装了两个Xcode的话可能会报上面错误,删掉其他只剩一个
xcode9以后(OCLint version 0.13, Version 9.2 beta (9C34b) 测试可用):
2.1 更新到最新的oclint, brew upgrade oclint
2.2 去github下载最新的oclint.sh,替换掉旧的
3. 试试手动将 工程=> Build Settings => 搜索COMPILER_INDEX_STORE_ENABLE 该配置设成NO



oclint_apply仓库地址

参考文章:

用OCLint给iOS代码做静态分析
OCLint 规则与结果分析

相关文章

  • 使用OCLint + Jenkins集成iOS代码静态分析

    使用OCLint + Jenkins集成iOS代码静态分析 Installing OCLint Updating ...

  • iOS使用OCLint做静态代码分析

    初识OCLint OCLint是一个静态代码分析工具,提高质量和减少缺陷通过检查C 、C++ 和Objective...

  • OCLint规则与结果分析

    OCLint是用来做c,c++和Objective-c的静态代码分析工具。在OCLint安装和使用中介绍了OCLi...

  • OCLint代码静态分析问题

    OCLint代码静态分析问题 oclint: error: one compiler command contai...

  • OCLint 安装使用

    简介 OCLint 官方文档[http://oclint.org/]OCLint是一种静态代码分析[https:/...

  • iOS工程自动化 - OCLint

    为什么要使用 OCLint 做为一个静态代码分析工具,我们引入 OCLint 的目的主要是为了提高我们的代码质量。...

  • OClint的使用

    关于OCLint OCLint 是基于LLVM/Clang(前端编译)而开发的代码静态分析工具。 OCLint可用...

  • iOS - OCLint静态代码分析

    来自:http://oclint.orgOCLint 就是一个建立在 Clang 上的工具,能够发现代码中潜在的问...

  • OCLint 代码静态分析

    OCLint 代码静态分析 为了提高代码质量和代码走查的效率,软件开发过程中一般会使用静态代码分析工具来对程序正确...

  • 学习OCLint的使用

    最近看了下自动代码静态分析的工具,学习了一下OCLint的使用,将整个的安装、脚本记录如下。 一、OCLint 的...

网友评论

  • 十一岁的加重:我又回来了,Jenkins上实践成功https://www.jianshu.com/p/913eb8bee96d
    十一岁的加重:@這Er 还差在Xcode中显示OCLint的警告了,感谢你的脚本
    這Er:@十一岁的加重 : :smile: :+1:
  • a5faeb700e91:问下楼主 编译成功分析成功,但是没有生成html文件啊
  • viveco:请问下,我没有使用你的xcode 脚本,但是没有生成 html 文件,但是生成了build 文件,里面有Lint.build 和 release -iphoneos
  • _阿南_:Command /bin/sh emitted errors but did not return a nonzero exit code to indicate failure
    报这个错是什么意思?

    并且也没有生成oclint_result.html文件。
  • 和运啊:楼主你好,我确实出现了in `===': invalid byte sequence in US-ASCII这个错误 ,但是加上你的指定编码后,更是狂暴一千多个错误“Shell Script Invocation Error”-"Unknown warning group Wreceiver-is-weak",什么鬼,求指导
  • 大胆造轮子:兄弟,-e Debug.m 这个语法,不起作用怎么办,虽然官方文档也是这么写的
    加下我QQ,讨论下呗:1486634154
    大胆造轮子:是的,哈哈,谢谢,我生成 html 的确是过滤掉了。

    // ============================
    另外还想请教一个问题:
    我设置report-type是xcode,我项目加了一个 target OCLint,里面加的Run script 加上 `bash ./oclint_apply.sh`,然后 build,xcode 没反应,也没报错;但是用终端在项目目录下执行这个脚本是能检测出来的。
    這Er:xcode会报错,但是最终生成的结果不包含
    大胆造轮子:我知道

    //====================
    # 自定义排除警告的目录,将目录字符串加到数组里面
    # 转化为:-e Debug.m -e Port.m -e Test
    exclude_files=("TestModel.m" "Pods")
    //====================

    这样还是会检测 TestModel.m
  • 大胆造轮子:怎么只检查项目中的某一个文件夹,或者怎么过滤掉文件夹?
    這Er:@大胆造轮子 脚本里有啊,看下汉字的注释,-e的命令
  • 十一岁的加重:▸ Build Succeeded
    -----编译数据生成完毕-----
    -----分析中-----
    排除目录:-e Pods -e MGBankCard -e MGBaseKit -e MGIDCard
    Traceback (most recent call last):
    File "/usr/local/bin/oclint-json-compilation-database", line 65, in <module>
    file_path = get_source_path(file_item["file"], file_item["directory"])
    File "/usr/local/bin/oclint-json-compilation-database", line 27, in get_source_path
    if file_attr.startswith(os.sep):
    AttributeError: 'NoneType' object has no attribute 'startswith'
    -----分析失败-----
    Build step 'Execute shell' marked build as failure
    [PMD] Skipping publisher since build result is FAILURE
    Finished: FAILURE

    求救
    十一岁的加重:@這Er 好的,明天去公司的Jenkins试试
    這Er:@十一岁的加重 更新了oclint_apply仓库代码,重新试下
    十一岁的加重:-----编译数据生成完毕-----
    -----分析中-----
    排除目录:-e Pods
    oclint: Not enough positional command line arguments specified!
    Must specify at least 1 positional argument: See: /usr/local/bin/oclint -help
    -----分析失败-----
    Build step 'Execute shell' marked build as failure
    [PMD] Skipping publisher since build result is FAILURE
    Finished: FAILURE
  • 十一岁的加重:好奇怪啊,一直配置不好PMD检测警告,它老是检测项目里的第三方,项目代码不检测,头痛啊
    244a3cd2d98a:brew install oclint 一直Failed to download resource "oclint"
    十一岁的加重:@這Er 是我的workspace里有主project和pod还有三个第三方的project,这样怎么排除啊,现在它老是检测这三个第三方的project
    這Er:有个-e 的配置排除一些目录
  • a2f037f7bfbb:为何我这里提示分析失败呢,会是哪些原因造成呢,谢谢
    這Er:@itsLUO 文章最后的解决方案可以么
    a2f037f7bfbb:@這Er 不能发图片呢,内容太长了, 前面一段话是这样的:oclint: error: one compiler command contains multiple jobs:
    這Er:@itsLUO log能不能贴下?
  • 十一岁的加重:jenkins pmd时,一直报
    PMDOclint.sh: line 17: xcpretty: command not found
    实际已经装了这个xcpretty
    十一岁的加重:@這Er 又解决了,都是环境变量引起的
    這Er:@十一岁的加重 你四楼不是问过了么:joy:
  • BillZhang88:oclint: error: one compiler command contains multiple jobs: 请问作者这个问题有没有遇到或者这个问题大概错在什么地方?
    這Er:文章中已经更新解决方案,更新到最新的脚本
  • 泺莫繁华:你好,我编译的时候-----生成编译数据失败-----
    Command /bin/sh failed with exit code 255
    你知道这个这么解决么?
    這Er:重启一下电脑,重新试试?
    Liric___:我也是
  • 东岳哥哥:遇到这个报错
    oclint: error: one compiler command contains multiple jobs
    但不知道怎么处理,就装了一个xcode9,有解决方法么
    b7040c026feb:@這Er 我遇到的是同样的问题,搜了官网的github的issue貌似很多人遇到了,并不是安装了两个xcode造成的。xcode9应该有兼容问题。
    b7040c026feb:@這Er 只有一个xcode
    這Er:bate版也算,只有一个Xcode么
  • 42975bfc3ff0:你好, 用jenkins 构建, 提示18行出错, 信息如下, 怎么解决
    ** CLEAN SUCCEEDED **

    /Users/Shared/Jenkins/Home/PMDOclint.sh: line 18: xcpretty: command not found
    xcodebuild: error: 'Gold.xcworkspace' does not exist.
    -----生成编译数据失败-----
    Build step 'Execute shell' marked build as failure
    [PMD] Skipping publisher since build result is FAILURE
    Finished: FAILURE
    這Er:@差不多__先生V :cry: 我的jenkins就是直接装的呀,你的账号是主账号么
    42975bfc3ff0:@這Er xcpretty 这个我已经装了, 应该是权限不足, 就是不能操作jenkins那个文件夹, 找了找又找不到改权限的方法
    這Er:你的jenkins的电脑上没有安装xcpretty命令,在文章中全局搜一下xcpretty,按照安装上应该就可以了
  • 21b2e9872035:myscheme=haha # 替换scheme -< 这个是填哪个
    21b2e9872035:@這Er 嚯嚯嚯。。可以。点个赞👍
    這Er:填自己项目的target的名字
  • 烛风小糊涂:请问 OCLint 能够在一张报表里面显示 Xcode Analyze 的结果和 OCLint 自己检查出来的结果吗?
    這Er:@烛风小糊涂 不了解:flushed:
  • 十一岁的加重:line 16: syntax error: unexpected end of file
    這Er:@十一岁的加重 :smile::+1:
    十一岁的加重:@這Er 已解决编码问题
    這Er:@十一岁的加重 报错的那一行代码发下
  • 十一岁的加重:line 6: xcpretty: command not found
    十一岁的加重:已解决 sudo gem install xcpretty
  • 這Er:@褪色的旧衬衫 你不会是用文本编辑器打开的吧,
    -report-type html -o oclint_result.html 如果命令里有这一行的话,试试Chrome打开oclint_result.html
    這Er:@wangbobo 检查下 -report-type html
    d90061a643a4:@褪色的旧衬衫 解决没,我今天尝试了一下,也是没有样式只有文本
    褪色的旧衬衫:@這Er 不是呀 就是用谷歌浏览器打开的 但是没有样式,全是文本
  • 褪色的旧衬衫:大兄弟 你那个生成的oclint_result报告是用什么展示的,怎么我这边生成的html报告是纯文本的?
    這Er:@21b2e9872035 格式问题的话 检查下 -report-type html
    21b2e9872035:使用的执行命令你是怎么改的

本文标题:iOS使用OCLint做静态代码分析

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