OCLint is a static code analysis tool for improving quality and reducing defects
by inspecting C, C++ and Objective-C code.
It looks for potential problems that aren't visible to compilers, for example:
Possible bugs - empty if/else/try/catch/finally statements
Unused code - unused local variables and parameters
Complicated code - high cyclomatic complexity, NPath complexity and high NCSS
Redundant code - redundant if statement and useless parentheses
Code smells - long method and long parameter list
Bad practices - inverted logic and parameter reassignment
...
For more information, visit http://oclint.org
1. OCLint
OCLint是一套工具的总称,其中包含以下工具:
oclint :是OCLint工具集最主要的指令,用于规则加载、编译分析选项以及生产分析报告。
oclint-json-compilation-database :用于在JSON Compilation Database format类型的编译文件compile_commands.json中提取必要信息。
oclint-xcodebuild :用于将xcodebuild生产的log文件xcodebuild.log转换为JSON Compilation Database format类型的文件。
2. xcodebuild
使用OCLint需要搭配Xcode,准确的来说是使用Xcode套件中的xcodebuild工具,xcodebuild可以对Xcode工程进行编译,生成对应的xcodebuild.log文件。
3. xcpretty
xcpretty是配合xcodebuild来生成并输出对应格式的工具,在OCLint的使用里,我们可以用xcpretty配合xcodebuild来替代oclint-xcodebuild来输出JSON Compilation Database format格式文件。
4. 时序图
在使用OCLint对iOS工程进行代码分析中所涉及到的工具我们都已经介绍完了,下面是这些工具对应使用的时序图:
配置和 运行 脚本
oclint_apply
使用oclint检测代码,在学习的过程中,为了方便写的一些脚本
替换workspace的名字
myworkspace="test.xcworkspace"
替换scheme的名字
myscheme="test"
输出方式 xcode/pmd/html
reportType="xcode"
nowReportType="-report-type html -o oclint_result.html"
自定义排除警告的目录,将目录字符串加到数组里面,结果中将不会含有Pods文件夹下文件编译警告
exclude_files=("test_js" "Pods")
Using OCLint in Xcode => 输出方式 xcode
Using OCLint with Jenkins CI => 输出方式 pmd
#!/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"
export LC_ALL=
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"
REPORT_HTML="html"
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} -sdk iphonesimulator -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=("cardloan_js" "Pods")
exclude=""
for i in ${exclude_files[@]}; do
exclude=${exclude}"-e "${i}" "
done
echo "排除目录:${exclude}"
# 分析reportType
if [[ ${reportType} =~ ${REPORT_PMD} ]]
then
nowReportType="-report-type pmd -o pmd.xml"
elif [[ ${reportType} =~ ${REPORT_HTML} ]]
then
nowReportType="-report-type html -o oclint_result.html"
else
nowReportType="-report-type xcode"
fi
# 自定义report 如:
# nowReportType="-report-type html -o oclint_result.html"
# 生成报表
oclint-json-compilation-database ${exclude} -- \
${nowReportType} \
-rc LONG_LINE=200 \
-disable-rule ShortVariableName \
-disable-rule ObjCAssignIvarOutsideAccessors \
-disable-rule AssignIvarOutsideAccessors \
-max-priority-1=100000 \
-max-priority-2=100000 \
-max-priority-3=100000
rm compile_commands.json
if [[ ${reportType} =~ ${REPORT_PMD} ]] && [ ! -f ./pmd.xml ]
then
echo "-----分析失败-----"
return -1
else
echo '-----分析完毕-----'
return 0
fi
}
# 替换workspace的名字
myworkspace="test.xcworkspace"
# 替换scheme的名字
myscheme="test"
# 输出方式 xcode/pmd
reportType="xcode"
oclintForProject ${myworkspace} ${myscheme} ${reportType}