劉玉輝, 王忠杰
(哈爾濱工業(yè)大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院, 哈爾濱 150001)
隨著開(kāi)源技術(shù)的興起,GitHub等開(kāi)源軟件取得了巨大的成功,目前,GitHub上已經(jīng)擁有超過(guò)6 700萬(wàn)個(gè)repo(代碼倉(cāng)庫(kù)),活躍用戶(hù)達(dá)到2 400萬(wàn)人,超過(guò)150萬(wàn)家公司和機(jī)構(gòu)進(jìn)駐。在開(kāi)源環(huán)境下,為了更好地實(shí)現(xiàn)團(tuán)隊(duì)合作,計(jì)算機(jī)相關(guān)專(zhuān)業(yè)教師也鼓勵(lì)學(xué)生在GitHub上嘗試項(xiàng)目開(kāi)發(fā)協(xié)作,更好地鍛煉提升自己。而針對(duì)學(xué)生在GitHub上協(xié)作完成的項(xiàng)目,教師如何進(jìn)行項(xiàng)目團(tuán)隊(duì)內(nèi)成員的貢獻(xiàn)度量,進(jìn)而為學(xué)生課程任務(wù)給出公平、公正的評(píng)分則成為一個(gè)問(wèn)題。
傳統(tǒng)的評(píng)分策略有:
(1)小組內(nèi)TeamLeader根據(jù)小組成員平時(shí)的表現(xiàn)制定組內(nèi)評(píng)級(jí)參考表,供教師或助教參考。
(2)教師或助教通過(guò)對(duì)組內(nèi)成員提問(wèn)考核,根據(jù)回答狀況來(lái)核定評(píng)分等。
這些傳統(tǒng)的方法在一定程度上可以解決項(xiàng)目團(tuán)隊(duì)成員評(píng)分問(wèn)題,但同時(shí)也存在一些不足,如:沒(méi)有充分利用項(xiàng)目團(tuán)隊(duì)開(kāi)發(fā)過(guò)程的數(shù)據(jù)信息、主觀(guān)因素會(huì)有部分影響、最終的問(wèn)答形式考核趨于片面,作弊應(yīng)付的可能性增大等。
為了解決上述問(wèn)題,本文提出GitHub開(kāi)源軟件項(xiàng)目團(tuán)隊(duì)協(xié)作過(guò)程評(píng)價(jià)的研究,可以幫助教師解決TA問(wèn)題。在GitHub API v3中共列舉了37種事件,如當(dāng)對(duì)一次提交進(jìn)行評(píng)論時(shí),就會(huì)觸發(fā)CommitCommentEvent事件。這些事件中包括項(xiàng)目?jī)?nèi)部多人合作觸發(fā)的事件和項(xiàng)目外部其它人員通過(guò)Fork→PullRequest→Merge途徑做出貢獻(xiàn),本文主要研究項(xiàng)目?jī)?nèi)部多人合作時(shí),各成員做出的貢獻(xiàn)并進(jìn)行度量。通過(guò)分析成員的貢獻(xiàn)行為建立成員貢獻(xiàn)行為指標(biāo)模型,然后設(shè)計(jì)量化貢獻(xiàn)計(jì)算方法,從而直觀(guān)得出項(xiàng)目?jī)?nèi)成員的個(gè)人貢獻(xiàn)。這樣充分挖掘并利用了項(xiàng)目團(tuán)隊(duì)協(xié)作開(kāi)發(fā)過(guò)程中在GitHub軟件倉(cāng)庫(kù)中保留的數(shù)據(jù)信息,使項(xiàng)目團(tuán)隊(duì)內(nèi)成員的貢獻(xiàn)度量更加準(zhǔn)確。
在軟件項(xiàng)目中,如何對(duì)項(xiàng)目團(tuán)隊(duì)內(nèi)開(kāi)發(fā)人員的貢獻(xiàn)度進(jìn)行度量一直是軟件倉(cāng)庫(kù)挖掘(Mining Software Repository,MSR領(lǐng)域)廣受關(guān)注的一個(gè)研究課題,傳統(tǒng)的度量方法包括Sackman等人[1]提出的以單詞量作為工作單位、程序的代碼行數(shù)(Lines of Code,LOC)、面向?qū)ο笾械念?lèi)以及函數(shù)構(gòu)件等,其中面向?qū)ο蟮能浖_(kāi)發(fā)中各種工作單位的討論在文獻(xiàn)[2]中已有清晰闡述。除了程序代碼的貢獻(xiàn),還有人從項(xiàng)目團(tuán)隊(duì)成員之間的協(xié)作討論、修復(fù)bug情況等方面相繼發(fā)表研究成果。Gousios等人[3]通過(guò)綜合傳統(tǒng)度量方法總結(jié)了一系列開(kāi)源環(huán)境下項(xiàng)目成員的貢獻(xiàn)行為,其中包括很多軟件資源庫(kù),如IRC、Wiki、Bug Database等,但這些資源庫(kù)的研究范圍與國(guó)內(nèi)實(shí)際情況不符。Amor等人[4]也根據(jù)軟件開(kāi)發(fā)過(guò)程中的跟蹤信息提出一套評(píng)估模型。此外,Treude等人[5]提出4方面貢獻(xiàn):代碼貢獻(xiàn)、方法平均復(fù)雜度、引入的bug、bug修復(fù),并收集4個(gè)團(tuán)隊(duì)、48位開(kāi)發(fā)者、為期12周的貢獻(xiàn)數(shù)據(jù),從而記錄整個(gè)過(guò)程的貢獻(xiàn)情況,以此完成驗(yàn)證。
本文從GitHub獲取項(xiàng)目團(tuán)隊(duì)內(nèi)各成員相關(guān)數(shù)據(jù),主要從以下方面進(jìn)行軟件倉(cāng)庫(kù)挖掘,將成員在團(tuán)隊(duì)中的貢獻(xiàn)具體化,可以幫助教師解決TA問(wèn)題。首先進(jìn)行理論研究:構(gòu)建成員貢獻(xiàn)行為指標(biāo)模型和設(shè)計(jì)量化貢獻(xiàn)計(jì)算方法,然后將理論成果應(yīng)用于實(shí)踐研究中,設(shè)計(jì)并實(shí)現(xiàn)GitHub團(tuán)隊(duì)項(xiàng)目成員貢獻(xiàn)評(píng)估Web應(yīng)用系統(tǒng)。其中,數(shù)據(jù)庫(kù)采用MySQL,后臺(tái)使用SpringMVC框架分層解耦為持久層、業(yè)務(wù)邏輯層和控制層,最后則在前端用Extjs將成員貢獻(xiàn)生成可視化展示。主要研究?jī)?nèi)容框架如圖1所示。
本文擬將從3個(gè)方面展開(kāi)研究闡述:成員貢獻(xiàn)行為數(shù)據(jù)建模、成員貢獻(xiàn)行為度量計(jì)算方法、成員貢獻(xiàn)行為數(shù)據(jù)的獲取與處理,而后將進(jìn)行系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)。這里針對(duì)各主題要點(diǎn)可得研究分述如下。
針對(duì)本研究,將引入如下GitHub開(kāi)發(fā)人員貢獻(xiàn)行為指標(biāo),設(shè)計(jì)詳情參見(jiàn)表1。
基于Gousios等人的研究,本文設(shè)計(jì)了一種項(xiàng)目團(tuán)隊(duì)內(nèi)的成員貢獻(xiàn)行為度量計(jì)算方法,計(jì)算公式如下所示:
C(d)=LOC(d)+CF(d),
(1)
其中,C(d)表示開(kāi)發(fā)人員d的總貢獻(xiàn);LOC(d)表示開(kāi)發(fā)人員d的相對(duì)凈代碼量;CF(d)表示開(kāi)發(fā)人員d對(duì)表1中各貢獻(xiàn)行為指標(biāo)(LOC除外)的貢獻(xiàn)函數(shù)。
圖1 研究?jī)?nèi)容框架
表1 GitHub開(kāi)發(fā)人員貢獻(xiàn)行為指標(biāo)
進(jìn)一步,研究推得LOC(d)和CF(d)的數(shù)學(xué)表述可分別如式(2)、式(3)所示:
(2)
(3)
每種貢獻(xiàn)行為指標(biāo)的貢獻(xiàn)度計(jì)算都是一個(gè)相對(duì)值,具體可參見(jiàn)表2。
表2 貢獻(xiàn)行為指標(biāo)的貢獻(xiàn)度計(jì)算
2.4.1 成員貢獻(xiàn)行為數(shù)據(jù)的設(shè)計(jì)功能分析
獲取學(xué)生提交到GitHub上的開(kāi)源軟件項(xiàng)目地址,克隆遠(yuǎn)程庫(kù)。在配置好Git之后,根據(jù)GitHub輸出的地址如 https://github.com/gnu-fripside/PaperManager.git,用命令git clone克隆對(duì)應(yīng)的本地庫(kù)。使用Java ProcessBuilder執(zhí)行g(shù)it指令,通過(guò)分析log日志得到所需的數(shù)據(jù)。
在分析項(xiàng)目團(tuán)隊(duì)內(nèi)的各個(gè)成員對(duì)該項(xiàng)目的貢獻(xiàn)之前,首先要考慮用什么來(lái)唯一確定地標(biāo)識(shí)各個(gè)成員。如圖2所示,在GitHub日志中有author name、author email、 committer name和committer email,就需要選擇其中之一來(lái)標(biāo)識(shí)成員的ID。研究可知,在Git分布式版本管理中,作者(author)指的是實(shí)際做出修改的人,提交者(committer)指的是最后將此工作成果提交到倉(cāng)庫(kù)的人,當(dāng)設(shè)計(jì)者為某個(gè)項(xiàng)目發(fā)布補(bǔ)丁,然后某個(gè)核心成員將該補(bǔ)丁并入項(xiàng)目時(shí),該人即為作者,而那個(gè)核心成員就是提交者,所以要研究描述成員的貢獻(xiàn)就要以實(shí)際做出修改的人為準(zhǔn)則來(lái)找到貢獻(xiàn)擁有者。另外,經(jīng)過(guò)測(cè)試,日志中記錄的author name類(lèi)似于昵稱(chēng),可隨意更改,若成員在開(kāi)發(fā)過(guò)程中更改作者名稱(chēng)則不能準(zhǔn)確跟蹤該成員的貢獻(xiàn),故而最終選擇author email作為唯一確定標(biāo)識(shí)成員的ID。
貢獻(xiàn)度的度量主要用到了項(xiàng)目的commits數(shù)據(jù)。commits數(shù)據(jù)是指項(xiàng)目從最開(kāi)始到當(dāng)前獲取的最新版本之間每次提交的信息,包括提交的版本號(hào)、作者的郵箱、提交時(shí)間、提交注釋信息、修改的文件及內(nèi)容、修改的行數(shù)統(tǒng)計(jì)等,下面即以L(fǎng)OC貢獻(xiàn)為例詳細(xì)闡釋解析數(shù)據(jù)獲取過(guò)程。
圖2 GitHub日志中成員ID選擇
2.4.2 LOC貢獻(xiàn)設(shè)計(jì)詳解
首先需要獲得項(xiàng)目團(tuán)隊(duì)內(nèi)成員的凈代碼量,換言之,即分析出項(xiàng)目最后一個(gè)提交版本的每行代碼的作者是誰(shuí),并進(jìn)行統(tǒng)計(jì)。本文算法的研究設(shè)計(jì)可參考代碼如下。
算法:項(xiàng)目?jī)?nèi)可按行度量文件的路徑獲取算法
輸入:項(xiàng)目所在路徑及項(xiàng)目?jī)?nèi)文件的根目錄filePath
輸出:一組可按行度量的文件路徑集合
GetFiles(filePath)
File_List[ ] ←Φ
File_Root[ ] ←filePath
for each file inFile_Root[ ] do
if file is directory and not hidden
thenGetFiles(filePath)
else if file is not Binary and not hidden
thenFile_List[ ] ←file
end for
其中判斷文件是否是二進(jìn)制時(shí),獲取文件數(shù)據(jù)的每個(gè)字節(jié)t,如果t<32且t!=9且t!=10且t!=13同時(shí)成立,則該文件為二進(jìn)制文件。獲得的符合要求的文件目錄如圖3所示。
圖3 可按行度量文件目錄
以PaperManager為例(項(xiàng)目地址為https://github.com/gnu-fripside/PaperManager.git)。研究得到所需的項(xiàng)目?jī)?nèi)所有的文件目錄后,就可以通過(guò)git blame命令逐一查看每個(gè)文件,如圖4所示,顯示內(nèi)容格式為:commit ID | 作者名稱(chēng) | 提交時(shí)間 | 代碼位于文件中的行數(shù)|實(shí)際代碼。為此將提取每行代碼的commit ID再進(jìn)行處理,上文已提到此處的作者名稱(chēng)不能唯一確定地標(biāo)識(shí)項(xiàng)目?jī)?nèi)的成員,而研究提取此處的commit ID的目的是為了建立每行代碼→commit ID→author email的邏輯關(guān)系。
由commit ID關(guān)聯(lián)author email有多種處理方式,這里可通過(guò)git show [commit ID] --pretty=format:"%ae" -shortstat做到更加方便快捷的處理,最后得到每行代碼對(duì)應(yīng)的作者郵箱,后續(xù)工作只需HashMap遍歷計(jì)數(shù)即可得到項(xiàng)目中每個(gè)成員的凈代碼量,設(shè)計(jì)運(yùn)行結(jié)果即如圖5所示。
圖4 每個(gè)文件git blame的具體內(nèi)容
圖5 項(xiàng)目成員凈代碼量
系統(tǒng)首頁(yè)主要內(nèi)容和架構(gòu)組織關(guān)系如圖6所示。
本功能可以得到成員貢獻(xiàn)行為度量各個(gè)指標(biāo)的具體值,依次為項(xiàng)目團(tuán)隊(duì)中成員的郵箱、項(xiàng)目最后一個(gè)版本中成員的凈代碼量LOC(以行為單位)、成員的提交數(shù)、成員參與該項(xiàng)目的時(shí)長(zhǎng)(以天為單位)、成員添加和刪除代碼行數(shù)、成員添加和刪除文檔行數(shù)、提交注釋中包含的Bug編號(hào)數(shù)。該項(xiàng)目功能的最終可視化效果則分別如圖7、圖8所示,進(jìn)而可以為每個(gè)指標(biāo)加上權(quán)重后就能得出成員貢獻(xiàn)排名。
圖6 系統(tǒng)首頁(yè)
圖7 成員絕對(duì)貢獻(xiàn)可視化
圖8 成員相對(duì)貢獻(xiàn)可視化
本文將參數(shù)默認(rèn)設(shè)置為:不同資源庫(kù)之間占比均勻且不同貢獻(xiàn)行為指標(biāo)模型之間占比均勻,由此可得項(xiàng)目?jī)?nèi)成員的貢獻(xiàn)度量。同樣以PaperManager為例(項(xiàng)目地址為https://github.com/gnu-fripside/PaperManager.git)進(jìn)行仿真測(cè)試,系統(tǒng)測(cè)試結(jié)果詳見(jiàn)表3。由表3可見(jiàn)系統(tǒng)評(píng)分與人工評(píng)分基本為正相關(guān),同理測(cè)試20組項(xiàng)目,結(jié)果證明此模型效果良好。
表3 系統(tǒng)測(cè)試結(jié)果
本文針對(duì)GitHub上學(xué)生的開(kāi)源團(tuán)隊(duì)項(xiàng)目構(gòu)建了成員貢獻(xiàn)行為指標(biāo)模型,提出度量成員貢獻(xiàn)的計(jì)算方法,設(shè)計(jì)并實(shí)現(xiàn)了基于SpringMVC的GitHub團(tuán)隊(duì)項(xiàng)目評(píng)估與監(jiān)控系統(tǒng)的Web應(yīng)用,利用GitHub軟件倉(cāng)庫(kù)中記錄的信息進(jìn)行挖掘,幫助教師更好地評(píng)判學(xué)生在GitHub項(xiàng)目中的貢獻(xiàn)。本系統(tǒng)還選取了20組項(xiàng)目,對(duì)該系統(tǒng)進(jìn)行體驗(yàn)測(cè)試,結(jié)果表明本軟件對(duì)項(xiàng)目團(tuán)隊(duì)內(nèi)各成員的評(píng)判結(jié)果與教師人工評(píng)判基本一致,效果良好。