基于軟件分析的智能化開發(fā)新型服務(wù)與技術(shù)(智能化軟件開發(fā)技術(shù)與應(yīng)用)
本文以技術(shù)文章的方式回顧梁老師在?SIG-程序分析?技術(shù)沙龍上的分享,回顧視頻也已經(jīng)上傳 B 站,歡迎小伙伴們點開觀看。
大家好,非常感謝大家來參加我們今天的?SIG-程序分析技術(shù)沙龍。我是來自華為云軟件分析 Lab 的梁廣泰,今天給大家分享的主題是?基于軟件分析的智能化開發(fā)新型服務(wù)與技術(shù)。
技術(shù)趨勢分析
先來看一下業(yè)界相關(guān)的技術(shù)趨勢。我從云服務(wù)廠商的角度來給大家介紹一下,當(dāng)前業(yè)界圍繞該領(lǐng)域有做哪些事情。
#?缺陷檢測與修復(fù)領(lǐng)域
首先看一下缺陷檢測與修復(fù)?領(lǐng)域。
##?Amazon - CodeGuru
Amazon 推出了一個叫?CodeGuru?[1]?的 offering,其主要功能是通過全方位的缺陷檢測和掃描,幫助程序員更快地識別出有問題的代碼,并提供智能建議以進行代碼修復(fù)。
CodeGuru Reviewer
顧名思義,Reviewer?子服務(wù)其實就是用機器學(xué)習(xí)的方式,通過自動化推理的算法提供智能化代碼審查的服務(wù),幫助程序員進行各種類型的代碼查找,提供代碼修復(fù)的建議。
CodeGuru Profiler
與其對應(yīng)的另一個子服務(wù)是?Profiler。該服務(wù)更多的是利用插樁技術(shù)來監(jiān)控程序運行時的狀態(tài),包括內(nèi)存的消耗、CPU 的使用率等。通過分析運行時數(shù)據(jù),提高程序的運行效率,甚至幫助程序員找到運行成本高昂的代碼行。
##?Microsoft - Azure
我們再來看一下微軟的 Azure。
Github Code Scanning
Github 作為一個代碼托管平臺,同時也是全球最大的代碼數(shù)據(jù)中心之一。圍繞這個中心,Github 開展了各種各樣的代碼分析服務(wù)。微軟收購 Github 之后,Azure 和 Github 進行了充分的集成,其中就包括了 Github 的 code scanning?[2]?服務(wù),可以在 Azure 上針對高危的 security issues 提供掃描的能力。
如下圖示,在 Github 的代碼提交頁面上,Code Scanning 會自動地將識別到的缺陷告警顯示在頁面上,幫助程序員更快地去發(fā)現(xiàn)問題,從而在代碼入庫前攔截掉這些問題。
Github Code Scanning?[2]
除此之外,Azure 的 Pipeline?[3]?也支持配置各種類型代碼掃描的任務(wù)。與其他云廠商思路不同的是,Pipeline 的缺陷分析工具并不是由微軟自己來提供,用戶可以自由地配置外部的 static analyzer。例如,用戶可以在本地部署一些靜態(tài)分析的服務(wù),在 Azure 里配置相關(guān)的鏈接,包括掃描的命令等,從而將本地和云端進行一個有機的集成。
與此同時,微軟也在不斷地繁榮自己的代碼分析能力。如下圖示,Visual Studio 提供了一些監(jiān)控的手段,用來幫助程序員更快地識別程序里的潛在問題,并給出更新提示。這其實和剛才提到的 Amazon CodeGuru Profiler 有類似之處。
##?阿里云 - CodeUp
阿里云通過 CodeUp?[5]?代碼托管平臺,也有在持續(xù)地拓展軟件分析的能力。
依托 PMD 和 Sonar 插件完成合規(guī)檢查
CodeUp 主要依托?開源代碼掃描工具 PMD(Programming Mistake Detector)[6] 和 Sonar 插件(主要用于代碼庫全量自動化掃描階段)來完成相關(guān)的合規(guī)檢查。
阿里云在 ICSE-SEIP’20 上發(fā)表了代碼自動修復(fù)技術(shù) PRECFIX?[8],能夠基于數(shù)據(jù)挖掘的方式做模式挖掘,從而提供代碼修復(fù)能力。
提供代碼智能評審,以提高程序員研發(fā)效率。
研發(fā)提效 - 智能評審 [7]
##?CODING 平臺
CODING?[9]?平臺(騰云扣釘科技有限公司,騰訊旗下全資子公司)也提供了代碼掃描的能力。CODING 目前在內(nèi)部集成了多種代碼掃描工具、數(shù)千條規(guī)則,提供了很多主流編程語言的漏洞檢測和修復(fù)的能力,同時支持用戶配置方案,支持集成外部工具。
CODING 提供了分支代碼質(zhì)量分析的功能,可以幫助管理者快速了解分支的代碼質(zhì)量,例如:
##?小結(jié)
國內(nèi)該類 DevOps - 檢查產(chǎn)品還不夠成熟,目前各大云廠商也是初步布局階段,尚未形成穩(wěn)定格局,市場機會尤在
企業(yè)設(shè)施云化、數(shù)字化轉(zhuǎn)型趨勢下,軟件質(zhì)量(可用性、可靠性、安全、韌性)屬性關(guān)注度將日益增強
主流云服務(wù)廠商,目前全部涉足該領(lǐng)域,對代碼缺陷檢測與修復(fù)關(guān)注度持續(xù)增強,進一步確認了該研究方向的投資價值和必要性
阿里圍繞缺陷修復(fù)數(shù)據(jù)挖掘有研究成果發(fā)布,微軟提供了 CodeQL 查詢語言等,進一步確認了該項目關(guān)鍵技術(shù)路徑(基于用戶修復(fù)數(shù)據(jù)進行歷史學(xué)習(xí)、基于 dsl 等提高缺陷檢測能力可擴展性等)的合理性
#?開源成分治理領(lǐng)域
在這個部分我們介紹一下開源成分(即 Open-Source Components?[10])治理。前面講到的缺陷分析領(lǐng)域,更多是針對程序員自己開發(fā)出來的代碼來分析,看里面是否有各種類型的問題。而開源成分更主要是圍繞程序員在開發(fā)的過程中,可能大量復(fù)用的外部第三方的開源成分。
現(xiàn)代軟件開發(fā)中開源成分的使用比例與日俱增,業(yè)界關(guān)注度也越來越高。那么,結(jié)合了開源成分的代碼應(yīng)該如何進行質(zhì)量的保障?其實這也是需要通過一系列的智能化開發(fā)服務(wù),或者軟件分析服務(wù)來做到的。
那么,在開源成分治理領(lǐng)域,相關(guān)的云服務(wù)廠商正在做哪些實踐呢?
##?Microsoft Azure - Github Dependabot
我們還是先來看一下微軟的 Azure。微軟在 Github 上通過 Dependabot?[11]?服務(wù),針對代碼倉里用到的三方庫成分進行掃描。具體來講,Dependabot 會先掃描出來代碼倉里具體依賴了哪些三方庫的成分,然后針對 Top 級的或者一些已知的漏洞列表,進行漏洞的關(guān)聯(lián)和預(yù)警。
## 阿里云 - CodeUp
阿里云的 CodeUp 也在做類似的事情。
當(dāng)前 CodeUp 主要是針對系統(tǒng)層面的中間件級別做成分分析,比如服務(wù)器層面的基礎(chǔ)設(shè)施是否存在安全隱患,還沒有在代碼層面上展開工作。如果某一個特定中間件的某個特定版本存在漏洞,CodeUp 會及時給出預(yù)警。這也是阿里云整個基礎(chǔ)設(shè)施里比較關(guān)鍵的一部分功能,能夠為客戶的 server 層面、虛擬機層面的安全能力進行保駕護航。
Web 掃描器
僅支持檢測在云安全中心防護范圍內(nèi)(即已安裝云安全中心 Agent)可以訪問公網(wǎng)的服務(wù)器,支持阿里云和非阿里云的服務(wù)器。
服務(wù)器組成成分分析
支持檢測云安全中心防護范圍內(nèi)的阿里云和非阿里云服務(wù)器;防護范圍非常有限,能力處于初級階段。
##?騰訊云 - WePack 制品掃描
騰訊云 WePack?[12]?提供了制品掃描的能力,掃描的對象更多是針對編譯后的編譯包。
WePack 通過對解壓縮后的二進制組件進行審視和定位,找出每個組件到底是來自于哪個開源社區(qū)的開源項目。在定位出來之后,WePack 會對組件進行漏洞關(guān)聯(lián),并針對高危的和一些中危的漏洞進行提示,幫助程序員更快地發(fā)現(xiàn)組件里的漏洞信息,并及時修復(fù)。
##?小結(jié)
軟件中開源成分與日俱增(開源成分比例 70%+,WhiteSource 20 年報告?[13]),開源成分管理成本日益嚴峻,亟需工具支撐
Gartner 2020 報告?[14]?預(yù)計到 24 年,50% 的軟件客戶都需要軟件提供商提供軟件 BOM 清單。SCA 能力將會越來越普遍的得以應(yīng)用,成為剛性服務(wù)
主流云服務(wù)廠商,目前大部分已涉足該領(lǐng)域,但目前提供的技術(shù)還處于早期階段,待進一步完善增強,進一步確認了該研究方向的投資價值和必要性
Github 提供了庫升級助手、阿里云提供了漏洞預(yù)警服務(wù)等,進一步確認了該項目關(guān)鍵技術(shù)路徑(基于開源社區(qū)數(shù)據(jù)進行庫升級替換模式挖掘、庫移植場景代碼自動化適配等)的合理性
華為云相關(guān)技術(shù)實踐
那在完成了相關(guān)技術(shù)的梳理之后,我們來看一下華為云正在做哪些技術(shù)實踐。
#?缺陷檢測與修復(fù)
##?CodeCheck
華為云的 CodeCheck 結(jié)合華為的通用編程規(guī)范和安全編碼規(guī)范,構(gòu)建了?3 級檢查 + 3 層運營的檢查與修復(fù)體系。
3 級檢查機制
首先,我們需要有一些對應(yīng)公司編碼規(guī)范的能力或者工具集來幫助程序員進行符合公司編碼規(guī)范的檢查。因此圍繞這個需求,我們打造了 CodeCheck 平臺。CodeCheck 當(dāng)前已經(jīng)在全公司范圍內(nèi)落地,也就是說每個華為的程序員在代碼提交入庫時,都會經(jīng)過 CodeCheck 系統(tǒng)的掃描和診斷。
如上圖示,CodeCheck 針對代碼檢測進行了多方位多角度的支撐,包括:
IDE 級?我們提供多種 IDE 的插件,程序員可以在寫完代碼之后,及時進行缺陷掃描和代碼修復(fù)。除此之外,我們還提供了一些自動化修復(fù)的能力。
IDE 級?我們提供多種 IDE 的插件,程序員可以在寫完代碼之后,及時進行缺陷掃描和代碼修復(fù)。除此之外,我們還提供了一些自動化修復(fù)的能力。
門禁級?鑒于門禁時間不能太長,整個的分析時長需要控制在分鐘級。所以在這一級,我們精選了一部分準(zhǔn)確率比較高、運行時間比較短的能力集成到門禁里。門禁級提供系統(tǒng)化的掃描。
門禁級?鑒于門禁時間不能太長,整個的分析時長需要控制在分鐘級。所以在這一級,我們精選了一部分準(zhǔn)確率比較高、運行時間比較短的能力集成到門禁里。門禁級提供系統(tǒng)化的掃描。
版本級?在最后出版本的時候,我們會提供全量分析的能力。
版本級?在最后出版本的時候,我們會提供全量分析的能力。
上述三個階段會形成互補,來全方位地保障華為內(nèi)部項目代碼的質(zhì)量。
在不同階段,CodeCheck 的分析有不同的要求:
3 層運營機制
CodeCheck 還提供了 3 層的運營體系:
公司層?會制定整體的代碼質(zhì)量體系,包括應(yīng)該遵循什么樣的流程和規(guī)范,工具應(yīng)該怎么落地和使用,需要提供出一個缺陷檢測的最小集合。
產(chǎn)品線層?在公司層之下,每個產(chǎn)品線會根據(jù)自己問題域的一些特定要求來定義不同的規(guī)則集,也就是說,在不同的產(chǎn)品線,規(guī)則集其實存在一定的可調(diào)整范圍,產(chǎn)品線可以針對自有特點來制定合適的規(guī)則集。另外,產(chǎn)品線也會給產(chǎn)品層提供指導(dǎo),并定義一些公共的規(guī)則。
產(chǎn)品層?具體到每一個產(chǎn)品,其規(guī)則又允許進行一定程度的定制和數(shù)據(jù)治理。鑒于靜態(tài)分析工具會存在一些誤報的場景,當(dāng)誤報發(fā)生時需要產(chǎn)品自建屏蔽庫來做一系列排查、標(biāo)記和屏蔽的工作。
CodeCheck 現(xiàn)已通過華為云的 DevCloud 向公司外用戶提供,大家可以來試用 CodeCheck 相關(guān)的服務(wù):https://www.xzssit.com.cn/support/codecheck/
##?diKTat
在 CodeCheck 平臺之上,我們還做了很多探索,其中之一就是我們在 2020 年與俄羅斯團隊一起合作打造的一款靜態(tài)分析工具 —— diKTat?[15],該工具主要是針對 Kotlin 提供輕量級的代碼分析。
Approach
dikTat 主要的原理是對接收的源代碼做一系列的 AST 掃描。在這里我們用到了 PSI 結(jié)構(gòu),在這個結(jié)構(gòu)上通過 visitor 模式進行遍歷,從而支持 code style 的整改以及一些公共規(guī)則的檢查。
PSI 結(jié)構(gòu)示例
另外,Kotlin 之前的靜態(tài)分析工具都依賴?Type-Resolution analysis,其分析成本比較高,相對來說使用效率會低一點。與之不同的是,dikTat 提供了?No-Type-Resolution analysis,在不進行 type resolution 的情況下,利用一些啟發(fā)式的規(guī)則來做分析。
Evaluation
經(jīng)過實驗證明,dikTat 能夠在多個任務(wù)上進行有效的分析,包括 code style 分析、formatting、基于 common coding rules 的檢測、代碼壞味道檢查等。
Achievements
dikTat 已發(fā)表在 ISSRE 2021?[16]。
我們將項目在 Github 上開源,當(dāng)前已獲得 280 個 star,有越來越多的開發(fā)者參與到項目貢獻中。大家可以在下面地址獲取源代碼:https://github.com/cqfn/diKTat
另外,dikTat 經(jīng)過短短半年時間的工作,現(xiàn)已被 Kotlin 社區(qū)所采納。在靜態(tài)分析的網(wǎng)站 [17] 上可以看到,dikTat 已成為了 Kotlin 官方認可的三個主要的工具之一。
#?開源治理:三方庫移植(升級/替換)
接下來,圍繞開源治理方面。我簡單介紹一下我們做了哪些探索。
我們當(dāng)前重點投入的是?三方庫相關(guān)的問題診斷和修復(fù),即因三方庫存在的漏洞,或其他方面的問題,導(dǎo)致項目中不能繼續(xù)使用的情況下,我們該如何快速地進行升級或替換。
##?移動應(yīng)用智能移植(from GMS to HMS)
背景挑戰(zhàn)
我們先看一個初步的嘗試。
由于一些市場因素,華為終端需要打造 HMS(即 Huawei Mobile Service)生態(tài)。在這個過程中,存在一個問題,即海外市場的應(yīng)用大部分都是基于 GMS(即 Google Mobile Service) 開發(fā)的,那么現(xiàn)有的應(yīng)用如何才能夠快速遷移到 HMS?我們不能夠要求程序員重新寫一套應(yīng)用,所以我們希望給開發(fā)者提供一個比較快捷高效的工具,幫助他們將基于 GMS 的應(yīng)用快速遷移到 HMS 生態(tài)。
問題分析與解決
針對這個問題場景,我們與華為內(nèi)部多個部門,聯(lián)合打造了一個移動應(yīng)用智能移植應(yīng)用。該應(yīng)用的主要架構(gòu)如下圖所示,假設(shè)我們存在一個待轉(zhuǎn)換的 GMS 應(yīng)用,第一步需要在應(yīng)用內(nèi)部識別出它調(diào)了哪些 GMS 接口,然后在 GMS SDK 層面將調(diào)用的接口自動對應(yīng)到 HMS SDK 上,并自動化地將 HMS SDK 上相應(yīng)的 API 適配到應(yīng)用的接口調(diào)用處,從而完成整個的轉(zhuǎn)換。
完成結(jié)果
該應(yīng)用作為 HMS Toolkit 里的核心能力之一,已在 2020 年正式發(fā)布,幫助我們更快地構(gòu)建 HMS 生態(tài)。歡迎大家到下面的地址了解并試用:
工具使用視頻介紹:https://www.youtube.com/watch?v=1b1Ap5xQHm4&feature=youtu.be
工具使用說明文檔:https://developer.huawei.com/consumer/cn/doc/development/Tools-Guides/convertor-0000001050147221
##?不可信三方庫的智能移植
GMS 到 HMS 只是一個庫的移植,我們可以將上一個工作的移植能力泛化到開源三方庫的治理上,提供有風(fēng)險的三方庫自動化修復(fù)能力,這就是我們當(dāng)前正在做的一個工作。
我們收集了大量開源項目代碼倉的數(shù)據(jù),基于這些代碼倉的原始數(shù)據(jù)構(gòu)建開源項目知識圖譜,例如某個項目發(fā)布了哪些版本,哪個版本對應(yīng)的是哪個 commit,每個 commit 發(fā)布 API 有哪些,這個項目中使用了哪些三方庫等。當(dāng)所有代碼倉的關(guān)聯(lián)關(guān)系構(gòu)建起來后,我們就可以在上面做很多數(shù)據(jù)挖掘的工作。比如,我們可以針對業(yè)界主流庫的一些低版本或有漏洞的版本做挖掘,看看社區(qū)是如何修復(fù)的漏洞,或者用到了哪些庫來替換這些有風(fēng)險的庫。
###?核心技術(shù)點 1:開源庫替換模式挖掘技術(shù)
這就是我們在做的第一個工作,即找出庫之間的替換模式,從而為后續(xù)風(fēng)險三方庫的替換及修復(fù)帶來一些洞察。
Approach
我們的大概思路如下圖示。針對每個開源項目的歷史做挖掘過濾,計算出每一個項目的三方庫演進歷史(即項目的依賴變更序列)。得到變更序列之后,引入序列模式挖掘算法。在這個過程中,我們會結(jié)合一定的指標(biāo)對結(jié)果進行過濾,包括熱門庫識別、時間修正等,從而保證模式的準(zhǔn)確率。
目前我們已經(jīng)挖掘到 1400 多個有效的替代模式,這個工作在 2020 年中國軟件大會上獲得了三等獎。
Implementation
我們在 SANER 2021 上發(fā)表了 “A Multi-Metric Ranking Approach for Library Migration Recommendations”,在前面工作思路的基礎(chǔ)上,引入了更多的指標(biāo)來做數(shù)據(jù)過濾。下圖是這個工作的實現(xiàn):
開源世界里的數(shù)據(jù)非常大,如何進行有效過濾,發(fā)掘出真正有價值的數(shù)據(jù),這其實是一個非常有挑戰(zhàn)的事情。我們在過濾環(huán)節(jié)進行了深入的探索,引入了很多指標(biāo)來幫助過濾,這些指標(biāo)匯總為一個洞察庫。基于洞察庫,我們孵化了一個網(wǎng)站:http://migration-helper.net/
下圖是洞察庫當(dāng)前的進展。大家可以看到,這個洞察庫一直在持續(xù)地演進和增強,網(wǎng)站頁面會實時顯示由 experts 確認后的 Migration 建議。用戶可以在這個網(wǎng)站查詢到,一些已知的風(fēng)險三方庫,業(yè)內(nèi)大部分人遷移到了哪個三方庫上。我們通過數(shù)據(jù)挖掘的方式提供給大家一些建議,從而提高開發(fā)者修復(fù)風(fēng)險三方庫的效率。
### 核心技術(shù)點 2:庫替換場景 API 適配模式挖掘技術(shù)
有了替換模式其實還不夠,當(dāng)你把一個庫 A 替換到庫 B 之后,問題來了,這個兩個庫之間的 API 可能是不兼容的,這種情況下我們應(yīng)該怎么辦?我們基于前面的挖掘工作進行了進一步的探索,即庫替換場景下的 API 適配模式挖掘。
這個工作也需要基于歷史數(shù)據(jù)來挖掘,即當(dāng)這個庫發(fā)生變化和遷移時,我們盡可能地將上層代碼的變更記錄提煉出來,通過形式化方法的技術(shù),去 specify API 的適配模式,我們會對這樣的模式進行挖掘,并把它以圖的結(jié)構(gòu)記錄到系統(tǒng)里。下圖是一個簡單示例,大家可以去閱讀我們和俄羅斯團隊聯(lián)合發(fā)表在 ISSRE 2021 的最新論文 [19] 了解更復(fù)雜的實現(xiàn)細節(jié)。
下圖是該工作的 approach overview。當(dāng)有了變更動作后,我們會進行一系列的數(shù)據(jù)挖掘處理,包括數(shù)據(jù)的拆分、最小化、聚類、提純等,最后得到模式集,保證最終結(jié)果的有效性。
這是一個從?org.json?替換到?google.code.gson?的具體示例。我們將這個示例中的代碼變換進行一系列的處理與挖掘,得到右側(cè)兩個 change pattern。后續(xù)若有程序員遇到類似庫替換的場景時,我們就可以通過應(yīng)用 pattern 來自動地做代碼適配。
大家可以看到,pattern 使用了不同的 node 來記錄變更的動作,包括一些代碼的增加?ActionInsertAfter?和刪除?ActionDelete?都刻畫在這個結(jié)構(gòu)中。
Evaluation
我們在一些開源典型場景上做了實驗,結(jié)果表示我們的方法能夠挖掘出很多有效的 patterns,如下圖左所示。我們將挖掘出的 patterns 還原到實例中,評估 patterns 的質(zhì)量(主要是覆蓋率),結(jié)果如下圖右所示,我們的方法在很多場景下還是有價值的,在大部分場景下適配的準(zhǔn)確率可以達到 70% 以上。
Implementation
我們已將上述工作集成到了 CodeCheck 中,近期有發(fā)布一個 CodeCheck IDEA 插件試用版(當(dāng)前僅支持 maven 工程),歡迎大家試用體驗:https://bbs.huaweicloud.com/blogs/285414
下圖是插件使用的一個示例。
安裝插件:打開 IDEA 插件市場離線安裝界面,選中安裝包單擊。
掃描項目依賴:右鍵點擊項目根目錄或者構(gòu)建文件,點擊?CodeCheck->Check Third-Party Libs?查看項目所有帶漏洞的依賴。
查看關(guān)聯(lián)漏洞:左鍵單擊表格第二列可查看具體漏洞信息。漏洞信息由內(nèi)部的漏洞收集平臺提供,經(jīng)過內(nèi)部評審。
庫修復(fù)預(yù)覽:選中修復(fù)建議后,點擊?Preview?按鈕可以預(yù)覽自動適配。
庫修復(fù)適配:點擊 Apply 按鈕可以應(yīng)用選中的適配(當(dāng)前僅支持構(gòu)建文件的自動適配)。
在 IDEA 里安裝完插件后,右鍵 maven 項目可以看到?CodeCheck -> Check Third-Party Libs?菜單選項,該選項用于檢查 maven 項目中應(yīng)用到的三方庫。觸發(fā)該選項后,后臺會自動分析項目的 dependencies,通過匹配漏洞庫的數(shù)據(jù),對匹配上的三方庫給出預(yù)警。
上面示例中,該項目依賴的三方庫被檢測出存在一系列漏洞,用戶可以點擊查看漏洞詳情。當(dāng)用戶確認是漏洞后,可以使用?Fixing Actions?來對漏洞進行自動化/半自動化的修復(fù)。我們提供?Preview?功能預(yù)覽修復(fù)前后的對比,Apply?功能將修復(fù)建議應(yīng)用到項目中,Revert?功能回退修復(fù)改動。
#?IntelliMerge 代碼智能合并
接下來,簡單介紹一下我們的代碼智能合并創(chuàng)新工作?IntelliMerge,該工作是我們與北大研究團隊在 OOPSLA’19 的聯(lián)合研究成果?[20]。
##?Motivation
現(xiàn)代軟件開發(fā),越來越多的是以團隊作戰(zhàn),團隊的代碼需要定期做同步,合并,以及提交。尤其是大型企業(yè)中,程序員會面臨非常復(fù)雜的合并場景,一是團隊規(guī)模越來越大,二是項目中可能會復(fù)用大量開源代碼。
比如華為的 EMUI 系統(tǒng),基于安卓做了一系列的開發(fā)定制,開發(fā)過程中是與安卓并行的,但在項目推進到一定程度的時候需要與開源的安卓代碼進行合并,這個合并場景下沖突量會非常巨大。因此大型企業(yè)中的合并問題是一個很痛的痛點。
圍繞上述場景,我們展開了一系列研究。我們發(fā)現(xiàn) Github 其實已經(jīng)提供了一些 merge 的能力,支持程序員在很多的分支之間做代碼的合并。但是,Github 并沒有去理解代碼本身,而更多地把代碼作為文本去處理,判斷合并是否有沖突,應(yīng)該如何合并。
Github Merging between branches
業(yè)界 Merging 技術(shù)
學(xué)術(shù)界針對合并技術(shù)已經(jīng)有了很多的工作,并且也有越來越多的人開始關(guān)注這個領(lǐng)域:
Unstructured/Textual: GitMerge?[21]?(Text-line based),?most popular,Github Merge 采用的技術(shù)
Semi-structured: jFSTMerge?[22]?(Tree based),?OOPSLA2017
Structured: AutoMerge?[23]?(AST based),?OOPSLA2018,成本極高
當(dāng) Merging ?遇上 Refactoring
調(diào)研發(fā)現(xiàn),傳統(tǒng)合并技術(shù)還有很多問題亟待解決。以重構(gòu)為例。
在大型項目中,我們會一定頻率上地進行代碼的重構(gòu) refractoring,整個代碼的變化會非常大,你甚至可能會將一個方法抽象到它的父類上,或者將一個方法進行移動,而實際上整個代碼的語義并沒有發(fā)生變化。傳統(tǒng)的合并技術(shù)并不理解代碼層面的操作,所以無法判斷改動前后語義是否等價。
因此我們會發(fā)現(xiàn),在重構(gòu)的場景下,傳統(tǒng)的 Merge 算法都會失效,尤其是最為廣泛應(yīng)用的 GitMerge。這會導(dǎo)致合并的結(jié)果非常糟糕,合并后的代碼很可能存在一定語義方面的問題(False Negative),沒有解決的沖突也不一定是真沖突(False Positive)。
Refactoring-Aware Merging
我們提出了一個 “Refactoring-Aware Merging” 的概念,嘗試去理解代碼的變更,從而判斷代碼是否進行了重構(gòu)。
若重構(gòu)發(fā)生,我們會通過代碼理解的技術(shù)去推導(dǎo)出重構(gòu)的行為,例如,代碼的變動是一個上移的行為(push down) 還是一個下移的行為(pull up),亦或是代碼片段的提取(extract)?當(dāng)重構(gòu)的行為被識別出來后,我們會對同一個代碼片段進行更細粒度的匹配。匹配完成后,再將傳統(tǒng)的 merge 算法應(yīng)用到代碼片段上,從而更加精準(zhǔn)地合并代碼。
##?Approach
下圖是我們工作的大概思路:
Step 1: Code-to-Graph?針對源碼文件的三個版本(base,left by developer A,right by developer B),進行代碼分析,構(gòu)建出對應(yīng)的 PEGs(Program Element Graphs)
Step 2: Matching?對 PEGs 進行節(jié)點匹配(vertices matching),將相同節(jié)點的代碼塊關(guān)聯(lián)起來
Step 3: Merging?關(guān)聯(lián)之后,在每一個節(jié)點上對具體的代碼塊做合并,輸出合并后的代碼文件
##?Evaluation
這是該工作的實驗結(jié)果。
對于沖突代碼塊(Conflict Blocks),實驗結(jié)果表明,我們的方法能夠大量降低潛在沖突塊的數(shù)量。
對于合并后的代碼(Merged Part),相比 jFSTMerge 與 GitMerge,IntelliMerge 準(zhǔn)確率(precision)有一定的下降,但 recall 是提高的(IntelliMerge 盡可能地幫助程序員自動合并了更多的代碼塊)。因此整體來講,IntelliMerge 的收益是更大的,在很小準(zhǔn)確率損失的情況下,節(jié)省了很多程序員的時間。
這個工作我們已開源在 Github 上,大家可以關(guān)注一下:https://github.com/Symbolk/IntelliMerge
注:precision 和 recall 的計算公式如下
#?SmartCommit 代碼提交智能分拆
最后介紹一下我們有關(guān)?代碼提交智能分拆?的研究成果?SmartCommit?[25],我們在最近的 FSE 2021 會議上進行了報告,并很榮幸地獲得了最佳論文獎。
##?Motivation
現(xiàn)在企業(yè)內(nèi)部就成提交代碼的時候,程序員代碼的提交往往沒有有效管控工具,來判斷他的提交是否滿足高內(nèi)聚低耦合的原則。
我們希望代碼的每次提交都可以保持只做一件事情。比如,在這個提交內(nèi)只做 formatting,或者只做某個 bug fix,或者只支持了某一個 new feature。
這是我們期望的:
而實際上,我們針對公司內(nèi)外很多項目做了大量的調(diào)研和分析,發(fā)現(xiàn)其實 commit 歷史記錄中會包含大量的所謂?組合式提交,即一個 commit 里包含了多個任務(wù)。根據(jù)統(tǒng)計數(shù)據(jù)來看,這種類別的提交記錄占比 11%~40%(MSR13/15 for open-source communities,ICSE15 for companies),這會大大提高項目的維護成本。
這是我們不提倡的:
##?Approach
基于這個場景,我們希望能夠針對用戶提交的 commit 做智能的理解,判斷它是否混雜了多個開發(fā)任務(wù),基于代碼分析的技術(shù)將 commit 拆分為多個原子型的 commit groups 或者 change groups。鼓勵程序員能夠單獨的去提交每個 change group。(圍繞這個工作我們還做了延展,比如程序員在提交的時候,commit message 該如何撰寫,如何更規(guī)范地寫 message,commit 應(yīng)該歸為 refractor/bug fix/new feature?)
SmartCommit 將代碼分析的技術(shù)與圖匹配的算法融合為一個圖分拆算法,會給程序員提供拆分 commit 的建議,盡量保持每個 commit 滿足高內(nèi)聚低耦合原則。下圖是實現(xiàn)思路。
##?Implementation
基于上述實現(xiàn)思路,我們提供了一個公開的系統(tǒng),源代碼已在 Github 上公開:https://github.com/Symbolk/SmartCommitCore
我們將這個系統(tǒng)實現(xiàn)為一個工具,通過圖形化界面可以很清晰地給程序員提示,比如當(dāng)前 commit 混雜了很多的開發(fā)任務(wù),每一個任務(wù)是什么,每個任務(wù)對應(yīng)的 change 是什么。程序員可以在這個工具上進行快速確認,若不認可工具的某些拆分,還可以手動整合一些 change group,調(diào)整完成后,工具還可以自動地將這些 change groups 提交。這樣,一個 composite commit 會幾乎自動地被拆分為多個滿足高內(nèi)聚原則的 cohesive commits。
##?Evaluation
我們采用了混合式方法進行實驗評估:
Industrial Field Study?我們在華為內(nèi)部的兩個項目上做了近 9 個月的實驗,邀請華為內(nèi)部的程序員使用這個工具,同時監(jiān)測程序員對工具結(jié)果的反饋,看他是否采納了工具給出的建議,并依據(jù)建議作出修訂。
Controlled Open-Source Experiment?我們在開源項目上也做了一些實驗。
并通過三角分析?[26]?增加我們對實驗結(jié)果的信心:
準(zhǔn)確率結(jié)果如下:
結(jié)果表明,工具給出的建議可能不是完全正確的,往往需要程序員做一些微調(diào)。但工具可以給程序員提供一個比較好的起點,可以很快速的引導(dǎo)程序員做出更加規(guī)范的提交。
一些思考
最后,圍繞智能化的可信軟件開發(fā)這個話題,談一談我們軟件分析 Lab 當(dāng)前的一些思考。
其實在軟件開發(fā)的很多環(huán)節(jié)里,都可以將程序分析這個技術(shù)嵌進去,比如:
編碼環(huán)節(jié)?包括常見的注釋生成,程序生成,代碼搜索等,還有今天提到的 API 遷移、代碼檢查修復(fù),開源成分治理等
單元測試?圍繞這個方面,我們也有在做一些探索,希望可以自動化地生成一些單元測試用例,來提高研發(fā)效率
代碼檢視?通常與代碼檢查、代碼修復(fù)結(jié)合在一起
代碼合入?代碼的智能合入與沖突消解、智能提交、智能同步、智能 cherry-pick
系統(tǒng)運維?智能補丁篩選等
其實在軟件開發(fā)的整個生命周期里,程序分析技術(shù)都發(fā)揮了非常關(guān)鍵的作用,甚至已經(jīng)在逐漸地扮演根技術(shù)的角色。十分開心能有這樣一個技術(shù)沙龍,希望?SIG-程序分析可以吸引更多的老師、同學(xué)、業(yè)界同仁一起來探討程序分析更多的話題。
我的報告就到這里,感謝大家。
參考
[1]Amazon CodeGuru - 可自動執(zhí)行的代碼審查服務(wù) - AWS 云服務(wù) https://aws.amazon.com/cn/codeguru/
[2]Github Features: Security https://github.com/features/security
[3]Azure Pipelines | Microsoft Azure https://azure.microsoft.com/en-us/services/devops/pipelines/
[4]Debug in Visual Studio with Azure Application Insights - Azure Monitor | Microsoft Docs https://docs.microsoft.com/en-us/azure/azure-monitor/app/visual-studio
[5]云效代碼管理 Codeup代碼托管企業(yè)級代碼管理平臺 - 阿里云 https://cn.aliyun.com/product/yunxiao
[6]PMD - An extensible cross-language static code analyzer. https://pmd.github.io/
[7]阿里巴巴自研代碼管理平臺技術(shù)解密 - 知乎 https://zhuanlan.zhihu.com/p/140425680
[8]Xindong Zhang, Chenguang Zhu, Yi Li, Jianmei Guo, Lihua Liu, and HaoboGu. ?Precfix: Large-scale patch recommendation by mining defect-patch pairs.InProceedings of the ACM/IEEE 42nd International Conference on SoftwareEngineering: Software Engineering in Practice, ICSE-SEIP’20, page 41–50,New York, NY, USA, 2020. Association for Computing Machinery. https://dl.acm.org/doi/10.1145/3377813.3381356
[9]CODING - 一站式軟件研發(fā)管理平臺 https://coding.net/
[10]Open-Source Components Definition by Law Insider https://www.lawinsider.com/dictionary/open-source-components
[11]Automated Security Fixes with Dependabot - Github Security https://github.blog/2019-05-23-introducing-new-ways-to-keep-your-code-secure/#automated-security-fixes-with-dependabot
[12]WePack | 獨立部署的高效制品管理服務(wù) https://wepack.coding.net/
[13]WhiteSource Report – DevSecOps Insights 2020 https://www.whitesourcesoftware.com/resources/research-reports/whitesource-devsecops-insights/
[14]Top 10 Trends in Data and Analytics, 2020 - Gartner https://www.gartner.com/account/signin?method=initialize&TARGET=http%253A%252F%252Fwww.gartner.com%252Fdocument%252F3984974
[15]diKTat | Strict coding standard for Kotlin and a custom set of rules for detecting code smells, code style issues and bugs https://www.cqfn.org/diKTat/
[16]Diktat: Lightweight Static Analysis for Kotlin. Andrey Kuleshov (Huawei Technologies Co., Ltd), Petr Trifanov (Huawei Technologies Co., Ltd), Vladislav Frolov (Huawei Technologies Co., Ltd) and Guangtai Liang (Huawei Technologies Co., Ltd) http://2021.issre.net/industry-accepted-papers
[17]A curated list of static analysis (SAST) tools for all programming languages, config files, build tools, and more. https://github.com/analysis-tools-dev/static-analysis
[18]H. He, Y. Xu, Y. Ma, Y. Xu, G. Liang and M. Zhou, "A Multi-Metric Ranking Approach for Library Migration Recommendations," 2021 IEEE International Conference on Software Analysis, Evolution and Reengineering (SANER), 2021, pp. 72-83, doi: 10.1109/SANER50967.2021.00016. https://ieeexplore.ieee.org/document/9426069
[19]The 32nd International Symposium on Software Reliability Engineering (ISSRE 2021) https://issre.net/
[20]Bo Shen, Wei Zhang, Haiyan Zhao, Guangtai Liang, Zhi Jin, and QianxiangWang. Intellimerge: A refactoring-aware software merging technique. Proc.ACM Program. Lang., 3 (OOPSLA), October 2019. https://dl.acm.org/doi/10.1145/3360596
[21]Git Merge https://git-scm.com/docs/git-merge
[22]Guilherme Cavalcanti, Paulo Borba, and Paola Accioly. 2017. Evaluating and improving semistructured merge. Proceedings of the ACM on Programming Languages 1, OOPSLA (2017), 59. https://dl.acm.org/doi/10.1145/3133883
[23]Fengmin Zhu and Fei He. 2018. Conflict resolution for structured merge via version space algebra. Proceedings of the ACM on Programming Languages 2, OOPSLA (2018), 166. https://dl.acm.org/doi/10.1145/3276536
[24]Bo Shen, Wei Zhang, Haiyan Zhao, Guangtai Liang, Zhi Jin, and QianxiangWang. Intellimerge: A refactoring-aware software merging technique. Proc.ACM Program. Lang., 3(OOPSLA), October 2019. https://dl.acm.org/doi/10.1145/3360596
[25]Bo Shen, Wei Zhang, Christian Kastner, Haiyan Zhao, Zhao Wei, Guangtai Liang, and Zhi Jin. Smartcommit: A graph-based interactive assistant for activity-oriented commits. In Proceedings of the 29th ACM Joint Meeting on European Software Engineering Conference and Symposium on the Foundations of Software Engineering, ESEC/FSE 2021, page 379–390, New York, NY, USA, 2021. Association for Computing Machinery. https://dl.acm.org/doi/abs/10.1145/3468264.3468551
[26]Alison Twycross. 2004. Research design: qualitative, quantitative and mixed methods approachesResearch design: qualitative, quantitative and mixed methods approaches Creswell John W Sage 320 £29 0761924426 0761924426. Nurse Researcher 12, 1 (sep 2004), 82–83. https://doi.org/10.7748/nr.12.1.82.s2
軟件開發(fā)
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。