使用PHPCS+GIT钩子保障团队开发中代码风格一致性实践
一、背景
筆者在6月份加入新團隊,新團隊這邊剛組建起來,基礎(chǔ)一些東西還處于待完善狀態(tài),比如筆者組內(nèi)同學(xué)約定使用PSR-2的編碼風(fēng)格規(guī)范,但是并不是所有人都嚴格按照PSR-2來提交代碼。
最大的原因就是口頭的約束力極為有限,而團隊中大家使用的編輯器不統(tǒng)一,有使用phpstorm,也有使用VS Code更有vim,而各種編輯器都有自己的格式化規(guī)則,因此代碼風(fēng)格統(tǒng)一是個問題;
具體一點來說,當(dāng)張三使用VS Code提交了一個代碼文件,李四pull代碼之后使用phpstorm進行格式化后再提交,代碼風(fēng)格發(fā)生變化提交到服務(wù)器,張三再pull代碼,使用VS Code格式化,代碼又一次發(fā)生變化;這樣反反復(fù)復(fù)的改變,開發(fā)同學(xué)會覺得麻煩,代碼審計同學(xué)也同樣麻煩;
在筆者上家公司的技術(shù)團隊,會由架構(gòu)組來處理類似的問題,于是這里筆者把上一個團隊實現(xiàn)的方式照搬過來,同樣在git的鉤子上做文章,如果有人的代碼不符合psr-2代碼風(fēng)格規(guī)范,通過git鉤子將不其commit,并且給出具體行號和具體的原因,更方便的是提供一個快速格式化的命令。
二、實現(xiàn)概要
三、安裝PHP-CS
php-cs可以用來檢測代碼是否符合PSR-2規(guī)范,同時支持對不符合規(guī)范的代碼自動格式化,讓其轉(zhuǎn)成PSR-2的編碼風(fēng)格。
3.1 安裝composer
php-cs依賴于composer,所以筆者需要先安裝composer,安裝的方法有很多種,這里提供mac操作系統(tǒng)下兩種安裝方法
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/composer3.2 安裝PHP-CS
安裝好composer之后,可以用composer快速安裝php-cs,安裝命令如下
composer global require "squizlabs/php_codesniffer=*"當(dāng)命令執(zhí)行完成之后,會在筆者當(dāng)前用戶的主目錄下創(chuàng)建一個 .composer 目錄,在目錄中包含了筆者需要的php-cs,此時筆者可以執(zhí)行下方命令來驗證是否安裝成功
~/.composer/vendor/bin/phpcs --help當(dāng)命令執(zhí)行后,如果能看到下方的一些信息,那么就代表安裝成功
- 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 omitted3.3 全局使用
前面筆者使用驗證的命令的路徑太長,后續(xù)如果要使用是極為不方便的,所以筆者需要將這寫路徑加入到全局中,加入的命令如下
ln -s ~/.composer/vendor/bin/phpcs /usr/local/bin/phpcs ln -s ~/.composer/vendor/bin/phpcbf /usr/local/bin/phpcbf當(dāng)執(zhí)行完成之后,可以使用短命令來驗證是否加入全局成功,可以用下方的命令
phpcs --help執(zhí)行成功之后,返回結(jié)果應(yīng)該和上方完整路徑返回的一致。
3.4 設(shè)置默認標準
phpcs默認的編碼格式并不是php-cs,所以當(dāng)不指定標準的時候,檢測的結(jié)果并不準確,但每次都手動指定也挺麻煩,所以筆者可以設(shè)置一個默認標準,命令如下:
phpcs --config-set default_standard PSR2 phpcbf --config-set default_standard PSR23.5 PHPCS檢測
現(xiàn)在筆者可以用phpcs來真實的試驗了,筆者先準備一個PHP文件,文件里面的內(nèi)容如下代碼示例,可以看出這份代碼并不符合PSR-2的風(fēng)格規(guī)范
<?phpfunction test_test(){echo 'daxia'; }test();通過PHP-CS檢測編碼風(fēng)格,命令如下
phpcs /Users/tangqingsong/mycode/test.php命令執(zhí)行完成之后,可以看到如下代碼提示,在提示中筆者能看到具體哪一行,提示級別,以及具體的提示原因
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: 4Mb3.6 PHPCS檢測
自動格式化編碼風(fēng)格命令
phpcbf /Users/tangqingsong/mycode/test.php命令執(zhí)行完成之后,可以看到如下返回提示,處理了哪一些文件,以及類型
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再次使用PHP-CS檢測
phpcs /Users/tangqingsong/mycode/test.php執(zhí)行完成之后,通過命令再次查看結(jié)果
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能看到最開始檢測有三次不合格,但現(xiàn)在只剩下一處了;這里說一下為什么phpcbf沒有幫完全處理呢,因為phpcbf只能處理代碼風(fēng)格等方式,而不能幫你處理里面的命名與代碼實現(xiàn)規(guī)則,所以有少部分還需要人為去更正,但并不會太多。
四、編輯器編輯與配置
很少開發(fā)者只使用終端就開發(fā)代碼,通常都會用到編輯器,因此筆者也需要把phpcs和編輯器進行結(jié)合
4.1 讓編輯器使用PSR-2標準
2. 設(shè)置->languages->php->code sniffer 中設(shè)置phpcs的路徑
3. 設(shè)置->Editor->Inspections展開點擊右側(cè)的PHP,勾選下面的兩個PHP,選擇使用PSR2
下面還有一處,也要選中
現(xiàn)在筆者使用phpstorm的格式化,將會自動格式化成psr-2的風(fēng)格。
4.2 集成phpcs
經(jīng)過上面的操作,phpstorm代碼格式化的規(guī)則基本與phpcs的規(guī)則基本一致了,但也有一小部分不一致,所以后面還要用到phpcs和phpcbf。
筆者如果每次都在終端去執(zhí)行phpcs風(fēng)格檢測花費時間可不少,為了提高工作效率,可以在phpstorm集成phpcs檢測規(guī)范的功能,設(shè)置路徑:Tools->External Tools->添加-> (/usr/local/bin/phpcs ) (FileDirFileDir/FileNameFileName)
4.3 集成phpcbf
如果每次都在終端去執(zhí)行phpcbf格式化,還是會有一些麻煩,所以筆者也可以在phpstorm集成phpcbf自動格式化功能,設(shè)置路徑:Tools->External Tools->添加-> (/usr/local/bin/phpcbf ) (FileDirFileDir/FileNameFileName)
五、GIT配置篇
當(dāng)前面一切準備就緒,筆者就可以在git鉤子里面增加強制的策略了,git鉤子腳本存放于項目下 .git/hooks/ 文件夾下,按照下面的步驟筆者來添加一個commit事件。
5.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" == "" ]; thenexit 0 fifor FILE in $FILES doecho "$FILE" | egrep -q "$PHPCS_FILE_PATTERN"RETVAL=$?if [ "$RETVAL" -eq "0" ]thenPHPCS_OUTPUT=$($PHPCS_BIN --standard=$PHPCS_CODING_STANDARD $FILE)PHPCS_RETVAL=$?if [ $PHPCS_RETVAL -ne 0 ];thenecho $PHPCS_OUTPUTexit 1fifi done exit 0需要注意的是讓這個文件有可執(zhí)行權(quán)限,最直接的辦法就是設(shè)置為777,參考命令如下:
chmod 777 .git/hooks/pre-commit5.2 本地鉤子
現(xiàn)在筆者故意讓php代碼風(fēng)格不一致,然后使用git commit來提交,看看git是否會阻止提交,以下面這份代碼為例
<?phpfunction test_test(){echo 'daxia'; }test();可以很明顯的看出來,這份代碼沒有按照駝峰命名法,大括號也沒用換行的兩處問題;把它保存在根目錄名為test.php文件,然后執(zhí)行g(shù)it commit命令,如下
git add test.php && git commit . -m 'test'命令執(zhí)行后,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成功,可以執(zhí)行下面的命令:
git status返回結(jié)果如下
位于分支 develop 您的分支與上游分支 'origin/develop' 一致。要提交的變更:(使用 "git reset HEAD <文件>..." 以取消暫存)新文件: test.php說明筆者前面的命令只成功執(zhí)行了 git add . 而后面commit則成功阻擋了。
5.3 服務(wù)端鉤子
前面一個步驟筆者已經(jīng)成功的在本地的commit鉤子中阻擋了觸發(fā),但是任然有可能有伙伴會繞過,或者新項目沒有部署等,導(dǎo)致可以最終提交上來的代碼還是存在不符合psr-2風(fēng)格,所以這個時候筆者就需要在服務(wù)端的push事件做一些處理。
這個時候筆者需要在服務(wù)器的鉤子事件中新增一個,pre-receive 文件。
在服務(wù)端去配置的時候遇到了幾個坑,后來筆者放棄了,有興趣的可以留言或私信。
作者:湯青松
微信:songboy8888
總結(jié)
以上是生活随笔為你收集整理的使用PHPCS+GIT钩子保障团队开发中代码风格一致性实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 形容人青铜是什么意思
- 下一篇: Memcached相关内容总结