3 # fast-update.pl [-h hours] [-m module] [-r branch]
5 # This command, fast-update.pl, does a (fast) cvs update of the current
6 # directory. It is fast because the cvs up command is only run on those
7 # directories / sub-directories where changes have occurred since the
10 # The last update time is stored in a ".fast-update" file in the current
11 # directory. Thus one can choose to only fast-update a branch of the tree
12 # and then fast-update the whole tree later.
14 # The first time this command is run in a directory the last cvs update
15 # time is assumed to be the timestamp of the CVS/Entries file.
19 my $filename = ".fast-update";
20 my $start_time = time();
23 my $module="SeaMonkeyAll";
30 &GetOptions
('d=s@' => \
@dirs, 'h=s' => \
$hours, 'm=s' => \
$module, 'r=s' => \
$branch, 'l' => \
$dirlocal);
32 #print "dirs = (@dirs), hours = ($hours), module = ($module), branch = ($branch), dirlocal = ($dirlocal)\n";
33 if (scalar(@dirs) > 0) {
34 # put .fast-update in the first directory listed
35 $filename = "$dirs[0]/$filename";
36 $filename =~ s
#mozilla/*##;
40 $hours = get_hours_since_last_update
();
47 # pull out the current directory
48 # if there is no such file, this will all just fail, which is ok
49 open REPOSITORY
, "<CVS/Repository";
50 $rootdir = <REPOSITORY
>;
51 $rootdir =~ tr/\r\n//d; # Remove newlines
54 # try to guess the current branch by looking at all the
55 # files in CVS/Entries
59 open ENTRIES
, "<CVS/Entries";
63 my ($type, $file, $ver, $date, $unknown, $tag) = @entry;
65 # the tag usually starts with "T"
66 $thisbranch = substr($tag, 1);
68 # look for more than one branch
71 if ($foundbranch and ($lastbranch ne $thisbranch)) {
72 die "Multiple branches in this directory, cannot determine branch\n";
75 $lastbranch = $thisbranch;
80 $branch = $lastbranch if ($foundbranch);
85 # check for a static Tag
86 # (at least that is what I think this does)
87 # (bonsai does not report changes when the Tag starts with 'N')
88 # (I do not really understand all this)
93 print "static tag, ignore branch\n";
100 my $url = "http://bonsai.mozilla.org/cvsquery.cgi?module=${module}&branch=${branch}&branchtype=match&sortby=File&date=hours&hours=${hours}&cvsroot=%2Fcvsroot";
103 if (scalar(@dirs) > 0) {
104 $dir_string = join(' ', @dirs);
105 my $esc_dir = escape
($dir_string);
106 $url .= "&dir=$esc_dir";
109 $url .= "&dirtype=local";
112 print "Contacting bonsai for updates to ${module} ";
113 print "on the ${branch} branch " if ($branch);
114 print "in the last ${hours} hours ";
115 print "within the $rootdir directory..\n" if ($rootdir);
116 print "\n" unless ($rootdir);
117 #print "url = $url\n";
119 # first try wget, then try lynx, then try curl
121 # this is my lame way of checking if a command succeeded AND getting
122 # output from it. I'd love a better way. -alecf@netscape.com
123 my $have_checkins = 0;
124 open CHECKINS
,"wget --quiet --output-document=- \"$url\"|" or
125 die "Error opening wget: $!\n";
127 $header = <CHECKINS
> and $have_checkins=1;
129 if (!$have_checkins) {
131 open CHECKINS
, "lynx -source '$url'|" or die "Error opening lynx: $!\n";
133 $header = <CHECKINS
> and $have_checkins = 1;
136 if (!$have_checkins) {
138 open CHECKINS
, "curl -s '$url'|" or die "Error opening curl $!\n";
140 $header = <CHECKINS
> and $have_checkins = 1;
143 $have_checkins || die "Couldn't get checkins\n";
145 open REALOUT
, ">.fast-update.bonsai.html" || die "argh $!\n";
146 print "Processing checkins...";
150 if (/js_file_menu\((.*),\s*\'(.*)\'\s*,\s*(.*),\s*(.*),\s*(.*),\s*(.*)\)/) {
151 my ($repos, $dir, $file, $rev, $branch, $event) =
152 ($1, $2, $3, $4, $5, $6);
153 $dir =~ s/\/Attic$//;
160 unlink '.fast-update.bonsai.html';
165 foreach $dir (sort @dirlist) {
166 next if ($lastdir eq $dir);
168 my $strippeddir = "";
171 # now strip out $rootdir
174 # only deal with directories that start with $rootdir
175 if (substr($dir, 0, (length $rootdir)) eq $rootdir) {
177 if ($dir eq $rootdir) {
180 $strippeddir = substr($dir,(length $rootdir) + 1 );
189 push @uniquedirs, $strippeddir;
194 if (scalar(@uniquedirs)) {
195 print "Updating tree... (" . scalar(@uniquedirs) . " directories)\n";
198 foreach $dir (sort @uniquedirs) {
202 $dirlist .= "\"$dir\" ";
205 $status |= spawn
("cvs -z3 -q -f up -l -d $dirlist\n");
211 $status |= spawn
("cvs -z3 -q -f up -l -d $dirlist\n");
215 print "No directories to update.\n";
220 set_last_update_time
($filename, $start_time);
221 print "successfully updated ";
224 print "error while updating ";
226 if ($module ne "all") {
229 if (scalar(@dirs) > 0) {
239 $pdir =~ s
|/*[^/]*/*$||;
241 #$pdir =~ s|[^/]*$||;
247 cvs_up_parent
($pdir);
249 $status |= system "cvs -z3 -q -f up -d -l $pdir\n";
252 sub get_hours_since_last_update
{
253 # get the last time this command was run
254 my $last_time = get_last_update_time
($filename);
255 if (!defined($last_time)) {
257 # This must be the first use of fast-update.pl so use the timestamp
259 # 1) is managed by cvs
260 # 2) the user should not be tampering with
261 # 3) that gets updated fairly frequently.
263 $last_time = (stat "CVS/Entries")[9];
264 if (defined($last_time)) {
265 $last_time -= 3600*24; # for safety go back a bit
266 print "use fallback time of ".localtime($last_time)."\n";
269 if(!defined($last_time)) {
270 print "last_time not defined\n";
273 # figure the hours (rounded up) since the last fast-update
274 my $hours = int(($start_time - $last_time + 3600)/3600);
275 print "last updated $hours hour(s) ago at ".localtime($last_time)."\n";
279 # returns time of last update if known
280 sub get_last_update_time
{
285 open FILE
, "<$filename";
287 if (!defined(line
)) {
290 # print "line = $line";
295 sub set_last_update_time
{
296 my ($filename, $time) = @_;
297 my $time_str = localtime($time);
298 open FILE
, ">$filename";
299 print FILE
"$time: last fast-update.pl at ".localtime($time)."\n";
305 $toencode=~s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
311 return system "$procname";