OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

背景

随着代码量的日益添加,以及团队的扩大,咱们往往由于需求需求尽快上线以及快速迭代,导致代码并不是很标准,时间长了就留下了一堆技能债,代码的质量也没有了确保。所以开端尝试一些代码质量相关建造,希望能够通过代码静态扫描的方法,协助咱们扫描出一些代码漏洞,然后尝试去修复漏洞和bug,以此来确保代码质量。

东西与渠道

本文触及的东西及渠道:

  • xcodebuild
  • xcpretty
  • oclint
  • infer
  • sonarqube
    • sonar-scanner
    • sonar-server
    • postgresql
    • sonar-swift

开源计划介绍及装备

大部分iOS渠道代码静态剖析基本是根据开源的oclint或许infer进行的,本文尽管运用sonarqube,但免费的剖析计划中心仍然是oclintinfer

sonarqube是一个开源的静态代码剖析渠道,供给免费的社区版,免费的社区版不支撑Objective-C,但github有供给开源的插件,Objective-C,付费的社区版plus有支撑Objective-C的剖析插件SonarCFamily for C

不管免费计划还是付费计划,首先都是根据xcodebuid过程中的日志来进行的,咱们这次首要针对开源计划来讲相关装备流程。

对于运用开源计划来说,本质流程如下:

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

xcodebuild

iOS中心东西,装置好Xcode就会自带此东西,由于oclint剖析的中心是xcodebuild在编译app过程中的log,所以需求xcodebuild(build失利也会对现已build的日志进行剖析,但尽量确保能够build成功)

假如项目是在workspace中需求指定-workspace和对应的scheme,能够通过xcodebuild -list检查

//履行
$ xcodebuild -list

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

//履行
$ xcodebuild -workspace CsdnPlus.xcworkspace -scheme CsdnPlus

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

咱们并不需求打出的IPA包能够装置到手机上,只是需求build过程中的日志罢了,所以咱们只需求打出模拟器下Debug包就能够了。

//履行
$ xcodebuild -showsdks

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

由于xcodebuild会有缓存,所以咱们每次履行前需求clean

$ xcodebuild -workspace CsdnPlus.xcworkspace -scheme CsdnPlus clean

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

履行build编译

$ xcodebuild -scheme CsdnPlus -workspace CsdnPlus.xcworkspace -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 12 Pro Max' -configuration Debug

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
能编译成功的话就能够进入下一步了

xcpretty

xcpretty is a fast and flexible formatter for xcodebuild. It does one thing, and it should do it well.

xcpretty是一个格局化xcodebuild输出的东西。装置:

$ gem install xcpretty

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

-r, --report 指定生成的陈述格局可选为junit, html, json-compilation-database

-o, --output指定生成的文件称号。 这儿咱们运用json-compilation-database格局,输出文件名为compile_commands.json (留意输出称号不能更改,否则后边oclint会报错,由于oclint源码中内置了校验称号,详细可检查源码)

用法:

紧跟在xcodebuild相关句子后边,比方:

$ xcodebuild [flags] | xcpretty

能够结合tee进行日志收集

$ xcodebuild [flags] | tee xcodebuild.log | xcpretty

履行完好指令生成编译数据compile_commands.json文件:

首先需求用xcodebuild cleanbuild项目,而且添加COMPILER_INDEX_STORE_ENABLE=NO参数,否则可能会出现报错:oclint: error: one compiler command contains multiple jobs报错

$ xcodebuild -scheme CsdnPlus -workspace CsdnPlus.xcworkspace -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 12 Pro Max' -configuration Debug GCC_PRECOMPILE_PREFIX_HEADER=YES CLANG_ENABLE_MODULE_DEBUGGING=NO COMPILER_INDEX_STORE_ENABLE=NO OTHER_CFLAGS="-DNS_FORMAT_ARGUMENT(A)= -D_Nullable_result=_Nullable" | tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json

OCLint

OCLint is a static code analysis tool for improving quality and reducing defects by inspecting C, C++ and Objective-C code

