1. 程式人生 > 其它 >專案commit前使用阿里規範做強制提交校驗

專案commit前使用阿里規範做強制提交校驗

              最近幾天一直在瞭解git 如何提交前做git強制校驗。因為專案使用的是coding,之前的gitlab 是有hook的設定的。可以在push時候做校驗,但是coding 我看了他們 的官網,沒找到設定hook的地方。於是決定換一種方式:在本地commit前做強制校驗。

          思路是這樣的:本地專案的.git/hook目錄下面是預設的提交前校驗,裡面有pre-commit.example、pre-commit-msg.example等shell指令碼檔案。帶example預設是不執行的,去掉字尾example就會做對應的校驗。那麼 是不是可以利用這點,在本地commit前來做校驗呢?

           好的 ,思路有了。首先是去掉pre-commit.example的字尾,隨便寫點shell指令碼,發現git commit 前 是可以執行的(簡單的加上一句echo 什麼內容都不要)。但是如何在commit前讓本地走阿里規範呢?

          帶著這個問題,繼續去思考。阿里規範本身是一套p3c的標準,在網上看到別人已經有寫好的現成的方案。於是藉助現成的方案:(參考 https://www.jianshu.com/p/b87ca8615c9c、https://www.jianshu.com/p/048627b20860 感謝作者)就是把阿里規範的原始碼 通過maven達成了jar包,然後使用 java jar的命令 來實現的。再然後把這行命令寫在本地的pre-commit腳本里面,這樣就可以實現commit 前校驗程式碼是否走阿里規範了。

     具體操作就是:去gitlab上下載 cp3的原始碼(地址:https://github.com/alibaba/p3c)下載到本地,通過maven命令達成jar包:如下

     

mvn clean package -Dmaven.test.skip=true

   打的jar包有好幾個,主要是使用 p3c-pmd-2.1.1-jar-with-dependencies.jar 。使用命令列:

  

java -Dpmd.language=en -cp /d/p3c-pmd-2.1.1-jar-with-dependencies.jar  net.sourceforge.pmd.PMD -d /d/workspace/community   -R rulesets/ali-p3c.xml -f text -shortnames
 

引數解釋:

  • -d 原始碼目錄,多個檔案或者目錄以,號分開
  • -R 指定規則,多個規則以,號分開。阿里規則路徑在包中rulesets/java/ali-*.xml
  • -f 報告格式,text html xml等。

附:PMD工具官方網站

好了,hook指令碼已經寫好了。但是這是一個.git  目錄下的檔案,不可能每個人都要在本地寫吧。而且裡面都是寫的絕對路徑。好吧,還需要一個指令碼,本地執行這個指令碼後,會在.git/hook目錄下生成 pre-commit的指令碼,這樣只需要手動執行下就可以了。唯一的不方便地方是 ,需要手動執行下才行。指令碼如下:   
#!/bin/sh
#本地提交前自動觸發阿里巴巴p3c規範指令碼
EJECT=0                 #REJECT變數,初始化為0
GIT_ROOT=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)

# 獲取.git/hooks/根目錄
HOOKS_DIR="$GIT_ROOT/.git/hooks"
# 沒有時建立該目錄
if [ ! -d "$HOOKS_DIR" ]; then
    mkdir "$HOOKS_DIR"
fi
# 所有需要hook的git hooks檔名
hook_names=(
    pre-commit
    )
# 在.git/hooks/下生成這些執行檔案
for hook_name in ${hook_names[@]}
do
    # 生成hook檔案
    REAL_HOOK_FILE=$HOOKS_DIR/$hook_name
    # 將模板檔案內容copy進去
    cp $GIT_ROOT/check.sh $REAL_HOOK_FILE
    # 替換模板檔案中的hook-tmp為正確的hook檔名
    #sed -i "" "s/check.sh/$hook_name/g" $REAL_HOOK_FILE
    # 修改hook檔案許可權
    chmod a+x $REAL_HOOK_FILE
done
#!/bin/sh
#
# An example hook script to make use of push options.
# The example simply echoes all push options that start with 'echoback='
# and rejects all pushes when the "reject" push option is used.
#
# To enable this hook, rename this file to "pre-receive".
EJECT=0                 #REJECT變數,初始化為0
BASE_PATH=$(cd `dirname $0`; pwd)     #BASE_PATH變數中為當前指令碼存放的路徑,比如當前指令碼路徑為/usr/local/script/shell.sh,則BASE_PATH=/usr/local/script/
PROJECT_ROOT=$(cd $(dirname ${BASH_SOURCE[0]})/../..; pwd)
java  -Dpmd.language=en   -cp   $PROJECT_ROOT/p3c-pmd-2.1.1-jar-with-dependencies.jar net.sourceforge.pmd.PMD -d $PROJECT_ROOT  -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=$?                                                           #REJECT變數接收上面的java命令執行的結果返回值
        if test $[REJECT] -eq 0
        then 
          echo -e "\033[36m commit success!!! \033[1m"  #藍色列印提交成功
        else
          echo -e "\033[31m 程式碼提交未通過阿里規範,不允許提交!!! \033[1m"        #紅色列印未通過
        fi
exit $REJECT                       

  這樣就可以了,因為是本地commit,如果想要跳過本地commit,直接在git base 後面 加上 git commit -m "註釋" --no-verify 或者手動 刪除.git/commit 目錄下的即可。

  這樣是可以了,還有個問題就是:能不能做成一個無感知的、因為每次要手動執行才能使用。這樣也不方便,而且如果別人不執行的話,也不知道啊。