1. 程式人生 > >OC靜態程式碼檢查實戰

OC靜態程式碼檢查實戰

此文已由作者楊曉授權網易雲社群釋出。

歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。


在Mac OS系統上,採用Xcodebuild Analyze命令和OClint工具,對iOS專案進行靜態程式碼檢查,輸出視覺化結果。然後將專案持續整合至CI平臺,並使用PMD外掛進行錯誤統計的展示。對此,本文由以下4個要點來闡述。


  1. 背景

  2. Xcodebuild命令列指令

  3. oclint工具獲取視覺化結果

  4. 持續整合


1.背景


AR家裝是感知與智慧中心的一個新專案,通過AR和VR技術,在iOS平臺上可以很好地展現樣板間設計和傢俱的實時場景。場景展示的功能是由Unity來完成,iOS主要負責UI和前後臺互動的功能,比如登入、許可權管理、下載等。由於專案成立不久,開發進度比較趕,程式碼以實現功能為主導,因此會對後續的程式碼管理和程式設計帶來較大的隱患。對此,QA希望通過對專案進行定期靜態程式碼檢查,來實現iOS端程式碼質量控制,以降低專案風險。


OC的靜態程式碼檢查工具比較常見的有Clang-Analyzer、 OClint等,qablog上有一篇關於Clang-Analyzer的介紹 iOS靜態程式碼檢查工具Clang Static Analyzer介紹。本人採用Clang-Analyzer方法在Terminal中嘗試,發現專案中引用的一些第三方庫,對一些版本號限制的編譯平臺會編譯失敗,嘗試解決無果後轉而使用OClint。


本專案採用Xcode自帶命令列Xcodebuild的Analyze功能,結合OClint工具,在Jenkins上整合靜態程式碼檢查。在實戰的過程中遇到了一些問題,繞了一些彎路,記錄下來希望對其他專案有所幫助。


環境配置:

  • Mac OS: 10.10.5(包括slave節點)

  • Souce Control: Git

  • Xcode Version: 7.3.1

  • OClint Version: 0.10.3

  • xcpretty


2.Xcodebuild命令列指令

其實,Xcode工具包含了靜態程式碼分析的功能,開啟專案程式,點選選單的Product->Analyze即可對程式碼進行掃描。

入口如圖1所示:


Alt pic




經過長時間地解析後,最終得到結果如圖2所示:


Alt pic



這種檢查方法的好處在於方便,直接在Xcode中執行,能按不同的方式檢視檢查結果,並能準確地定位出錯位置。

但對於QA來說,不足之處也是顯而易見的,整個過程需要定期執行靜態程式碼檢查,分類統計的結果雖適合開發自查,但並不適用於QA對程式碼質量把控。

對於命令列執行靜態程式碼檢查,可以利用Xcodebuild指令在命令列中執行Build、Analyze和Clean等功能,以下簡單介紹下Analyze和Clean的用法。

Xcodebuild Analyze

Xcodebuild功能非常強大,具體的用法可以通過man xcodebuild來檢視。本專案主要用到的是clean、analyze操作和一些配置資訊。

Xcodebuild指令基本用法介紹如下,需要進入到當前專案所在的目錄(projectName.xcproj或workspaceName.xcworkspace檔案所在目錄),然後執行相應指令,如下圖3所示。

xcodebuild [-project projectname][-target targetname ...] 
[configuration configurationname][-sdk [sdkfullpath | sdkname]]
[buildaction ...] [setting=value ...][-userdefault=value ...]

由於AR專案包含了iOS專案和Unity專案,兩個project在同一個workspace下,因此需要加入-workspace workspaceName.xcworkspace和-scheme schemeName。如果不加入引數,在xcodebuild執行過程中,可能會出現類似ld: library not found for -lxxxx的錯誤。


總結一下,其實到這一步就已經完成了最重要的靜態程式碼檢查工作了:xcodebuild -workspace workspaceName.xcworkspace -scheme schemeName analyze

Xcodebuild Clean

靜態程式碼檢查會生成.o連結檔案,執行過一次xcodebuild analyze後,如果此檔案沒有變化就不會再次編譯。而視覺化結果的輸出其實是依賴命令列的輸出結果,如果跳過了編譯過程,log中就不會有warning的記錄,就會預設當前檔案是沒有錯誤的。因此每次編譯前都需要清空專案一些中間過程的生成檔案,以確保每次檢查都是重新生成的連結庫。對此,簡單執行xcodebuild clean即可。

Xctool工具

Xctool工具是Xcodebuild命令列的一個替代產品。包含了xcpretty的功能。上述步驟也可用Xctool來執行


安裝配置Xctool,如下圖4所示。

brew install xctool

安裝完成後Xctool位於/usr/local/bin目錄下,執行如下命令列可以生成文中將提到的OClint可以解析的檔案格式,如下圖5所示。


