The attached two patches for contrib/hook-scripts/check-mime-type.pl came via a GitHub PR [1] a few days ago...
They can be applied in sequence: svn-patch-01-c73cb4415d.txt svn-patch-02-68cc555740.txt In principle I think the changes are useful, though might change behavior in a surprising way for those who are using the hook as it stands now. Would it make sense to copy check-mime-type.pl, calling it, say, check-mime-type-2.pl, and apply the changes to that file, keeping the original as it is now? [1] https://github.com/apache/subversion/pull/22 Cheers, Nathan
From c73cb4415da492d574d6bdc2ff2d1b602981e91e Mon Sep 17 00:00:00 2001 From: maddes-b <madde...@users.noreply.github.com> Date: Mon, 7 Sep 2020 20:06:56 +0200 Subject: [PATCH] Check also property-modified files in hook script check-mime-type.pl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * contrib/hook-scripts/check-mime-type.pl: (proplist) add property-modified files for checks Patch by: Matthias Bücher <maddes+subvers...@maddes.net> Suggested by: Leo Davis [1] [1] https://mail-archives.apache.org/mod_mbox/subversion-dev/201403.mbox/%3c1576503.m6xb7ud...@hurry.speechfxinc.com%3E --- contrib/hook-scripts/check-mime-type.pl | 41 ++++++++++++++----------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/contrib/hook-scripts/check-mime-type.pl b/contrib/hook-scripts/check-mime-type.pl index 3ded119f27..79c37d26eb 100755 --- a/contrib/hook-scripts/check-mime-type.pl +++ b/contrib/hook-scripts/check-mime-type.pl @@ -1,18 +1,19 @@ #!/usr/bin/env perl # ==================================================================== -# commit-mime-type-check.pl: check that every added file has the -# svn:mime-type property set and every added file with a mime-type -# matching text/* also has svn:eol-style set. If any file fails this -# test the user is sent a verbose error message suggesting solutions and -# the commit is aborted. +# check-mime-type.pl: check that every added or property-modified file +# has the svn:mime-type property set and every added or property-modified +# file with a mime-type matching text/* also has svn:eol-style set. +# If any file fails this test the user is sent a verbose error message +# suggesting solutions and the commit is aborted. # -# Usage: commit-mime-type-check.pl REPOS TXN-NAME +# Usage: check-mime-type.pl REPOS TXN-NAME # ==================================================================== -# Most of commit-mime-type-check.pl was taken from +# Most of check-mime-type.pl was taken from # commit-access-control.pl, Revision 9986, 2004-06-14 16:29:22 -0400. # ==================================================================== # Copyright (c) 2000-2004 CollabNet. All rights reserved. +# Copyright (c) 2014-2020 Apache Software Foundation (ASF). # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -25,6 +26,9 @@ # history and logs, available at http://subversion.tigris.org/. # ==================================================================== +use strict; +use Carp; + # Turn on warnings the best way depending on the Perl version. BEGIN { if ( $] >= 5.006_000) @@ -33,9 +37,6 @@ BEGIN { { $^W = 1; } } -use strict; -use Carp; - ###################################################################### # Configuration section. @@ -100,19 +101,20 @@ my $tmp_dir = '/tmp'; chdir($tmp_dir) or die "$0: cannot chdir `$tmp_dir': $!\n"; -# Figure out what files have added using svnlook. -my @files_added; +# Figure out what files have been added/property-modified using svnlook. +my @paths_to_check; +my $props_changed_re = qr/^(?:A |[U_ ]U) (.*[^\/])$/; foreach my $line (&read_from_process($svnlook, 'changed', $repos, '-t', $txn)) { - # Add only files that were added to @files_added - if ($line =~ /^A. (.*[^\/])$/) + # Add only files that were added/property-modified to @paths_to_check + if ($line =~ /$props_changed_re/) { - push(@files_added, $1); + push(@paths_to_check, $1); } } my @errors; -foreach my $path ( @files_added ) +foreach my $path ( @paths_to_check ) { my $mime_type; my $eol_style; @@ -183,8 +185,8 @@ if (@errors) join("\n", @errors), "\n\n", <<EOS; - Every added file must have the svn:mime-type property set. In - addition text files must have the svn:eol-style property set. + Every added/property-modified file must have the svn:mime-type property + set. In addition text files must have the svn:eol-style property set. For binary files try running svn propset svn:mime-type application/octet-stream path/of/file @@ -211,6 +213,7 @@ sub usage die "usage: $0 REPOS TXN-NAME\n"; } +# Start a child process safely without using a shell sub safe_read_from_pipe { unless (@_) @@ -255,6 +258,8 @@ sub safe_read_from_pipe } } +# Use safe_read_from_pipe to start a child process safely and exit the +# script if the child failed for whatever reason. sub read_from_process { unless (@_) -- 2.24.3 (Apple Git-128)
From 68cc555740b3f3f8f82a59cca34b1af247cc3909 Mon Sep 17 00:00:00 2001 From: maddes-b <madde...@users.noreply.github.com> Date: Mon, 7 Sep 2020 20:13:55 +0200 Subject: [PATCH] Enhanced platform support of hook script check-mime-type.pl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * contrib/hook-scripts/check-mime-type.pl: (svnlook) Cross Platform: sane executable determination Patch by: Matthias Bücher <maddes+subvers...@maddes.net> [1] http://perldoc.perl.org/perlport.html#PLATFORMS --- contrib/hook-scripts/check-mime-type.pl | 129 ++++++++++++++++++++---- 1 file changed, 109 insertions(+), 20 deletions(-) diff --git a/contrib/hook-scripts/check-mime-type.pl b/contrib/hook-scripts/check-mime-type.pl index 79c37d26eb..716b1a0792 100755 --- a/contrib/hook-scripts/check-mime-type.pl +++ b/contrib/hook-scripts/check-mime-type.pl @@ -28,6 +28,15 @@ use strict; use Carp; +use Config; +use Cwd; +use Env; +use File::Which qw(which); +use File::Temp qw(tempdir tempfile); + +my $old_dir; +my $os_windows = $^O eq 'MSWin32'; +my $os_dos = $^O eq 'dos'; # Turn on warnings the best way depending on the Perl version. BEGIN { @@ -35,6 +44,12 @@ BEGIN { { require warnings; import warnings; } else { $^W = 1; } + + $old_dir = getcwd; +} + +END { + chdir($old_dir); } @@ -42,31 +57,58 @@ BEGIN { # Configuration section. # Svnlook path. -my $svnlook = "/usr/bin/svnlook"; +my $svnlook; # Since the path to svnlook depends upon the local installation # preferences, check that the required program exists to insure that # the administrator has set up the script properly. { - my $ok = 1; - foreach my $program ($svnlook) + my $svnlook_exe = 'svnlook' . $Config{_exe}; + my @svnlook_paths; + + if ($os_windows || $os_dos) + { + # On Windows/DOS the environment is available + my $svn_bindir = $ENV{'SVN_BINDIR'}; + if (defined $svn_bindir and length $svn_bindir) + { + $svnlook_paths[++$#svnlook_paths] = "$svn_bindir/$svnlook_exe"; + } + + $svnlook = which($svnlook_exe); + if (defined $svnlook and length $svnlook) + { + $svnlook_paths[++$#svnlook_paths] = $svnlook; + } + undef $svnlook; + } + + # On Unix the environment is empty, define fallback with absolute path + $svnlook_paths[++$#svnlook_paths] = "/usr/bin/$svnlook_exe"; + + foreach my $program (@svnlook_paths) { if (-e $program) { unless (-x $program) { - warn "$0: required program `$program' is not executable, ", - "edit $0.\n"; - $ok = 0; + warn "$0: program `$program' is not executable.\n"; + next; } + $svnlook = $program; + last; } else { - warn "$0: required program `$program' does not exist, edit $0.\n"; - $ok = 0; + warn "$0: program `$program' does not exist.\n"; + next; } } - exit 1 unless $ok; + unless (defined $svnlook and length $svnlook) + { + warn "$0: required program `$svnlook_exe' does not exist or is not executable, maybe have to edit $0.\n"; + exit 1; + } } ###################################################################### @@ -95,9 +137,9 @@ sub ACCESS_READ_WRITE () { 'read-write' } ###################################################################### # Harvest data using svnlook. -# Change into /tmp so that svnlook diff can create its .svnlook +# Change into temp dir so that svnlook diff can create its .svnlook # directory. -my $tmp_dir = '/tmp'; +my $tmp_dir = tempdir( TMPDIR => 1, CLEANUP => 1 ); chdir($tmp_dir) or die "$0: cannot chdir `$tmp_dir': $!\n"; @@ -220,19 +262,66 @@ sub safe_read_from_pipe { croak "$0: safe_read_from_pipe passed no arguments.\n"; } - print "Running @_\n"; - my $pid = open(SAFE_READ, '-|', @_); - unless (defined $pid) + + my $openfork_available = !($os_windows || $os_dos); + if ($openfork_available) { - die "$0: cannot fork: $!\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"; + } } - unless ($pid) + else { - open(STDERR, ">&STDOUT") - or die "$0: cannot dup STDOUT: $!\n"; - exec(@_) - or die "$0: cannot exec `@_': $!\n"; + # Redirect the comment into a temp file and use that to work around + # Windows' (non-)handling of multi-line commands. + my @commandline = (); + my $command; + my $comment; + + while ($command = shift) + { + if ("-m" eq $command) + { + $comment = shift; + my ($handle, $tmpfile) = tempfile( DIR => $tmp_dir); + print $handle $comment; + close($handle); + + push(@commandline, "--file"); + push(@commandline, $tmpfile); + } + else + { + # Munge the command to protect it from the command line + $command =~ s/\"/\\\"/g; + if ($command =~ m"\s") { $command = "\"$command\""; } + if ($command eq "") { $command = "\"\""; } + if ($command =~ m"\n") + { + warn "$0: carriage return detected in command - may not work\n"; + } + push(@commandline, $command); + } + } + + print "Running @commandline\n"; + if ( $comment ) { print $comment; } + + # Now do the pipe. + open(SAFE_READ, "@commandline |") + or die "$0: cannot pipe to command: $!\n"; } + my @output; while (<SAFE_READ>) { -- 2.24.3 (Apple Git-128)