Skip to content

Instantly share code, notes, and snippets.

@bessarabov
Created March 24, 2014 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bessarabov/9741647 to your computer and use it in GitHub Desktop.
Save bessarabov/9741647 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
=begin comment
Это pre-commit hook. Этот скрипт запускается перед тем как как открывается
$EDITOR для ввода commit message.
Если этот скрипт завершвется с exit status != 0, то комит не происходит.
Можно запустить `git commit --no-verify` и тогда этот хук не будет выполнятся.
Вообще, все что тут написано — это неправильно. Все проверки, которые тут
выполняются работают с файлами на диске, а не с тем что будет закомичено.
В идельном мире нужно реализовать решение, как описано в блоге [yipit][yipit].
Но большинство комитов у нас — это комиты именно всего, поэтому сделано такое
неправильное решение, которое будет работать в большинстве случаев.
[yipit]: http://tech.yipit.com/2011/11/16/183772396/
=end comment
=cut
use strict;
use warnings;
use v5.10;
use String::ShellQuote;
use Term::ANSIColor qw(colored);
sub say {
print @_, "\n";
}
sub exit_with_message {
my ($message) = @_;
say colored(
"There was an error in the code. Plese use `git commit --no-verify`\n"
. "if you need to commit this broken code. But the better approach\n"
. "is to fix the problem.",
"red",
);
if (defined $message) {
say '';
say $message;
}
exit 123;
}
sub check_server_side_whitespaces {
my $exit_status = system("prove t/whitespaces.t &> /dev/null");
if ($exit_status != 0) {
exit_with_message(
"There was a problem with whitespace charachers in server side\n"
. "code. Run `prove t/whitespaces.t` to find the problems.\n"
. "There is a script `whiter` that can fix that errors (run it\n"
. "as `whiter --help` to find out how to use it)."
);
}
}
sub check_client_side_whitespaces {
my $exit_status = system("prove t/whitespaces_in_blocks.t &> /dev/null");
if ($exit_status != 0) {
exit_with_message(
"There was a problem with whitespace charachers in client side\n"
. "code. Run `prove t/whitespaces_in_blocks.t` to find the\n"
. "problems. There is a script `whiter` that can fix that\n"
. "errors (run it as `whiter --help` to find out how to use it)."
);
}
}
sub check_javascript {
my @files = find_files_in_staging_area();
my @files_with_jshint_errors;
my @files_with_jscs_errors;
foreach my $file (@files) {
next if $file =~ /\.deps\.js$/;
next if $file !~ /\.js$/;
my $string = shell_quote($file);
my $jshint_exit_status = system("jshint $string &> /dev/null");
push @files_with_jshint_errors, $string if $jshint_exit_status != 0;
my $jscs_exit_status = system("jscs $string &> /dev/null");
push @files_with_jscs_errors, $string if $jscs_exit_status != 0;
}
if (@files_with_jshint_errors or @files_with_jscs_errors) {
my $message =
"There was errors in checking javascript files that are going\n"
. "to be commited. See details with:\n"
;
if (@files_with_jshint_errors) {
$message .=
"\n"
. " "x4 . "jshint " . join(" ", @files_with_jshint_errors)
. "\n"
;
}
if (@files_with_jscs_errors) {
$message .=
"\n"
. " "x4 . "jscs " . join(" ", @files_with_jscs_errors)
. "\n"
;
}
exit_with_message( $message );
}
}
sub find_files_in_staging_area {
my $output = `git diff --cached HEAD --name-only --diff-filter=ACM`;
my @files = split /\n/, $output;
return @files;
}
sub main {
check_server_side_whitespaces();
check_client_side_whitespaces();
check_javascript();
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment