使用PHPCS+GIT鉤子保障團隊開發中代碼風格一致性實踐

  • 一、背景

筆者在6月份加入新團隊,新團隊這邊剛組建起來,基礎一些東西還處於待完善狀態,比如筆者組內同學約定使用PSR-2的編碼風格規範,但是並不是所有人都嚴格按照PSR-2來提交代碼。

最大的原因就是口頭的約束力極爲有限,而團隊中大家使用的編輯器不統一,有使用phpstorm,也有使用VS Code更有vim,而各種編輯器都有自己的格式化規則,因此代碼風格統一是個問題;

具體一點來說,當張三使用VS Code提交了一個代碼文件,李四pull代碼之後使用phpstorm進行格式化後再提交,代碼風格發生變化提交到服務器,張三再pull代碼,使用VS Code格式化,代碼又一次發生變化;這樣反反覆覆的改變,開發同學會覺得麻煩,代碼審計同學也同樣麻煩;
在筆者上家公司的技術團隊,會由架構組來處理類似的問題,於是這裏筆者把上一個團隊實現的方式照搬過來,同樣在git的鉤子上做文章,如果有人的代碼不符合psr-2代碼風格規範,通過git鉤子將不其commit,並且給出具體行號和具體的原因,更方便的是提供一個快速格式化的命令。

  • 二、實現概要

安裝php-cs
配置php-cs
集成到編輯器
git觸發檢測

  • 三、安裝PHP-CS

    • 3.1 安裝composer

php-cs可以用來檢測代碼是否符合PSR-2規範,同時支持對不符合規範的代碼自動格式化,讓其轉成PSR-2的編碼風格。

php-cs依賴於composer,所以筆者需要先安裝composer,安裝的方法有很多種,這裏提供mac操作系統下兩種安裝方法

brew安裝composer命令爲:

brew install composer

手動安裝composer命令爲:

wget https://getcomposer.org/download/1.7.1/composer.phar && chmod 777 composer.phar && mv composer.phar /usr/local/bin/composer
  • 3.2 安裝PHP-CS

安裝好composer之後,可以用composer快速安裝php-cs,安裝命令如下

composer global require "squizlabs/php_codesniffer=*"

當命令執行完成之後,會在筆者當前用戶的主目錄下創建一個 .composer 目錄,在目錄中包含了筆者需要的php-cs,此時筆者可以執行下方命令來驗證是否安裝成功

~/.composer/vendor/bin/phpcs --help

當命令執行後,如果能看到下方的一些信息,那麼就代表安裝成功

 -     Check STDIN instead of local files and directories
 -n    Do not print warnings (shortcut for --warning-severity=0)
 -w    Print both warnings and errors (this is the default)
 -l    Local directory only, no recursion
 -s    Show sniff codes in all reports
 -a    Run interactively
 -e    Explain a standard by showing the sniffs it includes
 -p    Show progress of the run
 -q    Quiet mode; disables progress and verbose output
 -m    Stop error messages from being recorded
       (saves a lot of memory, but stops many reports from being used)
 -v    Print processed files
 -vv   Print ruleset and token output
 -vvv  Print sniff processing information
 -i    Show a list of installed coding standards
 -d    Set the [key] php.ini value to [value] or [true] if value is omitted
  • 3.3 全局使用

前面筆者使用驗證的命令的路徑太長,後續如果要使用是極爲不方便的,所以筆者需要將這寫路徑加入到全局中,加入的命令如下

ln -s ~/.composer/vendor/bin/phpcs /usr/local/bin/phpcs
ln -s ~/.composer/vendor/bin/phpcbf /usr/local/bin/phpcbf

當執行完成之後,可以使用短命令來驗證是否加入全局成功,可以用下方的命令

phpcs --help

執行成功之後,返回結果應該和上方完整路徑返回的一致。

  • 3.4 設置默認標準

phpcs默認的編碼格式並不是php-cs,所以當不指定標準的時候,檢測的結果並不準確,但每次都手動指定也挺麻煩,所以筆者可以設置一個默認標準,命令如下:

phpcs --config-set default_standard PSR2
phpcbf --config-set default_standard PSR2
  • 3.5 PHPCS檢測

現在筆者可以用phpcs來真實的試驗了,筆者先準備一個PHP文件,文件裏面的內容如下代碼示例,可以看出這份代碼並不符合PSR-2的風格規範

<?php

function test_test(){
    echo 'daxia';
}


test();
  • 3.5.1 通過PHP-CS檢測編碼風格,命令如下

    phpcs /Users/tangqingsong/mycode/test.php

命令執行完成之後,可以看到如下代碼提示,在提示中筆者能看到具體哪一行,提示級別,以及具體的提示原因

