From b2f6783657f7f0cef2c4dc09966515f478030b0b Mon Sep 17 00:00:00 2001 From: pdmef Date: Fri, 18 Mar 2005 17:16:57 +0000 Subject: [PATCH] Rocco Rutte: moving towards auto-generating ChangeLog.mutt-ng git-svn-id: svn://svn.berlios.de/mutt-ng/trunk@200 e385b8ad-14ed-0310-8656-cc95a2468c6d --- cvslog2changelog.pl | 120 ----------------------- svnlog2changelog.pl | 230 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+), 120 deletions(-) delete mode 100644 cvslog2changelog.pl create mode 100755 svnlog2changelog.pl diff --git a/cvslog2changelog.pl b/cvslog2changelog.pl deleted file mode 100644 index 1f8b3be..0000000 --- a/cvslog2changelog.pl +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/perl - -# use Data::Dumper; - -%Authors = (roessler => 'Thomas Roessler ', - me => 'Michael Elkins '); - -@Changes = (); -$change = {}; - -while (<>) { - chomp $_; - if ($_ =~ /^Working file: (.*)$/) { - $workfile = $1; - $change->{workfile} = $workfile; - $change->{logmsg} = ''; - $change->{author} = ''; - $change->{revision} = ''; - -# print STDERR "workfile: ", $workfile, "\n"; - - } - elsif ($_ =~ /^(=======|------)/) { - if ($change->{revision}) { - - # Some beautifications: Date, author. - if ($change->{author} =~ /^(.*?)\s?\<(.*)\>/) { - $change->{author} = "$1 <$2>"; - } - $change->{date} =~ s!/!-!g; - - # Record the change. - push @Changes, $change unless $change->{logmsg} =~ /^#/; - $change = {}; - $change->{workfile} = $workfile; - $change->{logmsg} = ''; - $change->{author} = ''; - } - } elsif ($_ =~ /^revision ([0-9.]*)/) { - $change->{revision} = $1; - } elsif ($_ =~ /^date: ([^; ]*) ([^; ]*)( \+[0-9]+)?; author: ([^;]*);/) { - $change->{date} = $1; - $change->{hour} = $2; - $change->{author} = $Authors{$3} ? $Authors{$3} : $4; - $change->{committed} = $4; - } elsif ($_ =~ /^From: (.*)$/) { - $change->{author} = $1; - } elsif ($change->{revision}) { - if ($change->{logmsg} || $_) { - $change->{logmsg} .= $_ . "\n"; - } - } -} - -# print Dumper @Changes; - -undef $last_logmsg; undef $last_author; undef $last_date; undef $last_hour; undef $last_comm; -$files = []; - -for my $k (sort {($b->{date} cmp $a->{date}) || ($b->{hour} cmp $a->{hour}) || ($a->{author} cmp $b->{author}) || ($a->{workfile} cmp $b->{workfile})} @Changes) { - - if (!($last_date eq $k->{date}) || !($last_author eq $k->{author}) || - !($last_comm eq $k->{committed})) { - if (@$files) { - &print_entry ($files, $last_logmsg); - $files = []; - } - &print_header ($k->{author}, $k->{committed}, $k->{date}, $k->{hour}); - } - - if (@$files && !($last_logmsg eq $k->{logmsg})) { - &print_entry ($files, $last_logmsg); - $files = []; - } - - - $last_comm = $k->{committed}; - $last_logmsg = $k->{logmsg}; - $last_author = $k->{author}; - $last_date = $k->{date}; - $last_hour = $k->{hour}; - - push @$files, $k->{workfile}; -} - -if (@$files) { - &print_entry ($files, $last_logmsg); -} - -sub print_header { - my $author = shift; - my $committed = shift; - my $date = shift; - my $hour = shift; - - print $date, " ", $hour, " ", $author, " (", $committed, ")\n\n"; -} - -sub print_entry { - my $files = shift; - my $logmsg = shift; - - - print "\t* "; - my $c = ''; - - for my $f (@$files) { - print $c, $f; - $c = ', ' unless $c; - } - - print ": "; - - my $t = ''; - for my $l (split ('\n', $logmsg)) { - print $t, $l, "\n"; - $t = "\t" unless $t; - } - print "\n"; -} diff --git a/svnlog2changelog.pl b/svnlog2changelog.pl new file mode 100755 index 0000000..d35e9f1 --- /dev/null +++ b/svnlog2changelog.pl @@ -0,0 +1,230 @@ +#!/usr/bin/perl -w + +# Purpose: +# summarize and re-format subversion's log output to plain text +# +# Written by Rocco Rutte +# for internal use with mutt-ng . +# +# License: GPL +# +# Usage/Options: +# -t print only today's messages +# -s YYYY-MM-DD print only messages since (and including) date +# -i string use string for indentation +# -m number break lines at the latest at number columns +# -h help +# +# Note: lines matching ``^([^:]+):?$'' will be ignored if the first +# submatch in brackets is a known author; i.e. the logs +# +# | Foo Bar +# | added l33t c0d3 +# +# and +# +# | Foo Bar: +# | added l33t c0d3 +# +# will be interpreted as only 'added l33t c0d3' if 'Foo Bar' is known as +# an author. This does not count when grouping messages for authors, +# those lines are just skipped. This is hard-coded, see below. + +use strict; +use POSIX; +use Getopt::Std; + +# hard-coded configuration: this maps user to full names +my %commiters = ( + "ak1" => "Andreas Krennmair", + "nion" => "Nico Golde", + "pdmef" => "Rocco Rutte", + "dkg1" => "Daniel K. Gebhart" +); + +my %fmap = ( + "filesA" => "Added", + "filesM" => "Modified", + "filesD" => "Deleted" +); + +# default config +my %options = (); +my $linemax = 70; +my $today = ""; +my $since = ""; +my $indent = " "; + +# some stuff we need +my $currev = 0; +my $lastrev = 0; +my @curlog = (); +my $curentry = ""; +my $curauthor = ""; +my $count = 0; +my %changes = (); + +# nicely print log lines in itemized style with eye-candy indentation and +# somewhat smart line-breaking +sub niceline { + my ($text) = (@_); + my @lines = split (/\n/, $text); + for my $l (@lines) { + print "$indent$indent-"; + my @words = split (/\ /, $l); + my $c = length ($indent); + for my $w (@words) { + if (length ($w) + $c > $linemax) { + print "\n$indent$indent $w"; + $c = length ($indent); + } else { + print " $w"; + } + $c += length ($w) + 1; + } + print "\n"; + } +} + +sub usage { + print < +for use with mutt-ng + +Usage: + Print help: + svn log | svnlog2changelog.pl -h + + Print Subversion's log for today: + svn log | svnlog2changelog.pl -t [-i string] + + Print Subversion's log since (and including) YYYY-MM-DD + svn log | svnlog2changelog.pl -s YYYY-MM-DD [-i string] +EOF + ; +} + +sub isknown { + my ($name) = (@_); + for my $k (keys %commiters) { + if ($commiters{$k} eq $name) { + return (1); + } + } + return (0); +} + +# get and process options +getopts ("tm:s:hi:", \%options); +if (defined $options{'t'}) { + $today = strftime ("%Y-%m-%d", localtime (time ())); +} +if (defined $options{'m'} and $options{'m'} =~ /^[0-9]{2,}$/) { + $linemax = $options{'m'}; +} +if (defined $options{'s'} and $options{'s'} =~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/) { + $since = $options{'s'}; +} +if (defined $options{'h'}) { + &usage (); + exit (0); +} +if (defined $options{'i'}) { + $indent = $options{'i'}; +} + +# parse log +while () { + chomp; + if ($_ =~ /^r([0-9]+)/) { + $currev = $1; + @curlog = (); + $curauthor = ""; + $count = 0; + my @items = split (/\ \|\ /, $_); + my @dateinfo = split (/\ /, $items[2]); + $curentry = $dateinfo[0]; + ${$changes{$curentry}}{'author'} = $items[1]; + $curauthor = $items[1]; + # _keep_ latest rev. number for day + if (not defined ${$changes{$curentry}}{'rev'}) { + ${$changes{$curentry}}{'rev'} = substr ($items[0], 1); + } + # _keep_ latest commit time for day + if (not defined ${$changes{$curentry}}{'time'}) { + ${$changes{$curentry}}{'time'} = "$dateinfo[1] $dateinfo[2]"; + } + $count++; + next; + } + if ($count > 0) { + # ignore noise + if (length ($_) == 0 or $_ =~ /^[-]+$/ or + $_ =~ /^([^:]+):?$/ and &isknown ($1) or + $_ eq "Changed paths:") { + next; + } + if ($_ =~ /([A-Z]) \/((trunk|branches|tags).*)$/) { + my $what = $1; + my $target = $2; + ${${$changes{$curentry}}{"files$what"}}{$target} = 1; + } else { + # try to be smart and remove itemizations people make + my $clean = $_; + $clean =~ s/^[- \t*]*//; + if (length ($clean) > 0) { + # _pre_pend space for continued log and newline for + # new log lines for new revisions +# if (defined ${${$changes{$curentry}}{'log'}}{$curauthor} and +# length (${${$changes{$curentry}}{'log'}}{$curauthor}) > 0) { +# if ($lastrev eq $currev) { +# ${${$changes{$curentry}}{'log'}}{$curauthor} .= " "; +# } else { +# ${${$changes{$curentry}}{'log'}}{$curauthor} .= "\n"; +# } +# } +# ${${$changes{$curentry}}{'log'}}{$curauthor} .= "$clean"; + ${${$changes{$curentry}}{'log'}}{$curauthor} .= "$clean\n"; + $lastrev = $currev; + } + } + } +} + +my $first = ""; +my $first2 = ""; + +for my $k (sort { $b cmp $a } (keys (%changes))) { + # ignore noise + if (not defined %{${$changes{$k}}{'log'}} or + (length ($since) > 0 && length ($today) == 0 && ($k lt $since)) or + (length ($today) > 0 && ($k ne $today))) { + next; + } + # print first line with date, time and latest revision for current day + print "$first$k ${$changes{$k}}{'time'} "; + $first = "\n"; + $first2 = ""; + print "Latest Revision: ${$changes{$k}}{'rev'}\n\n"; + # per author: print his name and an itemized list of his log msgs. + # with smart line-breaking and indentation + for my $a (keys %{${$changes{$k}}{'log'}}) { + print "$first2$indent"; + if (defined $commiters{$a}) { + print $commiters{$a}; + } else { + print $a; + } + print ":\n"; + &niceline (${${$changes{$k}}{'log'}}{$a}); + $first2 = "\n"; + } + for my $a (keys %fmap) { + if (defined %{${$changes{$k}}{$a}}) { + print "$first$indent$fmap{$a} Files:\n"; + my $fixme = join (", ", keys %{${$changes{$k}}{$a}}); + &niceline ($fixme); + } + } +} -- 2.20.1