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

Last change on this file since 22 was 22, checked in by bruno, 12 years ago

Begin to work on pkg2build
Cope the module Linux::Distribution in the project as it's not packages for my distro
Will make delivery much easier.

  • Property svn:executable set to *
File size: 12.4 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: see at end
11
12use strict 'vars';
13use Getopt::Std;
14use Data::Dumper;
15use English;
16use AppConfig qw(:argcount :expand);
17use File::Basename;
18use Time::localtime qw(localtime);
19use POSIX qw(strftime);
20
21use vars qw (%defpkgdir %extpkgdir %version %confparam %filteredfiles $debug $LOG);
22%extpkgdir = ();
23%filteredfiles = ();
24$debug = 0;                 # Debug level
25$LOG = *STDOUT;             # Where to log
26use lib qw (lib);
27use common qw (env_init);
28use pb qw (pb_init);
29use distro qw (distro_init);
30use cms;
31use changelog qw (changelog);
32
33my %opts;                   # CLI Options
34my $action;                 # action to realize
35my $test = "FALSE";
36my $option = "";
37my @pkgs;
38my $pbtag;                  # Global TAG variable
39my $pbver;                  # Global VERSION variable
40my $pbrev;                  # GLOBAL REVISION variable
41my @date=(localtime->sec(), localtime->min(), localtime->hour(), localtime->mday(), localtime->mon(), localtime->year(), localtime->wday(), localtime->yday(), localtime->isdst());
42my $pbdate = strftime("%Y-%m-%d", @date);
43
44getopts('hl:p:qtv',\%opts);
45
46if (defined $opts{'h'}) {
47    syntax();
48    exit(0);
49}
50if (defined $opts{'v'}) {
51    $debug++;
52}
53if (defined $opts{'q'}) {
54    $debug=-1;
55}
56if (defined $opts{'l'}) {
57    open(LOG,"> $opts{'l'}") || die "Unable to log to $opts{'l'}: $!";
58    $LOG = *LOG;
59    $debug = 0  if ($debug == -1);
60    }
61# Handles project name if any
62if (defined $opts{'p'}) {
63    $ENV{'PBPROJ'} = env_init($opts{'p'});
64} else {
65    $ENV{'PBPROJ'} = env_init();
66}
67# Handles test option
68if (defined $opts{'t'}) {
69    $test = "TRUE";
70    # Works only for SVN
71    $option = "-r BASE";
72}
73
74# Get Action
75$action = shift @ARGV;
76die syntax() if (not defined $action);
77
78print $LOG "Project $ENV{'PBPROJ'}\n" if ($debug >= 0);
79print $LOG "Action: $action\n" if ($debug >= 0);
80
81# Act depending on action
82if ($action =~ /^cms2build$/) {
83    my $ptr = get_pkg();
84    @pkgs = @$ptr;
85    cms_init();
86
87    foreach my $pkg (@pkgs) {
88        if (-f "$ENV{'PBROOT'}/$pkg/VERSION") {
89            open(V,"$ENV{'PBROOT'}/$pkg/VERSION") || die "Unable to open $ENV{'PBROOT'}/$pkg/VERSION";
90            $pbver = <V>;
91            chomp($pbver);
92            close(V);
93        } else {
94            $pbver = $ENV{'PBVER'};
95        }
96
97        if (-f "$ENV{'PBROOT'}/$pkg/TAG") {
98            open(T,"$ENV{'PBROOT'}/$pkg/TAG") || die "Unable to open $ENV{'PBROOT'}/$pkg/TAG";
99            $pbtag = <T>;
100            chomp($pbtag);
101            close(T);
102        } else {
103            $pbtag = $ENV{'PBTAG'};
104        }
105        $pbrev = $ENV{'PBREVISION'};
106        print $LOG "\n" if ($debug >= 0);
107        print $LOG "Management of $pkg $pbver-$pbtag (rev $pbrev)\n" if ($debug >= 0);
108        die "Unable to get env var PBDESTDIR" if (not defined $ENV{'PBDESTDIR'});
109        # Clean up dest if necessary. The export will recreate it
110        my $dest = "$ENV{'PBDESTDIR'}/$pkg-$pbver";
111        pbrm_rf($dest) if (-d $dest);
112
113        # Export CMS tree for the concerned package to dest
114        # And generate some additional files
115        $OUTPUT_AUTOFLUSH=1;
116        print $LOG "$ENV{'PBCMSEXP'} of $pkg..." if ($debug >= 0);
117        # computes in which dir we have to work
118        my $dir = $defpkgdir{$pkg};
119        $dir = $extpkgdir{$pkg} if (not defined $dir);
120        system("$ENV{'PBCMSEXP'} $option $ENV{'PBROOT'}/$dir $dest 1>/dev/null");
121        if ($? == -1) {
122            print $LOG "failed to execute: $!\n" if ($debug >= 0);
123        } elsif ($? & 127) {
124            printf $LOG "child died with signal %d, %s coredump\n", ($? & 127),  ($? & 128) ? 'with' : 'without' if ($debug >= 0);
125        } else {
126            print $LOG " OK\n" if ($debug >= 0);
127        }
128
129        # Creates a REVISION file
130        open(R,"> $dest/REVISION") || die "Unable to create $dest/REVISION";
131        print R "$pbrev\n";
132        close(R);
133
134        # Extract cms log history and store it
135        system("$ENV{'PBCMSLOG'} $option $ENV{'PBROOT'}/$dir > $dest/$ENV{'PBCMSLOGFILE'}");
136        print $LOG "$ENV{'PBCMSLOG'} of $pkg..." if ($debug >= 0);
137        if ($? == -1) {
138            print $LOG "failed to execute: $!\n" if ($debug >= 0);
139        } elsif ($? & 127) {
140            printf $LOG "child died with signal %d, %s coredump\n", ($? & 127),  ($? & 128) ? 'with' : 'without' if ($debug >= 0);
141        } else {
142            print $LOG " OK\n" if ($debug >= 0);
143        }
144        my %build;
145        open(D,"$ENV{'PBCONF'}/DISTROS") || die "Unable to find $ENV{'PBCONF'}/DISTROS\n";
146        while (<D>) {
147            my $d = $_;
148            my ($dir,$ver) = split(/_/,$d);
149            chomp($ver);
150            my ($ddir, $dver, $dfam, $dtype, $dsuf) = distro_init($dir,$ver);
151            print $LOG "DEBUG: distro tuple: ".Dumper($ddir, $dver, $dfam, $dtype, $dsuf)."\n" if ($debug >= 1);
152            print $LOG "DEBUG Filtering PBDATE => $pbdate, PBTAG => $pbtag, PBVER => $pbver\n" if ($debug >= 1);
153
154            # Filter build files from the less precise up to the most with overloading
155            # Filter all files found, keeping the name, and generating in dest
156
157            # Find all build files first relatively to PBROOT
158            my %bfiles;
159            print $LOG "DEBUG dir: $ENV{'PBCONF'}/$pkg\n" if ($debug >= 1);
160            $build{"$ddir-$dver"} = "yes";
161            if (-d "$ENV{'PBCONF'}/$pkg/$dtype") {
162                opendir(BDIR,"$ENV{'PBCONF'}/$pkg/$dtype" || die "Unable to open dir $ENV{'PBCONF'}/$pkg/$dtype: $!");
163                foreach my $f (readdir(BDIR)) {
164                    next if ($f =~ /^\./);
165                    $bfiles{$f} = "$ENV{'PBCONF'}/$pkg/$dtype/$f";
166                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
167                }
168                closedir(BDIR);
169            } elsif (-d "$ENV{'PBCONF'}/$pkg/$dfam") {
170                opendir(BDIR,"$ENV{'PBCONF'}/$pkg/$dfam" || die "Unable to open dir $ENV{'PBCONF'}/$pkg/$dfam: $!");
171                foreach my $f (readdir(BDIR)) {
172                    next if ($f =~ /^\./);
173                    $bfiles{$f} = "$ENV{'PBCONF'}/$pkg/$dfam/$f";
174                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
175                }
176                closedir(BDIR);
177            } elsif (-d "$ENV{'PBCONF'}/$pkg/$ddir") {
178                opendir(BDIR,"$ENV{'PBCONF'}/$pkg/$ddir" || die "Unable to open dir $ENV{'PBCONF'}/$pkg/$ddir: $!");
179                foreach my $f (readdir(BDIR)) {
180                    next if ($f =~ /^\./);
181                    $bfiles{$f} = "$ENV{'PBCONF'}/$pkg/$ddir/$f";
182                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
183                }
184                closedir(BDIR);
185            } elsif (-d "$ENV{'PBCONF'}/$pkg/$ddir-$dver") {
186                opendir(BDIR,"$ENV{'PBCONF'}/$pkg/$ddir-$dver" || die "Unable to open dir $ENV{'PBCONF'}/$pkg/$ddir-$dver: $!");
187                foreach my $f (readdir(BDIR)) {
188                    next if ($f =~ /^\./);
189                    $bfiles{$f} = "$ENV{'PBCONF'}/$pkg/$ddir-$dver/$f";
190                    $bfiles{$f} =~ s~$ENV{'PBROOT'}~~;
191                }
192                closedir(BDIR);
193            } else {
194                $build{"$ddir-$dver"} = "no";
195                next;
196            }
197            print $LOG "DEBUG bfiles: ".Dumper(\%bfiles)."\n" if ($debug >= 1);
198
199            # Get all filters to apply
200            # They're cumulative from less specific to most specific
201            # suffix is .pbf
202            my @ffiles;
203            my ($ffile0, $ffile1, $ffile2, $ffile3);
204            if (-d "$ENV{'PBCONF'}/$pkg/pbfilter") {
205                $ffile0 = "$ENV{'PBCONF'}/$pkg/pbfilter/$dtype.pbf" if (-f "$ENV{'PBCONF'}/$pkg/pbfilter/$dtype.pbf");
206                $ffile1 = "$ENV{'PBCONF'}/$pkg/pbfilter/$dfam.pbf" if (-f "$ENV{'PBCONF'}/$pkg/pbfilter/$dfam.pbf");
207                $ffile2 = "$ENV{'PBCONF'}/$pkg/pbfilter/$ddir.pbf" if (-f "$ENV{'PBCONF'}/$pkg/pbfilter/$ddir.pbf");
208                $ffile3 = "$ENV{'PBCONF'}/$pkg/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBCONF'}/$pkg/pbfilter/$ddir-$dver.pbf");
209                push @ffiles,$ffile0 if (defined $ffile0);
210                push @ffiles,$ffile1 if (defined $ffile1);
211                push @ffiles,$ffile2 if (defined $ffile2);
212                push @ffiles,$ffile3 if (defined $ffile3);
213            }
214            my $config = AppConfig->new({
215                            # Auto Create variables mentioned in Conf file
216                            CREATE => 1,
217                            DEBUG => 0,
218                            GLOBAL => {
219                                # Each conf item is a hash
220                                ARGCOUNT => AppConfig::ARGCOUNT_HASH
221                            }
222                        });
223            my $ptr;
224            if (@ffiles) {
225                print $LOG "DEBUG ffiles: ".Dumper(\@ffiles)."\n" if ($debug >= 1);
226                $config->file(@ffiles);
227                $ptr = $config->get("filter");
228                print $LOG "DEBUG f:".Dumper($ptr)."\n" if ($debug >= 1);
229            } else {
230                $ptr = { };
231            }
232
233            # Apply now all the filters on all the files concerned
234            # All files are relative to PBROOT
235            # destination dir depends on the type of file
236            if (defined $ptr) {
237                foreach my $f (values %bfiles) {
238                    filter_file($f,$ptr,"$dest/pbconf/$ddir-$dver/".basename($f),$pkg,$dtype,$dsuf);
239                }
240                foreach my $f (keys %filteredfiles) {
241                    filter_file($f,$ptr,"$dest/$f",$pkg,$dtype,$dsuf);
242                }
243            }
244        }
245        if ($debug >= 0) {
246            my @found;
247            my @notfound;
248            foreach my $b (keys %build) {
249                push @found,$b if ($build{$b} =~ /yes/);
250                push @notfound,$b if ($build{$b} =~ /no/);
251            }
252            print $LOG "Build files generated for ".join(',',@found)."\n";
253            print $LOG "No Build files found for ".join(',',@notfound)."\n";
254        }
255        close(D);
256        # Prepare the dest directory for archive
257        if (-x "$ENV{'PBCONF'}/$pkg/pbpkginit") {
258            print $LOG " Executing $ENV{'PBCONF'}/$pkg/pbinit...\n" if ($debug >= 0);
259            system("cd $dest ; $ENV{'PBCONF'}/$pkg/pbinit");
260            if ($? == -1) {
261                print $LOG "failed to execute: $!\n" if ($debug >= 0);
262            } elsif ($? & 127) {
263                printf $LOG "child died with signal %d, %s coredump\n", ($? & 127),  ($? & 128) ? 'with' : 'without' if ($debug >= 0);
264            } else {
265                print $LOG " OK\n" if ($debug >= 0);
266            }
267        }
268        # Archive dest dir
269        chdir "$ENV{'PBDESTDIR'}";
270        print $LOG "Creating $pkg tar files (gzip... " if ($debug >= 0);
271        system("tar cfphz $pkg-$pbver.tar.gz $pkg-$pbver");
272        if ($? == -1) {
273            print $LOG "failed to execute: $!\n" if ($debug >= 0);
274        } elsif ($? & 127) {
275            printf $LOG "child died with signal %d, %s coredump\n", ($? & 127),  ($? & 128) ? 'with' : 'without' if ($debug >= 0);
276        } else {
277            print $LOG " OK)\n" if ($debug >= 0);
278            print $LOG "Under $ENV{'PBDESTDIR'}/$pkg-$pbver.tar.gz\n" if ($debug >= 0);
279            # Keep track of what is generated for build2pkg default
280            open(LAST,"> $ENV{'PBDESTDIR'}/LAST") || die "Unable to create $ENV{'PBDESTDIR'}/LAST";
281            print LAST "$pbver-$pbtag\n";
282            close(LAST);
283        }
284    }
285} elsif ($action =~ /^build2pkg$/) {
286    # Check whether we have a specific version to build
287    my $vertag = shift @ARGV;
288    if (not defined $vertag) {
289        open(LAST,"$ENV{'PBDESTDIR'}/LAST") || die "Unable to open $ENV{'PBDESTDIR'}/LAST\nYou may want to precise as parameter version-tag";
290        $vertag = <LAST>;
291        chomp($vertag);
292        close(LAST);
293    }
294    ($pbver,$pbtag) = split(/-/,$vertag);
295
296    # Get list of packages to build
297    my $ptr = get_pkg();
298    @pkgs = @$ptr;
299
300    # Get the running distro to build on
301
302    foreach my $pkg (@pkgs) {
303    }
304} else {
305    print $LOG "'$action' is not available\n";
306    syntax();
307}
308
309# Function which applies filter on files
310sub filter_file {
311
312my $f=shift;
313my $ptr=shift;
314my %filter=%$ptr;
315my $destfile=shift;
316my $pkg=shift;
317my $dtype=shift;
318my $dsuf=shift;
319
320print $LOG "DEBUG: From $f to $destfile\n" if ($debug >= 1);
321pbmkdir_p(dirname($destfile)) if (! -d dirname($destfile));
322open(DEST,"> $destfile") || die "Unable to create $destfile";
323open(FILE,"$ENV{'PBROOT'}/$f") || die "Unable to open $f: $!";
324while (<FILE>) {
325    my $line = $_;
326    foreach my $s (keys %filter) {
327        # Process single variables
328        print $LOG "DEBUG filter{$s}: $filter{$s}\n" if ($debug > 1);
329        my $tmp = $filter{$s};
330        next if (not defined $tmp);
331        # Expand variables if any single one found
332        if ($tmp =~ /\$/) {
333            eval { $tmp =~ s/(\$\w+)/$1/eeg };
334        # special case for ChangeLog
335        } elsif (($tmp =~ /^yes$/) && ($s =~ /^PBLOG$/) && ($line =~ /^PBLOG$/)) {
336            my $p = $defpkgdir{$pkg};
337            $p = $extpkgdir{$pkg} if (not defined $p);
338            changelog($dtype, $pkg, $pbtag, $dsuf, $p, \*DEST);
339            $tmp = "";
340        }
341        $line =~ s|$s|$tmp|;
342    }
343    print DEST $line;
344}
345close(FILE);
346close(DEST);
347}
348
349sub get_pkg {
350
351my @pkgs;
352
353# Get packages list
354if (not defined $ARGV[0]) {
355    @pkgs = keys %defpkgdir;
356} elsif ($ARGV[0] =~ /^all$/) {
357    @pkgs = keys %defpkgdir;
358    if (defined %extpkgdir) {
359        my $k = keys %extpkgdir;
360        if (defined $k) {
361            push(@pkgs, keys %extpkgdir);
362        }
363    }
364} else {
365    @pkgs = @ARGV;
366}
367print $LOG "Packages: ".join(',',@pkgs)."\n" if ($debug >= 0);
368return(\@pkgs);
369}
370
371sub syntax {
372
373    print "Syntax: pb [-vhqt][-p project] <action> [<params>...]\n";
374    print "\n";
375    print "-h : This help file\n";
376    print "-q : Quiet mode\n";
377    print "-t : Test mode (not done yet)\n";
378    print "-v : Verbose mode\n";
379    print "\n";
380    print "-p project : Name of the project you're working on\n";
381    print "             (or use the env variable PBPROJ)     \n";
382    print "\n";
383    print "<action> can be:\n";
384    print "\n";
385    print "\tcms2build: Create a tar file of the project under your CMS\n";
386    print "\t           CMS supported are SVN and CVS\n";
387    print "\t           parameters are packages to build\n";
388    print "\t           if not using default list\n";
389    print "\n";
390    print "\tbuild2pkg: Create packages for your running distribution  \n";
391    print "\t           first parameter is version-tag to build\n";
392    print "\t           if not using default version-tag\n";
393    print "\t           following parameters are packages to build\n";
394    print "\t           if not using default list\n";
395    print "\n";
396    print "\n";
397}
Note: See TracBrowser for help on using the repository browser.