iOS APP静态检测实践之 -- OCLint
$[timeformat('2021-10-08T10:37:57+08:00')]
#静态检测#代码检测

[toc]

跳转位置jumpID

点我跳转

参考文章

iOS使用OCLint做静态代码分析 OCLint 实现 Code Review - 给你的代码提提质量

安装

  • 安装xcpretty
sudo gem install xcpretty
  • 安装OCLint

    brew tap oclint/formulae
    
    brew install oclint
    

参数介绍

  • -R <路径> : 检测所用的规则的路径,默认路径$(/path/to/bin/oclint)/../lib/oclint/rules

  • -disable-rule <规则名>: 让相对应的规则失效(OCLint 规则列表)。

  • -rc <参数>=<值> :修改阈值

  • -report-type <报告类型>,有"text"、“html”、“json”、“pmd”、“xcode”几个类型

  • -o <路径> 报告生成路径。

oclint-json-compilation-database 指令

  • -i :包含进某些文件
  • -e : 过滤掉某些文件
# 排除Pods 里的文件
oclint-json-compilation-database -e Pods 
# 包含进Pods里的文件
oclint-json-compilation-database -i Pods

OCLint 官方文档 参考文章1

检查单个文件

oclint [options] <source> -- [compiler flags]
oclint sample.cpp -- -c

想要改变oclint 的行为,options参数 需要 在文件资源前面添加,比如 导出报告:-html -o report.html 想要改变 编译行为,需要在 -- 后面添加参数

oclint -html -o report.html sample.cpp -- -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -I/usr/include -I/usr/local/include -c
kIsysroot="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.4.sdk"
kFilePath="LXCategory/AppDelegate.m"
# 编译文件
clang -x objective-c -arch armv7 -std=gnu99 -fobjc-arc -O0 -isysroot $kIsysroot -g -I./Pods/Headers -c $kFilePath
# 分析文件
oclint -report-type=html -o=report.html $kFilePath -- -x objective-c -arch armv7 -std=gnu99 -fobjc-arc -O0  -isysroot $kIsysroot -g -I ./Pods/Headers -c

检查整个iOS项目

编译导出

  • 编译之前先 clean一下,然后再build
  • 导出日志文件 xcodebuild.log
  • xcpretty导出json文件
xcodebuild clean build -project $kProjectName -target $kTargetName -configuration $kConfigurationType -sdk $kSDKName | tee xcodebuild.log | xcpretty --report json-compilation-database 

workspace项目 可以参考xcodebuild的使用方法: xcodebuild archive -workspace "$workspaceName" -scheme "$scheme" -configuration "$kConfiguration"

分析项目

  • 命令添加分析规则
oclint-json-compilation-database -e LXCategory/Third -e  LXCategory/test -- \
-report-type html -o ./AppOutput/oclint-out/oclint_report.html \
-max-priority-1=100000 \
-max-priority-2=100000 -max-priority-3=100000 \
-disable-rule=InvertedLogic \
-disable-rule=CollapsibleIfStatements \
-disable-rule=UnusedMethodParameter \
-disable-rule=LongVariableName \
-disable-rule=ShortVariableName \
-disable-rule=UselessParentheses \
-disable-rule=IvarAssignmentOutsideAccessorsOrInit \
  • 配置文件添加分析规则
  1. 我们需要在项目根目录下创建一个名为.oclint的配置文件
  2. 在配置文件中添加规则
  3. 添加忽略文件等...

命令如下:

oclint-json-compilation-database -e LXCategory/Third -e LXCategory/test

.oclint配置文件内容如下:

rule-configurations:
  - key: CYCLOMATIC_COMPLEXITY # Cyclomatic complexity of a method 10
    value: 30
  - key: LONG_LINE
    value: 110
  - key: NCSS_METHOD # Number of non-commenting source statements of a method 30
    value: 50
  - key: LONG_VARIABLE_NAME
    value: 40
  - key: NESTED_BLOCK_DEPTH
    value: 6
  - key: MINIMUM_CASES_IN_SWITCH
    value: 2
  - key: SHORT_VARIABLE_NAME
    value: 1
  - key: TOO_MANY_METHODS
    value: 50
  - key: LONG_METHOD
    value: 100
disable-rules:
  - RedundantLocalVariable 
  - SHORT_VARIABLE_NAME 
  - LongVariableName
  - UnnecessaryElseStatement 
  - RedundantNilCheck 
  - RedundantIfStatement
  - InvertedLogic
  - AssignIvarOutsideAccessors
  - UseObjectSubscripting
  - BitwiseOperatorInConditional
  - PreferEarlyExit
  - UnusedMethodParameter

max-priority-1: 1000
max-priority-2: 1000
max-priority-3: 1000
enable-clang-static-analyzer: false

output: AppOutput/oclint-out/oclint_report.html
report-type: html
  • 个人Demo项目脚本如下
kTargetName="LXCategory"
kProjectName="LXCategory.xcodeproj"
kConfigurationType="Debug"
kSDKName="iphonesimulator"
kOuptputPath="AppOutput/oclint-out"

# html 报告导出路径
kHTML_Report_Name="oclint_report.html"
# 分析结果json文件名
kJSON_Data_Name="compile_commands.json"

# 清理、编译 -- 格式化导出json 1------------------
xcodebuild clean build -project $kProjectName -target $kTargetName -configuration $kConfigurationType -sdk $kSDKName | tee xcodebuild.log | xcpretty --report json-compilation-database 

echo "准备复制json文件 到目录:${kOuptputPath}..."
# 必须要复制到项目根目录下 才能分析成功
cp "build/reports/compilation_db.json" $kJSON_Data_Name
cp "build/reports/compilation_db.json" "${kOuptputPath}/${kJSON_Data_Name}"

echo "复制完毕..."

echo "准备进入导出文件目录: AppOutput/oclint-out  ..."

# 分析项目 2--------------------------------
# 方案一:
# 如果过不在命令里配置规则,就默认读取规则里的规则 配置文件里无法配置忽略文件😂
# oclint-json-compilation-database -e LXCategory/Third -e LXCategory/test

# 方案二:
# 命令里设置参数 读取命令里的规则
oclint-json-compilation-database -e LXCategory/Third -e  LXCategory/test -- \
-report-type html -o AppOutput/oclint-out/oclint_report.html \
-max-priority-1=100000 \
-max-priority-2=100000 -max-priority-3=100000 \
-disable-rule=InvertedLogic \
-disable-rule=CollapsibleIfStatements \
-disable-rule=UnusedMethodParameter \
-disable-rule=LongVariableName \
-disable-rule=ShortVariableName \
-disable-rule=UselessParentheses \
-disable-rule=IvarAssignmentOutsideAccessorsOrInit \

# 处理报告文件 3--------------------------
echo "准备打开 报告文件:😁"
pwd
sleep 2.0
# 打开 HTML 格式的报告文件
open "${kOuptputPath}/${kHTML_Report_Name}"
# 删除项目根目录下的json分析文件
rm $kJSON_Data_Name

注意事项

  • 忽略文件

忽略文件配置 -e Pods -e Pods,这个只能在命令中设置,配置文件中配置不了。

  • 检查文件

忽略文件配置 -i Pods -i Pods,这个只能在命令中设置,配置文件中配置不了。

  • 配置文件

配置文件的设置,会和命令设置 有冲突,二者选其一。