Announcement

Collapse
No announcement yet.

Hook script to reject files based on file extension

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hook script to reject files based on file extension

    Here is a pre-commit hook script written in Perl that will reject files based on the filename extension. You can supply extensions using standard filename globbing wildcards. For example, you can ban winrar archives with "*.rar *.r[0-9][0-9]" just like you would on the global-ignore list.

    You will need to update the path to "svnlook" in the script to match your installation.

    Code:
    #!/usr/bin/perl -w
    
    use strict;
    
    use Carp;
    use File::Basename;
    use Text::Glob qw( glob_to_regex );
    
    $Text::Glob::strict_leading_dot = 0;
    
    sub trim
    {
      my $string = shift;
      $string =~ s/^\s+//;
      $string =~ s/\s+$//;
      return $string;
    }
    
    sub convert_globs_to_regex
    {
      my @globs = split(/\s+/, trim(shift));
        
      # There should always be at least one ignore option.
      # If not, allow the commit to occur.
      unless (@globs)
      {
        exit 0;
      }
          
      my $match = glob_to_regex(shift(@globs));
      
      foreach (@globs)
      {
        $match = $match . "|" . glob_to_regex($_);
      }
      
      # Remove all modifier flags.
      $match =~ s/\(\?-xism:/(?:/g;
      
      return $match
    }
    
    sub read_from_process
      {
      unless (@_)
        {
          croak "$0: read_from_process passed no arguments.\n";
        }
      my ($status, @output) = &safe_read_from_pipe(@_);
      if ($status)
        {
          if (@output)
            {
              die "$0: `@_' failed with this output:\n", join("\n", @output), "\n";
            }
          else
            {
              die "$0: `@_' failed with no output.\n";
            }
        }
      else
        {
          return @output;
        }
      }
    
    sub safe_read_from_pipe
    {
      unless (@_)
        {
          croak "$0: safe_read_from_pipe passed no arguments.\n";
        }
      print "Running @_\n";
      my $pid = open(SAFE_READ, '-|');
      unless (defined $pid)
        {
          die "$0: cannot fork: $!\n";
        }
      unless ($pid)
        {
          open(STDERR, ">&STDOUT")
            or die "$0: cannot dup STDOUT: $!\n";
          exec(@_)
            or die "$0: cannot exec `@_': $!\n";
        }
      my @output;
      while (<SAFE_READ>)
        {
          chomp;
          push(@output, $_);
        }
      close(SAFE_READ);
      my $result = $?;
      my $exit   = $result >> 8;
      my $signal = $result & 127;
      my $cd     = $result & 128 ? "with core dump" : "";
      if ($signal or $cd)
        {
          warn "$0: pipe from `@_' failed $cd: exit=$exit signal=$signal\n";
        }
      if (wantarray)
        {
          return ($result, @output);
        }
      else
        {
          return $result;
        }
    }
    
    my $REPOS=$ARGV[0];            # Path to my repository
    my $TXN=$ARGV[1];              # contains the transaction id passed to the script
    my $SVNLOOK='/opt/CollabNet_Subversion/bin/svnlook'; # Path to my svnlook binary
    
    my @files_added;
    foreach my $line (&read_from_process($SVNLOOK, 'changed', $REPOS, '-t', $TXN))
      {
        # Add only files that were added to @files_added
        if ($line =~ /^A.  (.*[^\/])$/)
          {
            push(@files_added, $1);
          }
      }
    
    #my $match = convert_globs_to_regex ("*.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo *.rej *~ #*# .#* .*.swp .DS_Store");
    my $match = convert_globs_to_regex ("*.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo *.rej *~ #*# .#* .*.swp .DS_Store *.bak *.exe *.msi *.dll *.jar *.class *.rpm *.iso *.zip *.rar *.r[0-9][0-9] *.hqx *.tar *.gz *.tgz *.bz2 *.obj *.elf *.out");
    
    my @matching = ();
    foreach (@files_added)
      {
        push(@matching, $_) if basename($_) =~ m/$match/i;
      }
    
    if (@matching)
      {
        print STDERR "The following files are disallowed by the server configuration: @matching\n";
        exit 1;
      }
    
    exit 0;

  • #2
    That's very cool - Thank you.

    Ian

    Comment


    • #3
      My Qestion:
      Suppose if my all the svn repos are in /home/svn.For e.x /home/svn/proj1,/home/svn/proj2 like that.In scuh a case, where can i copy this script file ? please let me know your reply for further implementaion and it can save lots of issues.

      Regads,
      Varad

      Comment


      • #4
        As for me, the script location doesn't matter. Create the right path and it should work properly.
        Last edited by Alfred_Zab; 07-07-2014, 05:42 AM.

        Comment


        • #5
          As I understood, the script should be called like pre-commit hook?

          Comment


          • #6
            The script will need to be either in the hooks folder in the repository (with the correct name), or you'll need to create a symbolic link to wherever it is if you're using the same script for a large number of repositories.

            Comment


            • #7
              That only works if the directory already exist.

              prep4sure.com certification
              Last edited by qwickyy; 12-17-2015, 10:13 AM.

              Comment


              • #8
                Buy Lortab Online For Pain Relief. Lortab is the best pain relieving medication so buy lortab online without prescription legally anytime.
                Last edited by DonnaBaby; 05-20-2016, 11:56 AM.

                Comment


                • #9
                  On Unix platforms, this means supplying a script or program named exactly like the name of the hook. Of course, the template files are present for more than just informational purposes the easiest way to install a hook on Unix platforms is to simply copy the appropriate template file to a new file that lacks the .tmpl extension, customize the hook's contents, and ensure that the script is executable.

                  Comment

                  Working...
                  X