source: devel/pb/bin/pb.pl @ 17

Last change on this file since 17 was 17, checked in by Bruno Cornec, 13 years ago

Still in dev. phase - lots of changes - near the end for cms2build

  • Property svn:executable set to *
File size: 9.2 KB
Line 
1#!/usr/bin/perl -w
2#
3# Project Builder main application
4#
5# $Id$
6#
7# Copyright B. Cornec 2007
8# Provided under the GPL v2
9
10# Syntax: pb [-p project] <action> [<params>...]
11
12use strict;
13use Switch;
14use Getopt::Std;
15use Data::Dumper;
16use English;
17use AppConfig qw(:argcount :expand);
18use File::Basename;
19use Archive::Tar;
20use Time::localtime qw(localtime);
21use POSIX qw(strftime);
22
23use lib qw (lib);
24use vars qw (%defpkgdir %extpkgdir %version %param %filteredfiles);
25use common qw (env_init);
26use pb qw (defpkgdir extpkgdir version param filteredfiles pb_init);
27use distro qw (distro_init);
28use cms;
29use changelog qw (changelog);
30
31my %opts;                   # CLI Options
32my $action;                 # action to realize
33my $test = "FALSE";
34my $option = "";
35my @pkgs;
36my $pbtag;                  # Global TAG variable
37my $pbver;                  # Global VERSION variable
38my $pbrev;                  # GLOBAL REVISION variable
39my @date=(localtime->sec(), localtime->min(), localtime->hour(), localtime->mday(), localtime->mon(), localtime->year(), localtime->wday(), localtime->yday(), localtime->isdst());
40my $pbdate = strftime("%Y-%m-%d", @date);
41
42getopts('p:t',\%opts);
43
44# Handles project name if any
45if (defined $opts{'p'}) {
46    $ENV{'PBPROJ'} = env_init($opts{'p'});
47} else {
48    $ENV{'PBPROJ'} = env_init();
49}
50# Handles test option
51if (defined $opts{'t'}) {
52    $test = "TRUE";
53    # Works only for SVN
54    $option = "-r BASE";
55}
56
57# Get Action
58$action = shift @ARGV;
59die "Syntax: pb [-p project] <action> [<params>...]" if (not defined $action);
60
61print "Project $ENV{'PBPROJ'}\n";
62#print "Action: $action - ARGV:".Dumper(\@ARGV);
63
64# Act depending on action
65if ($action =~ /^cms2build$/) {
66    print "Action: cms2build\n";
67    # Get packages list
68    if (not defined $ARGV[0]) {
69        @pkgs = keys %defpkgdir;
70    } elsif ($ARGV[0] =~ /^all$/) {
71        @pkgs = keys %defpkgdir;
72        push(@pkgs, keys %extpkgdir);
73    } else {
74        @pkgs = @ARGV;
75    }
76    print "Packages:\n";
77    print Dumper(@pkgs);
78    cms_init();
79
80    foreach my $pkg (@pkgs) {
81
82        if (-f "$ENV{'PBROOT'}/$pkg/VERSION") {
83            open(V,"$ENV{'PBROOT'}/$pkg/VERSION") || die "Unable to open $ENV{'PBROOT'}/$pkg/VERSION";
84            $pbver = <V>;
85            chomp($pbver);
86            close(V);
87        } else {
88            $pbver = $ENV{'PBVER'};
89        }
90
91        if (-f "$ENV{'PBROOT'}/$pkg/TAG") {
92            open(T,"$ENV{'PBROOT'}/$pkg/TAG") || die "Unable to open $ENV{'PBROOT'}/$pkg/TAG";
93            $pbtag = <T>;
94            chomp($pbtag);
95            close(T);
96        } else {
97            $pbtag = $ENV{'PBTAG'};
98        }
99        $pbrev = $ENV{'PBREVISION'};
100        print "Management of $pkg $pbver-$pbtag (rev $pbrev)\n";
101        die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
102        # Clean up dest if necessary. The export will recreate it
103        my $dest = "$ENV{'PBDESTDIR'}/$pkg-$pbver";
104        pbrm_rf($dest) if (-d $dest);
105
106        # Export CMS tree for the concerned package to dest
107        # And generate some additional files
108        $OUTPUT_AUTOFLUSH=1;
109        print "$ENV{'PBCMSEXP'} of $pkg...";
110        # computes in which dir we have to work
111        my $dir = $defpkgdir{$pkg};
112        $dir = $extpkgdir{$pkg} if (not defined $dir);
113        system("$ENV{'PBCMSEXP'} $option $ENV{'PBROOT'}/$dir $dest 1>/dev/null");
114        if ($? == -1) {
115            print "failed to execute: $!\n";
116        } elsif ($? & 127) {
117            printf "child died with signal %d, %s coredump\n", ($? & 127),  ($? & 128) ? 'with' : 'without';
118        } else {
119            print " Done under $dest\n";
120        }
121
122        # Creates a REVISION file
123        open(R,"> $dest/REVISION") || die "Unable to create $dest/REVISION";
124        print R "$pbrev\n";
125        close(R);
126
127        # Extract cms log history and store it
128        system("$ENV{'PBCMSLOG'} $option $ENV{'PBROOT'}/$dir > $dest/$ENV{'PBCMSLOGFILE'}");
129        print "$ENV{'PBCMSLOG'} of $pkg...";
130        if ($? == -1) {
131            print "failed to execute: $!\n";
132        } elsif ($? & 127) {
133            printf "child died with signal %d, %s coredump\n", ($? & 127),  ($? & 128) ? 'with' : 'without';
134        } else {
135            print " OK\n";
136        }
137        open(D,"$ENV{'PBCONF'}/DISTROS") || die "Unable to find $ENV{'PBCONF'}/DISTROS\n";
138        while (<D>) {
139            my $d = $_;
140            my ($dir,$ver) = split(/_/,$d);
141            chomp($ver);
142            print "Generating build files for $dir ($ver)\n";
143            my ($ddir, $dver, $dfam, $dtype, $dsuf) = distro_init($dir,$ver);
144            #print Dumper($ddir, $dver, $dfam, $dtype, $dsuf);
145            #print "Filtering DDD => $pbdate, TTT => $pbtag, RRR => $pbtag$dsuf, VVV => $pbver\n";
146
147            # Filter build files from the less precise up to the most with overloading
148            # Filter all files found, keeping the name, and generating in dest
149
150            # Find all build files first relatively to PBROOT
151            my %bfiles;
152            #print "dir: $ENV{'PBCONF'}/$pkg\n";
153            if (-d "$ENV{'PBCONF'}/$pkg/$dtype") {
154                opendir(BDIR,"$ENV{'PBCONF'}/$pkg/$dtype" || die "Unable to open dir $ENV{'PBCONF'}/$pkg/$dtype: $!");
155                foreach my $f (readdir(BDIR)) {
156                    next if ($f =~ /^\./);
157                    $bfiles{$f} = "$ENV{'PBCONF'}/$pkg/$dtype/$f";
158                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
159                }
160                closedir(BDIR);
161            } elsif (-d "$ENV{'PBCONF'}/$pkg/$dfam") {
162                opendir(BDIR,"$ENV{'PBCONF'}/$pkg/$dfam" || die "Unable to open dir $ENV{'PBCONF'}/$pkg/$dfam: $!");
163                foreach my $f (readdir(BDIR)) {
164                    next if ($f =~ /^\./);
165                    $bfiles{$f} = "$ENV{'PBCONF'}/$pkg/$dfam/$f";
166                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
167                }
168                closedir(BDIR);
169            } elsif (-d "$ENV{'PBCONF'}/$pkg/$ddir") {
170                opendir(BDIR,"$ENV{'PBCONF'}/$pkg/$ddir" || die "Unable to open dir $ENV{'PBCONF'}/$pkg/$ddir: $!");
171                foreach my $f (readdir(BDIR)) {
172                    next if ($f =~ /^\./);
173                    $bfiles{$f} = "$ENV{'PBCONF'}/$pkg/$ddir/$f";
174                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
175                }
176                closedir(BDIR);
177            } elsif (-d "$ENV{'PBCONF'}/$pkg/$ddir-$dver") {
178                opendir(BDIR,"$ENV{'PBCONF'}/$pkg/$ddir-$dver" || die "Unable to open dir $ENV{'PBCONF'}/$pkg/$ddir-$dver: $!");
179                foreach my $f (readdir(BDIR)) {
180                    next if ($f =~ /^\./);
181                    $bfiles{$f} = "$ENV{'PBCONF'}/$pkg/$ddir-$dver/$f";
182                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
183                }
184                closedir(BDIR);
185            } else {
186                print "No Build Files found for $ddir-$dver\n";
187                next;
188            }
189            print "bfiles: ".Dumper(\%bfiles)."\n";
190
191            # Get all filters to apply
192            # They're cumulative from less specific to most specific
193            # suffix is .pbf
194            my @ffiles;
195            my ($ffile0, $ffile1, $ffile2, $ffile3);
196            if (-d "$ENV{'PBCONF'}/$pkg/pbfilter") {
197                $ffile0 = "$ENV{'PBCONF'}/$pkg/pbfilter/$dtype.pbf" if (-f "$ENV{'PBCONF'}/$pkg/pbfilter/$dtype.pbf");
198                $ffile1 = "$ENV{'PBCONF'}/$pkg/pbfilter/$dfam.pbf" if (-f "$ENV{'PBCONF'}/$pkg/pbfilter/$dfam.pbf");
199                $ffile2 = "$ENV{'PBCONF'}/$pkg/pbfilter/$ddir.pbf" if (-f "$ENV{'PBCONF'}/$pkg/pbfilter/$ddir.pbf");
200                $ffile3 = "$ENV{'PBCONF'}/$pkg/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBCONF'}/$pkg/pbfilter/$ddir-$dver.pbf");
201                push @ffiles,$ffile0 if (defined $ffile0);
202                push @ffiles,$ffile1 if (defined $ffile1);
203                push @ffiles,$ffile2 if (defined $ffile2);
204                push @ffiles,$ffile3 if (defined $ffile3);
205            }
206            my $config = AppConfig->new({
207                            # Auto Create variables mentioned in Conf file
208                            CREATE => 1,
209                            DEBUG => 0,
210                            GLOBAL => {
211                                # Each conf item is a hash
212                                ARGCOUNT => AppConfig::ARGCOUNT_HASH
213                            }
214                        });
215            print "ffiles: ".Dumper(\@ffiles)."\n";
216            if (@ffiles) {
217                $config->file(@ffiles);
218                my $ptr = $config->get("filter");
219                print "f:".Dumper($ptr)."\n";
220
221                # Apply now all the filters on all the files concerned
222                # All files are relative to PBROOT
223                # destination dir depends on the type of file
224                if (defined $ptr) {
225                    foreach my $f (values %bfiles) {
226                        filter_file($f,$ptr,"$dest/pbconf/$ddir-$dver/".basename($f),$pkg,$dtype,$dsuf);
227                    }
228                    foreach my $f (keys %filteredfiles) {
229                        filter_file($f,$ptr,"$dest/$f",$pkg,$dtype,$dsuf);
230                    }
231                }
232            }
233            # Prepare the dest directory for archive
234            if (-x "$ENV{'PBCONF'}/$pkg/pbpkginit") {
235                system("cd $dest ; $ENV{'PBCONF'}/$pkg/pbinit");
236                if ($? == -1) {
237                    print "failed to execute: $!\n";
238                } elsif ($? & 127) {
239                    printf "child died with signal %d, %s coredump\n", ($? & 127),  ($? & 128) ? 'with' : 'without';
240                } else {
241                    print " $dest\n";
242                }
243            }
244            # Archive dest dir
245            chdir "$dest/..";
246            print "Creating $pkg tar files (gzip... ";
247            system("tar cfphz $pkg-$pbver.tar.gz $pkg-$pbver");
248            if ($? == -1) {
249                print "failed to execute: $!\n";
250            } elsif ($? & 127) {
251                printf "child died with signal %d, %s coredump\n", ($? & 127),  ($? & 128) ? 'with' : 'without';
252            } else {
253                print " OK)\n";
254                print "Under $dest/../$pkg-$pbver.tar.gz\n";
255            }
256        }
257        close(D);
258    }
259} else {
260    print "'$action' is not available\n";
261    print "Available actions are:\n";
262    print "    cms2build\n";
263}
264
265# Function which applies filter on files
266sub filter_file {
267
268my $f=shift;
269my $ptr=shift;
270my %filter=%$ptr;
271my $destfile=shift;
272my $pkg=shift;
273my $dtype=shift;
274my $dsuf=shift;
275
276print "From $f to $destfile\n";
277pbmkdir_p(dirname($destfile)) if (! -d dirname($destfile));
278open(DEST,"> $destfile") || die "Unable to create $destfile";
279open(FILE,"$ENV{'PBROOT'}/$f") || die "Unable to open $f: $!";
280while (<FILE>) {
281    my $line = $_;
282    foreach my $s (keys %filter) {
283        # Process single variables
284        #print "debug: $filter{$s}\n";
285        my $tmp = $filter{$s};
286        next if (not defined $tmp);
287        # Expand variables if any single one found
288        if ($tmp =~ /\$/) {
289            eval { $tmp =~ s/(\$\w+)/$1/eeg };
290        # special case for ChangeLog
291        } elsif (($tmp =~ /^yes$/) && ($s =~ /^PBLOG$/)) {
292            $tmp = changelog($dtype, $pkg, $pbtag, $dsuf, \*DEST);
293        }
294        $line =~ s|$s|$tmp|;
295    }
296    print DEST $line;
297}
298close(FILE);
299close(DEST);
300}
Note: See TracBrowser for help on using the repository browser.