shellxctool -workspace workspaceName.xcworkspace -scheme schemeName cleanxctool -workspace workspaceName.xcworkspace -scheme schemeName -reporter json-compilation-database:compile_commands.json


3.OClint工具

- OClint在本專案中的作用是對Xcodebuild產生的log進行分析,獲取相關資料後生成html檔案或pmd檔案。


OClint安裝及配置

從OClint的GitHub專案連結中下載安裝包oclint-0.10.3-x86_64-darwin-15.5.0.tar.gz.

解壓後,在當前使用者的.bashrc目錄下配置環境變數,如下圖6所示

OCLINT_HOME=/pathexport PATH=$PATH:OCLINT_HOME/bin

然後執行source .bashrc即可

執行OClint確認環境配置是否正確,如下圖7所示。

$ oclintoclint: Not enough positional command line arguments specified!
Must specify at least 1 positional arguments: See: oclint -help

Xcodebuild 與 OClint結合

根據OClint官網的教程,執行如下:

xcodebuild analyze | tee xcodebuild.log將xcodebuild analyze的輸出資訊記錄在xcodebuild.log中。

oclint-xcodebuild xcodebuild.log 對log進行解析,生成compile_command.json。進行到這一步後命令行提示,如下圖8所示:

This binary is no longer under maintenance by OCLint team.Please consider using xcpretty (https://github.com/supermarin/xcpretty) instead!

對此,我們採用xcpretty,xcpretty可以用gem install xcpretty來下載安裝。根據教程,xcpretty可以通過--report json-compilation-database來生成OClint所需的json檔案。因此合併前兩步,如下圖9所示:

xcodebuild analyze | tee xcodebuild.log | xcpretty --report json-compilation-database

需要注意的是,這一步生成的json檔案在build/reports目錄下,並且名為compilation_db.json,和OClint預設生成的檔案命名和路徑均不同,因此需要移動至根目錄並重命名為compile_command.json。

若採用Xctool可以按照前文中給出的命令直接生成正確的compile_command.json檔案。

最後一步生成html或pmd檔案,如下圖10所示

oclint-json-compilation-database -e Pods-- -report-type pmd -o report.html

其中 -e Pods為去掉第三方庫的靜態程式碼檢查錯誤。 -report-type pmd可以選擇為pmd格式輸出,方便在Jenkins中通過PMD外掛檢視結果。-o report.html為指定輸出檔名稱。

引數配置,第一次執行的時候OClint會報錯,需要進行引數配置,如下圖11所示。

violation exceed threshold
P0=0[0], P1=41[10], P2=200[20]

查了一些資料發現,P1=41[10]是說P1(Normal級別 Warning)發現41個,但是限制為10個,超過10個則失敗。因此通過-max-priority-2=9999修改閾值。另外,還可以通過-disable-rule=LongLine來根據需要過濾一些warning的型別,具體的可以查閱文件或生成結果。


4.持續整合至Jenkins平臺

在整合到Jenkins平臺的過程中,由於是第一次使用Mac OS作為slave機器,在使用者許可權上遇到些問題。

在執行|xcpretty --report json-compilation-database的時候提示 xcpretty:command not found.

再三驗證命令列和xcpretty安裝正確後懷疑是賬號許可權問題。不像Linux和Windows的slave節點,Jenkins有一個獨立的賬號來執行shell指令碼。在Mac OS上,Jenkins執行的賬戶,是執行Jenkins中slave指令碼的賬戶。確認了機器上所有的使用者都可以執行xcpretty命令以後,我開始質疑是否是Jenkins執行在不可見的賬戶上。為了確認這個問題,查閱了一些資料後,發現可以通過Jenkins管理網站節點的System Info來確認,如下圖12所示。


Alt pic



從圖中,我們可以看到所用賬號的確是常用的netease賬號,但是netease賬號卻是可以執行xcpretty指令的。接著往下看,發現PATH變數與Terminal中檢視到的PATH變數不同,感覺找到了問題所在。在執行指令碼中加入如下語句即可,如圖13所示。


export PATH=$PATH:/Users/netease/.rvm/gems/ruby-2.1.1/bin
OCLINT_HOME=/Users/netease/Downloads/oclint-0.10.3export PATH=$PATH:$OCLINT_HOME/bin


至此Job配置完成,在配置中,加入Add Post-build Actions中的Publish PMD analysis results即可完成配置。PMD檔案的生成結果如下圖15所示。


Alt pic 


不過截止我寫完這篇文章,似乎OClint的PMD報告不支援編譯錯誤和警告的資料展示。考慮到資料的完整性,也可採用Html報告的格式。只需要將上一部中的Publish PMD analysis result改為Publish HTML Reports即可。


免費體驗雲安全(易盾)內容安全、驗證碼等服務

更多網易技術、產品、運營經驗分享請點選

相關文章:
【推薦】 web除錯利器_fiddler
【推薦】 #3.14Piday#我的圓周率日
【推薦】 怦然心動——iOS觸感反饋