[libcode-tidyall-perl] 275/374: allow_repeated_push

Jonas Smedegaard js at alioth.debian.org
Sun Sep 29 22:26:34 UTC 2013


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository libcode-tidyall-perl.

commit 08b5b841de872cd93011ceedd06880dad0378b2e
Author: Jonathan Swartz <swartz at pobox.com>
Date:   Thu Sep 27 04:16:32 2012 -0700

    allow_repeated_push
---
 lib/Code/TidyAll/Git/Prereceive.pm |   77 ++++++++++++++++++++++++++++++------
 1 file changed, 65 insertions(+), 12 deletions(-)

diff --git a/lib/Code/TidyAll/Git/Prereceive.pm b/lib/Code/TidyAll/Git/Prereceive.pm
index c42ae6b..2e65d55 100644
--- a/lib/Code/TidyAll/Git/Prereceive.pm
+++ b/lib/Code/TidyAll/Git/Prereceive.pm
@@ -1,18 +1,20 @@
 package Code::TidyAll::Git::Prereceive;
 use Code::TidyAll;
-use Code::TidyAll::Util qw(realpath tempdir_simple write_file);
+use Code::TidyAll::Util qw(dirname realpath tempdir_simple read_file write_file);
 use Capture::Tiny qw(capture);
+use Digest::SHA1 qw(sha1_hex);
 use IPC::System::Simple qw(capturex run);
 use Moo;
 use Try::Tiny;
 
 # Public
-has 'conf_name'        => ( is => 'ro' );
-has 'extra_conf_files' => ( is => 'ro', default => sub { [] } );
-has 'git_path'         => ( is => 'ro', default => sub { 'git' } );
-has 'reject_on_error'  => ( is => 'ro' );
-has 'tidyall_class'    => ( is => 'ro', default => sub { "Code::TidyAll" } );
-has 'tidyall_options'  => ( is => 'ro', default => sub { {} } );
+has 'allow_repeated_push' => ( is => 'ro', default => sub { 3 } );
+has 'conf_name'           => ( is => 'ro' );
+has 'extra_conf_files'    => ( is => 'ro', default => sub { [] } );
+has 'git_path'            => ( is => 'ro', default => sub { 'git' } );
+has 'reject_on_error'     => ( is => 'ro' );
+has 'tidyall_class'       => ( is => 'ro', default => sub { "Code::TidyAll" } );
+has 'tidyall_options'     => ( is => 'ro', default => sub { {} } );
 
 sub check {
     my ( $class, %params ) = @_;
@@ -45,9 +47,11 @@ sub check {
         }
 
         if ( my @error_results = grep { $_->error } @results ) {
-            my $error_count = scalar(@error_results);
-            $fail_msg = sprintf( "%d file%s did not pass tidyall check",
-                $error_count, $error_count > 1 ? "s" : "" );
+            unless ( $self->check_repeated_push($input) ) {
+                my $error_count = scalar(@error_results);
+                $fail_msg = sprintf( "%d file%s did not pass tidyall check",
+                    $error_count, $error_count > 1 ? "s" : "" );
+            }
         }
     }
     catch {
@@ -99,6 +103,33 @@ sub get_file_contents {
     return $contents;
 }
 
+sub check_repeated_push {
+    my ( $self, $input ) = @_;
+    if ( defined( my $allow = $self->allow_repeated_push ) ) {
+        my $cwd            = dirname( realpath($0) );
+        my $last_push_file = "$cwd/.prereceive_lastpush";
+        if ( -w $cwd || -w $last_push_file ) {
+            my $push_sig = sha1_hex($input);
+            if ( -f $last_push_file ) {
+                my ( $last_push_sig, $count ) = split( /\s+/, read_file($last_push_file) );
+                if ( $last_push_sig eq $push_sig ) {
+                    ++$count;
+                    print STDERR "*** Identical push seen $count times\n";
+                    if ( $count >= $allow ) {
+                        print STDERR "*** Allowing push to proceed despite errors\n";
+                        return 1;
+                    }
+                }
+                write_file( $last_push_file, join( " ", $push_sig, $count ) );
+            }
+            else {
+                write_file( $last_push_file, join( " ", $push_sig, 1 ) );
+            }
+        }
+    }
+    return 0;
+}
+
 1;
 
 __END__
@@ -157,8 +188,24 @@ is rejected and the reason(s) are output to the client. e.g.
 The configuration file (C<tidyall.ini> or C<.tidyallrc>) must be checked into
 git in the repo root directory, i.e. next to the .git directory.
 
-Unfortunately there is no easy way to bypass the pre-receive hook in an
-emergency.  It must be disabled in the repo being pushed to, e.g. by renaming
+In an emergency the hook can be bypassed by pushing the exact same set of
+commits 3 consecutive times (configurable via L</allow_repeated_push>):
+
+    % git push
+    ...
+    remote: 1 file did not pass tidyall check        
+
+    % git push
+    ...
+    *** Identical push seen 2 times
+    remote: 1 file did not pass tidyall check        
+
+    % git push
+    ...
+    *** Identical push seen 3 times
+    *** Allowing push to proceed despite errors
+
+Or you can disable the hook in the repo being pushed to, e.g. by renaming
 .git/hooks/pre-receive.
 
 Passes mode = "commit" by default; see L<modes|tidyall/MODES>.
@@ -167,6 +214,12 @@ Key/value parameters:
 
 =over
 
+=item allow_repeated_push
+
+Number of times a push must be repeated exactly after which it will be let
+through regardless of errors. Defaults to 3. Set to 0 or undef to disable this
+feature.
+
 =item conf_name
 
 Conf file name to search for instead of the defaults.

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libcode-tidyall-perl.git



More information about the Pkg-perl-cvs-commits mailing list