#!/usr/local/bin/perl -w # # Copyright (C) 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ # # Track which branches are still open or not in the bind9 cvs repository. # This is done so that work that is "in progress" (active) doesn't get # so easily forgotten about. # # This script updates doc/private/branches by adding new branches and moving # closed branches to the end of the file. New branches are found by walking # the cvs repository and extracting the new branches from the header fields # of the files there. # # doc/private/branches has one line per branch in the following field order: # name, status, to whom the branch belongs and comments. Comments are # in '(',')'. The first three field are single words. # # Note: this is intended to be run on the machine hosting the CVS repository. # %branches = (); %whom = (); %comments = (); %history = (); %dates = (); $repository = "/proj/cvs/prod"; $module = "bind9"; # # Make sure we have a up to date copy. If the previous ran failed for # any reason remove it (-C). # !system("cvs", "-d", $repository, "update", "-C", "doc/private/branches") || die "cannot update doc/private/branches: $!"; # # load existing content # open(BRANCHES, ") { my $branch; my $status; my $who; chomp; next if (/^-/); next if (/^Branch/); next if (/^\s/); $c = ""; if (m://.*:) { $c = $_; $c =~ s:.*?//\s*(.*)$:$1:; s:(.*?)//.*:$1:; } else { # # look for old style comment # if (m/\(.*\)/) { $c = $_; $c =~ s/.*\((.*)\).*$/$1/; s/\(.*\)//; } } s/\s*$//; next if (/^\s*$/); ($branch, $status, $who) = split; $status = "new" if (!defined($status)); $branches{$branch} = $status; $who = "" if (!defined($who)); $whom{$branch} = $who; $comments{$branch} = $c; } close (BRANCHES); # T 1999-03-15 21:15 +0000 vixie bind [ietf44:A] open(HISTORY, "cvs history -T -a 2> /dev/null |") || die("can't get history"); while () { my $tag; my $date; my $time; my $tz; my $who; my $mod; my $branch; chomp; s/[][]//g; s/:[^ \t]+$//; s/\s+/ /g; ($tag, $date, $time, $tz, $who, $mod, $branch) = split; next if ($mod ne $module ); next if ($tag ne "T" ); next if (exists($history{$branch})); $history{$branch} = $who; $dates{$branch} = "$date $time $tz"; # print "$_\n"; } close (HISTORY); # # Search repository for new branches. # # New branches have the following format "name:.0.#" # where # is the number of potential branches from this the revision. # open(FILES, "find $repository/$module -type f -name *,v -print |") || die "can't start find: $!"; while () { chomp; # print "file: $_\n"; # debug # $file = $_; # save for branch debug below. s:^$repository/::; s:/Attic/([^/]*)$:/$1:; s:,v$::; # # use cvs so that the file is locked. # #print "cvs -d $repository rlog -h $_\n"; open(FILE, "cvs -d $repository rlog -h $_|") || die "can't start cvs rlog -h $_: $!"; while () { chomp; next unless m/^symbolic names:$/; # skip until we find the tags while () { chomp; last if (m/^locks;/); # we are past the tags last if (m/^keyword/); # we are past the tags next unless m/\.0\.\d+$/; # skip if not a branch s/\s(.*):.*/$1/; # extract label if (!$branches{$_}) { $branches{$_} = "new"; if (exists($history{$_})) { $whom{$_} = $history{$_}; $comments{$_} = $dates{$_}; } else { $whom{$_} = ""; $comments{$_} = ""; } # print "branch: $_ $file\n"; # debug } } chomp while (); # let cvs rlog exit normally. } close(FILE); } close(FILES); # # Write out updated version. # open(BRANCHES, ">doc/private/newbranches") || die "can't open doc/private/branches: $!"; print BRANCHES "\nBranch\t\t\t\tStatus\tWhom\t// Comments\n"; print BRANCHES "-----------------------------------------------------------\n\n"; print BRANCHES "\t\t\t\tnew\t\tnot yet classified\n"; print BRANCHES "\t\t\t\topen\t\tdevelopement branch\n"; print BRANCHES "\t\t\t\tactive\t\tnot a development branch\n"; print BRANCHES "\t\t\t\treview\t\tready for review\n"; print BRANCHES "\t\t\t\tprivate\t\tprivate branch\n"; print BRANCHES "\t\t\t\tclosed\t\tfinished with\n"; print BRANCHES "\n"; foreach $key (sort keys %branches) { next if ($branches{$key} eq "closed"); print BRANCHES "$key"; $len = length($key); if ($len >= 32) { $tabs = 1; } else { $needed = int (32 - $len); $tabs = int ($needed / 8); if ($needed % 8 != 0) { $tabs++; } } for ($i = 0; $i < $tabs; $i++) { printf BRANCHES "\t"; } print BRANCHES "$branches{$key}\t"; print BRANCHES "$whom{$key}"; print BRANCHES "\t// $comments{$key}" if ($comments{$key} ne ""); print BRANCHES "\n"; } print BRANCHES "\n\n"; foreach $key (sort keys %branches) { next if ($branches{$key} ne "closed"); print BRANCHES "$key"; $len = length($key); if ($len >= 32) { $tabs = 1; } else { $needed = int (32 - $len); $tabs = int ($needed / 8); if ($needed % 8 != 0) { $tabs++; } } for ($i = 0; $i < $tabs; $i++) { printf BRANCHES "\t"; } print BRANCHES "$branches{$key}"; print BRANCHES "\t\t// $comments{$key}" if ($comments{$key} ne ""); print BRANCHES "\n"; } close(BRANCHES); # # Update if changed. # if (system("cmp", "-s", "doc/private/newbranches", "doc/private/branches")) { rename("doc/private/newbranches", "doc/private/branches") || die "Cannot rename: doc/private/newbranches -> doc/private/branches: $!"; !system("cvs", "-d", $repository, "commit", "-m", "auto update", "doc/private/branches") || die "cvs commit failed: $!"; } else { unlink("doc/private/newbranches"); }