iOS|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过程中的日志来进行的,我们这次主要针对开源方案来讲相关配置流程。
对于使用开源方案来说,本质流程如下:
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

xcodebuild iOS核心工具,安装好Xcode就会自带此工具,因为oclint分析的核心是xcodebuild在编译app过程中的log,所以需要xcodebuild(build失败也会对已经build的日志进行分析,但尽量保证可以build成功)
如果项目是在workspace中需要指定-workspace和对应的scheme,可以通过xcodebuild -list查看
//执行 $ xcodebuild -list

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

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


我们并不需要打出的IPA包可以安装到手机上,只是需要build过程中的日志而已,所以我们只需要打出模拟器下Debug包就可以了。
//执行 $ xcodebuild -showsdks

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

因为xcodebuild会有缓存,所以我们每次执行前需要clean
$ xcodebuild -workspace CsdnPlus.xcworkspace -scheme CsdnPlus clean


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

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

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

iOS|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
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

下载安装包安装:
https://github.com/oclint/oclint/releases

配置环境变量:
export PATH="/Users/csdn/oclint-22.02/bin:$PATH" source ~/.zshrc

在终端输入 oclint --version,验证是否安装成功。
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

在终端输入oclint --help 查看命令介绍
iOS|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,验证是否安装成功。iOS|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"
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

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 社区版本,下载
    iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
    文章图片
下载完安装包后,进入bin/macosx-universal-64 目录。执行命令:
$ sh sonar.sh start

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

控制台输出Started SonarQube说明启动成功。
在浏览器访问http://localhost:9000/,能打开页面说明启动成功。
默认账号为admin,密码为admin。
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

注意:如果启动失败可以去sonarqube/logs下查看日志。
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

安装时,发现sonarqube 8.9.7版本需要Java 11环境。所以需要先安装Java 11环境。
安装Java 11:
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

启动成功后我们在最下面会看到warning
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

警告建议我们自己配置数据库,需要说明的是SonarQube如果想持久化保存数据,是需要依赖数据库的。
SonarQube默认提供H2存储,只能暂时存储一些小项目结果,仅为了演示使用。
conf/sonar.properties下配置数据库地址即可。可选 MySQLOraclePostgreSQL
下面我们就来配置数据库(mysql后续将不再支持):这里我们使用的是PostgreSQL,配置参考
PostgreSQL 用Homebrew 执行命令安装PostgreSQL:
$ brew install postgresql //安装

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

安装完数据库后,启动数据库,执行命令:
$ pg_ctl -D /usr/local/var/postgres start //启动 $ createdb//创建数据库 $ psql//登录控制台

【iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统】数据库安装创建好后,我们需要提供一个数据库和账号sonarqube使用。执行命令:
CREATE USER sonarqube WITH PASSWORD 'sonarqube'; //创建用户 CREATE DATABASE sonar OWNER sonarqube; //创建属于该用户的数据库

创建完成后执行命令退出:
\q

iOS|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,此时警告已经消除了。
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

至此我们的sonarqube的前端服务已经配置完成了。
汉化包安装 通过Github 下载对应版本汉化包jar包插件。
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

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

sonar-swift 通过GitHub 下载对应插件
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

下载插件放到/extensions/plugins 目录下。重启sonarqube服务,就可以了。
sonar-scanner sonar-scanner 用来扫描本地代码,并且上传到SonarQube平台中。
  • 下载安装地址;按照不同的操作系统选择不同安装包即可。
    iOS|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目录下。
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

命令执行成功后,便可在sonarQube的前端页面看到对应的检测效果了。
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

检测效果图:
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

集成进Jenkins 我们项目本身已经有自动化构建服务,所以比较方便。
  • Jenkins项目配置,选项中增加OCLint(可以自己命名)选项
    iOS|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

iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

  • 企业微信通知, Shell中增加企业微信机器人URL
//获取本机IP local_ip=$(ifconfig | grep '\'| 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" } ] } }'

iOS|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 '\'| grep -v '127.0.0.1' | awk '{ print $2}' | awk 'NR==1')

  • 附上完整oclint.sh命令:
#!/bin/bashCOLOR_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' fiif 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 -> BridgeLabiPhonemyworkspace=$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.jsonif [ -f ./compile_commands.json ]; then echo -e $COLOR_SUCC'编译数据生成完毕'$COLOR_SUCC else echo -e $COLOR_ERR'编译数据生成失败'$COLOR_ERR return -1 fiecho -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.xmlecho -e $COLOR_SUCC'Infer代码分析开始'$COLOR_SUCC # --skip-analysis-in-path 是忽略扫描目录 infer run --skip-analysis-in-path Pods --keep-going --compilation-database compile_commands.jsonproduct_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_SUCCmv oclint.xml sonar-reports/echo -e $COLOR_SUCC'移动至sonar-reports完毕'$COLOR_SUCC echo -e $COLOR_SUCC'开始执行sonar-scanner扫描文件'$COLOR_SUCCecho -e $COLOR_SUCC'版本号:'${version_number}''$COLOR_SUCCsonar-scanner-Dsonar.projectVersion=$version_numberelseecho -e $COLOR_ERR'分析失败'$COLOR_ERRcurl '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 -1filocal_ip = $(ifconfig | grep '\'| 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就很鸡肋了)
    iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
    文章图片

    iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
    文章图片

    iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
    文章图片
云服务
方便我们的代码静态分析系统持续运行,我们可以购买云服务,将环境部署在云服务上。CSDN 开发云推出最优惠的活动,有需要的可以购买。
购买链接:
iOS|OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
文章图片

    推荐阅读