From c9951fa8c1d54fe1e7b5c657f2b940a00d921b76 Mon Sep 17 00:00:00 2001 From: Levente Polyak <anthraxx@archlinux.org> Date: Wed, 6 Dec 2023 17:47:10 +0100 Subject: [PATCH] dbscripts: remove obsolete svnlog script --- roles/dbscripts/files/svnlog | 1092 ---------------------------------- 1 file changed, 1092 deletions(-) delete mode 100755 roles/dbscripts/files/svnlog diff --git a/roles/dbscripts/files/svnlog b/roles/dbscripts/files/svnlog deleted file mode 100755 index defecd348..000000000 --- a/roles/dbscripts/files/svnlog +++ /dev/null @@ -1,1092 +0,0 @@ -#!/usr/bin/perl -w -our $ID = q($Id: svnlog,v 1.15 2009-02-28 23:02:39 eagle Exp $ ); -# -# svnlog -- Mail Subversion commit notifications. -# -# Written by Russ Allbery <rra@stanford.edu> -# Copyright 2005, 2006, 2007, 2009 -# Board of Trustees, Leland Stanford Jr. University -# Based on cvslog, copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 -# Board of Trustees, Leland Stanford Jr. University -# -# This program is free software; you may redistribute it and/or modify it -# under the same terms as Perl itself. - -############################################################################## -# Modules and declarations -############################################################################## - -# I want to use open (FOO, '-|', @command). -require 5.008; -use strict; - -use Date::Parse qw(str2time); -use Encode qw(decode encode FB_CROAK); -use Getopt::Long qw(GetOptions); -use IPC::Open2 qw(open2); -use POSIX qw(strftime); - -# The path to the repository, set later. -our $REPOSITORY; - -# The default path to svnlook, which can be overridden on the command line. -our $SVNLOOK = 'svnlook'; - -# Debugging is off by default. -our $DEBUG = 0; - -# Clean up $0 for errors. -our $FULLPATH = $0; -$0 =~ s%^.*/%%; - -############################################################################## -# Utility functions -############################################################################## - -# Given a prefix and a reference to an array, return a list of all strings in -# that array with the common prefix stripped off. Also strip off any leading -# ./ if present. -sub simplify { - my ($prefix, $list) = @_; - my @stripped = @$list; - for (@stripped) { - s%^\Q$prefix\E/*%%; - s%^\./+%%; - } - return @stripped; -} - -# Run the given command, capturing its output and returning the output as an -# array. Be aware for huge inputs that the output is read entirely into -# memory. -sub read_command { - my (@command) = @_; - my $pid = open (CMD, '-|', @command) or die "$0: cannot fork @command\n"; - my @output = <CMD>; - close CMD; - my $status = $?; - if ($status != 0) { - my $error = "$0: pipe from '@command' failed:"; - my $exit = $status >> 8; - my $signal = $status & 127; - $error .= " status=$exit" if $exit; - $error .= " signal=$signal" if $exit; - die "$error\n"; - } - if ($DEBUG) { - print "Output from @command:\n"; - print @output; - print '-' x 78, "\n"; - } - return @output; -} - -############################################################################## -# Parsing functions -############################################################################## - -# Given a hash to hold the data we're accumulating and the revision number of -# the change, get the general information about the commit message. This -# gives us the user making the change, the date, and the commit message. Sets -# author, date, and message in the provided hash, with date being the Unix -# timestamp. -sub parse_info { - my ($data) = @_; - my $rev = $$data{revision}; - my @info = read_command ($SVNLOOK, 'info', $REPOSITORY, '-r', $rev); - chomp (@info); - - # User, date, and then size of log message (ignored). - $$data{author} = shift @info; - $$data{date} = str2time (shift @info); - shift @info; - - # Remainder is the log message, although strip off any trailing blank - # lines. - pop @info while (@info && $info[-1] =~ /^\s*$/); - $$data{message} = @info ? join ("\n", @info, '') : ''; -} - -# Given a hash to hold the data we're accumulating and the revision number of -# the change, obtain the list of files affected. For right now, we ignore -# property modifications. Anything other than an add (A) or delete (D) is -# treated as a modification. Sets prefix, added, modified, deleted, and files -# in the provided hash. -sub parse_files { - my ($data) = @_; - my $rev = $$data{revision}; - my @info = read_command ($SVNLOOK, 'changed', $REPOSITORY, '-r', $rev); - - # Go through the files and in the process, calculate the common prefix. - # Start with the dirname of the first file and remove a level of directory - # structure until we find a match for every file. - my $prefix; - my (@added, @modified, @deleted); - for (@info) { - my ($flag, $props, $file) = /^(.)(.) (.*)$/; - next unless $file; - if ($file !~ m%/$% && $flag ne '_') { - $$data{summarizable} = 1; - } - if ($flag eq 'A') { push (@added, $file) } - elsif ($flag eq 'D') { push (@deleted, $file) } - else { - push (@modified, $file); - if ($props ne ' ') { - $$data{propchange}{$file} = 1; - } - if ($flag eq 'U') { - $$data{contents}{$file} = 1; - } - } - if (defined $prefix) { - while ($prefix && index ($file, $prefix) != 0) { - $prefix =~ s%/*([^/]+)/*$%%; - } - } else { - $prefix = $file; - $prefix =~ s%/*([^/]+)/*$%%; - } - } - unless (@added || @deleted || @modified) { - die "$0: unable to get list of changed files from svnlook\n"; - } - - # Stash the data. - $$data{prefix} = $prefix; - $$data{added} = [ sort @added ]; - $$data{modified} = [ sort @modified ]; - $$data{deleted} = [ sort @deleted ]; - $$data{files} = [ sort @added, @modified, @deleted ]; -} - -# Given the data hash and a reference to the diff output, build the -# metainformation about what changed. Right now, this just grabs information -# about copies. -sub parse_metadata { - my ($data, $diff) = @_; - my ($propchange, $property); - for my $line (@$diff) { - if ($line =~ /^Copied: (.*?) \((from rev \d+, .*)\)$/) { - $$data{copied}{$1} = $2; - undef $propchange; - } - } -} - -# Given the revision, get the diff for that revision. Note that this stores -# the full diff output in memory. -sub parse_diff { - my ($rev) = @_; - my @diff = read_command ($SVNLOOK, 'diff', $REPOSITORY, '-r', $rev); - return @diff; -} - -# Given the data hash, parse the commit message and look for Debian bug -# closers. Return all of the bugs found. -sub parse_debbugs { - my ($data) = @_; - - # The regex for matching the bug closers, taken from the Debian - # Developer's Reference Manual with capturing parens added to grab the bug - # numbers. - my $close = qr/closes:\s*(?:bug)?\#\s*(\d+)(?:,\s*(?:bug)?\#\s*(\d+))*/i; - - # Scan through the commit message looking for added bug closers. - my @bugs = ($$data{message} =~ /$close/g); - @bugs = map { defined $_ ? $_ : () } @bugs if @bugs; - return @bugs; -} - -############################################################################## -# Formatting functions -############################################################################## - -# Determine the From header of the message from the user provided. Right now, -# this is dead simple, but I'm guessing it will get more complex later as I -# find more ways of getting this information. -# -# We currently assume that all names containing non-ASCII characters are -# encoded in UTF-8. If they're not, we send them verbatim in the mail -# message. -sub build_from { - my ($data) = @_; - my $user = $$data{author}; - my $name = (getpwnam $user)[6] || ''; - $name =~ s/,.*//; - my $utf8 = eval { decode ('utf-8', $name, FB_CROAK) }; - unless ($@) { - $name = encode ('MIME-Q', $utf8); - } - if ($name =~ /[^\w ]/) { - $name = '"' . $name . '"'; - } - return "From: " . ($name ? "$name <$user>" : $user) . "\n"; -} - -# Takes the data hash, a prefix to add to the subject header, and a flag -# saying whether to give a full list of files no matter how long it is. Form -# the subject line of our message. Try to keep the subject under 78 -# characters by just giving a count of files if there are a lot of them. -sub build_subject { - my ($data, $prefix, $long) = @_; - my $subject = "Subject: " . $prefix . $$data{prefix} . ' '; - my $length = 78 - length ($subject); - $length = 8 if $length < 8; - my @files = simplify ($$data{prefix}, $$data{files}); - my $files = join (' ', map { my $f = $_; $f =~ s%/$%%; $f } @files); - $files =~ s/[\n\r]/ /g; - if (!$long && length ($files) > $length) { - $subject .= '(' . @files . (@files > 1 ? " files" : " file") . ')'; - } else { - $subject .= "($files)"; - } - return $subject; -} - -# Generate file lists, one file per line, with the appropriate heading and -# including additional information for modified files. Takes the data hash -# and the heading. -sub build_filelist { - my ($data, $heading) = @_; - my $key = lc $heading; - return '' unless $$data{$key} && @{ $$data{$key} }; - my $output = "$heading:\n"; - for my $file (@{ $$data{$key} }) { - my $cleanfile = $file; - $cleanfile =~ s%/+$%%; - if ($key ne 'modified') { - $output .= " $file\n"; - } else { - $output .= " $file"; - if ($$data{propchange}{$file}) { - my @attrs = ('properties'); - unshift (@attrs, 'contents') if $$data{contents}{$file}; - my $attrs = '(' . join (', ', @attrs) . ')'; - my $length = length ($file) + 2; - $length += 8 - $length % 8; - if (78 - $length < length ($attrs)) { - $output .= "\n $attrs\n"; - } else { - $output .= "\t$attrs\n"; - } - } else { - $output .= "\n"; - } - } - if ($key eq 'added') { - if ($$data{copied}{$cleanfile}) { - $output .= " ($$data{copied}{$cleanfile})\n"; - } - } - } - return $output; -} - -# Build the subheader of the report, listing the files changed and some other -# information about the change. Takes the data hash, the revision, and a flag -# saying whether to show the author of the change. Returns the header as a -# string. -sub build_header { - my ($data, $rev, $showauthor) = @_; - my $date = strftime ('%A, %B %e, %Y @ %T', localtime $$data{date}); - $date =~ s/ / /; - my $header = " Date: $date\n"; - $header .= " Author: $$data{author}\n" if $showauthor; - $header .= "Revision: $rev\n"; - return $header; -} - -# Build a report for a particular commit; this includes the list of affected -# files and the commit message. Returns the report as a string. Takes the -# data hash. -sub build_message { - my ($data) = @_; - my $message = ''; - if ($$data{message}) { - $message .= $$data{message}; - if ($$data{added} || $$data{modified} || $$data{deleted}) { - $message .= "\n"; - } - } - $message .= build_filelist ($data, 'Added'); - $message .= build_filelist ($data, 'Modified'); - $message .= build_filelist ($data, 'Deleted'); - return $message; -} - -# Given the revision and the diff, check to see if it's longer than 200KB -# (this limit should be configurable). If it is, suppress the diff and -# print out a message explaining why. Otherwise, return the diff as a text -# string. (We use lots of memory. I guess I don't care that much.) -sub build_diff { - my ($rev, $diff) = @_; - my $length = 0; - for (@$diff) { - $length += length ($_); - } - if ($length > 200 * 1024) { - my $old = $rev - 1; - return "The diff is longer than the limit of 200KB.\n" - . "Use svn diff -r $old:$rev to see the changes.\n"; - } else { - return join ('', @$diff); - } -} - -# Build a summary of the changes by running the patch through diffstat. This -# gives a basic idea of the order of magnitude of the changes. Takes the data -# hash (for file prefix), revision, and the path to diffstat as arguments, and -# optionally takes a reference to the array holding the diff if it was already -# obtained for other reasons (if not, we'll run svnlook ourselves). -# -# Doesn't handle binary files properly yet (they'll just disappear in the -# diffstat output rather than being marked binary). I need to see the svn -# diff output again to know what to do. -sub build_summary { - my ($data, $diffstat, $diff) = @_; - $diffstat ||= 'diffstat'; - unless ($diff) { - $diff = [ parse_diff ($data) ]; - } - open2 (\*OUT, \*IN, $diffstat, '-w', '78') - or die "$0: cannot fork $diffstat: $!\n"; - for (@$diff) { - s%^(\*\*\*|---|\+\+\+) \Q$$data{prefix}\E/*%$1 %; - s%^(Added|Modified|Deleted): \Q$$data{prefix}\E/*%$1: %; - print IN $_; - } - close IN; - my @stats = <OUT>; - close OUT; - if ($DEBUG) { - print "Output from diffstat:\n"; - print @stats; - print '-' x 78, "\n"; - } - my $offset = index ($stats[0], '|'); - unshift (@stats, '-' x $offset, "+\n"); - return @stats; -} - -############################################################################## -# Configuration handling -############################################################################## - -# svnlog takes all of the same parameters as both command-line arguments and -# configuration file parameters. Right now, we only support a simple -# configuration file that's the same for every path; that will probably change -# in the future. -# -# This function takes in a list of Getopt::Long options and parses both the -# configuration file and the command line. Normally, the command-line options -# override the configuration file; the exceptions are the address and header -# parameters, where all provided options are merged together into one list. -# There are three options only supported as command-line options, not as -# configuration file parameters: help, version, and config. -# -# Returns a reference to a config hash that contains the parameters provided -# as keys. -sub configure { - my (@rules) = @_; - my %config; - - # Parse command-line options. - Getopt::Long::Configure ('bundling', 'no_ignore_case', 'require_order'); - GetOptions (\%config, @rules) or exit 1; - - # Handle special options. - if ($config{help}) { - print "Feeding myself to perldoc, please wait....\n"; - exec ('perldoc', '-t', $FULLPATH); - } elsif ($config{version}) { - my @version = split (' ', $ID); - shift @version if $ID =~ /^\$Id/; - my $version = join (' ', @version[0..2]); - $version =~ s/,v\b//; - $version =~ s/(\S+)$/($1)/; - $version =~ tr%/%-%; - print $version, "\n"; - exit; - } - - # If a config file was specified, read it. All of the options in @rules - # are also allowed in the config file except help, version, and config. - if ($config{config}) { - my %keys = map { - my $key = $_; - $key =~ s/\|.*//; - $key =~ s/=.*//; - if ($key =~ /^(help|version|config)$/) { - (); - } else { - $key => 1; - } - } @rules; - open (CONFIG, '<', $config{config}) - or die "$0: cannot open $config{config}: $!\n"; - local $_; - while (<CONFIG>) { - next if /^\s*\#/; - next if /^\s*$/; - chomp; - my ($key, $value) = /^\s*(\S+):\s+(.*)/; - unless ($value) { - warn "$0:$config{config}:$.: invalid config syntax: $_\n"; - next; - } - unless ($keys{$key}) { - warn "$0:$config{config}:$.: unrecognized config line: $_\n"; - next; - } - $value =~ s/\s+$//; - $value =~ s/^\"(.*)\"$/$1/; - if ($key eq 'address' || $key eq 'header') { - if ($config{$key}) { - push (@{ $config{$key} }, $value); - } else { - $config{$key} = [ $value ]; - } - } else { - $config{$key} = $value unless defined $config{$key}; - } - } - close CONFIG; - } - - # Set some defaults if needed and then return. - $config{diffstat} ||= 'diffstat'; - unless ($config{sendmail}) { - my ($path) = grep { -x $_ } qw(/usr/sbin/sendmail /usr/lib/sendmail); - $config{sendmail} = $path || '/usr/lib/sendmail'; - } - $config{subject} ||= 'Commit in '; - return %config; -} - -############################################################################## -# Main routine -############################################################################## - -# Parse the command line and load the configuration file, if any. The long -# option has to be listed first to get the hash table loaded properly, -# unfortunately. -my @options = ('address|a=s@', 'config|c=s', 'confirm', 'debug|D', - 'debbugs=s', 'diff|d', 'diffstat=s', 'from|f=s', - 'header|H=s@', 'help|h', 'include|i=s@', 'long-subject|l', - 'omit-author|o', 'sendmail=s', 'subject|p=s', 'summary|s', - 'svnlook=s', 'version|v'); -my %config = configure (@options); -die "$0: no addresses specified\n" unless ($config{address}); -$DEBUG = $config{debug} if $config{debug}; -$SVNLOOK = $config{svnlook} if $config{svnlook}; - -# Unbuffer output for debugging. -$| = 1 if $DEBUG; - -# There must now be two command-line arguments remaining: the path to the -# repository and the revision number of the change. -die "Usage: $0 [options] <repository> <revision>\n" unless @ARGV == 2; -$REPOSITORY = shift; -my $revision = shift; - -# Get the data. -my %data; -$data{revision} = $revision; -parse_info (\%data); -parse_files (\%data); - -# If we were told to include only particular files, exit if none of those -# files were modified. -if ($config{include}) { - my $found = 0; - for my $file (@{ $data{files} }) { - if (grep { $file =~ /$_/ } @{ $config{include} }) { - $found = 1; - } - } - exit unless $found; -} - -# Get the diff. Right now, this is unconditional because of parse_metadata. -my @diff = parse_diff ($revision); - -# Get additional metadata. -parse_metadata (\%data, \@diff); - -# Get the From header. -my $from = $config{from} ? "From: $config{from}\n" : build_from (\%data); - -# Prompt the user if we should ask for confirmation. -if ($config{confirm}) { - my $response; - open (TTY, '>/dev/tty') or exit; - do { - print TTY "\nSend notification to @{ $config{address} } (y/n)? "; - $response = <STDIN>; - } until ($response =~ /^[yn]/i); - exit if $response =~ /^n/i; - close TTY; -} - -# Send debbugs control message if needed. -if ($config{debbugs}) { - my @bugs = parse_debbugs (\%data); - if (@bugs) { - if ($DEBUG) { - open (MAIL, '>&STDOUT') - or die "$0: cannot dup standard output: $!\n"; - } else { - open (MAIL, "| $config{sendmail} -t -oi -oem") - or die "$0: cannot fork $config{sendmail}: $!\n"; - } - print MAIL "To: $config{debbugs}\n"; - print MAIL $from; - print MAIL "\n"; - print MAIL "tag $_ pending\n" for @bugs; - print MAIL "thanks\n"; - close MAIL; - unless ($? == 0) { - warn "$0: debbugs sendmail exit status " . ($? >> 8) . "\n"; - } - if ($DEBUG) { - print '-' x 78, "\n"; - } - } -} - -# Open our mail program for the main mail message. -if ($DEBUG) { - open (MAIL, '>&STDOUT') or die "$0: cannot dup standard output: $!\n"; -} else { - open (MAIL, "| $config{sendmail} -t -oi -oem") - or die "$0: cannot fork $config{sendmail}: $!\n"; -} -my $oldfh = select MAIL; -$| = 1; -select $oldfh; - -# Build the mail headers. -print MAIL "To: ", join (', ', @{ $config{address} }), "\n"; -print MAIL $from; -if ($config{header}) { - for my $header (@{ $config{header} }) { - print MAIL $header, ($header =~ /\n\z/ ? '' : "\n"); - } -} -my $subj = build_subject (\%data, $config{subject}, $config{'long-subject'}); -print MAIL $subj, "\n"; - -# Add a User-Agent header with the version of svnlog. -my @version = split (' ', $ID); -shift @version if $ID =~ /^\$Id/; -print MAIL "User-Agent: svnlog/$version[1]\n"; -print MAIL "\n"; - -# Build the rest of the message and write it out. Is it the right thing to -# always try to do the summary and diff, or is this going to bite me for tags? -print MAIL build_header (\%data, $revision, !$config{'omit-author'}); -print MAIL "\n", build_message (\%data); -print MAIL "\n", build_summary (\%data, $config{diffstat}, \@diff) - if $config{summary} && $data{summarizable}; -print MAIL "\n", build_diff ($revision, \@diff) if $config{diff}; - -# Make sure sending mail succeeded. -close MAIL; -unless ($? == 0) { die "$0: sendmail exit status " . ($? >> 8) . "\n" } -exit 0; -__END__ - -############################################################################## -# Documentation -############################################################################## - -=head1 NAME - -svnlog - Mail Subversion commit notifications - -=head1 SYNOPSIS - -B<svnlog> [B<-Ddhlosv>] [B<-a> I<address> ...] [B<--confirm>] [B<-c> I<file>] - [B<--debbugs>=I<address>] [B<--diffstat>=I<path>] [B<-f> I<from>] - [B<-H> I<header> ...] [B<-i> I<regex> ...] [B<--sendmail>=I<path>] - [B<-p> I<prefix>] [B<--svnlook>=I<path>] I<repository> I<revision> - -=head1 REQUIREMENTS - -Subversion, including the B<svnlook> command-line tool; Perl 5.8.0 or later; -B<diffstat> for the B<-s> option; and a sendmail command that can accept -formatted mail messages for delivery. - -=head1 DESCRIPTION - -B<svnlog> is intended to be run out of Subversion's post-commit hook, -generates a commit notification, and sends it via e-mail. The format is -almost identical to the format of mail generated by B<cvslog>. By default, -the commit message will contain the author, date, and revision number; the -files added, deleted, or modified; and the commit message. Optionally, the -full diff of the commit or a diffstat(1) summary of the changes, or both, -can be added to the notification. - -For information on how to add B<svnlog> to your Subversion repository, see -L<"INSTALLATION"> below. All necessary configuration options can be given -on the command line, but if you would prefer you can also use the B<-c> -option to point B<svnlog> at a configuration file. See L<"CONFIG FILE"> -below for the syntax. - -The full path to the repository and the revision number of the change must -be given on the command line. These are the same parameters that Subversion -passes to its post-commit hook. B<svnlog> must be able to find B<svnlook> -to work; if B<svnlook> isn't on the default path, specify it via either the -B<--svlook> command-line option or the I<svnlook> configuration parameter. - -At least one B<-a> option must be given or at least one I<address> parameter -must be set in the configuration file; otherwise, B<svnlog> has nowhere to -send mail and nothing to do. - -=head1 OPTIONS - -All of these options except B<-c>, B<-h>, and B<-v> can also be set in a -configuration file specified with B<-c>. See L<"CONFIG FILE"> below for the -syntax. - -=over 4 - -=item B<-a> I<address>, B<--address>=I<address> - -Send the commit notification to I<address>. This option may occur more than -once, and all specified addresses will receive a copy of the notification -(including any addresses set in the configuration file, if any). There is -no way to override the addresses set in the configuration file, just add -more addresses. - -=item B<-c> I<file>, B<--config>=I<file> - -Load configuration options from I<file>. See L<"CONFIG FILE"> below for the -syntax. Normally, command-line options override values set in the -configuration file, but settings for B<-a> (I<address>) and B<-H> -(I<header>) are cumulative between the command line and the configuration -file. - -=item B<--confirm> - -Prompt for user confirmation before sending the commit notification. The -user must answer C<y> or C<n>, and if they answer C<n>, B<svnlog> will exit -without doing anything further. - -This option is something of a hack. It will only work if it can open the -user's tty to print the prompt, which means that it may only work with local -repositories or remote repositories accessed via ssh. If it cannot open the -tty, it will exit quietly (as if the user said C<n>), but if this function -is called by a daemon that may have a tty of F</dev/console>, its operation -is unpredictable. Recommended only for use with local repositories. - -=item B<-D>, B<--debug> - -Prints out the information B<svnlog> got from Subversion as it works. This -option is mostly useful for developing B<svnlog> and checking exactly what -data Subversion provides. - -=item B<--debbugs>=I<address> - -This is a special feature probably only of use to Debian developers. If this -flag is given, scan the commit message for any bug closers (using the same -syntax as is used in Debian changelog files). If any bug closers are found, -send a separate mail message to I<address> with the debbugs commands to tag -those bugs as pending. The easiest way to get the appropriate bug closers -into the commit message when working on Debian packages is to use B<debcommit> -to commit changes. - -In versions of svnlog prior to 1.11, this option instead checked the diff for -modifications to F<debian/changelog>. This proved too likely to tag bugs -spuriously when importing old source and was changed to only look in the -commit message. - -=item B<-d>, B<--diff> - -Append the full diff output for each change to the notification message -provided that it is less than 200KB. If longer than that, just append a -note saying that the diff is too large and giving the B<svn> command that -would display it. - -=item B<--diffstat>=I<path> - -Sets the path to B<diffstat>. If this option isn't given, B<svnlog> -defaults to attempting to find B<diffstat> in its path (and what its path is -will depend a great deal on your Subversion configuration). - -=item B<-f> I<from>, B<--from>=I<from> - -Sets the From header of the mail generated by B<svnlog> to I<from>. This -must be syntactically valid as the contents of an RFC 2822 From header (a -simple address of course qualifies). If this option is not given, the -From header will be set to the user who made the commit, with their full -name added if they're found in the local password file or equivalent. -(Normally, the local mail system will then append a local domain to form -an e-mail address.) - -I<from> should be specified in UTF-8. If it is, it will be encoded using -RFC 2047 encoding if needed. If it is encoded in some other character -set, B<svnlog> will try to use it in the mail message without modification -or encoding, which may produce surprising results. - -=item B<-H> I<header>, B<--header>=I<header> - -Include I<header> in the headers of the mail message. I<header> must be a -valid mail header (including the keyword, colon, and space). This option -may be given multiple times, and all of the headers (including any specified -in the configuration file) will be included in the message. There is no way -to override the headers set in the configuration file, just add to them. - -=item B<-h>, B<--help> - -Print out this documentation (which is done simply by feeding the script to -C<perldoc -t>). - -=item B<-i> I<regex>, B<--include>=I<regex> - -Only send a notification message if one of the files modified matches the -regular expression I<regex>. If none do, the commit will be silently -ignored. This option may be given multiple times, and a notification -message will be sent if any of the files in the commit match any of the -provided regular expressions. There is no way to override include patterns -set in the configuration file, just add to them. - -If the notification is sent, all details about that commit will be sent, -including listing files that don't match the regexes, including other -changes in summary and diff output, and so forth. - -=item B<-l>, B<--long-subject> - -Normally, B<svnlog> will just list the number of changed files rather than -the complete list of them if the subject would otherwise be too long (more -than 78 characters). This flag disables that behavior and includes the full -list of modified files in the subject header of the mail, no matter how long -it is. Currently, B<svnlog> does not wrap the header, so using this option -can result in a message that is not syntactically valid. - -=item B<-o>, B<--omit-author> - -Omit the author information from the commit notification. This is useful -where all commits are done by the same person (so the author information is -just noise) or where the author information isn't actually available. The -author will still appear in the From header of the commit message unless the -B<-f> option is also given. - -=item B<--sendmail>=I<path> - -Sets the path to B<sendmail>. If this option is not given, B<svnlog> will -search for sendmail in F</usr/sbin> and then F</usr/lib>, falling back on -using F</usr/lib/sendmail> (and probably failing) if neither appears to -exist. - -=item B<-p> I<prefix>, B<--subject>=I<prefix> - -Sets the Subject prefix for all commit messages. Appended to this prefix -will be the relative path in the repository to the lowermost parent -directory of all changed files and then a list of files (or a count of -files) in parentheses. If this option is not given, the default prefix is -C<Commit in >. Note that you will normally want I<prefix> to end in a -trailing space. - -=item B<-s>, B<--summary> - -Append to each commit notification a summary of the changes, produced by -generating diffs and feeding those diffs to diffstat(1). diffstat(1) must -be installed to use this option; see also the B<--diffstat> option to -specify the path to the program. - -=item B<--svnlook>=I<path> - -Sets the path to B<svnlook>. If this option is not given, B<svnlog> attempt -to find B<diffstat> in its path (and what its path is will depend a great -deal on your Subversion configuration). - -=item B<-v>, B<--version> - -Print out the version of B<svnlog> and exit. - -=back - -=head1 CONFIGURATION - -B<svnlog> can be told to read a configuration file with the B<-c> option. -The syntax of this file is one configuration parameter per line in the -format: - - parameter: value - -The value may be enclosed in double-quotes and must be enclosed in -double-quotes if there is leading or trailing whitespace that should be part -of the value. Whitespace after the colon and before the value (or an -opening double quote) is ignored. There is no way to continue a line; each -parameter must be a single line. Lines beginning with C<#> are comments and -ignored, as are blank lines. - -The configuration parameters are exactly the same as the long names of the -command-line options, with the exception that B<--config>, B<--help>, and -B<--version> have no corresponding parameters (for obvious reasons). As -with the command-line options, the I<address> and I<header> parameters may -be given multiple times; for all other parameters, the last value is taken -if the paramter occurs multiple times. - -When setting a boolean parameter like I<summary> or I<diff>, the value -should be C<1> if you want to turn it on and C<0> if you want to turn it -off. - -Command-line options always override the configuration file except for the -B<--address> and B<--header> options, as noted. - -=head1 INSTALLATION - -Follow these steps to add B<svnlog> to your project: - -=over 4 - -=item 1. - -Install B<svnlog> on your system in some convenient location. You may need -to change the path to Perl on the first line of the script if your Perl -isn't in F</usr/bin/perl>. B<svnlog> does not have to be inside the -F<hooks> directory of the Subversion repository; it can be anywhere -(F</usr/local/bin>, for instance). - -=item 2. - -In the F<hooks> directory of your Subversion repository, create a file named -F<post-commit> with the contents: - - #!/bin/sh - /path/to/svnlog <options> "$1" "$2" - -where C</path/to/svnlog> is the full path to wherever you installed -B<svnlog> and <options> are whatever options you wish to use. Be sure to -include at least one B<-a> option (or a B<-c> option pointing to a -configuration file that includes at least one I<address> parameter setting) -so that B<svnlog> knows where to send the mail. - -It's best to always specify the path to B<svnlook> with the B<--svnlook> -option (and the path to B<diffstat> with B<--diffstat> if you're using it) -even if you think that program will be in the default path, since Subversion -can be run under unusual situations (such as by a web server) and the path -may not be what you expect. - -=back - -That's all there is to it. Try committing to your repository and see if -mail is sent as you expect. Note that if you're configuring B<svnlog> to -send commit notifications to a mailing list, you may need to use the B<-f> -option to set the From header to an address that's allowed to mail that -list. It's a good idea to test your configuration with B<-a> pointing to -your own e-mail address so that you see what the From header looks like and -can find any problems. - -=head1 EXAMPLES - -The following examples show the B<svnlog> command line that would go into -the Subversion post-commit hook, so they assume that $1 is the path to the -repository and $2 is the revision number. - -A minimalist configuration, sending mail to commits@example.com: - - /usr/local/bin/svnlog -a commits@example.com "$1" "$2" - -A more typical configuration, specifying the paths to B<svnlog> and -B<diffstat>, sending commit notifications from commit-mailer@example.com -(perhaps a special address that can send to mailing lists and discards any -replies), sending them to proj-commits@example.com and to user@example.com, -and including diffstat output. - - /usr/local/bin/svnlog --svnlook=/usr/bin/svnlook \ - --diffstat=/usr/bin/diffstat --summary \ - --from="Subversion Commits <commit-mailer@example.com>" \ - -a proj-commits@example.com -a user@example.com \ - "$1" "$2" - -Here is the same example, but taking all of its parameters from a -configuration file: - - /usr/local/bin/svnlog -c /usr/local/etc/svnlog.conf "$1" "$2" - -where F</usr/local/etc/svnlog.conf> contains: - - # svnlog configuration - svnlook: /usr/bin/svnlook - diffstat: /usr/bin/diffstat - summary: 1 - from: Subversion Commits <commit-mailer@example.com> - address: proj-commits@example.com - address: user@example.com - -Finally, here is an example for a Debian package maintainer. Send all -commits, including diffs, to pkg-debian@lists.example.com, and cc -control@bugs.debian.org with tag commands when appropriate. Also add the -headers: - - X-Debian-Commit: yes - X-Comment: Generated by svlog - -to each commit message. - - /usr/local/bin/svnlog --svnlook=/usr/bin/svnlook \ - --diff --debbugs=control@bugs.debian.org \ - --header="X-Debian-Commit: yes" \ - --header="X-Comment: Generated by svnlog" \ - --address=pkg-debian@lists.debian.org \ - "$1" "$2" - -The From header on the mail will be the default, derived from the user -making the commit and the name from the local password file. - -=head1 DIAGNOSTICS - -=over 4 - -=item cannot dup standard output: %s - -(Fatal) B<svnlog> is running in debug mode (B<-D>) and was unable to send -the output that would normally go into a mail message to standard output -instead. - -=item cannot fork %s: %s - -(Fatal) B<svnlog> was unable to run a program that it wanted to run. This -may result in no notification being sent or in information missing. -Generally this means that the program in question was missing or B<svnlog> -couldn't find it for some reason. - -=item cannot open %s: %s - -(Fatal) B<svnlog> was unable to open the configuration file specified with -B<-c> or B<--config>. The file may be missing or not readable by the user -running B<svnlog>. - -=item pipe from '%s' failed: %s - -(Fatal) Some program invoked by B<svnlog> to get some information (usually -B<svnlook>) failed or died unexpectedly. There may be other error messages -before this one that explain what happened. The exit status and any fatal -signal received by the program are appended. - -=item invalid config syntax: %s - -(Warning) The given line in the configuration file was syntactically -invalid. See L<"CONFIG FILE"> for the correct syntax. - -=item no addresses specified - -(Fatal) There was no B<-a> or B<--address> command-line option and no -B<address> parameter in a config file. At least one recipient address must -be specified for the Subversion commit notification. - -=item unable to get list of changed files from svnlook - -(Fatal) B<svnlog> was unable to understand any of the output of C<svnlook -changed> and therefore was unable to tell what files were changed by this -commit. There may be other error messages before this one that explain what -happened. - -=item unrecognized config line: %s - -(Warning) The given configuration parameter isn't one of the ones that -B<svnlog> knows about. - -=back - -=head1 FILES - -=over 4 - -=item F</usr/sbin/sendmail> - -=item F</usr/lib/sendmail> - -The default paths to B<sendmail> if the B<--sendmail> option and I<sendmail> -configuration parameter are not given. B<svnlog> first tries the former and -then the latter. - -=back - -=head1 ENVIRONMENT - -=over 4 - -=item PATH - -Used to find B<svnlook> (and B<diffstat> when the B<-s> option is in -effect) if the B<--svnlook> and B<--diffstat> command-line options or -configuration parameters are not given. - -=back - -=head1 CAVEATS - -B<svnlog> assumes that the full name in the local password file or -equivalent is encoded in UTF-8. If it appears to be valid UTF-8, it will -be used as UTF-8, which may mangle the name if it were actually in a -different encoding. If it's not valid UTF-8, B<svnlog> will use the full -name without modification in the mail message, which may result in a -syntactically invalid mail message and unexpected results. - -=head1 BUGS - -B<svnlog>, when given the B<-l> option, can generate syntactically invalid -e-mail messages. The Subject header needs to be properly wrapped and some -solution found to filenames longer than 998 characters (probably using RFC -2047 encoding). - -No MIME type is declared in the mail message, which means that if your log -messages (or file names or diffs) aren't US-ASCII, the results are unlikely -to be what you want. You can work around this, if all of your commit -messages are in the same character set, with command-line options like: - - --header="MIME-Version: 1.0" - --header="Content-Type: text/plain; charset=utf-8" - -but B<svnlog> should really be able to figure this out for itself and should -do the right thing with log messages in multiple character sets. - -URLs for the diffs are not yet supported. If you want this added, please -e-mail me the details of how to construct an appropriate URL and I'll see -what I can do. - -B<svnlog> always reads the entire diff into memory. This may not be -desirable on low-memory machines when processing huge changes such as -merges. The functions that need the diff output to gather information -should be able to scan the diff a line at a time when needed. - -The diff size limit should be configurable, and what to include in the diff -output should also be configurable. B<mailer.py> supports specifying -whether one wants diffs for adds, deletes, and modifications separately. - -B<svnlog> runs the command-line B<svnlook> program and parses its output -rather than using the Perl bindings. It was easier, but the Perl bindings -would be more efficient. - -=head1 SEE ALSO - -debcommit(1), diffstat(1), svnlook(1). - -The Subversion manual at L<http://svnbook.red-bean.com/>. - -diffstat is at L<http://invisible-island.net/diffstat/>. - -Current versions of this program are available from its web site at -L<http://www.eyrie.org/~eagle/software/svnlog/>. - -=head1 AUTHOR - -Russ Allbery <rra@stanford.edu>. - -=head1 COPYRIGHT AND LICENSE - -Copyright 2005, 2006, 2007, 2009 Board of Trustees, Leland Stanford Jr. -University. - -Based on cvslog, copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Board of -Trustees, Leland Stanford Jr. University. - -This program is free software; you may redistribute it and/or modify it -under the same terms as Perl itself. - -=cut -- GitLab