安装
-
建议使用
Homebrew
安装://依次执行 brew tap oclint/formulae //设置第三方仓库 brew install oclint //安装 //如未安装Homebrew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" //安装和OCLint配合使用的xcpretty gem install xcpretty
规则
OCLint是根据一系列定制的规则进行静态分析的,
OCLint所有规则
- 默认情况下,
OCLint
会使用所有的规则,但我们可以编写脚本配置规则:-
-disable-rule 规则名
命令:不使用该规则 -
-rc 规则名=新值
命令:重新设置新的规则值 - 如何自定义规则:参考文章
-
命令解释
oclint
:是 OCLint 工具集最主要的指令,主要作用是规则加载、编译分析选项以及生成分析报告oclint-json-compilation-database
: 的作用是在JSON Compilation Database format
类型的编译文件compile_commands.json
中提取必要的信息。oclint-xcodebuild
:用于将xcodebuild
生成的log
文件xcodebuild.log
转换为JSON Compilation Database format
类型xcodebuild
是苹果发布自动构建的工具,可以通过命令行脚本的方式编译、打包Xcode工程。
可以在终端输入man xcodebuild
来查询相关用法-
一个常见的分析命令如下:
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; \ 解释: \:用于表示后面的代码追加在本行,这样避免了一行命令过长的情况 -e:忽略某个文件、目录 -report-type:输出类型,支持HTML、XML等类型 -rc:表示某个规则,可以在后面具体制定
OCLint in 控制台
//控制台编译:如果你没有开发者证书,可加-sdk iphonesimulator
编译
xcodebuild -workspace 项目名.xcworkspace -scheme 项目名 -sdk iphonesimulator -configuration Debug
//编译,增强可读性
xcodebuild -workspace 项目名.xcworkspace -scheme 项目名 -sdk iphonesimulator -configuration Debug | xcpretty -r json-compilation-database -o compile_commands.json
- 参数说明:
-
-r
:--report
输出格式,可以是:Junit、html、json-compilation-database -
-o
:--output
输出路径 -
-sdk
:编译环境
-
OCLint in Xcode 使用--重点
-
步骤一:点击项目新增
new target
,选择Aggregate
作为模板:
-
步骤二:为
new target
进行命名:
-
步骤三:点击
build phase
,选择Add Run Script
:
-
步骤四:输入规则如下图和代码:
# workspace的名字(需要手动修改) WORKSPACE=ProjectApp.xcworkspace # scheme的名字(需要手动修改) SCHEME=ProjectApp #编译 xcodebuild -workspace $WORKSPACE -scheme $SCHEME clean&& xcodebuild -workspace $WORKSPACE -scheme $SCHEME \ -configuration Debug \ COMPILER_INDEX_STORE_ENABLE=NO \ #xcpretty生成compile_commands.json #oclint分析并生成指定格式报告(html) -report-type命令指定报告类型 #-e参数指定需要忽略的文件,即这些文件不用分析 | xcpretty -r json-compilation-database -o compile_commands.json&& oclint-json-compilation-database -e Pods -e Vender -- \ -report-type xcode \ #设置规则 -disable-rule ProblematicBaseClassDestructor \ -disable-rule DestructorOfVirtualClass \ -disable-rule AssignIvarOutsideAccessors \ -disable-rule ParameterReassignment \ -disable-rule ShortVariableName \ -disable-rule RedundantLocalVariable \ -disable-rule TooManyFields \ -disable-rule TooManyMethods \ -disable-rule UnusedLocalVariable \ -disable-rule UnusedMethodParameter \ -disable-rule HighCyclomaticComplexity \ -disable-rule HighNcssMethod \ -rc LongClass=1000 \ -rc LONG_LINE=200 \ -rc LongMethod=100 \ -rc TooManyParameters=8 \ -rc DeepNestedBlock=5 \ -max-priority-1=100000 \ -max-priority-2=100000 \ -max-priority-3=100000; \ rm compile_commands.json or source ~/.bash_profile cd ${SRCROOT} xcodebuild clean xcodebuild -workspace demo.xcworkspace -scheme demo | xcpretty -r json-compilation-database --output compile_commands.json oclint-json-compilation-database -v \ -e Pods \ -e MGLivenessDetection \ -e MGBaseKit \ -e MGIDCard \ oclint_args -- -report-type xcode \ -disable-rule ObjCAssignIvarOutsideAccessors \ -disable-rule ShortVariableName \ -rc=MINIMUM_CASES_IN_SWITCH=3 \ -rc=CYCLOMATIC_COMPLEXITY=10 \ -rc=LONG_CLASS=700 \ -rc=LONG_LINE=200 \ -rc=NCSS_METHOD=40 \ -rc=NESTED_BLOCK_DEPTH=5 \ -rc=TOO_MANY_FIELDS=20 \ -rc=TOO_MANY_METHODS=30 \ -rc=TOO_MANY_PARAMETERS=6 exit
-
步骤五:运行,静态分析
Command + B
封装成脚本
实例1:
#! /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 自己的项目名.xcworkspace -scheme 自己的项目名Scheme \
-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; \
实例2:
#!/bin/bash
# 指定编码
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"
function checkDepend () {
command -v xcpretty >/dev/null 2>&1 || {
echo >&2 "I require xcpretty but it's not installed. Install:gem install xcpretty";
exit
}
command -v oclint-json-compilation-database >/dev/null 2>&1 || {
echo >&2 "I require oclint-json-compilation-database but it's not installed. Install:brew install oclint";
exit
}
}
function oclintForProject () {
# 检测依赖
checkDepend
projectName=$1
scheme=$2
reportType=$3
REPORT_PMD="pmd"
REPORT_XCODE="Xcode"
myworkspace=${projectName}
myscheme=${scheme}
echo "myworkspace是:${myworkspace}"
echo "myscheme是:${myscheme}"
echo "reportType为:${reportType}"
# 清除上次编译数据
if [ -d ./build/derivedData ]; then
echo '-----清除上次编译数据derivedData-----'
rm -rf ./build/derivedData
fi
# xcodebuild -workspace $myworkspace -scheme $myscheme clean
xcodebuild clean
echo '-----开始编译-----'
# 生成编译数据
xcodebuild -workspace ${myworkspace} -scheme ${myscheme} -UseModernBuildSystem=NO -derivedDataPath ./build/derivedData -configuration Debug COMPILER_INDEX_STORE_ENABLE=NO | xcpretty -r json-compilation-database -o compile_commands.json
if [ -f ./compile_commands.json ]
then
echo '-----编译数据生成完毕-----'
else
echo "-----生成编译数据失败-----"
return -1
fi
echo '-----分析中-----'
# 自定义排除警告的目录,将目录字符串加到数组里面
# 转化为:-e Debug.m -e Port.m -e Test
exclude_files=("Pods")
exclude=""
for i in ${exclude_files[@]}; do
exclude=${exclude}"-e "${i}" "
done
echo "排除目录:${exclude}"
# 分析reportType =~判断子字符串包含关系
if [[ ${reportType} =~ ${REPORT_PMD} ]]
then
nowReportType="-report-type html -o pmd.html"
else
nowReportType="-report-type Xcode"
fi
# 自定义report 如:
# nowReportType="-report-type html -o oclint_result.html"
echo "**************${nowReportType}"
# 生成报表
oclint-json-compilation-database ${exclude} -- \
${nowReportType} \
-rc=LONG_CLASS=1500 \
-rc=NESTED_BLOCK_DEPTH=5 \
-rc=LONG_VARIABLE_NAME=80 \
-rc=LONG_METHOD=200 \
-rc=LONG_LINE=300 \
-disable-rule ShortVariableName \
-disable-rule ObjCAssignIvarOutsideAccessors \
-disable-rule AssignIvarOutsideAccessors \
-disable-rule TooManyMethods \
-disable-rule BitwiseOperatorInConditional \
-max-priority-1=100000 \
-max-priority-2=100000 \
-max-priority-3=100000
#rm compile_commands.json
if [[ ${reportType} =~ ${REPORT_PMD} ]] && [ ! -f ./pmd.html ]
then
echo "-----分析失败-----"
return -1
else
echo '-----分析完毕-----'
return 0
fi
}
# 替换workspace的名字
myworkspace="Project.xcworkspace"
# 替换scheme的名字
myscheme="Project"
# 输出方式 Xcode/pmdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
reportType="pmd"
oclintForProject ${myworkspace} ${myscheme} ${reportType}
保存oclint.sh
文件在同项目的顶级目录里面,然后控制台执行:sh oclint.sh
or ./oclint.sh
参照
参考文章
参考文章1
参考文章2