OCLint 是根据 Clang Tooling 开发的静态剖析东西,首要用来发现编译器检查不到的那些潜在的关键技能问题。是进行OC代码剖析的中心东西,首要对上一步生成的compile_commands.json进行剖析,生成陈述

指令装置:

$ brew tap oclint/formulae
$ brew install oclint

我主张运用装置包来装置OCLint,Homebrew 装置只能装置到20.11版别,最新Xcode 版别对应的是22.02。假如装置版别不符合,OClint剖析出来只要一堆compiler error

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

下载装置包装置:

https://github.com/oclint/oclint/releases

装备环境变量:

export PATH="/Users/csdn/oclint-22.02/bin:$PATH"
source ~/.zshrc

在终端输入 oclint --version,验证是否装置成功。

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
在终端输入oclint --help 检查指令介绍
OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
其间咱们首要运用oclint-json-compilation-database指令,Github源码

oclint-json-compilation-database指令支撑指定校验文件夹和过滤指定文件夹,本质上最终履行oclint -p指令,能够通过附加-v检查,一起还支撑运用--后边跟上oclint履行参数。 例如:

// 此处--符号后的参数是传递给oclint的
$ oclint-json-compilation-database -v -e Pods -e xxxx -- -report-type html -o report.html

oclint-rc选项能够自定义校验的参数值,例如:

$ oclint-json-compilation-database -v -e Pods -e xxxx -- -rc LONG_METHOD=60 -rc LONG_LINE=100

别的当咱们需求自定义多个oclint参数时,咱们能够将装备写在.oclint文件中

disable-rules:                      // 不运用的规矩
   - LongLine
rulePaths:                          // oclint校验规矩地点的途径,Mac端默许在/usr/local/lib/oclint/rules,假如不需求自定义规矩的话能够不装备此项
  - /etc/rules
rule-configurations:                // 自定义装备参数
  - key: CYCLOMATIC_COMPLEXITY
    value: 15
  - key: NPATH_COMPLEXITY
    value: 300
output: oclint.xml                  // 生成的陈述
report-type: xml                    // 生成的陈述格局支撑html、xml、json等
max-priority-1: 20                  // 等级1的问题最大个数,假如检测出的问题超越这个个数就会自动终止
max-priority-2: 40                  // 等级2的问题最大个数
max-priority-3: 60                  // 等级3的问题最大个数
enable-clang-static-analyzer: false //

以下是OCLint内置支撑的72条Rule,能够通过 --list-enabled-rules x检查

$ oclint --list-enabled-rules x
enabled rules:
- TooManyMethods
- DestructorOfVirtualClass
- DeadCode
- EmptyForStatement
- AvoidDefaultArgumentsOnVirtualMethods
- ProblematicBaseClassDestructor
- MisplacedDefaultLabel
- EmptyFinallyStatement
- CallingProhibitedMethod
- RedundantIfStatement
- CollapsibleIfStatements
- UnnecessaryElseStatement
- ConstantConditionalOperator
- DeepNestedBlock
- AssignIvarOutsideAccessors
- UnnecessaryNullCheckForDealloc
- RedundantNilCheck
- RedundantLocalVariable
- EmptyDoWhileStatement
- UnusedMethodParameter
- BitwiseOperatorInConditional
- ReturnFromFinallyBlock
- MultipleUnaryOperator
- DoubleNegative
- MissingCallToBaseMethod
- EmptyWhileStatement
- ShortVariableName
- ParameterReassignment
- UselessParentheses
- ThrowExceptionFromFinallyBlock
- UnnecessaryDefaultStatement
- HighNcssMethod
- PreferEarlyExit
- MissingBreakInSwitchStatement
- TooManyParameters
- CallingProtectedMethod
- AvoidBranchingStatementAsLastInLoop
- MissingAbstractMethodImplementation
- MissingHashMethod
- MisplacedNullCheck
- MisplacedNilCheck
- UseContainerLiteral
- LongLine
- ForLoopShouldBeWhileLoop
- HighNPathComplexity
- LongMethod
- EmptySwitchStatement
- RedundantConditionalOperator
- EmptyTryStatement
- EmptyCatchStatement
- UseObjectSubscripting
- AvoidPrivateStaticMembers
- EmptyElseBlock
- InvertedLogic
- LongClass
- LongVariableName
- GotoStatement
- BrokenOddnessCheck
- UseNumberLiteral
- TooFewBranchesInSwitchStatement
- UseBoxedExpression
- JumbledIncrementer
- EmptyIfStatement
- BranchDivergence
- MissingDefaultStatement
- HighCyclomaticComplexity
- NonCaseLabelInSwitchStatement
- ConstantIfExpression
- BrokenNullCheck
- BrokenNilCheck
- TooManyFields
- UnusedLocalVariable

