Litmus程式碼質量平臺實踐總結

美團點評點餐發表於2017-12-22

背景

程式碼質量在專案開發中是一個很重要的地方,更好的質量的程式碼,能夠產生更少的bug,也能使開發人員更不容易犯錯,產品的質量得到提升。那麼怎麼定義程式碼質量,怎麼測量以及如何展現就成為我們內部平臺Litmus的主要探索領域。

之前的文章有多次提到我們團隊內部的Litmus平臺,它是一個自動化程式碼審查反饋的系統,能夠給開發者提供當前程式碼的各種維度的分析結果,幫助開發人員更好的解決潛在的bug和更好的管理組織程式碼檔案。

目前,我們的系統已經不斷迭代和執行了近4個月,得到了不錯的效果,也籌備和設計了後續的開源計劃。同時也從日常使用中優化了自身很多方面,我們決定在這裡完整的介紹一下我們的Litmus程式碼質量檢查平臺,關於它是如何構建和架構的,以及在構建這個平臺中所產生的對程式碼質量問題的思考和總結。

什麼是程式碼質量

程式碼質量是一個很抽象的概念,但是它貫穿於整個程式開發中,並且大部分的bug和delay,以及開發中的體驗,都來自於程式碼質量的偏低。我們一直在探索如何將這個抽象的概念具體的定義出來。隨著業務的增加,隨著團隊的發展,專案程式碼會越來越多,變得越來越難維護,這些變化並不是一天形成的,而是每次提交每次合併帶來的一點點的複雜和混亂,因為沒有監控和人力問題,導致專案越來越臃腫和繁雜。我們希望對這個過程進行插手,探索和改進整個流程。

首先我們對現有的工具進行了一番調查,比如sonar等一些學院派的檢查工具,這些工具在使用上就非常困難,資料也略複雜和專業,用在業務中將會是一個overkill,於是我們決定自己建立一套質量管理平臺。

最先進入我們計劃的就是Lint工具提供的語法和風格檢查,也是最容易看到直觀的結果的檢查。於是我們統一了團隊的ESLint和TSLint規則,最開始整合在開發流程中,由於眾多歷史專案和成員的開發習慣,這一步驟經常會被避免掉,於是我們決定將Lint檢查放在服務端統一執行作為一個最後的確認,如果有Lint錯誤將不允許合併程式碼。其次我們發現程式碼的重複度和程式碼的複雜度也是一個重要的指標,具體的指標下文有介紹。

同時我們認為,程式碼質量檢測應該是一個自動執行的東西,程式設計師不應該從工作流上有所改變,它應該自動分析我們的程式碼提交,給出結果反饋,程式設計師再進行相應的修改,整個過程需要流暢和迅速,同時結果的展示應該儘可能的簡單,去掉專業化的描述,讓學習成本降到最低,直接看到問題即可。帶著這些想法,我們嘗試構建了Litmus平臺。

基礎介紹

利用內部倉庫系統的鉤子,在每次專案提交PR和Merge後觸法鉤子,傳送請求到我們的伺服器。伺服器便會依照之前對每個專案設定好的配置資訊,進行檢查,檢查完畢後,檢查結果將會通過內部im工具傳送給PR提交者,他便可以通過頁面看到檢查結果並有可能對程式碼進行相應的調整。

目前檢測主要有3個維度,分別是語法規則,複製貼上率和程式碼複雜度:

  • 語法規則也就是ESLint,TSLint等lint工具的檢測,通過對錯誤和警告數量的計算得到一個程式碼結果的分數。
  • 複製貼上率代表程式碼中間的相似部分,在程式碼中出現大面積的相似程式碼,就是一個質量不好的地方,可能出現修改了一處另一處沒有被修改導致出現問題的情況。通過重複的多少計算出一個合理的分數來代表結果。
  • 程式碼複雜度是一個較為複雜的概念,具體的介紹比較多,關於介紹可以參考我們之前的詳細的文章

系統部分截圖如下(敏感資料被遮蓋):

Litmus程式碼質量平臺實踐總結

Litmus程式碼質量平臺實踐總結

整體架構

最初的架構可以在這個文章中找到,那時候的技術棧很雜,同時擴充套件性也不高,維護起來會很麻煩。我們不斷的對litmus進行修改,目前的架構可以用這個圖來展示:

