diff options
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/maintainers/branch-patchgen.pl | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/Documentation/maintainers/branch-patchgen.pl b/Documentation/maintainers/branch-patchgen.pl new file mode 100644 index 00000000..8fca948d --- /dev/null +++ b/Documentation/maintainers/branch-patchgen.pl @@ -0,0 +1,134 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use SVN::Client; + +my $branch = 'svn://anonsvn.kde.org/home/kde/branches/KDE/3.5'; +my $tag = 'svn://anonsvn.kde.org/home/kde/tags/KDE/3.5.10'; + +sub svn_err { + my $err = shift; + my $str = $err->strerror(); + $str = '<no strerror>' unless defined $str; + print STDERR "ERROR: $str\n"; + while ($err) { + my $msg = $err->message(); + $msg = '<no message>' unless defined $msg; + print STDERR "$msg\n"; + $err = $err->child(); + } + exit 1; +} +$SVN::Error::handler = \&svn_err; + +my $last_tag_rev; +sub tag_info_receiver { + my ($path, $info) = @_; + $last_tag_rev = $info->last_changed_rev(); +} + +my %tag_rev = (); +my $first_tag_rev; +sub tag_log_receiver { + my ($changed_paths, $revision) = @_; + for my $path (keys %$changed_paths) { + my $lcp = $changed_paths->{$path}; + my $copyrev = $lcp->copyfrom_rev(); + next if $copyrev == $SVN::Core::INVALID_REVNUM; + $path =~ s:^/tags/KDE/3\.5\.0/::; + next if defined $tag_rev{$path}; + $tag_rev{$path} = $copyrev; + $first_tag_rev = $revision; + # print "$path copied from $revision\n"; + } +} + +my %mod_rev = (); +sub branch_log_receiver { + my ($changed_paths, $revision) = @_; + for my $path (keys %$changed_paths) { + my $lcp = $changed_paths->{$path}; + next if $path =~ m:/branches/KDE/3\.5/kde-common/:; + if ($path =~ m:/branches/KDE/3\.5/(kdelibs|kdevelop)/:) { + $mod_rev{$1} = $revision; + } + elsif ($path =~ m:/branches/KDE/3\.5/([^/]+/[^/]+)/:) { + $mod_rev{$1} = $revision; + } + else { + print "Skipping path $path\n"; + } + } +} + +my $mod; +sub mod_log_receiver { + my ($changed_paths, $revision, $author, $date, $message) = @_; + $author = '?' unless defined $author; + my $msg = $message; + $msg = '' unless defined $message; + $msg =~ s/\r//g; + $msg =~ s/\n\n.*//s; + $msg =~ s/\s+$//; + $msg =~ s/\s+/ /g; + $msg =~ s/^(.{70,110})\. .*/$1. .../ if length($msg) > 120; + $msg =~ s/^(.{70,115}) .*/$1.../ if length($msg) > 120; + $msg =~ s/^(.{117}).*/$1.../ if length($msg) > 120; + print PATCH "r$revision | $author\n$msg\n"; + for my $path (sort keys %$changed_paths) { + my $lcp = $changed_paths->{$path}; + my $chg = $lcp->action(); + next unless $path =~ m:/branches/KDE/3\.5/\Q$mod\E/(.*):; + print PATCH " $chg $1\n"; + } +} + +$| = 1; +my $svn = SVN::Client->new() || die; +my $pool1 = $svn->pool(); +print "Finding tag info... "; +my $pool2 = SVN::Pool->new($pool1); +$svn->info($tag, undef, 'HEAD', \&tag_info_receiver, 0, $pool2); +print "tag last modified at r$last_tag_rev\n"; +print "Examining tag log... "; +$svn->log($tag, 'HEAD', 0, 1, 1, \&tag_log_receiver, $pool2); +print "tag first created at r$first_tag_rev\n"; +print "Examining branch changes since r$first_tag_rev...\n"; +$svn->log($branch, $first_tag_rev, 'HEAD', 1, 1, \&branch_log_receiver, $pool2); +$pool2->clear(); +print "Now generating individual patch files\n"; +for (sort keys %mod_rev) { + $mod = $_; + my $tag_dir = $mod; + my $tag_rev = $first_tag_rev; + while ($tag_dir) { + if (defined $tag_rev{$tag_dir}) { + $tag_rev = $tag_rev{$tag_dir}; + last; + } + $tag_dir =~ s:/?[^/]+$::; + } + my $revision = $mod_rev{$mod}; + my $patchfile = "$mod-r$revision.patch"; + $patchfile =~ s:/:_:g; + next if -e $patchfile; + print "Creating $patchfile; logging since r$tag_rev\n"; + open PATCH, '+>', $patchfile or die "Error opening $patchfile"; + $svn->diff([], "$tag/$mod", $last_tag_rev, "$branch/$mod", $revision, + 1, 1, 0, \*PATCH, \*STDERR, $pool2); + seek PATCH, 0, 0 or die "Failed to rewind $patchfile"; + $_ = join('', <PATCH>); + s:^(---|\+\+\+) (.*?)\((\.\.\./[^/]+/KDE/[^/]+)/(.*?)\):$1 $4/$2 ($3):gm; + my $patch = $_; + seek PATCH, 0, 0 or die "Failed to rewind $patchfile"; + print PATCH "Changes between KDE 3.5.10 tag and KDE 3.5 branch r$revision.\n"; + print PATCH "Only looking at subdirectory $mod here.\n"; + print PATCH "Logs since r$tag_rev of the branch but this might be wrong.\n\n"; + $svn->log("$branch/$mod", $tag_rev, $revision, 1, 0, + \&mod_log_receiver, $pool2); + $pool2->clear(); + print PATCH "\n\n$patch"; + close PATCH or die "Error closing $patchfile"; +} |