利用OCLint对代码进行静态审查

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文件;

文件形式如图:


利用OCLint对代码进行静态审查_第1张图片
生成报告样式

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


你可能感兴趣的:(利用OCLint对代码进行静态审查)