# Global variables
my (@files) = ();
my (@ebuilds) = ();
-my ($input, $entry, $user, $date, $text, $version, $year);
+my ($input, $editor, $entry, $user, $date, $text, $version, $year);
my (%versions) = ();
+my (%actions) = ();
# Read the current ChangeLog
if (-f 'ChangeLog') {
# Figure out what has changed around here
open C, 'cvs -n up 2>&1 |' or die "Can't run cvs -n up: $!\n";
while (<C>) {
- /ChangeLog/ and next;
- /^[MCAR] (\S+)/ and push @files, $1;
+ /ChangeLog/ and next;
+ /^([ARMC]) (\S+)/ or next;
+ push @files, $2;
+ ($actions{$2} = $1) =~ tr/ARMC/+-/d;
}
# Forget ebuilds that only have changed copyrights, unless that's all
@ebuilds = grep /\.ebuild$/, @files;
@files = grep !/\.ebuild$/, @files;
if (@ebuilds) {
- open C, "cvs diff -U 0 @ebuilds 2>&1 |" or die "Can't run cvs diff: $!\n";
- $_ = <C>;
- while (defined $_) {
- if (/^cvs diff: (([^\/]*?)\.ebuild) was removed/) {
- push @files, $1;
- $versions{$2} = 0; # existing ebuild that was removed
- }
- elsif (/^Index: (([^\/]*?)\.ebuild)\s*$/) {
- my ($f, $v) = ($1, $2);
- # check if more than just copyright date changed.
- # skip some lines
- $_ = <C>; # ====================================
- $_ = <C>; # RCS file: ...
- $_ = <C>; # retrieving revision
- $_ = <C>; # diff -u ...
- $_ = <C>; # --- vim-6.2-r6.ebuild
- $_ = <C>; # +++ vim-6.2-r6.ebuild
- while (<C>) {
- last if /^[A-Za-z]/;
- if (/^[-+](?!# Copyright)/) {
- push @files, $f;
- $versions{$v} = 0; # existing ebuild that has changed
- last;
- }
- }
- # at this point we've either added $f to @files or not,
- # and we have the next line in $_ for processing
- next;
- }
- elsif (/^cvs.*?: (([^\/]*?)\.ebuild) is a new entry/) {
- push @files, $1;
- $versions{$2} = -1; # new ebuild, will create a new entry
- }
- # other cvs output is ignored
- $_ = <C>;
- }
+ open C, "cvs diff -U 0 @ebuilds 2>&1 |" or die "Can't run cvs diff: $!\n";
+ $_ = <C>;
+ while (defined $_) {
+ if (/^cvs diff: (([^\/]*?)\.ebuild) was removed/) {
+ push @files, $1;
+ $versions{$2} = 0; # existing ebuild that was removed
+ }
+ elsif (/^Index: (([^\/]*?)\.ebuild)\s*$/) {
+ my ($f, $v) = ($1, $2);
+ # check if more than just copyright date changed.
+ # skip some lines
+ $_ = <C>; # ====================================
+ $_ = <C>; # RCS file: ...
+ $_ = <C>; # retrieving revision
+ $_ = <C>; # diff -u ...
+ $_ = <C>; # --- vim-6.2-r6.ebuild
+ $_ = <C>; # +++ vim-6.2-r6.ebuild
+ while (<C>) {
+ last if /^[A-Za-z]/;
+ if (/^[-+](?!# Copyright)/) {
+ push @files, $f;
+ $versions{$v} = 0; # existing ebuild that has changed
+ last;
+ }
+ }
+ # at this point we've either added $f to @files or not,
+ # and we have the next line in $_ for processing
+ next;
+ }
+ elsif (/^cvs.*?: (([^\/]*?)\.ebuild) is a new entry/) {
+ push @files, $1;
+ $versions{$2} = -1; # new ebuild, will create a new entry
+ }
+ # other cvs output is ignored
+ $_ = <C>;
+ }
}
close C;
# Allow ChangeLog entries with no changed files, but give a fat warning
unless (@files) {
- print "**\n\n";
- print "** NOTE: No changed files found. Normally echangelog should\n";
- print "** be run after all affected files have been added and/or\n";
- print "** modified. Did you forget to cvs add?\n";
- print "**\n\n";
+ print STDERR "**\n";
+ print STDERR "** NOTE: No changed files found. Normally echangelog should\n";
+ print STDERR "** be run after all affected files have been added and/or\n";
+ print STDERR "** modified. Did you forget to cvs add?\n";
+ print STDERR "**\n";
}
-# Get the input from the cmdline or stdin
+# Get the input from the cmdline, editor or stdin
if ($ARGV[0]) {
$input = "@ARGV";
} else {
- local $/ = undef;
- print "Please type the log entry, ctrl-d to finish, ctrl-c to abort\n";
- $input = <>;
+ # Testing for defined() allows ECHANGELOG_EDITOR='' to cancel EDITOR
+ $editor = defined($ENV{'ECHANGELOG_EDITOR'}) ? $ENV{'ECHANGELOG_EDITOR'} :
+ $ENV{'EDITOR'} || undef;
+ if ($editor) {
+ system("$editor .#ChangeLog");
+ if ($? != 0) {
+ # This usually happens when the editor got forcefully killed; and
+ # the terminal is probably messed up: so we reset things.
+ system('/usr/bin/stty sane');
+ print STDERR "Editor died! Reverting to stdin method.\n";
+ undef $editor;
+ } else {
+ if (open I, "<.#ChangeLog") {
+ local $/ = undef;
+ $input = <I>;
+ close I;
+ } else {
+ print STDERR "Error opening .#ChangeLog: $!\n";
+ print STDERR "Reverting to stdin method.\n";
+ undef $editor;
+ }
+ unlink '.#ChangeLog';
+ }
+ }
+ unless ($editor) {
+ print "Please type the log entry: use Ctrl-d to finish, Ctrl-c to abort...\n";
+ local $/ = undef;
+ $input = <>;
+ }
}
die "Empty entry; aborting\n" unless $input =~ /\S/;
die "Please set ECHANGELOG_USER or run as non-root\n" if $user =~ / root@/;
$date = strftime("%d %b %Y", localtime);
$entry = "$date; $user ";
-$entry .= join ', ', grep !/files.digest|Manifest/, @files; # don't list digests
+$entry .= join ', ', map "$actions{$_}$_", grep !/files.digest|Manifest/, @files;
$entry .= ':';
$entry = Text::Wrap::fill(' ', ' ', $entry); # does not append a \n
$entry .= "\n$input"; # append user input
# NOTE: The first two branches here are disabled via '&& 0'
# because they use the new but unsanctioned ChangeLog format.
if (0 && !defined $version) { # <--- NOTE disabled via '0'
- # Changing a patch or something, not an ebuild, so put the entry
- # after the first *version line (really guessing)
- $text =~ s/^( \*.*? ) # find the *version line
- \s*\n(?=\ \ \d|\*|\z) # suck up trailing whitespace
- /$1\n\n$entry\n\n/mx
- or die "Failed to insert new entry (1)\n";
+ # Changing a patch or something, not an ebuild, so put the entry
+ # after the first *version line (really guessing)
+ $text =~ s/^( \*.*? ) # find the *version line
+ \s*\n(?=\ \ \d|\*|\z) # suck up trailing whitespace
+ /$1\n\n$entry\n\n/mx
+ or die "Failed to insert new entry (1)\n";
} elsif (0 && $versions{$version} > -1) { # <--- NOTE disabled via '0'
- # Insert after the *version line
- $text =~ s/^( \*\Q$version\E ) # find the *version line = $1
- (?:\.|\.ebuild)? # some poorly formed entries
- \s+ ( \(.*\) ) # (date) = $2
- \s*\n(?=\ \ \d|\*|\z) # suck up trailing whitespace
- /$1 $2\n\n$entry\n\n/mx
- or die "Failed to insert new entry (2)\n";
+ # Insert after the *version line
+ $text =~ s/^( \*\Q$version\E ) # find the *version line = $1
+ (?:\.|\.ebuild)? # some poorly formed entries
+ \s+ ( \(.*\) ) # (date) = $2
+ \s*\n(?=\ \ \d|\*|\z) # suck up trailing whitespace
+ /$1 $2\n\n$entry\n\n/mx
+ or die "Failed to insert new entry (2)\n";
} elsif (!defined $version || $versions{$version} > -1) {
- # Changing an existing patch or ebuild, no new version marker
- # required
- $text =~ s/^( .*? ) # grab header
- \s*\n(?=\ \ \d|\*|\z) # suck up trailing whitespace
- /$1\n\n$entry\n\n/sx
- or die "Failed to insert new entry (3)\n";
+ # Changing an existing patch or ebuild, no new version marker
+ # required
+ $text =~ s/^( .*? ) # grab header
+ \s*\n(?=\ \ \d|\*|\z) # suck up trailing whitespace
+ /$1\n\n$entry\n\n/sx
+ or die "Failed to insert new entry (3)\n";
} else {
- # Insert at the top with a new version marker
- $text =~ s/^( .*? ) # grab header
- \s*\n(?=\ \ \d|\*|\z) # suck up trailing whitespace
- /$1\n\n*$version ($date)\n\n$entry\n\n/sx
- or die "Failed to insert new entry (4)\n";
+ # Insert at the top with a new version marker
+ $text =~ s/^( .*? ) # grab header
+ \s*\n(?=\ \ \d|\*|\z) # suck up trailing whitespace
+ /$1\n\n*$version ($date)\n\n$entry\n\n/sx
+ or die "Failed to insert new entry (4)\n";
}
sub update_copyright {
- my ($t) = @_;
- my ($year) = strftime('%Y', localtime);
- $t =~ s/^# Copyright \d+(?= )/$&-$year/m or
- $t =~ s/^(# Copyright \d+)-(\d+)/$1-$year/m;
- return $t;
+ my ($t) = @_;
+ my ($year) = strftime('%Y', localtime);
+ $t =~ s/^# Copyright \d+(?= )/$&-$year/m or
+ $t =~ s/^(# Copyright \d+)-(\d+)/$1-$year/m;
+ return $t;
}
# Update the copyright year in the ChangeLog
# the right thing to do
opendir D, '.' or die "Can't opendir .: $!\n";
for my $e (grep /\.ebuild$/, readdir D) {
- print "updating $e\n";
- my ($etext, $netext);
- open E, "<$e" or warn("Can't read $e to update copyright year\n"), next;
- { local $/ = undef; $etext = <E>; }
- close E;
-
- # Attempt the substitution and compare
- $netext = update_copyright($etext);
- next if $netext eq $etext; # skip this file if no change.
-
- # Write the new ebuild
- open E, ">$e.new" or warn("Can't open $e.new\n"), next;
- print E $netext and
- close E or warn("Can't write $e.new\n"), next;
-
- # Move things around and show the diff
- system "diff -U 0 $e $e.new";
- rename "$e.new", $e or warn("Can't rename $e.new: $!\n");
+ my ($etext, $netext);
+ open E, "<$e" or warn("Can't read $e to update copyright year\n"), next;
+ { local $/ = undef; $etext = <E>; }
+ close E;
+
+ # Attempt the substitution and compare
+ $netext = update_copyright($etext);
+ next if $netext eq $etext; # skip this file if no change.
+
+ # Write the new ebuild
+ open E, ">$e.new" or warn("Can't open $e.new\n"), next;
+ print E $netext and
+ close E or warn("Can't write $e.new\n"), next;
+
+ # Move things around and show the diff
+ system "diff -U 0 $e $e.new";
+ rename "$e.new", $e or warn("Can't rename $e.new: $!\n");
}
close D;
# Move things around and show the ChangeLog diff
system 'diff -Nu ChangeLog ChangeLog.new';
rename 'ChangeLog.new', 'ChangeLog' or die "Can't rename ChangeLog.new: $!\n";
+
+# vim:sw=4 ts=8 expandtab