FILE: /Users/song/mycode/test.php
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
FOUND 2 ERRORS AND 1 WARNING AFFECTING 3 LINES
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 1 | WARNING | [ ] A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is
   |         |     defined on line 3 and the first side effect is on line 8.
 3 | ERROR   | [x] Opening brace should be on a new line
 8 | ERROR   | [x] Expected 1 newline at end of file; 0 found
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Time: 79ms; Memory: 4Mb
  • 3.6 PHPCS檢測
  • 3.6.1 自動格式化編碼風格命令

    phpcbf /Users/tangqingsong/mycode/test.php

命令執行完成之後,可以看到如下返回提示,處理了哪一些文件,以及類型

PHPCBF RESULT SUMMARY
----------------------------------------------------------------------
FILE                                                  FIXED  REMAINING
----------------------------------------------------------------------
/Users/song/mycode/test.php                           2      1
----------------------------------------------------------------------
A TOTAL OF 2 ERRORS WERE FIXED IN 1 FILE
----------------------------------------------------------------------

Time: 68ms; Memory: 4Mb
  • 3.6.2 再次使用PHP-CS檢測

    phpcs /Users/tangqingsong/mycode/test.php

執行完成之後,通過命令再次查看結果

FILE: /Users/song/mycode/test.php
----------------------------------------------------------------------------------------------------------------------------------------------
FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE
----------------------------------------------------------------------------------------------------------------------------------------------
 1 | WARNING | A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute
   |         | logic with side effects, but should not do both. The first symbol is defined on line 3 and the first side effect is on line 9.
----------------------------------------------------------------------------------------------------------------------------------------------

Time: 71ms; Memory: 4Mb

能看到最開始檢測有三次不合格,但現在只剩下一處了;這裏說一下爲什麼phpcbf沒有幫完全處理呢,因爲phpcbf只能處理代碼風格等方式,而不能幫你處理裏面的命名與代碼實現規則,所以有少部分還需要人爲去更正,但並不會太多。

  • 四、GIT配置篇

當前面一切準備就緒,筆者就可以在git鉤子裏面增加強制的策略了,git鉤子腳本存放於項目下 .git/hooks/ 文件夾下,按照下面的步驟筆者來添加一個commit事件。

  • 4.1 新增鉤子文件

在你的項目根目錄下,使用vim命令或其他方式,新增一個文件 ./.git/hooks/pre-commit,然後把下面的腳本放進去,之後再保存。

#!/bin/sh
PHPCS_BIN=/usr/local/bin/phpcs
PHPCS_CODING_STANDARD=PSR2
PHPCS_FILE_PATTERN="\.(php)$"

FILES=$(git diff HEAD^..HEAD --stat)

if [ "$FILES" == "" ]; then
 exit 0
fi

for FILE in $FILES
do
 echo "$FILE" | egrep -q "$PHPCS_FILE_PATTERN"
 RETVAL=$?
 if [ "$RETVAL" -eq "0" ]
 then

     PHPCS_OUTPUT=$($PHPCS_BIN --standard=$PHPCS_CODING_STANDARD $FILE)
     PHPCS_RETVAL=$?

     if [ $PHPCS_RETVAL -ne 0 ];
     then
         echo $PHPCS_OUTPUT
         exit 1
     fi
 fi
done
exit 0

需要注意的是讓這個文件有可執行權限,最直接的辦法就是設置爲777,參考命令如下:

chmod 777 .git/hooks/pre-commit
  • 4.2 本地鉤子

現在筆者故意讓php代碼風格不一致,然後使用git commit來提交,看看git是否會阻止提交,以下面這份代碼爲例

<?php

function test_test(){
    echo 'daxia';
}

test();

可以很明顯的看出來,這份代碼沒有按照駝峯命名法,大括號也沒用換行的兩處問題;把它保存在根目錄名爲test.php文件,然後執行git commit命令,如下

git add test.php && git commit . -m 'test'

命令執行後,git返回瞭如下信息,便終止了

FILE: /Users/song/mycode/work/xiaoyu/test.php
----------------------------------------------------------------------------------------------------------------------------------------------
FOUND 2 ERRORS AND 1 WARNING AFFECTING 3 LINES
----------------------------------------------------------------------------------------------------------------------------------------------
 1 | WARNING | [ ] A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should
   |         |     execute logic with side effects, but should not do both. The first symbol is defined on line 3 and the first side effect
   |         |     is on line 8.
 3 | ERROR   | [x] Opening brace should be on a new line
 8 | ERROR   | [x] Expected 1 newline at end of file; 0 found
----------------------------------------------------------------------------------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------------------------------------------------------------------------------

Time: 63ms; Memory: 4Mb

驗證一下git是否commit成功,可以執行下面的命令:

git status

返回結果如下

位於分支 develop
您的分支與上游分支 'origin/develop' 一致。
要提交的變更:
  (使用 "git reset HEAD <文件>..." 以取消暫存)
    新文件:   test.php

說明筆者前面的命令只成功執行了 git add . 而後面commit則成功阻擋了

轉自:使用PHPCS+GIT鉤子保障團隊開發中代碼風格一致性實踐

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章