Litmus程式碼質量平臺實踐總結

整個Litmus被分成3個部分,一個是處理請求的Server,這個是核心;一個是包含著各種檢查器的Core,是一個純演算法庫;一個是儲存資料的MongoDB。整個Ltimus使用JavaScript編寫。下面分別來介紹下每個組成部分

Litmus Server

Server可以說是整個系統的核心部分,它負責提供web介面,處理介面請求,同時還會接受倉庫系統觸發的鉤子請求,分別從資料庫中拿到資料來展示和執行檢查器。Server的啟動需要兩份配置檔案,一個是對server本身的埠,資料庫地址之類的基本資訊(Litmus Config);另一個是對每一個需要檢查的專案的具體配置資訊檔案(Project Config)。

當倉庫的鉤子被觸發,倉庫將會發起一個請求(在倉庫配置),請求我們的Server,接收到請求後,將會知道一個任務需要檢查了,就會將任務推進檢查佇列(Working Queue),檢查佇列是一個能夠同時執行多個任務的任務佇列,每次執行任務,通過開啟一個程式,執行Litmus Core檢查器演算法程式。檢查結果將會通過事件傳送被監聽,然後寫入資料庫。

Litmus Core

Core是檢查器的演算法庫,它是一個純粹的接收資料,計算,然後產生結果的庫,不能感知到外部的任何結構,所有的檢查器位於此。需要注意的是,由於要使用ESLint等Lint工具,我們需要將團隊的規則做成sharable config的形式,打包成一個npm包,全域性安裝這個包和其peerDependencies在Server執行的主機上,才能使檢查器訪問到正確的規則檔案。從實際來說,大部分團隊的ESLint規則也都是一套全團隊適用,這樣才能風格統一。

MongoDB

資料庫用來存放所有的檢查結果,通過在配置檔案中給出資料庫的地址讓Server能夠操作它。為了更快速的檢索我們建立了一些索引。

Litmus部署

最早期,Litmus為團隊內部使用的專案,沒有考慮到向外擴充套件來設計系統的結構。但是隨著不斷的擴張,我們希望能夠將系統的運維工作分發給各個團隊的使用者,而不是一個集中化的管理在我們團隊,這樣我們承擔的運維任務就要少很多,同時機器的資源也得到了保證,於是就需要其餘的團隊能夠方便簡潔的搭建整個系統。

為了簡化自身部署,同時能夠給其他團隊測試試用版本,我們參考Ghost CLI開發了安裝的CLI程式,能夠一行命令安裝好所需要的各種元件和程式碼。當然,配置檔案的內容還是需要使用者自己來填寫。

實踐效果分析

我們在不斷的迭代中,也在同時的關注litmus整體使用情況,對此我們選擇了上線之後到2017年底,幾個較為活躍的專案進行統計分析,將分數做成圖表,在這裡展示部分統計圖:

Litmus程式碼質量平臺實踐總結

Litmus程式碼質量平臺實踐總結

Litmus程式碼質量平臺實踐總結

可以看到團隊對質量平臺的重視程度,並且編寫程式碼的確受到了Lint工具的反饋,重視起程式碼質量。對於這些資料和我們的詳細使用情況分析,以及對現有系統的改進計劃,將會在下一篇文章中詳細介紹。

未來的計劃

在經過了實際使用後,發現有些指標的作用並沒有我們期望的那樣優秀,表現略平庸,於是我們決定在檢測維度上和展示方式上進行一些改進升級。目前的維度還沒有足夠全面,需要有更多的指標加入才能更好的發揮程式碼審查的作用。一些新的維度正在被籌備和設計的同時,也將會一改以前使用列表的方式展示資料的方式,採用結構圖的方式結合不同的顏色來視覺化結果。這些都是我們在使用過程中的探索,目的也是打造一個完善的程式碼質量評測流程,能夠為團隊帶來實際更大的改進。

關於大家關注的開源計劃,我們希望能夠將內部團隊的使用體驗打造至極致後,經過公司內部多團隊的測試體驗不斷的優化自身,再向外部開源一整套解決方案。具體的開源形式還沒有確定下來,不過這都是被提上日程的事情,關於Litmus的開發還在不斷的迭代之中,大家拭目以待。


相關文章