假如咱们运用.oclint最终咱们将.oclint放在与compile_commands.json相同的途径下,并在该途径下履行指令:

$ oclint-json-compilation-database -v -e Pods

或许直接履行指令:

$ oclint-json-compilation-database -e Pods -- -report-type pmd \
    -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 \
    -allow-duplicated-violations=false\
    -max-priority-1=100000 \
    -max-priority-2=100000 \
    -max-priority-3=100000 >> oclint.xml

最终会生成oclint.xml(也能够自己生成html格局,直接检查作用)

Infer

InferFacebook开源的一款代码扫描软件,能够剖析Objective-CJava或许C代码,陈述潜在的问题。任何人都能够运用Infer检测运用,这能够将那些严峻的 bug 摧残在发布之前,一起避免运用崩溃和性能低下。

  • 指令装置
$ brew install infer

在终端输入 infer --version,验证是否装置成功。

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
InferOCLint一样,都是剖析compile_commands.json文件。在compile_commands.json文件相同途径下履行指令:

# --skip-analysis-in-path 是疏忽扫描目录
$ infer run --skip-analysis-in-path Pods --keep-going --compilation-database compile_commands.json

留意:指令中一定要有--keep-going 否则会有过错导致无法进行剖析。 别的需求在xcodebuild指令中添加OTHER_CFLAGS="-DNS_FORMAT_ARGUMENT(A)= -D_Nullable_result=_Nullable"

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
扫描出的成果会在工程目录下的 infer-out 文件中,其间详细的代码会以 csv,txt,json 的格局别离存在对应的文件中。

总结:OCLint基本上剖析都是一些代码标准的问题,Infer能够检查出空指针拜访、资源泄露以及内存泄露。

sonarqube

sonarqube是一个供给代码静态剖析的渠道,供给了一套完好的静态剖析计划,包括后端及前端页面,能够结合jenkinsgitlab等渠道来进行代码剖析。sonarqube分社区版别和商业化版别,能扫描多种语言而且开源。官网地址。 由于其底层源码为java开发的,所以对java代码支撑比较完善,但是免费的社区版并不支撑OC,所以咱们假如要凭借此渠道的话,有以下两种方法:

  • 开源插件sonar-swift ,支撑Objective-CSwift / Java,支撑导入 SwiftLintInferOCLintLizardFauxpas 东西的扫描剖析成果。最新v1.6版别,兼容SonarQube 8.9LTS版别。该插件是好未来研发团队研发而且开源。
  • 付费运用社区版plus,供给了SonarCFamily for C插件 有官方供给技能支撑,250+的rules可供选择,不可自定义规矩。

咱们将运用开源插件计划。

sonar-services(sonarqube)装置

sonarqube 装置有两种方法

  • docker 装置
$ docker pull sonarqube:8.9.7-community
  • 下载二进制装置包 选中 8.9.7LTS 社区版别,下载
    OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

下载完装置包后,进入bin/macosx-universal-64 目录。履行指令:

$ sh sonar.sh start

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

控制台输出Started SonarQube阐明发动成功。

在浏览器拜访http://localhost:9000/,能翻开页面阐明发动成功。 默许账号为admin,暗码为admin。

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

