#!/usr/bin/env perl # Simple wrapper to the editor for svn. # # For commits, remove trailing whitespace and trailing newlines from # the log message, and abort if there is a non-printable character # (except \n). The file name needs to match /^svn-commit/, i.e. this # does not apply to "svn propedit --revprop svn:log". # # This script can be run in various ways, e.g. by setting $SVN_EDITOR # to the path to this wrapper. # # Copyright (c) 2008-2020 Vincent Lefevre . # This program is free software; you may redistribute it # and/or modify it under the same terms as Perl itself. use strict; use warnings; use Config; use open ':locale'; my ($proc) = '$Id: svneditor 127623 2020-05-16 09:17:34Z vinc17/zira $' =~ /^.Id: (\S+) / or die; # svn currently calls the editor with one argument: the file name. @ARGV == 1 or $! = 1, die "Usage: $proc \n"; sub getmtime ($) { my $mtime = (stat $_[0])[9]; # If mtime isn't available, something wrong could have occurred. defined $mtime or die "$proc: can't stat file $_[0]: $!\n"; return $mtime; } sub signame ($) { my $s = $_[0]; # Get the signal name (see perlipc(1) man page). my @signame = split / /, $Config{sig_name}; return defined $signame[$s] ? " (SIG$signame[$s])" : ""; } my $file = $ARGV[0]; my $mtime1 = getmtime $file; # If $EDITOR isn't set, run emacs because this is what I like. # Feel free to change it to something else. :) system $ENV{EDITOR} || 'emacs', @ARGV; if ($?) { my $s; die "$proc: ". ($? == -1 ? "cannot execute editor ($!)" : ($s = $? & 127) ? "editor killed by signal $s".signame($s). ", with".($? & 128 ? '' : 'out')." coredump" : "editor terminated with exit value ".($? >> 8))."\n"; } exit if $file !~ /^svn-commit/; # Exit without touching anything if file hasn't been modified. my $mtime2 = getmtime $file; exit if $mtime2 == $mtime1; my $changed = 0; my $s = ''; open FILE, '<', $file or die "$proc: can't open file $file (R): $!\n"; while () { last if $_ eq "--This line, and those below, will be ignored--\n"; last if /^--Cette ligne, et les suivantes ci-dessous, seront/; s/[\t ]+$// and $changed = 1; $s .= $_; chomp; /[^[:print:]]/ and $! = 1, die "Log message contains a non-printable character. Aborting.\n"; } close FILE or die "$proc: can't close file $file (R): $!\n"; $s =~ s/\n+\z// || $changed or exit; print "Log message has been cleaned up\n"; open FILE, '>', $file or die "$proc: can't open file $file (W): $!\n"; print FILE $s or die "$proc: can't write to file $file: $!\n"; close FILE or die "$proc: can't close file $file (W): $!\n";