實戰iOS-objectivec&swift靜態代碼分析

在此感謝前交友事業部小夥伴:HaiYi、LV、Yong,曾經的協助!objective-c

本文主要闡述使用SonarQube構建iOS:Objective-C、Swift靜態代碼分析,包括分享遇到的坑,文章有限,一些細節不能到位的,請各位腦補下,謝謝。
SonarQube簡介
舊版Sonar展現維度以下(當時應該是11年左右開始使用的):
v2-ec68c6f48a4bed2172607258637dc911_hd.jpgshell

舊版sonar展現維度數據庫

新版SonarQube已經改變了關注維度,推出質量模型:express

Bugs:是出現了明顯錯誤或是高度近似指望以外行爲的代碼。

漏洞:是指代碼中可能出現被黑客利用的潛在風險點。

壞味道:代碼異味會困擾代碼的維護者並下降他們的開發效率。主要的衡量標準是修復它們所需的時間。

建議根據團隊須要更新到新版本:至少5.6+以上。
v2-a53c6122fb700401b6c91b06357797eb_hd.jpg
新版SonarQube質量模型編程

SonarQube架構
SonarQube平臺的組成:json

數據庫:存放SoanrQube的配置數據,代碼質量的快照數據

Web服務:用於查看SonarQube配置數據,代碼質量的快照數據

分析器:對項目代碼進行分析,生成質量結果數據並存於數據庫中

插件:各類語言支持的插件

v2-5412f3772a6e1bcbb6533e76a00f51eb_hd.jpg

不要忽略了CI:
雖然SonarQube具有分析器,能夠對多種編程語言進行構建分析,可是依然建議使用CI工具,例如Jenkins來管理平常構建,讓SonarQube僅僅展現最終數據便可。swift

v2-4be3049b1947f6b9e722a4bc4493b7ae_hd.jpg

iOS靜態代碼分析
目前iOS核心開發語言:Objective-C,也有很多項目採用了Swift語言,逐步過渡,所以項目的組成有兩種模式:xcode

單一語言使用:Objective-C、Swift

混合語言使用:Objective-C+Swift

下面經過實戰分析兩種模式的構建。微信

iOS靜態代碼分析的計劃
Objective-C原覺得就跟Java構建同樣,如此簡單,架構

v2-9671b98f55fd275df3584739fd3b7b15_hd.jpg

美好的計劃

實際遇到的坑是很大的,並且很受傷,

v2-59f73652ebbead9dad8e0ccb71864188_hd.jpg

踩過坑的路才踏實
v2-6f6f9f5c43ffa45bfa1d29fcb0cd0c8e_hd.jpg

捅一萬刀也不過度

iOS靜態代碼分析:Objective-C實戰
工欲善其事必先利其器,工具以下:

環境工具:XCode 8.2+、Xcpretty 0.2.八、OCLint 0.十二、xctool、gcovr

構建靜態分析插件

SonarCFamily:

v2-4ae15f995ff68626b38e6a7ea750f008_hd.jpg

官方插件太貴了,找開源吧

開源SonarQube Plugin for Objective C(傳送門)

插件安裝參考網上教程,下載jar拷貝到SonarQube項目目錄下:extensions/plugins

v2-0fdc5e8e7af4349b5259886375a99a45_hd.png

安裝成功的示例

構建腳本

run-sonar.sh

在Jenkins的Execute shell配置腳本以下,也能夠按照項目要求重名更好格式

cd $WORKSPACE

xcodebuild -workspace xxx.xcworkspace -scheme xxx clean build | tee xcodebuild.log | xcpretty --report json-compilation-database


mv build/reports/compilation_db.json compile_commands.json


oclint-json-compilation-database -exclude Pods -- -report-type pmd -o oclint.xml -max-priority-1 99999 -max-priority-2 99999 -max-priority-3 99999 -rc LONG_LINE=140 -rc LONG_METHOD=80 -rc NCSS_METHOD=50 -rc SHORT_VARIABLE_NAME=1 -rc CYCLOMATIC_COMPLEXITY=13 -rc MINIMUM_CASES_IN_SWITCH=2 -rc NPATH_COMPLEXITY=1500


rm -rf sonar-reports

mkdir sonar-reports


cat oclint.xml  | sed "s#Switch Statements Should Have Default Rule#switch statements should have default#g" \

| sed "s#missing hash method#must override hash with isEqual#g" \

| sed "s#prefer early exits and continue#use early exits and continue#g" \

| sed "s#use boxed expression#replace with boxed expression#g" \

| sed "s#use container literal#replace with container literal#g" \

| sed "s#use number literal#replace with number literal#g" \

| sed "s#use object subscripting#replace with object subscripting#g" \

| sed "s#missing default in switch statements#switch statements should have default#g" \

| sed "s#unnecessary default statement in covered switch statement#switch statements don't need default when fully covered#g" \

| sed "s#covered switch statements dont need default#switch statements don't need default when fully covered#g" > sonar-reports/oclint.xml


rm -f sonar-project.properties 

cat > sonar-project.properties <<- EOF 

sonar.projectKey=xxx-iOS

sonar.projectName=xxx-iOS 

sonar.projectVersion=x.x.x

sonar.language=objectivec 

sonar.sources=sources 

sonar.sourceEncoding=UTF-8 

sonar.objectivec.oclint.reportPath=sonar-reports/oclint.xml 

EOF 


/bin/sh sonar-scanner -X

構建結果
v2-365265d120ba44211e148b93ae26eeac_hd.jpg

獨門絕技介紹(感謝交友事業部:haiyi大神傾親奉獻)

