美文网首页
利用OCLint对代码进行静态审查

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

作者: smallLabel | 来源:发表于2017-03-02 16:24 被阅读669次

    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

    相关文章

      网友评论

          本文标题:利用OCLint对代码进行静态审查

          本文链接:https://www.haomeiwen.com/subject/rihkgttx.html