diff options
author | Markus Ullmann <jokey@gentoo.org> | 2007-10-23 12:49:33 +0000 |
---|---|---|
committer | Markus Ullmann <jokey@gentoo.org> | 2007-10-23 12:49:33 +0000 |
commit | 97eafa6d84a5139daa86a222260466f8e35f1432 (patch) | |
tree | 06eb5df5785d5ba42f59123f2737d76084fa6c6e /scripts | |
parent | Fix local descs (diff) | |
download | jokey-97eafa6d84a5139daa86a222260466f8e35f1432.tar.gz jokey-97eafa6d84a5139daa86a222260466f8e35f1432.tar.bz2 jokey-97eafa6d84a5139daa86a222260466f8e35f1432.zip |
add some git helping scripts
svn path=/trunk/; revision=290
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/echangelog | 441 | ||||
-rwxr-xr-x | scripts/package | 34 | ||||
-rwxr-xr-x | scripts/sr-commit | 26 |
3 files changed, 501 insertions, 0 deletions
diff --git a/scripts/echangelog b/scripts/echangelog new file mode 100755 index 0000000..604b77f --- /dev/null +++ b/scripts/echangelog @@ -0,0 +1,441 @@ +#!/usr/bin/perl -w +# +# echangelog: Update the ChangeLog for an ebuild. For example: +# +# $ echangelog 'Add ~alpha to KEYWORDS' +# 4a5,7 +# > 10 Feb 2003; Aron Griffis <agriffis@gentoo.org> oaf-0.6.8-r1.ebuild : +# > Add ~alpha to KEYWORDS +# > + +use strict; +use POSIX qw(strftime getcwd setlocale); + +# Fix bug 21022 by restricting to C locale +setlocale(&POSIX::LC_ALL, "C"); + +use Text::Wrap; +$Text::Wrap::columns = 77; +$Text::Wrap::unexpand = 0; + +# Global variables +my (@files, @ebuilds, @conflicts, @trivial, @unknown, @new_versions, %actions); +my ($input, $editor, $entry, $user, $date, $text, $version, $year, $vcs); + +my %vcs = ( cvs => { diff => "cvs -f diff -U0", + status => "cvs -fn up", + add => "cvs -f add", + skip => 6, + regex => qr/^Index: ()(([^\/]*?)\.ebuild)\s*$/ }, + svn => { diff => "svn diff -N", + status => "svn status", + add => "svn add", + skip => 6, + regex => qr/^Index: ()(([^\/]*?)\.ebuild)\s*$/ }, + git => { diff => "git diff", + status => "git diff-index HEAD --name-status", + add => "git add", + skip => 4, + regex => qr/^diff \-\-git \S*\/((\S*)\.ebuild)/ } + +); + +# Figure out what kind of repo we are in. + +if ( -d "CVS" ) { + $vcs = "cvs"; +} elsif ( -d '.svn' ) { + $vcs = "svn"; +} elsif ( open GIT, "git rev-parse --git-dir |" ) { + $vcs = "git"; + close GIT; +} else { + die "No CVS, .git, .svn directories found, what kind of repo is this?"; +} + +# Read the current ChangeLog +if (-f 'ChangeLog') { + open I, '<ChangeLog' or die "Can't open ChangeLog for input: $!\n"; + { local $/ = undef; $text = <I>; } + close I; +} else { + # No ChangeLog here, maybe we should make one... + if (<*.ebuild>) { + open C, "portageq envvar PORTDIR |" or die "Can't find PORTDIR"; + my ($new) = <C>; + close C; + $new =~ s/\s+$//; + open I, "< $new/skel.ChangeLog" + or die "Can't open $new/skel.ChangeLog for input: $!\n"; + { local $/ = undef; $text = <I>; } + close I; + my ($cwd) = getcwd(); + $cwd =~ m|.*/(\w+-\w+)/([^/]+)| + or die "Can't figure out category/package.. sorry!\n"; + my ($category, $package_name) = ($1, $2); + $text =~ s/^\*.*//ms; # don't need the fake entry + $text =~ s/<CATEGORY>/$category/; + $text =~ s/<PACKAGE_NAME>/$package_name/; + } else { + die "This should be run in a directory with ebuilds...\n"; + } +} + + +# Figure out what has changed around here +open C, $vcs{$vcs}{status}.' 2>&1 |' or die "Can't run ".$vcs{$vcs}{status}.": $!\n"; +while (<C>) { + if (/^C\s+(\S+)/) { + if($vcs eq "git") { + my $filename = $2; + $filename =~ /\S*\/(\S*)/; + if( -d $1 ) { + next; + } + push @conflicts, $1; + next; + } + push @conflicts, $1; + next; + } elsif (/^\?\s+(\S+)/) { + if($vcs eq "git") { + my $filename = $2; + $filename =~ /\S*\/(\S*)/; + if( -d $1 ) { + next; + } + push @unknown, $1; + next; + } else { + push @unknown, $1; + } + $actions{$1} = '+'; + next; + } elsif (/^([ARMD])\s+(\S+)/) { + my ($status, $filename) = ($1,$2); + if($vcs eq "git") { + $filename =~ /\S*\/(\S*)/; + $filename = $1; + } + if( -d $filename ) { + next; + } + push @files, $filename; + ($actions{$filename} = $status) =~ tr/DARM/-+-/d; + } +} + +# Separate out the trivial files for now +@files = grep { + !/files.digest|Manifest|ChangeLog/ or do { push @trivial, $_; 0; } +} @files; + +@unknown = grep { + !/files.digest|Manifest|ChangeLog/ or do { push @trivial, $_; 0; } +} @unknown; + +# Don't allow any conflicts +if (@conflicts) { + print STDERR <<EOT; +$vcs reports the following conflicts. Please resolve them before +running echangelog. +EOT + print STDERR map "C $_\n", @conflicts; + exit 1; +} + +# Don't allow unknown files (other than the trivial files that were separated +# out above) +if (@unknown) { + print STDERR <<EOT; +$vcs reports the following unknown files. Please use "$vcs add" before +running echangelog, or remove the files in question. +EOT + print STDERR map "? $_\n", @unknown; + exit 1; +} + +# Sort the list of files as portage does. None of the operations through +# the rest of the script should break this sort. +sub sortfunc($$) { + my ($a, $b) = @_; + (my $va = $a) =~ s/.*?-(\d.*?)(?:\.ebuild)?$/$1/; + (my $vb = $b) =~ s/.*?-(\d.*?)(?:\.ebuild)?$/$1/; + my ($na, $sa, $sna, $ra) = ($va =~ /^(.*?)(?:_(alpha|beta||pre|rc|p)(\d*))?(?:-r(\d+))?$/); + my ($nb, $sb, $snb, $rb) = ($vb =~ /^(.*?)(?:_(alpha|beta||pre|rc|p)(\d*))?(?:-r(\d+))?$/); + my (@na) = split /\.|(?<=\d)(?=[^\d\.])/, $na; + my (@nb) = split /\.|(?<=\d)(?=[^\d\.])/, $nb; + my $retval; + + # + # compare version numbers first + # + for (my $i = 0; defined $na[$i] or defined $nb[$i]; $i++) { + # def vs. undef + return +1 if defined $na[$i] and !defined $nb[$i]; + return -1 if defined $nb[$i] and !defined $na[$i]; + + # num vs. num + if ($na[$i] =~ /^\d/ and $nb[$i] =~ /^\d/) { + $retval = ($na[$i] <=> $nb[$i]); + return $retval if $retval; + next; + } + + # char vs. char + if ($na[$i] =~ /^\D/ and $nb[$i] =~ /^\D/) { + $retval = ($na[$i] cmp $nb[$i]); + return $retval if $retval; + next; + } + + # num vs. char + $retval = ($na[$i] =~ /\d/ and -1 or +1); + return $retval; + } + + # + # compare suffix second + # + if (defined $sa and !defined $sb) { + return +2 if $sa eq "p"; + return -2; + } + if (defined $sb and !defined $sa) { + return -3 if $sb eq "p"; + return +3; + } + + if (defined $sa) { # and defined $sb + $retval = ($sa cmp $sb); + if ($retval) { + return +4 if $sa eq "p"; + return -4 if $sb eq "p"; + return $retval; # suffixes happen to be alphabetical order, mostly + } + + # compare suffix number + return +5 if defined $sna and !defined $snb; + return -5 if defined $snb and !defined $sna; + if (defined $sna) { # and defined $snb + $retval = ($sna <=> $snb); + return $retval if $retval; + } + } + + # + # compare rev third + # + return +6 if defined $ra and !defined $rb; + return -6 if defined $rb and !defined $ra; + if (defined $ra) { # and defined $rb + return ($ra <=> $rb); + } + + # + # nothing left to compare + # + return 0; +} +@files = sort sortfunc @files; + +# Forget ebuilds that only have changed copyrights, unless that's all +# the changed files we have + +@ebuilds = grep /\.ebuild$/, @files; +@files = grep !/\.ebuild$/, @files; + +if (@ebuilds) { + if ($vcs eq "git") { + open C, $vcs{$vcs}{diff}." 2>&1 |" or die "Can't run: ".$vcs{$vcs}{diff}."$!\n"; + } else { + open C, $vcs{$vcs}{diff}." @ebuilds 2>&1 |" or die "Can't run: ".$vcs{$vcs}{diff}."$!\n"; + } + $_ = <C>; + while (defined $_) { + # only possible with cvs + if (/^$vcs diff: (([^\/]*?)\.ebuild) was removed/) { + push @files, $1; + } + + # We assume GNU diff output format here. + # git format: diff --git a/app-doc/repodoc/metadata.xml b/app-doc/repodoc/metadata.xml + elsif (/$vcs{$vcs}{regex}/) { + my ($f) = ($2); + # file was removed from git + if (/^deleted file mode/) { + $_ = <C>; # just eat the line + } + # check if more than just copyright date changed. + # skip some lines (vcs dependent) + foreach(1..$vcs{$vcs}{skip}){ + $_ = <C>; + } + while (<C>) { + last if /^[A-Za-z]/; + if (/^[-+](?!# Copyright)/) { + push @files, $f; + last; + } + } + # at this point we've either added $f to @files or not, + # and we have the next line in $_ for processing + next; + } + elsif (/^$vcs.*?: (([^\/]*?)\.ebuild) is a new entry/) { + push @files, $1; + push @new_versions, $2; # new ebuild, will create a new entry + } + # other cvs output is ignored + $_ = <C>; + } +} +close C; + +# When a package move occurs, the versions appear to be new even though they are +# not. Trim them from @new_versions in that case. +@new_versions = grep { $text !~ /^\*\Q$_\E\s/m } @new_versions; + +# Check if we have any files left, otherwise re-insert ebuild list +# (of course, both might be empty anyway) +@files = @ebuilds unless (@files); + +# Allow ChangeLog entries with no changed files, but give a fat warning +unless (@files) { + print STDERR "**\n"; + print STDERR "** NOTE: No non-trivial changed files found. Normally echangelog\n"; + print STDERR "** should 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"; + @files = sort sortfunc @trivial; + @files = qw/ChangeLog/ unless @files; # last resort to put something in the list +} + +# Get the input from the cmdline, editor or stdin +if ($ARGV[0]) { + $input = "@ARGV"; +} else { + # 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.new"); + 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.new") { + local $/ = undef; + $input = <I>; + close I; + } else { + print STDERR "Error opening ChangeLog.new: $!\n"; + print STDERR "Reverting to stdin method.\n"; + undef $editor; + } + unlink 'ChangeLog.new'; + } + } + 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/; + +# If there are any long lines, then wrap the input at $columns chars +# (leaving 2 chars on left, one char on right, after adding indentation below). +$input =~ s/^\s*(.*?)\s*\z/$1/s; # trim whitespace +$input = Text::Wrap::fill('', '', $input) if ($input =~ /^.{80}/m); +$input =~ s/^/ /gm; # add indentation + +# Prepend the user info to the input +unless ($user = $ENV{'ECHANGELOG_USER'}) { + my ($fullname, $username) = (getpwuid($<))[6,0]; + $fullname =~ s/,.*//; # remove GECOS, bug 80011 + $user = sprintf "%s <%s\@gentoo.org>", $fullname, $username; +} +# Make sure that we didn't get "root" +die "Please set ECHANGELOG_USER or run as non-root\n" if $user =~ /<root@/; +$date = strftime("%d %b %Y", gmtime); +$entry = "$date; $user "; +$entry .= join ', ', map "$actions{$_}$_", @files; +$entry .= ':'; +$entry = Text::Wrap::fill(' ', ' ', $entry); # does not append a \n +$entry .= "\n$input"; # append user input + +# Each one of these regular expressions will eat the whitespace +# leading up to the next entry (except the two-space leader on the +# front of a dated entry), so it needs to be replaced with a +# double carriage-return. This helps to normalize the spacing in +# the ChangeLogs. +if (@new_versions) { + # Insert at the top with a new version marker + $text =~ s/^( .*? ) # grab header + \s*\n(?=\ \ \d|\*|\z) # suck up trailing whitespace + /"$1\n\n" . + join("\n", map "*$_ ($date)", reverse @new_versions) . + "\n\n$entry\n\n"/sxe + or die "Failed to insert new entry (4)\n"; +} else { + # 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"; +} + +sub update_copyright { + my ($t) = @_; + (my $year = $date) =~ s/.* //; + $t =~ s/^# Copyright \d+(?= )/$&-$year/m or + $t =~ s/^(# Copyright \d+)-(\d+)/$1-$year/m; + return $t; +} + +# Update the copyright year in the ChangeLog +$text = update_copyright($text); + +# Write the new ChangeLog +open O, '>ChangeLog.new' or die "Can't open ChangeLog.new for output: $!\n"; +print O $text or die "Can't write ChangeLog.new: $!\n"; +close O or die "Can't close ChangeLog.new: $!\n"; + +# Update affected ebuild copyright dates. There is no reason to update the +# copyright lines on ebuilds that haven't changed. I verified this with an IP +# lawyer. +for my $e (grep /\.ebuild$/, @files) { + 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"); +} + +# 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"; + +# Okay, now we have a starter ChangeLog to work with. +# The text will be added just like with any other ChangeLog below. +# Add the new changelog to vcs, maybe it already is added, but who cares right? +system("$vcs{$vcs}{add} ChangeLog 2>&1 >> /dev/null") + +# vim:sw=4 ts=8 expandtab diff --git a/scripts/package b/scripts/package new file mode 100755 index 0000000..295ce39 --- /dev/null +++ b/scripts/package @@ -0,0 +1,34 @@ +#!/usr/bin/perl -w +# +# echangelog: Update the ChangeLog for an ebuild. For example: +# +# $ echangelog 'Add ~alpha to KEYWORDS' +# 4a5,7 +# > 10 Feb 2003; Aron Griffis <agriffis@gentoo.org> oaf-0.6.8-r1.ebuild : +# > Add ~alpha to KEYWORDS +# > + +use strict; +use POSIX qw(strftime getcwd setlocale); + +# Fix bug 21022 by restricting to C locale +setlocale(&POSIX::LC_ALL, "C"); + +use Text::Wrap; +$Text::Wrap::columns = 77; +$Text::Wrap::unexpand = 0; + +# Global variables +open C, "portageq envvar PORTDIR |" or die "Can't find PORTDIR"; +my ($new) = <C>; +close C; +$new =~ s/\s+$//; +my ($cwd) = getcwd(); +$cwd =~ m|.*/(\w+-\w+)/([^/]+)| + or die "Can't figure out category/package.. sorry!\n"; +my ($category, $package_name) = ($1, $2); +print $category; +print "/"; +print $package_name; + +# vim:sw=4 ts=8 expandtab diff --git a/scripts/sr-commit b/scripts/sr-commit new file mode 100755 index 0000000..64eafa1 --- /dev/null +++ b/scripts/sr-commit @@ -0,0 +1,26 @@ +#!/bin/bash + +PACKAGE=$(/home/jokey/gentoo/my-scripts/package) +if [[ "${PACKAGE}" == "Can't figure out category/package.. sorry!" ]] ; then + echo "Is this a package dir???" + exit 1 +fi + +if [[ "$1" == "" ]] ; then + echo "No commit message today?" + exit 1 +fi + +if [[ "$2" != "" ]] ; then + MESSAGE=$2 + /home/jokey/gentoo/my-scripts/echangelog "${MESSAGE}" +else + echo "no changelog message today?" + MESSAGE=$1 +fi + +for each in *.ebuild; do + ebuild $each manifest +done +git add . +git commit -a -m "${PACKAGE}: ${MESSAGE}" |