Last active
August 29, 2015 14:10
-
-
Save s-shin/3974b0df3ef69d54d49b to your computer and use it in GitHub Desktop.
Git pre-commit sample for PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
use strict; | |
use warnings; | |
use Term::ANSIColor; | |
use Term::ReadLine; | |
my $term = Term::ReadLine->new('pre-commit'); | |
BEGIN { | |
# STDOUTに吐いても良い気もするが、pre-commit.sampleがSTDERRに吐いているので | |
# このスクリプトでも原則STDERRに出力を行うことにする。 | |
sub print_err { print STDERR @_ } | |
} | |
# ### PHP ### | |
# 参考: | |
# * http://blog.manaten.net/entry/645 | |
# * https://github.com/FriendsOfPHP/PHP-CS-Fixer | |
# phpcsコマンドのチェック | |
my $is_phpcs_installed = not system('hash phpcs 2>/dev/null'); | |
unless ($is_phpcs_installed) { | |
print_err colored('*** You should install PHP_CodeSniffer. ***', 'bold on_yellow'); | |
print_err q{ | |
URL: https://github.com/squizlabs/PHP_CodeSniffer | |
RUN: composer g require "squizlabs/php_codesniffer=*" | |
}; | |
} | |
# php-cs-fixerコマンドのチェック | |
my $is_php_cs_fixer_installed = not system('hash php-cs-fixer 2>/dev/null'); | |
unless ($is_php_cs_fixer_installed) { | |
print_err colored('*** You should install PHP Coding Standards Fixer. ***', 'bold on_yellow'); | |
print STDERR q{ | |
URL: http://cs.sensiolabs.org/ | |
RUN: composer g require fabpot/php-cs-fixer | |
}; | |
} | |
# stagedなPHPファイルの取得 | |
my @modified_php_files = split /\n/, | |
`git diff-index --name-only --cached --diff-filter=ACMR HEAD | grep -e '\\.php\$'`; | |
exit unless @modified_php_files; | |
# 'php -l'によるコンパイルエラーチェック | |
my @compiling_results; | |
foreach my $php_file (@modified_php_files) { | |
# リダイレクトの順番は意図的(標準エラーを取得)。 | |
my @compiling_result = `php -l $php_file 2>&1 1>/dev/null`; | |
# $?は直近のコマンド戻り値 | |
if ($?) { | |
push @compiling_results, { | |
file => $php_file, | |
error => join("\n", @compiling_result), | |
}; | |
} | |
} | |
if (@compiling_results) { | |
print_err colored('*** PHP Compilation Error! ***', 'bold on_red'); | |
print_err "\n"; | |
foreach my $result (@compiling_results) { | |
print_err '# ' . $result->{file}, "\n"; | |
print_err $result->{error}, "\n"; | |
} | |
exit 1; | |
} | |
# コミットを中断させるなら1にする。 | |
my $reject_commit = 0; | |
# php-cs-fixerによる自動修正。 | |
# phpcsより先に基本的な修正をしてしまう。 | |
# 修正した時は自動修正が問題ないか確認できるようコミットを中断する。 | |
if ($is_php_cs_fixer_installed) { | |
# php-cs-fixerコマンドは複数ファイルを同時に処理できない… | |
my @fixed_files; | |
foreach my $php_file (@modified_php_files) { | |
my @result = `php-cs-fixer fix --level=psr2 $php_file`; | |
if ($?) { | |
my $file = $result[0]; | |
$file =~ s/^[ ]+\d\) (.*)$/$1/; | |
chomp $file; | |
push @fixed_files, $file; | |
} | |
} | |
if (@fixed_files) { | |
print_err colored('*** Some codes are automatically fixed! ***', 'bold on_red'), "\n"; | |
print_err "\n"; | |
print_err 'Automodified files:', "\n"; | |
print_err " $_\n" foreach (@fixed_files); | |
print_err "\n"; | |
print_err colored('Please check these changes and commit them.', 'bold'), "\n\n"; | |
$reject_commit = 1; | |
} | |
} | |
# phpcsによるコーディングスタイルチェック | |
if ($is_phpcs_installed) { | |
my $files = join ' ', @modified_php_files; | |
my @phpcs_result = `phpcs --standard=PSR2 --encoding=utf-8 --report=full $files`; | |
if ($?) { | |
print_err colored('*** You should review the coding style! ***', 'bold on_yellow'), "\n"; | |
print_err @phpcs_result, "\n"; | |
# 修正を促す | |
unless ($reject_commit) { | |
my $input = $term->readline('Fix them? (Y/n) '); | |
$reject_commit = 1 if !$input || lc($input) ne 'n'; | |
print_err "\n"; | |
} | |
} | |
} | |
if ($reject_commit) { | |
print_err 'This commit is aborted.', "\n"; | |
} | |
print_err "\n"; | |
exit $reject_commit; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment