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

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

Works for build files generation wtih filter and variable expansion. Happy ;-)

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