Advertisement
Guest User

git pre-commit hook

a guest
Sep 19th, 2012
318
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 2.21 KB | None | 0 0
  1. #!/usr/bin/env perl
  2. # Copy me to the .git/hooks directory and rename file to "pre-commit"
  3. #
  4. # This script is invoked by "git commit" and runs some PHP and JS syntax checks
  5. # on the files staged for commit. It exits with a non-zero status if any check
  6. # fails.
  7.  
  8. use strict;
  9. use warnings;
  10.  
  11. exit run_hooks(\&check_php_syntax, \&check_js_syntax);
  12.  
  13. sub run_hooks {
  14.     my @hooks = @_;
  15.  
  16.     # Get a list of files staged for commit
  17.     my @staged_files = staged_files();
  18.  
  19.     # Stash unstaged changes. That is, set the working copy
  20.     # to the same state as HEAD, but keep any changes that have been
  21.     # staged for commit.
  22.     run_command('git', 'stash', 'save', '--quiet', '--keep-index');
  23.  
  24.     # Execute each hook on the changes
  25.     my $failed = 0;
  26.     foreach my $hook (@hooks) {
  27.         $failed = $hook->(@staged_files) || $failed;
  28.     }
  29.  
  30.     # Restore the stashed changes to the working copy
  31.     run_command('git', 'stash', 'pop', '--quiet');
  32.  
  33.     print "\nAborting commit due to pre-commit hook errors...\n" if $failed;
  34.  
  35.     return $failed;
  36. }
  37.  
  38. sub run_command {
  39.     system(@_) == 0 or die "system @_ failed: $?";
  40. }
  41.  
  42. sub staged_files {
  43.     my $output = qx{git diff --cached --name-status};
  44.     my @lines = split("\n", $output);
  45.     my @staged_files;
  46.  
  47.     # parse diff to extract status and file name
  48.     foreach my $line (@lines) {
  49.         my ($status, $name) = split /\s+/, $line, 2;
  50.         $name =~ s/(?:^")|(?:"$)//g; # extract name from quotes
  51.         next if $status eq 'D'; # skip deleted items
  52.         push @staged_files, $name;
  53.     }
  54.  
  55.     return @staged_files;
  56. }
  57.  
  58. sub check_php_syntax {
  59.     my @files = grep /(?:\.php)|(?:\.ctp)$/, @_;
  60.     my $failed = 0;
  61.  
  62.     local $/ = undef; # enable slurp mode
  63.  
  64.     foreach my $file (@files) {
  65.         my $output = qx{php -l $file};
  66.         my $error = ($output =~ /Parse error/);
  67.         $failed = $failed || $error;
  68.  
  69.         print $output if $error;
  70.     }
  71.  
  72.     print "\n" if $failed;
  73.  
  74.     return $failed;
  75. }
  76.  
  77. sub check_js_syntax {
  78.     my @files = grep /\.js/, @_;
  79.     my $failed = 0;
  80.  
  81.     local $/ = undef; # enable slurp mode
  82.  
  83.     foreach my $file (@files) {
  84.         my $output = qx{jsl -nologo -nofilelisting -nosummary -nocontext -process $file};
  85.         my $code = ($? >> 8);
  86.         my $error = ($code >= 3);
  87.         $failed = $failed || $error;
  88.  
  89.         print $output if $error;
  90.     }
  91.  
  92.     return $failed;
  93. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement