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

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

本文主要闡述使用SonarQube構建iOS:Objective-C、Swift靜態代碼分析,包括分享遇到的坑,文章有限,一些細節不能到位的,請各位腦補下,謝謝。

SonarQube簡介

舊版Sonar展現維度以下(當時應該是11年左右開始使用的):

舊版sonar展現維度

新版SonarQube已經改變了關注維度,推出質量模型:
  • Bugs:是出現了明顯錯誤或是高度近似指望以外行爲的代碼。
  • 漏洞:是指代碼中可能出現被黑客利用的潛在風險點。
  • 壞味道:代碼異味會困擾代碼的維護者並下降他們的開發效率。主要的衡量標準是修復它們所需的時間。
建議根據團隊須要更新到新版本:至少5.6+以上。
新版SonarQube質量模型

SonarQube架構

SonarQube平臺的組成:
  • 數據庫:存放SoanrQube的配置數據,代碼質量的快照數據
  • Web服務:用於查看SonarQube配置數據,代碼質量的快照數據
  • 分析器:對項目代碼進行分析,生成質量結果數據並存於數據庫中
  • 插件:各類語言支持的插件
不要忽略了CI:
雖然SonarQube具有分析器,能夠對多種編程語言進行構建分析,可是依然建議使用CI工具,例如Jenkins來管理平常構建,讓SonarQube僅僅展現最終數據便可。

iOS靜態代碼分析

目前iOS核心開發語言:Objective-C,也有很多項目採用了Swift語言,逐步過渡,所以項目的組成有兩種模式:
  • 單一語言使用:Objective-C、Swift
  • 混合語言使用:Objective-C+Swift
下面經過實戰分析兩種模式的構建。

iOS靜態代碼分析的計劃

Objective-C原覺得就跟Java構建同樣,如此簡單,
美好的計劃
實際遇到的坑是很大的,並且很受傷,
踩過坑的路才踏實

捅一萬刀也不過度

iOS靜態代碼分析:Objective-C實戰

工欲善其事必先利其器,工具以下:
  • 環境工具:XCode 8.2+、Xcpretty 0.2.八、OCLint 0.十二、xctool、gcovr
  • 構建靜態分析插件
  • SonarCFamily:
  • 官方插件太貴了,找開源吧
  • 開源SonarQube Plugin for Objective C(傳送門
  • 插件安裝參考網上教程,下載jar拷貝到SonarQube項目目錄下:extensions/plugins
安裝成功的示例

  • 構建腳本
  • 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複製代碼
  • 構建結果
  • 獨門絕技介紹(感謝交友事業部: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:

  • 官方插件太貴了,找開源吧
安裝成功的示例

  • 構建腳本
  • 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複製代碼
  • 構建結果

  • 注意事項
  • 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:
  • 若是不設置,關聯規則有問題
  • 目前暫無遇到缺失規則問題


  • 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複製代碼
  • 構建結果
沒有看到掃描規則問題展現,估計是配置文件或者構建文件路徑有問題,暫且告一段落吧,有折騰出來的小夥伴喊一下,謝謝喲,^_^

微信公衆號:樂少黑板報
git

相關文章
相關標籤/搜索