如何生成整合了阿里巴巴JAVA編碼規(guī)范的PMD包配合GitLab提升團(tuán)隊(duì)代碼質(zhì)量

代碼不只是用來運(yùn)行的犁功,更是用來閱讀的

編碼規(guī)范

代碼規(guī)范看似只是簡單的一個(gè)編碼的規(guī)范氓轰,對代碼格式、變量命名浸卦、注釋格式等做一個(gè)統(tǒng)一規(guī)范署鸡,看似有點(diǎn)強(qiáng)迫你改變編碼風(fēng)格的味道。但是當(dāng)你和許多團(tuán)隊(duì)協(xié)同開發(fā)過許多項(xiàng)目限嫌,寫過許多代碼之后再回頭來看的話靴庆,你就會發(fā)現(xiàn)它真的就是個(gè)規(guī)范,啊不怒医,真的是個(gè)好東西炉抒。有沒有看過國慶閱兵上的方陣,當(dāng)所有軍人著裝統(tǒng)一裆熙,排列整齊端礼,一起從長安街走過得時(shí)候,會不會被他們帶來的視覺沖擊所震撼入录。編碼規(guī)范就如其中的軍規(guī)蛤奥,當(dāng)大量的代碼都具有統(tǒng)一性整齊性時(shí),帶給每個(gè)參與的人的視覺效果也是極具沖擊性的僚稿。當(dāng)然除了視覺效果凡桥,愉悅了心情之外,這種統(tǒng)一性蚀同,為每個(gè)參與編碼的人員統(tǒng)一了風(fēng)格缅刽,彼此之間互相閱讀代碼的效率就高了啊掏,團(tuán)隊(duì)間的協(xié)作效率也就高了。常見的比較受認(rèn)可的編碼規(guī)范衰猛,基本都是大廠的(廢話迟蜜,沒點(diǎn)頭銜在高傲的程序猿前誰會服誰),例如:Google啡省、Sun娜睛、阿里巴巴等大廠都有發(fā)布自己的編碼規(guī)范,這些可都是集萬千大神的工程實(shí)踐總結(jié)卦睹,這些總結(jié)幫助行業(yè)人員提高了開發(fā)質(zhì)量和效率畦戒,大大降低了代碼的維護(hù)成本

阿里巴巴JAVA編碼規(guī)范

好多大廠都發(fā)布了編碼規(guī)范结序,為何選阿里巴巴的呢障斋?第一,阿里給的規(guī)范更加符合國人的習(xí)慣徐鹤,畢竟里面絕大部分都是國人垃环;第二就是阿里的規(guī)范文檔都是中文的,方便閱讀返敬,也降低了一些翻譯的歧義性等等晴裹。(真實(shí)理由其實(shí)就一個(gè),我英文不好)有用過谷歌規(guī)范的再去用阿里的就會深有體會了救赐,谷歌的規(guī)范畢竟比較符合西方人習(xí)慣,很多注釋上的規(guī)范很蛋疼的只磷。

阿里巴巴的JAVA編程規(guī)范经磅,至今為止已更迭了多個(gè)版本,2018年6月6日钮追,《阿里巴巴Java開發(fā)手冊(詳盡版)》v1.4正式在GitHub上發(fā)布预厌,這是史上內(nèi)容最全、修正最為徹底的一個(gè)版本元媚,并且增加了單元測試規(guī)約內(nèi)容轧叽,這也是阿里官方對外發(fā)布的最后一個(gè)PDF版本,值得收藏刊棕。

《阿里巴巴Java開發(fā)手冊》是阿里內(nèi)部Java工程師所遵循的開發(fā)規(guī)范炭晒,涵蓋編程規(guī)約、單元測試規(guī)約甥角、異常日志規(guī)約网严、MySQL規(guī)約、工程規(guī)約嗤无、安全規(guī)約等震束,這是近萬名阿里Java技術(shù)精英的經(jīng)驗(yàn)總結(jié)怜庸,并經(jīng)歷了多次大規(guī)模一線實(shí)戰(zhàn)檢驗(yàn)及完善。這是阿里回饋給Java社區(qū)的一份禮物垢村,希望能夠幫助企業(yè)開發(fā)團(tuán)隊(duì)在Java開發(fā)上更高效割疾、容錯(cuò)、有協(xié)作性嘉栓,提高代碼質(zhì)量宏榕,降低項(xiàng)目維護(hù)成本。

這里是阿里巴巴Java編碼規(guī)范的GitHub傳送門胸懈。里面提供了多種代碼規(guī)范檢測方式:

  • IntelliJ IDEA插件集成方式
  • Eclipse 插件集成方式
  • pmd工具集成方式

對應(yīng)的IDE插件可以看一下這篇文章《阿里巴巴Java開發(fā)規(guī)約插件p3c詳細(xì)教程及使用感受

為了和GitLab能夠配合担扑,進(jìn)行提交時(shí)自動化得代碼檢查,這邊選擇了第三種pmd工具集成方式趣钱。

打成PMD工具Jar包