構建錯誤errors generated

3 errors generated.

20 errors generated.

20 errors generated.

20 errors generated.

8 errors generated.

19 errors generated.

3 errors generated.

63 errors generated.

檢查OCLint,升級到0.12版本,與XCode8.2+配合

構建錯誤does not exist

The rule 'OCLint:use number literal' does not exist.

The rule 'OCLint:use object subscripting' does not exist.

The rule 'OCLint:ill-placed default label in switch statement' does not exist.

The rule 'OCLint:Switch Statements Misplaced Default Label' does not exist.

主要緣由是sonar-objective-c-plugin-0.5.0-SNAPSHOT.jar中未包含此規則,能夠經過修改源碼添加規則解決(網上有一堆教程),比較繁瑣的是,不一樣項目遇到不一樣錯誤,須要添加屢次,則屢次打包jar,再導入SonarQube,開銷大,haiyi大大給的祕籍是:用sed替換構建的oclint.xml文件

sed "s#missing hash method#must override hash with isEqual#g"

將缺失規則:missing hash method,替換爲:must override hash with isEqual,每次遇到有缺失的新規則,腳本替換便可,至於怎麼準確匹配,去看看質量配置的具體含義再替換。

Objective-C實戰總結

    安裝構建工具所需版本號
    xcodebuild構建項目生成compile_commands.json
    oclint-json-compilation-database構建compile_commands.json生成oclint.xml
    sed替換oclint.xml缺失規則
    sonar-project.properties配置oclint.xml文件路徑
    /bin/sh sonar-scanner -X 增長-X輸出debug日誌跟蹤

iOS靜態代碼分析:Swift實戰
工欲善其事必先利其器,工具以下:

環境工具

brew install Swiftlint

gem install slather

sudo pip install lizard

構建靜態分析插件

SonarSwifty:
v2-2dfbd4be2a6c2e1f62fdac1bac00f8b9_hd.jpg

官方插件太貴了,找開源吧

開源sonar-swift(傳送門)

插件安裝參考網上教程(backelite-sonar-swift-plugin-0.3.4.jar SonarQube5.4/5/6/6/3測試經過),下載jar拷貝到SonarQube項目目錄下:extensions/plugins

v2-3632e351b30df730d6dc547305070794_hd.png

安裝成功的示例

構建腳本

run-sonar.sh

在Jenkins的Execute shell配置腳本以下,也能夠按照項目要求重名更好格式

cd $WORKSPACE

rm -rf kuai-swiftlint.txt

swiftlint lint --path Duobao > xxx-swiftlint.txt


rm -rf sonar-project.properties

cat > sonar-project.properties <<- EOF

sonar.projectKey=xxx-iOS-swift

sonar.projectName=xxx-iOS-swift

sonar.projectVersion=x.x.x

sonar.language=swift

sonar.projectDescription=xxx with Swift

sonar.sources=sources

sonar.swift.workspace=xxx.xcworkspace

sonar.swift.appScheme=xxx

sonar.sourceEncoding=UTF-8

sonar.swift.swiftlint.report=xxx-swiftlint.txt

EOF

/bin/sh sonar-scanner -X

構建結果

v2-cc1fd32ffe519463b956c61dc8040c9b_hd.jpg

注意事項

The structure of the plugin is based on the sonar-objective-c plugin.

In SonarQube under Quality Profiles the used Linter can be specified by selecting either the SwiftLint Profile or the Tailor Profile as Default profile for Swift Projects:

v2-2ae00afbf0fabecf0195d7c0dc050669_hd.jpg

若是不設置,關聯規則有問題

目前暫無遇到缺失規則問題


Swift實戰總結

    安裝構建工具所需版本號
    swiftlint生成xxx-swiftlint.txt
    sonar-project.properties配置xxx-swiftlint.txt文件路徑
    /bin/sh sonar-scanner -X 增長-X輸出debu

iOS靜態代碼分析:Objective-C+Swift實戰
這裏不詳細介紹實戰過程,直接說總結

Objective-C+Swift:分開構建,腳本以下,當作兩個項目配置如上文所示

Objective-C+Swift:一塊兒構建,本質上他們兩個的插件是不一樣的,可是能夠利用sonar模塊的概念來構建

ObjectiveC_Swift目錄結構

--ObjectiveC:完整項目文件

--Swift:完整項目文件

腳本以下

sonar.projectKey=objectivec_swift

sonar.projectName=objectivec_swift

sonar.projectVersion=1.9.0

sonar.sourceEncoding=UTF-8

#分模塊

sonar.modules=objective,swift


#構建objectivec

objective.sonar.projectName=objectivec

objective.sonar.language=objectivec

objective.sonar.projectBaseDir=objectivec

objective.sonar.sources=sources

objective.sonar.oclint.reportPath=sonar-reports/oclint.xml


#構建swift

swift.sonar.projectName=swift

swift.sonar.language=swift

swift.sonar.sources=sources

swift.sonar.projectBaseDir=swift

swift.sonar.swift.workspace=swift/xxx.xcworkspace

swift.sonar.swift.appScheme=Duobao

swift.sonar.sourceEncoding=UTF-8

swift.sonar.swift.swiftlint.report=swift/xxx-swiftlint.txt

構建結果

v2-145517c851a928f32555619a13c21725_hd.jpg

沒有看到掃描規則問題展現,估計是配置文件或者構建文件路徑有問題,暫且告一段落吧,有折騰出來的小夥伴喊一下,謝謝喲,^_^

微信公衆號:樂少黑板報

相關文章
相關標籤/搜索