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 occured 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";
29
&GetOptions('d=s' => \$dir, 'h=s' => \$hours, 'm=s' => \$module, 'r=s' => \$branch);
31
#print "dir = ($dir), hours = ($hours), module = ($module), branch = ($branch)\n";
38
$hours = get_hours_since_last_update();
45
# pull out the current directory
46
# if there is no such file, this will all just fail, which is ok
47
open REPOSITORY, "<CVS/Repository";
48
$rootdir = <REPOSITORY>;
52
# try to guess the current branch by looking at all the
53
# files in CVS/Entries
57
open ENTRIES, "<CVS/Entries";
61
my ($type, $file, $ver, $date, $unknown, $tag) = @entry;
63
# the tag usually starts with "T"
64
$thisbranch = substr($tag, 1);
66
# look for more than one branch
69
if ($foundbranch and ($lastbranch ne $thisbranch)) {
70
die "Multiple branches in this directory, cannot determine branch\n";
73
$lastbranch = $thisbranch;
78
$branch = $lastbranch if ($foundbranch);
83
# check for a static Tag
84
# (at least that is what I think this does)
85
# (bonsai does not report changes when the Tag starts with 'N')
86
# (I do not really understand all this)
91
print "static tag, ignore branch\n";
98
my $url = "http://bonsai.mozilla.org/cvsquery.cgi?module=${module}&branch=${branch}&branchtype=match&sortby=File&date=hours&hours=${hours}&cvsroot=%2Fcvsroot";
100
my $esc_dir = escape($dir);
102
$url .= "&dir=$esc_dir";
105
print "Contacting bonsai for updates to ${module} ";
106
print "on the ${branch} branch " if ($branch);
107
print "in the last ${hours} hours ";
108
print "within the $rootdir directory..\n" if ($rootdir);
109
#print "url = $url\n";
111
# first try wget, then try lynx, then try curl
113
# this is my lame way of checking if a command succeeded AND getting
114
# output from it. I'd love a better way. -alecf@netscape.com
115
my $have_checkins = 0;
116
open CHECKINS,"wget --quiet --output-document=- \"$url\"|" or
117
die "Error opening wget: $!\n";
119
$header = <CHECKINS> and $have_checkins=1;
121
if (!$have_checkins) {
123
open CHECKINS, "lynx -source '$url'|" or die "Error opening lynx: $!\n";
125
$header = <CHECKINS> and $have_checkins = 1;
128
if (!$have_checkins) {
130
open CHECKINS, "curl -s '$url'|" or die "Error opening curl $!\n";
132
$header = <CHECKINS> and $have_checkins = 1;
135
$have_checkins || die "Couldn't get checkins\n";
137
open REALOUT, ">.fast-update.bonsai.html" || die "argh $!\n";
138
print "Processing checkins...";
142
if (/js_file_menu\((.*),\s*\'(.*)\'\s*,\s*(.*),\s*(.*),\s*(.*),\s*(.*)\)/) {
143
my ($repos, $dir, $file, $rev, $branch, $event) =
144
($1, $2, $3, $4, $5, $6);
151
unlink '.fast-update.bonsai.html';
156
foreach $dir (sort @dirlist) {
157
next if ($lastdir eq $dir);
159
my $strippeddir = "";
162
# now strip out $rootdir
165
# only deal with directories that start with $rootdir
166
if (substr($dir, 0, (length $rootdir)) eq $rootdir) {
168
if ($dir eq $rootdir) {
171
$strippeddir = substr($dir,(length $rootdir) + 1 );
180
push @uniquedirs, $strippeddir;
185
if (scalar(@uniquedirs)) {
186
print "Updating tree..($#uniquedirs directories)\n";
189
foreach $dir (sort @uniquedirs) {
193
$dirlist .= "\"$dir\" ";
196
$status |= spawn("cvs -z3 -q -f up -l -d $dirlist\n");
202
$status |= spawn("cvs -z3 -q -f up -l -d $dirlist\n");
206
print "No directories to update.\n";
211
set_last_update_time($filename, $start_time);
212
print "successfully updated $module/$dir\n";
215
print "error while updating $module/$dir\n";
223
$pdir =~ s|/*[^/]*/*$||;
225
#$pdir =~ s|[^/]*$||;
231
cvs_up_parent($pdir);
233
$status |= system "cvs -z3 -q -f up -d -l $pdir\n";
236
sub get_hours_since_last_update {
237
# get the last time this command was run
238
my $last_time = get_last_update_time($filename);
239
if (!defined($last_time)) {
241
# This must be the first use of fast-update.pl so use the timestamp
243
# 1) is managed by cvs
244
# 2) the user should not be tampering with
245
# 3) that gets updated fairly frequently.
247
$last_time = (stat "CVS/Entries")[9];
248
if (defined($last_time)) {
249
$last_time -= 3600*24; # for safety go back a bit
250
print "use fallback time of ".localtime($last_time)."\n";
253
if(!defined($last_time)) {
254
print "last_time not defined\n";
257
# figure the hours (rounded up) since the last fast-update
258
my $hours = int(($start_time - $last_time + 3600)/3600);
259
print "last updated $hours hour(s) ago at ".localtime($last_time)."\n";
263
# returns time of last update if known
264
sub get_last_update_time {
269
open FILE, "<$filename";
271
if (!defined(line)) {
274
# print "line = $line";
279
sub set_last_update_time {
280
my ($filename, $time) = @_;
281
my $time_str = localtime($time);
282
open FILE, ">$filename";
283
print FILE "$time: last fast-update.pl at ".localtime($time)."\n";
289
$toencode=~s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
295
return system "$procname";