fixing permissions on scripts
[koha.git] / misc / buildrelease
1 #!/usr/bin/perl
2 # This script uses standard 8-space tabs with 4-space indents
3 # vi users can :set sw=4 ai sm
4
5 use Getopt::Long;
6 use vars qw( $verbose_p );
7
8 GetOptions(
9     'verbose|v' => \$verbose_p,
10 ) || exit(1);
11
12 print <<EOM;
13 ***************************************
14 * Welcome to the Koha Release Builder *
15 ***************************************
16 EOM
17
18 #----------------------------------------------------------
19 # To guess the version, we need to first guess where this
20 # script itself is Otherwise we will have different results
21 # depending on whether the script is called as ./buildrelease
22 # or misc/buildrelease. If we run the script from misc, we
23 # will also get errors from "cvs update" later, so this is
24 # rather important information
25 #----------------------------------------------------------
26 print STDERR "Perl reports that buildrelease is $0\n" if $verbose_p;
27 my $self_path;
28 if ($0 =~ /^(\.\/)*buildrelease$/) {
29     $self_path = 'buildrelease';
30 } elsif ($0 =~ /^(?:(\.\/)*\/)?misc\/buildrelease$/) {
31     $self_path = 'misc/buildrelease';
32 } else {
33     print <<EOM;
34
35 WARNING: Unable to determine where the buildrelease script is located.
36          The version number guessed by the next step might be wrong.
37 EOM
38     $self_path = (-f 'buildrelease')? 'buildrelease': 'misc/buildrelease';
39 }
40 print STDERR "Assuming buildrelease is $self_path\n" if $verbose_p;
41
42 #----------------------------------------------------------
43 # Fixup the current directory
44 #----------------------------------------------------------
45 if ($self_path eq 'buildrelease') {
46     print <<EOM;
47
48 WARNING: You should run the buildrelease script from the top of the koha
49          CVS module.  I will try to change to the correct directory, but
50          it is better if you had ran this script there in the first place.
51 EOM
52     chdir ".." || die "..: chdir: $!\n";
53     $self_path = 'misc/buildrelease';
54 }
55
56 #----------------------------------------------------------
57 # Start the release builder
58 #----------------------------------------------------------
59 #sub guess_kohahtmldir ($;$);
60 #----------------------------------------------------------
61 # DIRECTORIES where source code is located
62 #----------------------------------------------------------
63 my $kohadir=`pwd`;
64 chomp $kohadir;
65 #my $kohahtmldir=guess_kohahtmldir($kohadir, "/koha/koha/koha-html/");
66 my $roothomedir=(getpwuid(0))[7];       # ~root is traditionally just /
67 $roothomedir='/root' unless defined $roothomedir;
68
69 my $has_kohaautobuild_conf = 0;
70
71 if (-e "$roothomedir/.kohaautobuild.conf") {
72     print STDERR "$roothomedir/.kohaautobuild.conf found\n" if $verbose_p;
73     open C, "<$roothomedir/.kohaautobuild.conf";
74     while (<C>) {
75         chomp;
76         if (/kohadir=(.*)/) {
77             $kohadir=$1;
78         }
79 #       if (/kohahtmldir=(.*)/) {
80 #           $kohahtmldir=$1;
81 #       }
82     }
83     $has_kohaautobuild_conf = 1;
84 }
85
86 my $input;
87
88 print qq |
89 This script will automatically build a release tarball.
90
91 The script assumes that you already have the koha and koha-html modules checked
92 out for the release that you want to build, although it will update the modules
93 before building.
94 |;
95 print "\nWhere is the 'koha' cvs module located? [$kohadir]: ";
96 chomp($input = <STDIN>);
97 if ($input) {
98     $kohadir=$input;
99 #    unless ($has_kohaautobuild_conf) {
100 #       $kohahtmldir=guess_kohahtmldir($kohadir, $kohahtmldir);
101 #    }
102 }
103
104
105 #print "\nWhere is the 'koha-html' cvs module located [$kohahtmldir]: ";
106 #chomp($input = <STDIN>);
107 #if ($input) {
108 #    $kohahtmldir=$input;
109 #}
110
111 open (C, ">$roothomedir/.kohaautobuild.conf");
112 print C qq|
113 kohadir=$kohadir
114 #kohahtmldir=$kohahtmldir
115 |;
116 print STDERR "$roothomedir/.kohaautobuild.conf written\n" if $verbose_p;
117
118 #----------------------------------------------------------
119 # which VERSION are we building ?
120 #----------------------------------------------------------
121 print <<EOM;
122
123 Guessing the next release version. You may need to enter your SourceForge password.
124 EOM
125 chdir $kohadir;
126 open (CVSLOG, "cvs log $self_path|");
127 my $symbolicnamessection=0;
128 my $symbolicnames;
129 my $highestversion;
130 my $highestrc;
131 my $released;
132 my $majorversion;
133 my $majorversionrc;
134 while (<CVSLOG>) {
135     if (/^symbolic names:/) {
136         $symbolicnamessection=1;
137         print STDERR "Scanning symbolic names from cvs output\n" if $verbose_p;
138     }
139     if ($symbolicnamessection && (/^\s+([^:]*):/)) {
140         my $tag=$1;
141         if ($tag=~/(?:R|rel)_(.*)/) {
142             my $version='';
143             my $rc=0;
144             my $id=$1;
145             $id =~ s/[-_]/\./g;
146             print STDERR "Found a tag for release $id\n" if $verbose_p;
147             if ($id =~/(.*)RC(.*)/) {
148                 $version=$1;
149                 $rc=$2;
150                 $version =~ /^(\d+\.\d+)(?:\.|[RC]|$)/;
151                 if (versioncompare($version, $majorversion->{$1})) {
152                     $majorversion->{$1}=$version;
153                     $majorversionrc->{$1}=$rc;
154                     print STDERR "Setting major version for $1 to $version $rc\n" if $verbose_p;
155                 }
156                 if (versioncompare($version, $highestversion)) {
157                     $highestversion=$version;
158                     $released=0;
159                     $highestrc=$rc;
160                     print STDERR "Setting highest version to $highestversion $highestrc\n" if $verbose_p;
161                 }
162             } else {
163                 $version=$id;
164                 $version =~ /^(\d+\.\d+)(?:\.|[RC]|$)/;
165                 if (versioncompare($version, $majorversion->{$1})) {
166                     $majorversion->{$1}=$version;
167                     $majorversionrc->{$1}=0;
168                     print STDERR "Setting major version for $1 to $version $rc\n" if $verbose_p;
169                 }
170                 if (versioncompare($version, $highestversion)) {
171                     $highestversion=$version;
172                     $released=1;
173                     $highestrc=0;
174                     print STDERR "Setting highest version to $highestversion $highestrc\n" if $verbose_p;
175                 }
176             }
177             $symbolicnames->{$version}->{$rc}=1;
178             print STDERR "Setting symbolic name mapping for version $version $rc to 1\n" if $verbose_p;
179         }
180     }
181 }
182
183 my $releaseversion='';
184 my $currentversion='';
185
186 my $cvs_entries_path = $self_path;
187 $cvs_entries_path =~ s/[^\/]+$/CVS\/Entries/;
188 print STDERR "Assuming CVS/Entries is $cvs_entries_path\n" if $verbose_p;
189
190 my $branchdata=`grep buildrelease $cvs_entries_path`;
191 chomp $branchdata;
192 my $branch=(split(m#/#, $branchdata))[5];
193 $branch =~ s/^T//;
194 $branch =~ s/^(?:R|rel)_//;
195 $branch =~ s/[-_]/./g;
196 print STDERR "Detected branch $branch\n" if $verbose_p;
197
198 if ($branch =~ /\S/ && defined $majorversion->{$branch}) {
199     $highestversion=$majorversion->{$branch};
200     $highestrc=$majorversionrc->{$branch};
201     ($highestrc) ? ($released=0) : ($released=1);
202     print STDERR "Using highest version for branch $branch\n" if $verbose_p;
203 }
204
205 if ($released) {
206     my @components=split(/\./, $highestversion);
207     if (@components < 3) { # if it's something like just 2.2 or 2.4
208         $releaseversion = $highestversion.".1RC1";
209     } else {
210         $components[$#components]++;
211         $nexthighestversion=join '.', @components;
212         my $minornumber=(split(/\./, $highestversion))[1];
213         if ($minornumber/2 == int($minornumber/2)) {
214             $releaseversion=$nexthighestversion."RC1";
215         } else {
216             $releaseversion=$nexthighestversion;
217         }
218     }
219     $currentversion=$highestversion;
220 } else {
221     $releaseversion=$highestversion."RC".($highestrc+1);
222     $currentversion=$highestversion."RC$highestrc";
223 }
224
225
226 print "Current release tag is $currentversion.\n";
227 print "\nWould you like to bump that up to $releaseversion (or manually enter version)?  [Y]/N: ";
228 chomp($input = <STDIN>);
229 my $tagging_needs_confirmation = 0;
230 if ($input =~ /^n/i) {
231     print "\nWould you like to rebuild the $currentversion tarball?  Y/[N]: ";
232     chomp($input = <STDIN>);
233     if ($input =~ /^y/i) {
234         $releaseversion=$currentversion;
235         $tagging_needs_confirmation = 1;
236     } else {
237         print "What should the new version be? [$releaseversion]: ";
238         chomp ($input=<STDIN>);
239         if ($input) {
240             $releaseversion=$input;
241         }
242     }
243 } else {
244     print "What should the new version be? [$releaseversion]: ";
245     chomp ($input=<STDIN>);
246     if ($input) {
247         $releaseversion=$input;
248     }
249 }
250
251
252 print "\nWould you like to tag the CVS repository?\n(answer yes if releasing tarball)  Y/[N]: ";
253 chomp ($input=<STDIN>);
254 my $cvstag=0;
255 if ($input=~/^y/i) {
256     $cvstag=1;
257 }
258 print "The CVS repository ",($cvstag?"WILL BE TAGGED\n":"will not be tagged\n");
259
260
261 if ($cvstag && $tagging_needs_confirmation) {
262         print "\n\n";
263         print "Do not do this if you have released the tarball to anybody, as it will\n";
264         print "overwrite the tag marking the files that were in the tarball:\n\n";
265         print "Confirm that you want to overwrite the tag for $releaseversion? Y/[N]: ";
266         chomp($input = <STDIN>);
267         if ($input =~ /^n/i || $input !~ /\S/) {
268             print "\nStopping.  Please re-run buildrelease now.\n";
269             exit;
270         }
271 }
272
273
274 my $sfuserid='';
275 if ($cvsroot=$ENV{'CVSROOT'}) {
276     $cvsroot=~m#(.*)\@cvs#;
277     $sfuserid=$1;
278 } else {
279     $ENV{'CVS_RSH'}='ssh';
280     print "\nWhat is your userid at SourceForge: ";
281     chomp($input = <STDIN>);
282     if ($input) {
283         $sfuserid=$input;
284     }
285     $ENV{'CVSROOT'}="$sfuserid\@cvs.koha.sourceforge.net:/cvsroot/koha";
286 }
287 my $tagname=$releaseversion;
288 $tagname=~s/\./-/g;
289
290 print qq|
291 Updating your checked-out copy of the 'koha' CVS files.
292 You may need to enter your SourceForge password.
293 Using $kohadir.
294 |;
295 chdir($kohadir) || die "$kohadir: $!\n";
296 # system("cvs update -P");
297 if ($cvstag) {
298     print qq|
299 Tagging koha with tag R_$tagname
300 |;
301     system("cvs tag -F R_$tagname");
302 }
303
304 #----------------------------------------------------------
305 # MOVE files to /tmp and build tar.gz
306 #----------------------------------------------------------
307
308 my $rootdir="/tmp/koha-".$releaseversion;
309 system("rm -rf $rootdir");
310 mkdir ($rootdir, 0700);
311 chdir($rootdir) || die "$rootdir: $!\n";
312
313 mkdir("intranet-cgi", 0755);
314 mkdir("intranet-html", 0755);
315 mkdir("opac-cgi", 0755);
316 mkdir("opac-html", 0755);
317 mkdir("scripts", 0755);
318 mkdir("scripts/z3950daemon", 0755);
319 mkdir("modules", 0755);
320 mkdir("docs", 0755);
321
322 # Create koha.version file
323 open (KV, ">$rootdir/koha.version");
324 print KV "$releaseversion\n";
325 close KV;
326
327 # Copy all CVS files to intranet-cgi
328 # FIXME: "cp -a" is GNU-ism. It is not portable.
329 system("cp -a $kohadir/* $rootdir/intranet-cgi");
330
331 # Move C4 to modules directory
332 system("mv $rootdir/intranet-cgi/C4 $rootdir/modules");
333
334 # Move files from intranet-cgi to root of tarball
335 system("mv $rootdir/intranet-cgi/misc/info/* $rootdir");
336 system("mv $rootdir/intranet-cgi/misc/installer.pl $rootdir");
337 system("mv $rootdir/intranet-cgi/misc/koha.upgrade $rootdir");
338 system("mv $rootdir/intranet-cgi/misc/Install.pm $rootdir");
339 #system("mv $rootdir/intranet-cgi/kohareporter $rootdir"); # does not exist ??
340 chmod 0770, "$rootdir/installer.pl";
341 chmod 0770, "$rootdir/koha.upgrade";
342 system("mv $rootdir/intranet-cgi/misc/koha.conf $rootdir");
343 system("mv $rootdir/intranet-cgi/misc/koha.mysql $rootdir");
344 system("mv $rootdir/intranet-cgi/misc/sampledata-1.2 $rootdir");
345 system("gzip -9 $rootdir/sampledata-1.2");
346
347 # Copy files from intranet-cgi to opac-cgi
348 system("cp $rootdir/intranet-cgi/detail.pl $rootdir/opac-cgi");
349 system("cp $rootdir/intranet-cgi/moredetail.pl $rootdir/opac-cgi");
350 system("cp $rootdir/intranet-cgi/search.pl $rootdir/opac-cgi");
351 system("cp $rootdir/intranet-cgi/subjectsearch.pl $rootdir/opac-cgi");
352 system("cp $rootdir/intranet-cgi/logout.pl $rootdir/opac-cgi");
353 system("mv $rootdir/intranet-cgi/opac/* $rootdir/opac-cgi");
354 system("rmdir $rootdir/intranet-cgi/opac");
355
356
357 # Move files from intranet-cgi to /scripts/ directory
358 system("mv $rootdir/intranet-cgi/updater $rootdir/scripts");
359 system("mv $rootdir/intranet-cgi/misc $rootdir/scripts");
360
361 # move only batch & daemon. pl script stay here
362 system("mv $rootdir/intranet-cgi/z3950/processz3950queue $rootdir/scripts/z3950daemon/");
363 system("mv $rootdir/intranet-cgi/z3950/*.sh $rootdir/scripts/z3950daemon/");
364
365 # Remove extraneous files from intranet-cgi
366 system("rm -f $rootdir/intranet-cgi/ChangeLog.bak");
367 system("rm -f $rootdir/intranet-cgi/SendMessages");
368 system("rm -f $rootdir/intranet-cgi/buildrelease");
369 system("rm -rf $rootdir/intranet-cgi/t");
370
371 # Set all .pl scripts executable
372 system("find $rootdir/intranet-cgi -name '*.pl' -exec chmod a+x \\{\\} \\;");
373 # Copy all CVS files to intranet-html and opac-html
374 # FIXME: "cp -a" is GNU-ism. It is not portable.
375 #system("cp -a $kohahtmldir/intranet-html/* $rootdir/intranet-html");
376 #system("cp -a $kohahtmldir/opac-html/* $rootdir/opac-html");
377
378 # Copy koha-tmpl files
379 # FIXME: "cp -a" is GNU-ism. It is not portable.
380 system('cp', '-a', "$rootdir/intranet-cgi/koha-tmpl/opac-tmpl", "$rootdir/opac-html");
381 system('cp', '-a', "$rootdir/intranet-cgi/koha-tmpl/intranet-tmpl", "$rootdir/intranet-html");
382 #copy index files (they are just redirections to main.pl)
383 system("cp $rootdir/intranet-cgi/koha-tmpl/opac.html $rootdir/opac-html/index.html");
384 system("cp $rootdir/intranet-cgi/koha-tmpl/intranet.html $rootdir/intranet-html/index.html");
385 system('rm', '-rf', "$rootdir/intranet-cgi/koha-tmpl");
386
387 # Remove junk from directory
388 system("find $rootdir -name CVS -exec rm -rf \\{\\} \\; 2>/dev/null");
389 system("find $rootdir -name *~ -exec rm -rf \\{\\} \\; 2>/dev/null");
390 system("find $rootdir -name .#* -exec rm -rf \\{\\} \\; 2>/dev/null");
391
392 chdir("/tmp");
393 system("tar czf /tmp/koha-$releaseversion.tar.gz koha-".$releaseversion);
394 system("rm -rf $rootdir");
395
396 print qq|
397 ============
398 = ALL DONE =
399 ============
400
401 Your new tarball is located in /tmp/koha-$releaseversion.tar.gz
402
403 |;
404
405
406 # Given two version numbers (v1, v2), returns 0 if v1 <= v2, or 1 if v1 > v2
407 sub versioncompare {
408     my $v1=shift;
409     my $v2=shift;
410     my @v1=split(/\./, $v1);
411     my @v2=split(/\./, $v2);
412     my $count=$#v1;
413     ($#v2>$count) && ($count=$#v2);
414     for (my $index=0; $index<$count; $index++) {
415         if ($v1[$index]>$v2[$index]) {
416             return 1;
417         }
418     }
419     return 0;
420 }
421
422 #sub guess_kohahtmldir ($;$) {
423 #    my($kohadir, $default) = @_;
424 #    my $kohahtmldir;
425     # It probably makes sense to assume that the 'koha' and 'koha-html'
426     # modules are checked out within the same parent directory
427 #    if (-d $kohadir && $kohadir =~ /^(.*)\/[^\/]+$/) {
428 #       $kohahtmldir = "$1/koha-html"
429 #    } else {
430 #       $kohahtmldir = $default;
431 #    }
432 #    return $kohahtmldir;
433 #}
434