1.简介
OCLint用于C,C++和Objective-C的静态源代码分析工具,用于提高代码质量,减少瑕疵。
2.安装
2.1安装简述
OCLint是一个开源的项目,可以通过源码安装,需要设置对应的环境变量,也可以使用作者发布的release进行安装,不过推荐使用Homebrew安装。
2.2安装方法
1、首先需要设置brew的第三方仓库oclint/formulae。
brew tap oclint/formulae
2、然后安装OCLint。
brew install oclint
针对对OCLint升级的方法:
brew update
brew upgrade oclint
使用brew cleanup可以清理旧版本的安装数据。
3.检查
安装完成后可运行oclint –version检查是否安装成功
3.OCLint命令说明
详细执行代码质量检查的方法已集成到脚本中,使用方式见下述。
关于脚本中各命令的解释可参考OCLint 安装与使用。
4.使用方式
此章节主要介绍如何使用脚本进行代码质量检查。
1、将附录中保存为xxx.sh文件;
2、chmod +x xxx.sh;
3、.sh文件赋值到要检测的工程目录下;
4、cd 到工程目录;
5、运行脚本 ./xxx.sh;
6、执行完成后会在工程目录下生成oclintReport.html文件;
文件形式如图:
5.结果参数说明
这篇文章发布时OCLint版本为0.11.0,最新oclint包含71个检查规则,主要对针对nil值的检查,cocoa的obj检查,类型转换,空值的检查,简洁语法的检查,参数,size和不使用的参数和变量的检查。
主要分为9大类:
Basic
Cocoa
Convention
Empty
Migration
Naming
Redundant
Size
Unused
OCLint的静态分析结果,警告的级别是从P1,P2,P3依次降低的,可以根据生成的报告找到对应的规则,以及修改建议。
比如下面是一条生成的警告信息:
..../.../SuperLoggerPreviewView.m:165:5:bitwise operator in conditional [basic|P2]
·..../.../SuperLoggerPreviewView.m:165:5:的意思是产生警告的文件以及对应的行号。
·bitwise operator in conditional:描述信息。
·[basic|P2]这个信息中basic是指检查规则的类型,对应检查规则的9大类别,P2是警告的级别
可以在Rule Index 的第一个分类Basic中可以找到bitwiseoperatorinconditional,就是需要了解的规则信息:
6.禁止OCLint的检查
有的时候在已知的情况下一段代码会产生OCLint的警告,但是因为其他的一些原因,我们又不能修改代码,或者还没有找到更好的修改方式的时候,可以在代码中禁止OCLint的检查。
6.1注解
可以使用注解的方法禁止OCLint的检查,语法是:
__attribute__((annotate("oclint:suppress[unusedmethod parameter]")))
比如我们知道一个参数没有使用,而又不想产生警告信息就可以这样写:
-(IBAction)turnoverValueChanged:
(id) __attribute__((annotate("oclint:suppress[unusedmethod parameter]"))) sender
{
int i; // won't suppress this one
[self calculateTurnover];
}
对于方法的注解可以这样写:
bool__attribute__((annotate("oclint:suppress"))) aMethod(int aParameter)
{
// warnings within this method aresuppressed at all
// like unused aParameter variable andempty if statement
if (1) {}
return true;
}
6.2!OCLint
也可以通过//!OCLint注释的方式,不让OCLint检查。比如:
void a() {
int unusedLocalVariable; //!OCLINT
}
注释要写在对应的行上面才能禁止对应的检查,比如对于空的if/else禁止检查的注释为:
if (true) //!OCLint
{
// it is empty
}
OCLint官方规则文档中文说明OCLint官方规则文档中文说明
注:笔者没有使用xcworkspace,所以当工程中有xcworkspace时,可能需要修改脚本内容,可参考oclint=project=build=done以上的编译命令。
另笔者在调研过程中发现一个不错的工具,godeyes,不过可能不太稳定。
附录
脚本命令
# import path
export PATH=${PATH}:/usr/local/bin
# import what we have in bash_profile
source ~/.bash_profile
# oclint
workspaceExt=".xcworkspace"
tempPath=""
project_path=$(pwd)
project_name=$(ls | grep xcodeproj | awk -F.xcodeproj '{print $1}')
# 更新第三方库
#if [ -f Podfile ]; then
#echo "==========pod update========="
#pod update
#fi
# find .xcworkspace
for workspacePath in `find ${project_path} -name "$project_name$workspaceExt" -print`
do
tempPath=${workspacePath}
break
done
echo "===========oclint=========="
if [ "$tempPath" == "" ];then
# oclint clean
xctool -project ${project_name}.xcodeproj \
-scheme ${project_name} \
-reporter json-compilation-database:compile_commands.json \
clean
echo "===========oclint=project=clean=done========="
# build
#xctool -project ${project_name}.xcodeproj \
#-scheme ${project_name} \
#-reporter json-compilation-database:compile_commands.json \
#build
xcodebuild |xcpretty -r json-compilation-database
mv build/reports/compilation_db.json compile_commands.json
echo "===========oclint=project=build=done========="
else
# oclint clean
xctool -workspace ${project_name}.xcworkspace \
-scheme ${project_name} \
-reporter json-compilation-database:compile_commands.json \
clean
echo "===========oclint=workspace=clean=done========="
# build
xctool -workspace ${project_name}.xcworkspace \
-scheme ${project_name} \
-reporter json-compilation-database:compile_commands.json \
build
echo "===========oclint=workspace=build=done========="
fi
# 生成报表
oclint-json-compilation-database -v \
-e Pods \
oclint_args -- -report-type html -o oclintReport.html \
-disable-rule ObjCAssignIvarOutsideAccessors \
-disable-rule AssignIvarOutsideAccessors \
-disable-rule UnusedMethodParameter \
-disable-rule InvertedLogic \
-disable-rule UseNumberLiteral \
-disable-rule UseContainerLiteral \
-rc=MINIMUM_CASES_IN_SWITCH=3 \
-rc=LONG_VARIABLE_NAME=40 \
-disable-rule ShortVariableName \
-rc=CYCLOMATIC_COMPLEXITY=10 \
-rc=LONG_CLASS=1000 \
-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
# 删除 compile_commands.json 可能会很大
jsonPath=$project_path/"compile_commands.json"
#echo ${jsonPath}
rm $jsonPath
open oclintReport.html
# 删除生成的build文件
buildFilePath=$project_path/"build"
rm -f -R $buildFilePath
exit
export PATH=${PATH}:/usr/local/bin
# import what we have in bash_profile
source ~/.bash_profile
# oclint
workspaceExt=".xcworkspace"
tempPath=""
project_path=$(pwd)
project_name=$(ls | grep xcodeproj | awk -F.xcodeproj '{print $1}')
# 更新第三方库
#if [ -f Podfile ]; then
#echo "==========pod update========="
#pod update
#fi
# find .xcworkspace
for workspacePath in `find ${project_path} -name "$project_name$workspaceExt" -print`
do
tempPath=${workspacePath}
break
done
echo "===========oclint=========="
if [ "$tempPath" == "" ];then
# oclint clean
xctool -project ${project_name}.xcodeproj \
-scheme ${project_name} \
-reporter json-compilation-database:compile_commands.json \
clean
echo "===========oclint=project=clean=done========="
# build
#xctool -project ${project_name}.xcodeproj \
#-scheme ${project_name} \
#-reporter json-compilation-database:compile_commands.json \
#build
xcodebuild |xcpretty -r json-compilation-database
mv build/reports/compilation_db.json compile_commands.json
echo "===========oclint=project=build=done========="
else
# oclint clean
xctool -workspace ${project_name}.xcworkspace \
-scheme ${project_name} \
-reporter json-compilation-database:compile_commands.json \
clean
echo "===========oclint=workspace=clean=done========="
# build
xctool -workspace ${project_name}.xcworkspace \
-scheme ${project_name} \
-reporter json-compilation-database:compile_commands.json \
build
echo "===========oclint=workspace=build=done========="
fi
# 生成报表
oclint-json-compilation-database -v \
-e FMMapKit/3rd \
oclint_args -- -report-type html -o oclintReport.html \
-disable-rule ObjCAssignIvarOutsideAccessors \
-disable-rule AssignIvarOutsideAccessors \
-disable-rule UnusedMethodParameter \
-disable-rule InvertedLogic \
-disable-rule UseNumberLiteral \
-disable-rule UseContainerLiteral \
-rc=MINIMUM_CASES_IN_SWITCH=3 \
-rc=LONG_VARIABLE_NAME=40 \
-disable-rule ShortVariableName \
-rc=CYCLOMATIC_COMPLEXITY=10 \
-rc=LONG_CLASS=1000 \
-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
# 删除 compile_commands.json 可能会很大
jsonPath=$project_path/"compile_commands.json"
#echo ${jsonPath}
rm $jsonPath
open oclintReport.html
# 删除生成的build文件
buildFilePath=$project_path/"build"
rm -f -R $buildFilePath
exit