留意:假如发动失利能够去sonarqube/logs下检查日志。

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
装置时,发现sonarqube 8.9.7版别需求Java 11环境。所以需求先装置Java 11环境。 装置Java 11:
OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

发动成功后咱们在最下面会看到warning

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

警告主张咱们自己装备数据库,需求阐明的是SonarQube假如想持久化保存数据,是需求依靠数据库的。

SonarQube默许供给H2存储,只能暂时存储一些小项目成果,仅为了演示运用。

conf/sonar.properties下装备数据库地址即可。可选 MySQLOraclePostgreSQL

下面咱们就来装备数据库(mysql后续将不再支撑):这儿咱们运用的是PostgreSQL,装备参阅

PostgreSQL

用Homebrew 履行指令装置PostgreSQL:

$ brew install postgresql //装置

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

装置完数据库后,发动数据库,履行指令:

$ pg_ctl -D /usr/local/var/postgres start //发动
$ createdb                                //创立数据库
$ psql                                    //登录控制台

数据库装置创立好后,咱们需求供给一个数据库和账号sonarqube运用。履行指令:

CREATE USER sonarqube WITH PASSWORD 'sonarqube';//创立用户
CREATE DATABASE sonar OWNER sonarqube;//创立属于该用户的数据库

创立完结后履行指令退出:

\q

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

然后咱们去sonarqube/conf目录下修改sonar.properties,将数据库相应装备装备完结

sonar.jdbc.username=sonarqube
sonar.jdbc.password=sonarqube
sonar.jdbc.url=jdbc:postgresql://localhost/sonar

修改完结后在sonarqube/bin/macosx-universal-64/目录下履行: sh sonar.sh restart,此刻警告现已消除了。

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

至此咱们的sonarqube的前端服务现已装备完结了。

汉化包装置

通过Github 下载对应版别汉化包jar包插件。

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
下载插件放到/extensions/plugins 目录下。重启sonarqube服务,就能够看到汉化后的界面。
OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

sonar-swift

通过GitHub 下载对应插件

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
下载插件放到/extensions/plugins 目录下。重启sonarqube服务,就能够了。

sonar-scanner

sonar-scanner 用来扫描本地代码,而且上传到SonarQube渠道中。

  • 下载装置地址;按照不同的操作系统选择不同装置包即可。
    OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
  • 装备环境变量:
$ vim ~/.bash_profile
#sonar-scanner for cli
export PATH=$PATH:/Users/csdn/scanner/bin:$PATH
$ source ~/.bash_profile

sonar-scanner 分为两种运用方法:

  • 装备文件方法:

在需求扫描项目根目录下新建sonar-project.properties 文件,内容如下:

sonar.projectKey=CsdnPlus
sonar.projectName=CsdnPlus
sonar.language=objc
sonar.sources=/Users/csdn/.jenkins/workspace/csdn_build_ios/
sonar.objectivec.workspace=CsdnPlus.xcworkspace
sonar.objectivec.appScheme=CsdnPlus
sonar.sourceEncoding=UTF-8
sonar.junit.reportsPath=sonar-reports/
sonar.objectivec.oclint.report=sonar-reports/oclint.xml
sonar.swift.infer.report=infer-out/report.json

进入项目根目录下,然后输入sonar-scanner指令,履行代码剖析。

  • 指令行方法:

在指令中设置了参数:

sonar-scanner -Dsonar.projectKey=CsdnPlus -Dsonar.projectName=CsdnPlus -Dsonar.projectName=CsdnPlus -Dsonar.projectVersion=5.1.0

假如咱们要SonarQube疏忽一些指定目录或许文件的扫描,能够在装备中添加sonar.exclusions 例如:

//疏忽指定文件目录或许文件
sonar.exclusions=**/Resource/**,**/*.py

或许能够在指令中设置参数,例如:

sonar-scanner -Dsonar.exclusions=**/Resource/**,**/*.py  -Dsonar.projectKey=CsdnPlus -Dsonar.projectName=CsdnPlus -Dsonar.projectName=CsdnPlus -Dsonar.projectVersion=5.1.0