由于阿里的GitHub中p3c/p3c-pmd提供的只是規(guī)則代碼涌献,主體PMD代碼是以依賴方式引入,要把它制作成一個(gè)可獨(dú)立運(yùn)行的工具包首有,需要將所有依賴的包都封裝到一起燕垃,打成一個(gè)胖Jar包,才能夠在本地獨(dú)立得運(yùn)行井联。

  1. 從GitHub中把p3c的代碼庫下載下來(可用git clone也可以直接在GitHub中下載zip包)
  2. 安裝Gradle
  3. 進(jìn)入到p3c-pmd目錄中卜壕,初始化Gradle項(xiàng)目
# gradle init
  1. 編輯build.gradle,加入jar塊(最后一塊代碼塊)
apply plugin: 'java'
apply plugin: 'maven'

group = 'com.alibaba.p3c'
version = '1.3.6'

description = """p3c-pmd"""

sourceCompatibility = 1.7
targetCompatibility = 1.7
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

configurations.all {
}

repositories {
     maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
     maven { url "http://repo.maven.apache.org/maven2" }
}
dependencies {
    compile group: 'net.sourceforge.pmd', name: 'pmd-java', version:'5.5.2'
    compile group: 'net.sourceforge.pmd', name: 'pmd-vm', version:'5.5.2'
    testCompile group: 'net.sourceforge.pmd', name: 'pmd-test', version:'5.5.2'
}
jar {
    from {
        // 添加依懶到打包文件
        configurations.runtime.collect{zipTree(it)}
    }
}
  1. 開始構(gòu)建Gradle項(xiàng)目

Windows下:

cd /path/to/p3c-pmd/
gradlew.bat build

Linux下:

cd /path/to/p3c-pmd/
./gradlew build
  1. 構(gòu)建完成后在build/libs/中會生成p3c-pmd-1.3.6.jar包烙常,到此就獲取到了我們需要的胖Jar包了
  2. 為啥會有第7步轴捎,直接拿這個(gè)胖Jar去檢查文件的話,會出現(xiàn)如下問題:
java -cp p3c-pmd-1.3.6.jar net.sourceforge.pmd.PMD -d test.java -R rulesets/java/ali-comment.xml

執(zhí)行后報(bào)錯(cuò):

Exception in thread "main" java.lang.NullPointerException
        at net.sourceforge.pmd.cli.PMDParameters.getLanguage(PMDParameters.java:223)
        at net.sourceforge.pmd.cli.PMDParameters.transformParametersIntoConfiguration(PMDParameters.java:151)
        at net.sourceforge.pmd.PMD.run(PMD.java:490)
        at net.sourceforge.pmd.cli.PMDCommandLineInterface.run(PMDCommandLineInterface.java:167)
        at net.sourceforge.pmd.PMD.main(PMD.java:477)

為啥空指針異常了蚕脏,去查看PMD源碼侦副,發(fā)現(xiàn)PMD獲取不到資源文件中的語言值。而這個(gè)資源文件在META-INFO中驼鞭。上面的構(gòu)建方式?jīng)]有去解決Jar包中META-INFO文件下的文件合并問題秦驯。每個(gè)依賴的jar包在合并時(shí)都是復(fù)制進(jìn)來,這就導(dǎo)致了原先的PMD包中有net.sourceforge.pmd.cpd.Language和net.sourceforge.pmd.lang.Language這兩個(gè)文件挣棕,而p3c-pmd中也有這兩個(gè)文件译隘,沖突了。

我們要做得就是將包解壓出來洛心,然后確保這兩個(gè)文件都只有一份在META-INFO文件夾中固耘,并且保證:

net.sourceforge.pmd.cpd.Language文件的值為

net.sourceforge.pmd.cpd.JavaLanguage

net.sourceforge.pmd.lang.Language文件的值為

net.sourceforge.pmd.lang.java.JavaLanguageModule

最后重新打成Jar包就好了。至此皂甘,生成的jar包才是正確可用的編碼規(guī)范檢查工具玻驻。

這里,很多人肯定用多了IDE,都已經(jīng)忘記java中jar包基本的操作了璧瞬,這里附上Jar包基本的操作傳送門户辫。
還有,Java打Jar包的幾種方式嗤锉。

檢查源碼

接下來就可以用生成的jar進(jìn)行代碼檢查了

java -cp p3c-pmd-1.3.6.jar net.sourceforge.pmd.PMD -d E:\CodeRepos\data-server-test\data-server-core\src\main\java\com  -R rulesets/java/ali-comment.xml
E:\CodeRepos\data-server-test\data-server-core\src\main\java\com\jiniutech\common\BeanConvert.java:6:   【BeanConvert】 注釋缺少@author信息
E:\CodeRepos\data-server-test\data-server-core\src\main\java\com\jiniutech\common\BeanConvert.java:7:   接口方法【getBean】必須使用javadoc注釋

參數(shù)解釋:

  • -d 源碼目錄渔欢,多個(gè)文件或者目錄以,號分開
  • -R 指定規(guī)則,多個(gè)規(guī)則以,號分開瘟忱。阿里規(guī)則路徑在包中rulesets/java/ali-*.xml
  • -f 報(bào)告格式奥额,text html xml等。

