зеркало из https://github.com/mozilla/pjs.git
215 строки
5.9 KiB
Perl
Executable File
215 строки
5.9 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
|
|
use File::Temp qw(tempdir);
|
|
|
|
my $cvs_host = "dm-cvs01";
|
|
my $bonsai_host = "dm-webtools02";
|
|
|
|
my $cvsroot_path = "/cvsroot";
|
|
my $bonsai_path = "/var/www/webtools/bonsai-cvs";
|
|
|
|
my $remote_cvs_path = "/cvsdisk/jail$cvsroot_path";
|
|
my $local_cvs_path = "/cvsdisk/jail$cvsroot_path";
|
|
|
|
$|=1;
|
|
|
|
my $hostname=`hostname`;
|
|
chomp $hostname;
|
|
$hostname =~ s/\..*$//; # truncate at a dot in case of a poorly configured hostname
|
|
if ($hostname ne $bonsai_host) {
|
|
print "You must only run this program on $bonsai_host.";
|
|
exit 1;
|
|
}
|
|
|
|
my $tempdir = tempdir('/tmp/cvsfix-temp-XXXXXXXXX', CLEANUP => 1);
|
|
$::ENV{'CVS_RSH'} = 'ssh';
|
|
my @files = ();
|
|
|
|
sub verify_file {
|
|
my ($cvsroot, $filename, $rev) = @_;
|
|
|
|
chdir $tempdir;
|
|
system("cvs -q -d $cvsroot co -r $rev $filename");
|
|
if (!-e $filename) {
|
|
print "File $filename does not exist.\n";
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
print "--\nNOTICE: you must have ssh agent forwarding enabled with your CVS key\n";
|
|
print "available via your agent for this to work!! You must also have root access\n";
|
|
print "to $cvs_host with a key available to your agent!!\n";
|
|
print "\nPlease enter your email address used for CVS: ";
|
|
my $cvsuser = <STDIN>;
|
|
chomp $cvsuser;
|
|
$cvsuser =~ s/\@/%/;
|
|
my $cvsroot = "$cvsuser\@$cvs_host:$cvsroot_path";
|
|
|
|
my $groups = `ssh $cvs_host groups $cvsuser`;
|
|
if ($groups !~ /\bcvsadm\b/) {
|
|
print "ERROR: The $cvsuser account on $cvs_host is not a member of the cvsadm group.\n";
|
|
print "Aborted.\n";
|
|
exit;
|
|
}
|
|
|
|
sub parse_bonsai_backout_file {
|
|
my $data = $_[0];
|
|
my @lines = split("\n", $data);
|
|
foreach my $line (@lines) {
|
|
if ($line =~ /^cvs update -j(\S+) -j\S+ (\S+)$/) {
|
|
print "$2 rev:$1\n";
|
|
push @files, [$2, $1] if verify_file($cvsroot, $2, $1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (($::ARGV[0]) && ($::ARGV[0] =~ /^http/)) {
|
|
print "--\n";
|
|
my $data = `wget -O- -nv "$::ARGV[0]"`;
|
|
parse_bonsai_backout_file($data);
|
|
}
|
|
elsif (($::ARGV[0]) && (-r $::ARGV[0])) {
|
|
print "--\n";
|
|
open INFILES, "<", $::ARGV[0];
|
|
local $/;
|
|
print "Reading files from $::ARGV[0]...\n";
|
|
my $data = <INFILES>;
|
|
close INFILES;
|
|
parse_bonsai_backout_file($data);
|
|
}
|
|
|
|
if (0 == @files) {
|
|
print <<EOF;
|
|
--
|
|
Enter one filename per line, including the leading 'mozilla'. Enter revision
|
|
numbers as prompted. Hit Enter on a blank line to end. Alternatively, you
|
|
may also enter the URL to the "Show commands which could be used to back out
|
|
these changes" page on Bonsai, listing only the files from this checkin.
|
|
EOF
|
|
print "file: ";
|
|
my $filename = <STDIN>;
|
|
chomp $filename;
|
|
if ($filename =~ /^http/) {
|
|
print "--\n";
|
|
my $data = `wget -O- -nv "$filename"`;
|
|
parse_bonsai_backout_file($data);
|
|
}
|
|
else {
|
|
while ($filename) {
|
|
print "revision: ";
|
|
my $rev = "";
|
|
while (!$rev) {
|
|
$rev = <STDIN>;
|
|
chomp $rev;
|
|
if ($rev !~ /^\d+(\.\d+)+$/) {
|
|
print "Invalid revision.\n";
|
|
$rev = "";
|
|
}
|
|
}
|
|
push @files, [$filename, $rev] if verify_file($cvsroot, $filename, $rev);
|
|
print "file: ";
|
|
$filename = <STDIN>;
|
|
chomp $filename;
|
|
}
|
|
}
|
|
}
|
|
|
|
sub get_log_message {
|
|
my ($cvsroot, $filename, $rev) = @_;
|
|
my $cvslog = `cvs -d $cvsroot log -r$rev $filename`;
|
|
|
|
if ($cvslog !~ /----\nrevision $rev\n/s) {
|
|
print "$filename revision $rev not found.\n";
|
|
exit;
|
|
}
|
|
|
|
$cvslog =~ s/^.*?----\nrevision $rev\n//s;
|
|
$cvslog =~ s/^date.*?\n//s;
|
|
$cvslog =~ s/^branches:\s+\d.*?\n//s;
|
|
$cvslog =~ s/\n=============================================================================\n$//s;
|
|
return $cvslog;
|
|
}
|
|
|
|
my $have_first = 0;
|
|
my $first_log = "";
|
|
print "--\nReading existing commit messages...\n";
|
|
foreach $fileref (@files) {
|
|
my $log = get_log_message($cvsroot, $fileref->[0], $fileref->[1]);
|
|
if (!$have_first) {
|
|
$first_log = $log;
|
|
$have_first = 1;
|
|
}
|
|
else {
|
|
if ($log ne $first_log) {
|
|
print "ERROR: " . $fileref->[0] . " revision " . $fileref->[1] . "\n" .
|
|
"is not part of the same commit. Please only enter files that are\n" .
|
|
"part of the same commit.\n\nAborted.\n";
|
|
print "Original message:\n-----\n$first_log\n-----\nThis file's message:\n-----\n$log\n-----\n";
|
|
print "Tempdir at $tempdir\nPress Enter when done examining: ";
|
|
my $foo = <STDIN>;
|
|
exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
open FILE, ">$tempdir/cvsmsgfix";
|
|
print FILE "$first_log\n";
|
|
print FILE <<EOF;
|
|
CVS: ==================================================================
|
|
CVS: Please edit the log message for
|
|
EOF
|
|
foreach $fileref (@files) {
|
|
print FILE "CVS: " . $fileref->[0] . " rev:" . $fileref->[1] . "\n";
|
|
}
|
|
print FILE <<EOF;
|
|
CVS: Lines begining with CVS: will be ignored.
|
|
CVS: ==================================================================
|
|
EOF
|
|
close FILE;
|
|
|
|
my $editor = "/usr/bin/vim";
|
|
if ($::ENV{'EDITOR'}) {
|
|
$editor = $::ENV{'EDITOR'};
|
|
}
|
|
print "Running external editor on commit message...\n";
|
|
system($editor,"$tempdir/cvsmsgfix");
|
|
|
|
my $logmsg = `cat $tempdir/cvsmsgfix | grep -v ^CVS:`;
|
|
chomp $logmsg;
|
|
|
|
unlink "$tempdir/cvsmsgfix";
|
|
|
|
if ($logmsg eq $first_log) {
|
|
print "You appear to have made no changes. Aborting.\n";
|
|
exit;
|
|
}
|
|
|
|
print "--\nYour revised log message is:\n--------\n$logmsg\n--------\n";
|
|
my $answer = "";
|
|
while ($answer !~ /^[yn]$/i) {
|
|
print "Ready to commit? (y/n) ";
|
|
$answer = <STDIN>;
|
|
chomp $answer;
|
|
}
|
|
|
|
if ($answer =~ /n/i) {
|
|
print "Aborted.\n";
|
|
exit;
|
|
}
|
|
|
|
print "--\nApplying change:\n";
|
|
foreach my $fileref (@files) {
|
|
system("cvs","-d",$cvsroot,"admin","-m" . $fileref->[1] . ":$logmsg\n",$fileref->[0]);
|
|
}
|
|
print "--\nForcing update of local mirrored repository copy for bonsai...\n";
|
|
sleep 1; # give $cvs_host time for kernel buffers to flush? Seems to miss the first couple files if we don't do this.
|
|
foreach my $fileref (@files) {
|
|
system("rsync","-e","ssh","-ai","root\@$cvs_host:$remote_cvs_path/" . $fileref->[0] . ",v","$local_cvs_path/" . $fileref->[0] . ",v");
|
|
}
|
|
print "--\nRebuilding bonsai cvs history:\n";
|
|
chdir "$bonsai_path";
|
|
foreach my $fileref (@files) {
|
|
system("perl","rebuildcvshistory.cgi","default","1970/01/01 00:00:00",$fileref->[0]);
|
|
}
|