这儿的中心就是在上面步骤中由OCLint生成的oclint.xml文件与Infer生成的report.json,别的留意oclint.xml有必要放至sonar-reports文件下。report.jsonInfer生成的infer-out目录下。

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

指令履行成功后,便可在sonarQube的前端页面看到对应的检测作用了。

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

检测作用图:

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

集成进Jenkins

咱们项目本身现已有自动化构建服务,所以比较方便。

  • Jenkins项目装备,选项中添加OCLint(能够自己命名)选项

    OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

  • 构建Shell指令中,添加OCLint相关指令

if [ "$MODE"x = "OCLint"x ]
then
    sh /Users/csdn/.jenkins/workspace/csdn_build_ios/fastlane/oclint.sh "$GIT_BRANCH"
fi

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

  • 企业微信通知, Shell中添加企业微信机器人URL
//获取本机IP
local_ip=$(ifconfig | grep '\<inet\>'| grep -v '127.0.0.1' | awk '{ print $2}' | awk 'NR==1')
curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=31ef53a9-1e97-42c6-9cc7-fb4432bd41f9' \
       -H 'Content-Type: application/json' \
       -d '
                {
                "msgtype":"news",
                "news":{
                "articles":[
                {
                "title":"SonarQube 静态代码扫描完结",
                "url":"http://'${local_ip}':9000/",
                "description":"APP称号:CSDNAPP\n扫描代码分支:'$1'",
                "picurl":"https://img-bss.csdnimg.cn/202103251639445966.png"
            }
        ]
    }
}'

OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统

一些有用的shell指令

获取APP称号:

product_name=`sed -n '/PRODUCT_NAME/{s/PRODUCT_NAME = //;s/;//;s/^[[:space:]]*//;s/\"//g;p;q;}' ./$myscheme.xcodeproj/project.pbxproj`

获取APP版别:

version_number=`sed -n '/MARKETING_VERSION/{s/MARKETING_VERSION = //;s/;//;s/^[[:space:]]*//;s/\"//g;p;q;}' ./$myscheme.xcodeproj/project.pbxproj`

获取本机IP地址:

local_ip = $(ifconfig | grep '\<inet\>'| grep -v '127.0.0.1' | awk '{ print $2}' | awk 'NR==1')
  • 附上完好oclint.sh指令:
#!/bin/bash
COLOR_ERR="\033[1;31m"    #出错提示
COLOR_SUCC="\033[0;32m"  #成功提示
COLOR_QS="\033[1;37m"  #问题色彩
COLOR_AW="\033[0;37m"  #答案提示
COLOR_END="\033[1;34m"     #色彩结束符
# 寻觅项目的 ProjectName
function searchProjectName () {
    # maxdepth 查找文件夹的深度
    find . -maxdepth 1 -name "*.xcodeproj"
}
function oclintForProject () {
    # 预先检测所需的装置包是否存在
    if which xcodebuild 2>/dev/null; then
    echo 'xcodebuild exist'
    else
    echo 'xcodebuild 未装置,请装置Xcode'
    fi
    if which oclint 2>/dev/null; then
    echo 'oclint exist'
    else
    echo 'oclint 未装置,请装置OCLint'
    fi
    if which xcpretty 2>/dev/null; then
    echo 'xcpretty exist'
    else
    gem install xcpretty
    fi
    # 指定编码
    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 xcpretty=/usr/local/bin/xcpretty # xcpretty 的装置方位能够在终端用 which xcpretty找到
    searchFunctionName=`searchProjectName`
    path=${searchFunctionName}
    # 字符串替换函数。//表明全局替换 /表明匹配到的第一个成果替换。
    path=${path//.\//}  # ./BridgeLabiPhone.xcodeproj -> BridgeLabiPhone.xcodeproj
    path=${path//.xcodeproj/} # BridgeLabiPhone.xcodeproj -> BridgeLabiPhone
    myworkspace=$path".xcworkspace" # workspace姓名
    myscheme=$path  # scheme姓名
    # 铲除前次编译数据
    if [ -d ./derivedData ]; then
    echo -e $COLOR_SUCC'-----铲除前次编译数据derivedData-----'$COLOR_SUCC
    rm -rf ./derivedData
    fi
    # xcodebuild clean
    xcodebuild -scheme $myscheme -workspace $myworkspace clean
    # # 生成编译数据
    xcodebuild -scheme $myscheme -workspace $myworkspace -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 12 Pro Max' -configuration Debug GCC_PRECOMPILE_PREFIX_HEADER=YES CLANG_ENABLE_MODULE_DEBUGGING=NO COMPILER_INDEX_STORE_ENABLE=NO OTHER_CFLAGS="-DNS_FORMAT_ARGUMENT(A)= -D_Nullable_result=_Nullable" | tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json
    if [ -f ./compile_commands.json ]; then
    echo -e $COLOR_SUCC'编译数据生成结束'$COLOR_SUCC
    else
    echo -e $COLOR_ERR'编译数据生成失利'$COLOR_ERR
    return -1
    fi
    echo -e $COLOR_SUCC'OCLint代码剖析开端'$COLOR_SUCC
    # 生成报表
    oclint-json-compilation-database -e Pods -- -report-type pmd \
    -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 \
    -allow-duplicated-violations=false\
    -max-priority-1=100000 \
    -max-priority-2=100000 \
    -max-priority-3=100000 >> oclint.xml
    echo -e $COLOR_SUCC'Infer代码剖析开端'$COLOR_SUCC
    # --skip-analysis-in-path 是疏忽扫描目录
    infer run --skip-analysis-in-path Pods --keep-going --compilation-database compile_commands.json
    product_name=`sed -n '/PRODUCT_NAME/{s/PRODUCT_NAME = //;s/;//;s/^[[:space:]]*//;s/\"//g;p;q;}' ./$myscheme.xcodeproj/project.pbxproj`
    version_number=`sed -n '/MARKETING_VERSION/{s/MARKETING_VERSION = //;s/;//;s/^[[:space:]]*//;s/\"//g;p;q;}' ./$myscheme.xcodeproj/project.pbxproj`
    if [ -f ./oclint.xml -a -f ./infer-out/report.json ]; then
    rm compile_commands.json
    echo -e $COLOR_SUCC'代码剖析结束'$COLOR_SUCC
    mv oclint.xml sonar-reports/
    echo -e $COLOR_SUCC'移动至sonar-reports结束'$COLOR_SUCC
    echo -e $COLOR_SUCC'开端履行sonar-scanner扫描文件'$COLOR_SUCC
    echo -e $COLOR_SUCC'版别号:'${version_number}''$COLOR_SUCC
    sonar-scanner  -Dsonar.projectVersion=$version_number
    else
    echo -e $COLOR_ERR'剖析失利'$COLOR_ERR
    curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=31ef53a9-1e97-42c6-9cc7-fb4432bd41f9' \
    -H 'Content-Type: application/json' \
    -d '
           {
           "msgtype": "text",
           "text": {
              "content": "APP称号:'${product_name}'\nAPP版别:'${version_number}'\nOCLint剖析失利"
           }
       }'
       return -1
       fi
       local_ip = $(ifconfig | grep '\<inet\>'| grep -v '127.0.0.1' | awk '{ print $2}' | awk 'NR==1')
       curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=31ef53a9-1e97-42c6-9cc7-fb4432bd41f9' \
       -H 'Content-Type: application/json' \
       -d '
                {
                "msgtype":"news",
                "news":{
                "articles":[
                {
                "title":"SonarQube 静态代码扫描完结",
                "url":"http://'${local_ip}':9000/",
                "description":"APP称号:'${product_name}'\nAPP版别:'${version_number}'扫描代码分支:'$1'",
                "picurl":"https://csdn-app.csdn.net/1024store_1024pt.png"
            }
        ]
    }
}'
}
oclintForProject $1
  • Jenkins 装备PMD(当然有了SonarQube,PMD就很鸡肋了)
    OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
    OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
    OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统