附:PMD工具官方網(wǎng)站

集成到GitLab的hooks中

hook機(jī)制在很多系統(tǒng)中都有访诱,hook機(jī)制使得GitLab能在特定的重要?jiǎng)幼靼l(fā)生前/時(shí)/后觸發(fā)自定義的腳本垫挨。GitLab在每次項(xiàng)目init時(shí),就會在每一個(gè)項(xiàng)目里創(chuàng)建一個(gè)hooks文件夾的軟鏈接触菜,指向一個(gè)特定文件夾九榔。所以在hooks里的操作都是全局操作,是面向所有項(xiàng)目的涡相。

[root@localhost data-server.git]# ll -la 
total 32
lrwxrwxrwx.  1 polkitd root   47 Oct 25 02:43 hooks -> /opt/gitlab/embedded/service/gitlab-shell/hooks

這里是GitLab Hooks的官方文檔哲泊。

由于我們想要達(dá)到的效果是每次提交前進(jìn)行代碼檢查,因此要用到pre-receive文件催蝗,首先將p3c-pmd-1.3.6.jar 包復(fù)制到hooks中切威,然后在hooks中創(chuàng)建pre-receive文件,內(nèi)容如下:

#!/bin/sh
#

REJECT=0

while read oldrev newrev refname; do
    if [ "$oldrev" = "0000000000000000000000000000000000000000" ];then
        oldrev="${newrev}^"
    fi

    files=`git diff --name-only ${oldrev} ${newrev}  | grep -e "\.java$"`

    if [ -n "$files" ]; then
        TEMPDIR="tmp"
        for file in ${files}; do
            mkdir -p "${TEMPDIR}/`dirname ${file}`" >/dev/null
            git show $newrev:$file > ${TEMPDIR}/${file}
        done;

        files_to_check=`find $TEMPDIR -name '*.java'`

        /home/jdk1.8.0_191/bin/java -cp hooks/p3c-pmd-1.3.6.jar net.sourceforge.pmd.PMD -d ${files_to_check} -R rulesets/java/ali-comment.xml,rulesets/java/ali-concurrent.xml,rulesets/java/ali-constant.xml,rulesets/java/ali-exception.xml,rulesets/java/ali-flowcontrol.xml,rulesets/java/ali-naming.xml,rulesets/java/ali-oop.xml,rulesets/java/ali-orm.xml,rulesets/java/ali-other.xml,rulesets/java/ali-set.xml -f text
        REJECT=$?

        rm -rf $TEMPDIR
    fi
done

exit $REJECT

要注意的是pre-receive文件必須沒有任何后綴丙号,且為可執(zhí)行文件(+X)先朦。

這個(gè)腳本在每次提交前檢查所有提交的后綴名.java的文件,然后用得到的p3c-pmd-1.3.6.jar 包對這些文件進(jìn)行代碼檢查犬缨,然后返回結(jié)果烙无。如果存在不規(guī)范的代碼則返回給提交者錯(cuò)誤信息,如下圖


代碼提交檢測報(bào)錯(cuò)圖

這樣強(qiáng)制進(jìn)行代碼檢查就完成了遍尺。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市涮拗,隨后出現(xiàn)的幾起案子乾戏,更是在濱河造成了極大的恐慌,老刑警劉巖三热,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鼓择,死亡現(xiàn)場離奇詭異,居然都是意外死亡就漾,警方通過查閱死者的電腦和手機(jī)呐能,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摆出,你說我怎么就攤上這事朗徊。” “怎么了偎漫?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵爷恳,是天一觀的道長。 經(jīng)常有香客問我象踊,道長温亲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任杯矩,我火速辦了婚禮栈虚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘史隆。我一直安慰自己魂务,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布逆害。 她就那樣靜靜地躺著头镊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪魄幕。 梳的紋絲不亂的頭發(fā)上相艇,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機(jī)與錄音纯陨,去河邊找鬼坛芽。 笑死,一個(gè)胖子當(dāng)著我的面吹牛翼抠,可吹牛的內(nèi)容都是我干的咙轩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼阴颖,長吁一口氣:“原來是場噩夢啊……” “哼活喊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起量愧,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤钾菊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后偎肃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體煞烫,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年累颂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了滞详。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖料饥,靈堂內(nèi)的尸體忽然破棺而出蒲犬,到底是詐尸還是另有隱情,我是刑警寧澤稀火,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布暖哨,位于F島的核電站,受9級特大地震影響凰狞,放射性物質(zhì)發(fā)生泄漏篇裁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一赡若、第九天 我趴在偏房一處隱蔽的房頂上張望达布。 院中可真熱鬧,春花似錦逾冬、人聲如沸黍聂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽产还。三九已至,卻和暖如春嘀趟,著一層夾襖步出監(jiān)牢的瞬間脐区,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工她按, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留牛隅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓酌泰,卻偏偏與公主長得像媒佣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子陵刹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容