source: devel/pb/lib/ProjectBuilder/Base.pm @ 322

Last change on this file since 322 was 322, checked in by Bruno Cornec, 12 years ago

Trying to solve the remaining issues for upstream projects with local CMS (begin)

File size: 43.6 KB
Line 
1#!/usr/bin/perl -w
2#
3# Base subroutines for the Project-Builder project
4#
5# $Id$
6#
7
8package ProjectBuilder::Base;
9
10use strict;
11use lib qw (lib);
12use File::Basename;
13use File::Path;
14use File::stat;
15use File::Copy;
16use File::Temp qw(tempdir);
17use Data::Dumper;
18use POSIX qw(strftime);
19use Time::localtime qw(localtime);
20
21use ProjectBuilder::Changelog qw (pb_changelog);
22
23# Inherit from the "Exporter" module which handles exporting functions.
24 
25use Exporter;
26 
27# Export, by default, all the functions into the namespace of
28# any code which uses this module.
29 
30our $debug = 0;
31our $LOG = \*STDOUT;
32
33our @ISA = qw(Exporter);
34our @EXPORT = qw(pb_env_init pb_conf_read pb_conf_read_if pb_conf_get pb_conf_get_if pb_cms_init pb_mkdir_p pb_system pb_rm_rf pb_get_filters pb_filter_file pb_filter_file_pb pb_filter_file_inplace pb_cms_export pb_cms_log pb_cms_isdiff pb_cms_copy pb_cms_checkout pb_get_date pb_log pb_log_init pb_get_pkg $debug $LOG);
35
36$ENV{'PBETC'} = "$ENV{'HOME'}/.pbrc";
37
38sub pb_env_init {
39
40my $proj=shift || undef;
41my $pbinit=shift || undef;
42my $ver;
43my $tag;
44
45#
46# Check project name
47# Could be with env var PBPROJ
48# or option -p
49# if not define take the first in conf file
50#
51if ((defined $ENV{'PBPROJ'}) &&
52    (not (defined $proj))) {
53    $proj = $ENV{'PBPROJ'};
54}
55
56#
57# We get the pbconf file for that project
58# and use its content
59#
60my ($pbconf) = pb_conf_read("$ENV{'PBETC'}","pbconfurl");
61pb_log(2,"DEBUG pbconfurl: ".Dumper($pbconf)."\n");
62
63my %pbconf = %$pbconf;
64if (not defined $proj) {
65    # Take the first as the default project
66    $proj = (keys %pbconf)[0];
67    if (defined $proj) {
68        pb_log(0,"WARNING: using $proj as default project as none has been specified\n");
69        pb_log(0,"         Please either create a pbconfurl reference for project $proj in $ENV{'PBETC'}\n");
70        pb_log(0,"         or call pb with the -p project option or use the env var PBPROJ\n");
71        pb_log(0,"         if you want to use another project\n");
72    }
73}
74die "No project defined - use env var PBPROJ or -p proj or a pbconfurl entry in $ENV{'PBETC'}" if (not (defined $proj));
75
76# That's always the environment variable that will be used
77$ENV{'PBPROJ'} = $proj;
78pb_log(2,"PBPROJ: $ENV{'PBPROJ'}\n");
79
80if (not defined ($pbconf{$ENV{'PBPROJ'}})) {
81    die "Please create a pbconfurl reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n";
82}
83
84#
85# Detect the root dir for hosting all the content generated with pb
86#
87# Tree will look like this:
88#
89#             maint pbdefdir                         PBDEFDIR            dev dir (optional)   PBDEVDIR
90#                  |                                                        |
91#            ------------------------                                --------------------
92#            |                      |                                |                  |
93#         pbproj1                pbproj2             PBPROJ       pbproj1           pbproj2   PBDEVPROJ
94#            |                                                       |
95#  ---------------------------------------------                ----------
96#  *      *        *       |        |          |                *        *
97# 1.0    dev    pbconf    ...     build     delivery PBCONF    dev      tag                   PBDEVROOT
98#                  |                           |     PBDESTDIR           |
99#               ------                        pbrc   PBBUILDDIR       -------
100#               |    |                                                |     |
101#              dev  tag                              PBROOT          1.0   1.1
102#                    |
103#                 -------
104#                 |     |
105#                1.0   1.1
106#                       |
107#               ----------------------------------
108#               |          |           |         |
109#             pkg1      pbproj1.pb   pbfilter   pbcl
110#               |
111#        -----------------
112#        |      |        |
113#       rpm    deb    pbfilter
114#
115#
116# (*) By default, if no relocation in .pbrc, dev dir is taken in the maint pbdefdir (when appropriate)
117# Names under a pbproj and the corresponding pbconf should be similar
118#
119
120my ($pbdefdir) = pb_conf_get_if("pbdefdir");
121my %pbdefdir = %$pbdefdir;
122
123if (not defined $ENV{'PBDEFDIR'}) {
124    if ((not defined $pbdefdir) || (not defined $pbdefdir{$ENV{'PBPROJ'}})) {
125        pb_log(0,"WARNING: no pbdefdir defined, using /var/cache\n");
126        pb_log(0,"         Please create a pbdefdir reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
127        pb_log(0,"         if you want to use another directory\n");
128        $ENV{'PBDEFDIR'} = "/var/cache";
129    } else {
130        # That's always the environment variable that will be used
131        $ENV{'PBDEFDIR'} = $pbdefdir{$ENV{'PBPROJ'}};
132    }
133}
134# Expand potential env variable in it
135eval { $ENV{'PBDEFDIR'} =~ s/(\$ENV.+\})/$1/eeg };
136
137pb_log(2,"PBDEFDIR: $ENV{'PBDEFDIR'}\n");
138#
139# Set delivery directory
140#
141$ENV{'PBDESTDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/delivery";
142
143pb_log(2,"PBDESTDIR: $ENV{'PBDESTDIR'}\n");
144#
145# Removes all directory existing below the delivery dir
146# as they are temp dir only
147# Files stay and have to be cleaned up manually if needed
148# those files serves as communication channels between pb phases
149# Removing them prevents a following phase to detect what has been done before
150#
151if (-d $ENV{'PBDESTDIR'}) {
152    opendir(DIR,$ENV{'PBDESTDIR'}) || die "Unable to open directory $ENV{'PBDESTDIR'}: $!";
153    foreach my $d (readdir(DIR)) {
154        next if ($d =~ /^\./);
155        next if (-f "$ENV{'PBDESTDIR'}/$d");
156        pb_rm_rf("$ENV{'PBDESTDIR'}/$d") if (-d "$ENV{'PBDESTDIR'}/$d");
157    }
158    closedir(DIR);
159}
160if (! -d "$ENV{'PBDESTDIR'}") {
161    pb_mkdir_p($ENV{'PBDESTDIR'}) || die "Unable to recursively create $ENV{'PBDESTDIR'}";
162}
163
164#
165# Set build directory
166#
167$ENV{'PBBUILDDIR'}="$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/build";
168if (! -d "$ENV{'PBBUILDDIR'}") {
169    pb_mkdir_p($ENV{'PBBUILDDIR'}) || die "Unable to recursively create $ENV{'PBBUILDDIR'}";
170}
171
172pb_log(2,"PBBUILDDIR: $ENV{'PBBUILDDIR'}\n");
173#
174# Set temp directory
175#
176if (not defined $ENV{'TMPDIR'}) {
177    $ENV{'TMPDIR'}="/tmp";
178}
179$ENV{'PBTMP'} = tempdir( "pb.XXXXXXXXXX", DIR => $ENV{'TMPDIR'}, CLEANUP => 1 );
180pb_log(2,"PBTMP: $ENV{'PBTMP'}\n");
181
182#
183# The following part is only useful when in cms2build
184# In VMs/VEs we want to skip that by providing a good PBCONF env var.
185# return values in that case are useless
186#
187return if (defined $ENV{'PBCONF'});
188
189#
190# Check pbconf compliance
191#
192my ($pbconfdir) = pb_conf_get_if("pbconfdir");
193my %pbconfdir = %$pbconfdir;
194
195if ((defined $pbconfdir) && (defined $pbconfdir{$ENV{'PBPROJ'}})) {
196    # That's always the environment variable that will be used
197    $ENV{'PBCONF'} = $pbconfdir{$ENV{'PBPROJ'}};
198} else {
199    pb_log(0,"WARNING: no pbconfdir defined, using $ENV{'PBDIR'}/$ENV{'PBPROJ'}/pbconf\n");
200    pb_log(0,"         Please create a pbconfdir reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
201    pb_log(0,"         if you want to use another directory\n");
202    $ENV{'PBCONF'} = "$ENV{'PBDIR'}/$ENV{'PBPROJ'}/pbconf";
203}
204pb_log(2,"PBCONF: $ENV{'PBCONF'}\n");
205
206my ($scheme, $account, $host, $port, $path) = pb_get_uri($pbconf{$ENV{'PBPROJ'}});
207
208if ((! -d "$ENV{'PBCONF'}") || (defined $pbinit)) {
209    pb_log(1,"Checking out pbconf\n");
210    pb_cms_checkout($scheme,$pbconf{$ENV{'PBPROJ'}},$ENV{'PBCONF'});
211} else {
212    pb_log(1,"pbconf found, checking content\n");
213    my $cmsurl = pb_cms_getinfo($scheme,$ENV{'PBCONF'},"URL:");
214    my ($scheme2, $account2, $host2, $port2, $path2) = pb_get_uri($cmsurl);
215    if ($scheme2 ne $scheme) {
216        pb_log(1,"WARNING: Content of $ENV{'PBCONF'} irrelevant, cleaning up and checking it out\n");
217        pb_rm_rf("$ENV{'PBCONF'}");
218        pb_cms_checkout($scheme,$pbconf{$ENV{'PBPROJ'}},$ENV{'PBCONF'});
219    } elsif ($cmsurl ne $pbconf{$ENV{'PBPROJ'}}) {
220        # The local content doesn't correpond to the repository
221        pb_log(0,"ERROR: Inconsistency detected:\n");
222        pb_log(0,"       * $ENV{'PBCONF'} refers to $cmsurl but\n");
223        pb_log(0,"       * $ENV{'PBETC'} refers to $pbconf{$ENV{'PBPROJ'}}\n");
224        die "Project $ENV{'PBPROJ'} is not Project-Builder compliant.";
225    } else {
226        pb_log(1,"Content correct - doing nothing - you may want to update your repository however\n");
227        # they match - do nothing - there may be local changes
228    }
229}
230
231# Check where is our PBROOT (release tag name can't be guessed the first time)
232if (not defined $ENV{'PBROOT'}) {
233    if (! -f ("$ENV{'PBDESTDIR'}/pbrc")) {
234        opendir(DIR,$ENV{'PBCONF'}) || die "Unable to open directory $ENV{'PBCONF'}: $!";
235        my $maxmtime = 0;
236        foreach my $d (readdir(DIR)) {
237            pb_log(3,"Looking at \'$d\'...");
238            next if ($d =~ /^\./);
239            next if (! -d "$ENV{'PBCONF'}/$d");
240            my $s = stat("$ENV{'PBCONF'}/$d");
241            next if (not defined $s);
242            pb_log(3,"KEEP\n");
243            # Keep the most recent
244            pb_log(2," $s->mtime\n");
245            if ($s->mtime > $maxmtime) {
246                $ENV{'PBROOT'} = "$ENV{'PBCONF'}/$d";
247                $maxmtime = $s->mtime;
248            }
249        }
250        closedir(DIR);
251        die "No directory found under $ENV{'PBCONF'}" if (not defined $ENV{'PBROOT'});
252        pb_log(0,"WARNING: no pbroot defined, using $ENV{'PBROOT'}\n");
253        pb_log(0,"         Please use -r release if you want to use another release\n");
254    } else {
255        my ($pbroot) = pb_conf_read_if("$ENV{'PBDESTDIR'}/pbrc","pbroot");
256        # That's always the environment variable that will be used
257        die "Please remove inconsistent $ENV{'PBDESTDIR'}/pbrc" if ((not defined $pbroot) || (not defined $pbroot->{$ENV{'PBPROJ'}}));
258        $ENV{'PBROOT'} = $pbroot->{$ENV{'PBPROJ'}};
259    }
260} else {
261    # transform in full path if relative
262    $ENV{'PBROOT'} = "$ENV{'PBCONF'}/$ENV{'PBROOT'}" if ($ENV{'PBROOT'} !~ /^\//);
263    die "$ENV{'PBROOT'} is not a directory" if (not -d $ENV{'PBROOT'});
264}
265
266my %version = ();
267my %defpkgdir = ();
268my %extpkgdir = ();
269my %filteredfiles = ();
270my %supfiles = ();
271
272if ((-f "$ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb") and (not defined $pbinit)) {
273    # List of pkg to build by default (mandatory)
274    my ($defpkgdir,$pbpackager) = pb_conf_get("defpkgdir","pbpackager");
275    # List of additional pkg to build when all is called (optional)
276    # Valid version names (optional)
277    # List of files to filter (optional)
278    # Project version and tag (optional)
279    my ($extpkgdir, $version, $filteredfiles, $supfiles, $pkgv, $pkgt) = pb_conf_get_if("extpkgdir","version","filteredfiles","supfiles","projver","projtag");
280    pb_log(2,"DEBUG: defpkgdir: ".Dumper($defpkgdir)."\n");
281    pb_log(2,"DEBUG: extpkgdir: ".Dumper($extpkgdir)."\n");
282    pb_log(2,"DEBUG: version: ".Dumper($version)."\n");
283    pb_log(2,"DEBUG: filteredfiles: ".Dumper($filteredfiles)."\n");
284    pb_log(2,"DEBUG: supfiles: ".Dumper($supfiles)."\n");
285    # Global
286    %defpkgdir = %$defpkgdir;
287    %extpkgdir = %$extpkgdir if (defined $extpkgdir);
288    %version = %$version if (defined $version);
289    %filteredfiles = %$filteredfiles if (defined $filteredfiles);
290    %supfiles = %$supfiles if (defined $supfiles);
291    #
292    # Get global Version/Tag
293    #
294    if (not defined $ENV{'PBVER'}) {
295        if ((defined $pkgv) && (defined $pkgv->{$ENV{'PBPROJ'}})) {
296            $ENV{'PBVER'}=$pkgv->{$ENV{'PBPROJ'}};
297        } else {
298            die "No projver found in $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb";
299        }
300    }
301    die "Invalid version name $ENV{'PBVER'} in $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb" if (($ENV{'PBVER'} !~ /[0-9.]+/) && (not defined $version) && ($ENV{'PBVER'} =~ /$version{$ENV{'PBPROJ'}}/));
302   
303    if (not defined $ENV{'PBTAG'}) {
304        if ((defined $pkgt) && (defined $pkgt->{$ENV{'PBPROJ'}})) {
305            $ENV{'PBTAG'}=$pkgt->{$ENV{'PBPROJ'}};
306        } else {
307            die "No projtag found in $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb";
308        }
309    }
310    die "Invalid tag name $ENV{'PBTAG'} in $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb" if ($ENV{'PBTAG'} !~ /[0-9.]+/);
311
312
313    if (not defined $ENV{'PBPACKAGER'}) {
314        if ((defined $pbpackager) && (defined $pbpackager->{$ENV{'PBPROJ'}})) {
315            $ENV{'PBPACKAGER'}=$pbpackager->{$ENV{'PBPROJ'}};
316        } else {
317            die "No pbpackager found in $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb";
318        }
319    }
320} else {
321    if (defined $pbinit) {
322        my $ptr = pb_get_pkg();
323        my @pkgs = @$ptr;
324        @pkgs = ("pkg1") if (not @pkgs);
325
326        open(CONF,"> $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb") || die "Unable to create $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb";
327        print CONF << "EOF";
328#
329# Project Builder configuration file
330# For project $ENV{'PBPROJ'}
331#
332# \$Id\$
333#
334
335#
336# What is the project URL
337#
338#pbproj $ENV{'PBPROJ'} = svn://svn.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
339#pbproj $ENV{'PBPROJ'} = svn://svn+ssh.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
340#pbproj $ENV{'PBPROJ'} = cvs://cvs.$ENV{'PBPROJ'}.org/$ENV{'PBPROJ'}/devel
341#pbproj $ENV{'PBPROJ'} = http://www.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
342#pbproj $ENV{'PBPROJ'} = ftp://ftp.$ENV{'PBPROJ'}.org/src/$ENV{'PBPROJ'}-devel.tar.gz
343#pbproj $ENV{'PBPROJ'} = file:///src/$ENV{'PBPROJ'}-devel.tar.gz
344#pbproj $ENV{'PBPROJ'} = dir:///src/$ENV{'PBPROJ'}-devel
345
346#
347# Packager label
348#
349#pbpackager $ENV{'PBPROJ'} = "William Porte <bill\@$ENV{'PBPROJ'}.org>"
350#
351
352# For delivery to a machine by SSH (potentially the FTP server)
353# Needs hostname, account and directory
354#
355#sshhost $ENV{'PBPROJ'} = www.$ENV{'PBPROJ'}.org
356#sshlogin $ENV{'PBPROJ'} = bill
357#sshdir $ENV{'PBPROJ'} = /$ENV{'PBPROJ'}/ftp
358#sshport $ENV{'PBPROJ'} = 22
359
360#
361# For Virtual machines management
362# Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
363# followed by '_' and by release number
364# a .vmtype extension will be added to the resulting string
365# a QEMU rhel_3 here means that the VM will be named rhel_3.qemu
366#
367#vmlist $ENV{'PBPROJ'} = mandrake_10.1,mandrake_10.2,mandriva_2006.0,mandriva_2007.0,mandriva_2007.1,mandriva_2008.0,redhat_7.3,redhat_9,fedora_4,fedora_5,fedora_6,fedora_7,rhel_3,rhel_4,rhel_5,suse_10.0,suse_10.1,suse_10.2,suse_10.3,sles_9,sles_10,gentoo_nover,debian_3.1,debian_4.0,ubuntu_6.06,ubuntu_7.04,ubuntu_7.10
368
369#
370# Valid values for vmtype are
371# qemu, (vmware, xen, ... TBD)
372#vmtype $ENV{'PBPROJ'} = qemu
373
374# Hash for VM stuff on vmtype
375#vmntp default = pool.ntp.org
376
377# We suppose we can commmunicate with the VM through SSH
378#vmhost $ENV{'PBPROJ'} = localhost
379#vmlogin $ENV{'PBPROJ'} = pb
380#vmport $ENV{'PBPROJ'} = 2222
381
382# Timeout to wait when VM is launched/stopped
383#vmtmout default = 120
384
385# per VMs needed paramaters
386#vmopt $ENV{'PBPROJ'} = -m 384 -daemonize
387#vmpath $ENV{'PBPROJ'} = /home/qemu
388#vmsize $ENV{'PBPROJ'} = 5G
389
390#
391# Global version/tag for the project
392#
393#projver $ENV{'PBPROJ'} = devel
394#projtag $ENV{'PBPROJ'} = 1
395
396# Hash of valid version names
397#version $ENV{'PBPROJ'} = devel,stable
398
399# Adapt to your needs:
400# Optional if you need to overwrite the global values above
401#
402EOF
403       
404        foreach my $pp (@pkgs) {
405            print CONF << "EOF";
406#pkgver $pp = stable
407#pkgtag $pp = 3
408EOF
409        }
410        foreach my $pp (@pkgs) {
411            print CONF << "EOF";
412# Hash of default package/package directory
413#defpkgdir $pp = dir-$pp
414EOF
415        }
416
417        print CONF << "EOF";
418# Hash of additional package/package directory
419#extpkgdir minor-pkg = dir-minor-pkg
420
421# List of files per pkg on which to apply filters
422# Files are mentioned relatively to pbroot/defpkgdir
423EOF
424        foreach my $pp (@pkgs) {
425            print CONF << "EOF";
426#filteredfiles $pp = Makefile.PL,configure.in,install.sh,$pp.8
427#supfiles $pp = $pp.init
428EOF
429        }
430        close(CONF);
431        pb_mkdir_p("$ENV{'PBROOT'}/pbfilter") || die "Unable to create $ENV{'PBROOT'}/pbfilter";
432        open(CONF,"> $ENV{'PBROOT'}/pbfilter/all.pbf") || die "Unable to create $ENV{'PBROOT'}/pbfilter/all.pbf";
433        print CONF << "EOF";
434#
435# \$Id\$
436#
437# Filter for all files
438#
439# PBSRC is replaced by the source package format
440#filter PBSRC = ftp://ftp.$ENV{'PBPROJ'}.org/src/%{name}-%{version}.tar.gz
441
442# PBVER is replaced by the version (\$pbver in code)
443#filter PBVER = \$pbver
444
445# PBDATE is replaced by the date (\$pbdate in code)
446#filter PBDATE = \$pbdate
447
448# PBLOG is replaced by the changelog if value is yes
449#filter PBLOG = yes
450
451# PBTAG is replaced by the tag (\$pbtag in code)
452#filter PBTAG = \$pbtag
453
454# PBREV is replaced by the revision (\$pbrev in code)
455#filter PBREV = \$pbrev
456
457# PBPKG is replaced by the package name (\$pbpkg in code)
458#filter PBPKG = \$pbpkg
459
460# PBPACKAGER is replaced by the packager name (\$pbpackager in code)
461#filter PBPACKAGER = \$pbpackager
462
463# PBDESC contains the description of the package
464#filter PBDESC = "Bla-Bla"
465
466# PBURL contains the URL of the Web site of the project
467#filter PBURL = http://www.$ENV{'PBPROJ'}.org
468EOF
469        close(CONF);
470        open(CONF,"> $ENV{'PBROOT'}/pbfilter/rpm.pbf") || die "Unable to create $ENV{'PBROOT'}/pbfilter/rpm.pbf";
471        print CONF << "EOF";
472#
473# \$Id\$
474#
475# Filter for rpm build
476#
477
478# PBGRP is replaced by the RPM group of apps
479# Cf: http://fedoraproject.org/wiki/RPMGroups
480#filter PBGRP = Applications/Archiving
481
482# PBLIC is replaced by the license of the application
483# Cf: http://fedoraproject.org/wiki/Licensing
484#filter PBLIC = GPL
485
486# PBDEP is replaced by the list of dependencies
487#filter PBDEP =
488
489# PBSUF is replaced by the package name (\$pbpkg in code)
490#filter PBSUF = \$pbsuf
491
492# PBOBS is replaced by the Obsolete line
493#filter PBOBS =
494
495EOF
496        close(CONF);
497        open(CONF,"> $ENV{'PBROOT'}/pbfilter/deb.pbf") || die "Unable to create $ENV{'PBROOT'}/pbfilter/deb.pbf";
498        print CONF << "EOF";
499#
500# \$Id\$
501#
502# Filter for debian build
503#
504# PBGRP is replaced by the group of apps
505#filter PBGRP = utils
506
507# PBLIC is replaced by the license of the application
508# Cf:
509#filter PBLIC = GPL
510
511# PBVER is replaced by the version (\$pbver in code)
512#filter PBVER = \$pbver
513
514# PBDEP is replaced by the list of dependencies
515#filter PBDEP =
516
517# PBSUG is replaced by the list of suggestions
518#filter PBSUG =
519
520# PBREC is replaced by the list of recommandations
521#filter PBREC =
522
523# PBLOG is replaced by the changelog if value is yes
524#filter PBLOG = yes
525
526# PBPKG is replaced by the package name (\$pbpkg in code)
527#filter PBPKG = \$pbpkg
528
529# PBPACKAGER is replaced by the packager name (\$pbpackager in code)
530#filter PBPACKAGER = \$pbpackager
531
532EOF
533        close(CONF);
534        open(CONF,"> $ENV{'PBROOT'}/pbfilter/md.pbf") || die "Unable to create $ENV{'PBROOT'}/pbfilter/md.pbf";
535        print CONF << "EOF";
536# Specific group for Mandriva for $ENV{'PBPROJ'}
537# Cf: http://wiki.mandriva.com/en/Development/Packaging/Groups
538filter PBGRP = Archiving/Backup
539
540# PBLIC is replaced by the license of the application
541# Cf: http://wiki.mandriva.com/en/Development/Packaging/Licenses
542#filter PBLIC = GPL
543
544EOF
545        close(CONF);
546        open(CONF,"> $ENV{'PBROOT'}/pbfilter/novell.pbf") || die "Unable to create $ENV{'PBROOT'}/pbfilter/novell.pbf";
547        print CONF << "EOF";
548# Specific group for SuSE for $ENV{'PBPROJ'}
549# Cf: http://en.opensuse.org/SUSE_Package_Conventions/RPM_Groups
550filter PBGRP = Productivity/Archiving/Backup
551
552# PBLIC is replaced by the license of the application
553# Cf: http://en.opensuse.org/Packaging/SUSE_Package_Conventions/RPM_Style#1.6._License_Tag
554#filter PBLIC = GPL
555
556EOF
557        close(CONF);
558        foreach my $pp (@pkgs) {
559            pb_mkdir_p("$ENV{'PBROOT'}/$pp/deb") || die "Unable to create $ENV{'PBROOT'}/$pp/deb";
560            open(CONF,"> $ENV{'PBROOT'}/$pp/deb/control") || die "Unable to create $ENV{'PBROOT'}/$pp/deb/control";
561            print CONF << "EOF";
562Source: PBPKG
563Section: PBGRP
564Priority: optional
565Maintainer: PBPACKAGER
566Build-Depends: debhelper (>= 4.2.20), PBDEP
567Standards-Version: 3.6.1
568
569Package: PBPKG
570Architecture: amd64 i386 ia64
571Section: PBGRP
572Priority: optional
573Depends: \${shlibs:Depends}, \${misc:Depends}, PBDEP
574Recommends: PBREC
575Suggests: PBSUG
576Description:
577 PBDESC
578 .
579 Homepage: PBURL
580
581EOF
582            close(CONF);
583            open(CONF,"> $ENV{'PBROOT'}/$pp/deb/copyright") || die "Unable to create $ENV{'PBROOT'}/$pp/deb/copyright";
584            print CONF << "EOF";
585This package is debianized by PBPACKAGER
586`date`
587
588The current upstream source was downloaded from
589ftp://ftp.$ENV{'PBPROJ'}.org/src/.
590
591Upstream Authors: Put their name here
592
593Copyright:
594
595   This package is free software; you can redistribute it and/or modify
596   it under the terms of the GNU General Public License as published by
597   the Free Software Foundation; version 2 dated June, 1991.
598
599   This package is distributed in the hope that it will be useful,
600   but WITHOUT ANY WARRANTY; without even the implied warranty of
601   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
602   GNU General Public License for more details.
603
604   You should have received a copy of the GNU General Public License
605   along with this package; if not, write to the Free Software
606   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
607   MA 02110-1301, USA.
608
609On Debian systems, the complete text of the GNU General
610Public License can be found in /usr/share/common-licenses/GPL.
611
612EOF
613            close(CONF);
614            open(CONF,"> $ENV{'PBROOT'}/$pp/deb/changelog") || die "Unable to create $ENV{'PBROOT'}/$pp/deb/changelog";
615            print CONF << "EOF";
616PBLOG
617EOF
618            close(CONF);
619            open(CONF,"> $ENV{'PBROOT'}/$pp/deb/compat") || die "Unable to create $ENV{'PBROOT'}/$pp/deb/compat";
620            print CONF << "EOF";
6214
622EOF
623            close(CONF);
624            open(CONF,"> $ENV{'PBROOT'}/$pp/deb/pkg1.dirs") || die "Unable to create $ENV{'PBROOT'}/$pp/deb/$pp.dirs";
625            print CONF << "EOF";
626EOF
627            close(CONF);
628            open(CONF,"> $ENV{'PBROOT'}/$pp/deb/$pp.docs") || die "Unable to create $ENV{'PBROOT'}/$pp/deb/$pp.docs";
629            print CONF << "EOF";
630INSTALL
631COPYING
632AUTHORS
633NEWS
634README
635EOF
636            close(CONF);
637            open(CONF,"> $ENV{'PBROOT'}/$pp/deb/rules") || die "Unable to create $ENV{'PBROOT'}/$pp/deb/rules";
638            print CONF << 'EOF';
639#!/usr/bin/make -f
640# -*- makefile -*-
641# Sample debian/rules that uses debhelper.
642# GNU copyright 1997 to 1999 by Joey Hess.
643#
644# $Id$
645#
646
647# Uncomment this to turn on verbose mode.
648#export DH_VERBOSE=1
649
650# Define package name variable for a one-stop change.
651PACKAGE_NAME = PBPKG
652
653# These are used for cross-compiling and for saving the configure script
654# from having to guess our platform (since we know it already)
655DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
656DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
657
658CFLAGS = -Wall -g
659
660ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
661        CFLAGS += -O0
662else
663        CFLAGS += -O2
664endif
665ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
666        INSTALL_PROGRAM += -s
667endif
668config.status: configure
669        dh_testdir
670
671        # Configure the package.
672        CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr
673 --mandir=\$${prefix}/share/man
674
675# Build both architecture dependent and independent
676build: build-arch build-indep
677
678# Build architecture dependent
679build-arch: build-arch-stamp
680
681build-arch-stamp:  config.status
682        dh_testdir
683
684        # Compile the package.
685        $(MAKE)
686
687        touch build-stamp
688
689# Build architecture independent
690build-indep: build-indep-stamp
691
692build-indep-stamp:  config.status
693        # Nothing to do, the only indep item is the manual which is available as html in original source
694        touch build-indep-stamp
695
696# Clean up
697clean:
698        dh_testdir
699        dh_testroot
700        rm -f build-arch-stamp build-indep-stamp #CONFIGURE-STAMP#
701        # Clean temporary document directory
702        rm -rf debian/doc-temp
703        # Clean up.
704        -$(MAKE) distclean
705        rm -f config.log
706ifneq "$(wildcard /usr/share/misc/config.sub)" ""
707        cp -f /usr/share/misc/config.sub config.sub
708endif
709ifneq "$(wildcard /usr/share/misc/config.guess)" ""
710        cp -f /usr/share/misc/config.guess config.guess
711endif
712
713        dh_clean
714
715# Install architecture dependent and independent
716install: install-arch install-indep
717
718# Install architecture dependent
719install-arch: build-arch
720        dh_testdir
721        dh_testroot
722        dh_clean -k -s
723        dh_installdirs -s
724
725        # Install the package files into build directory:
726        # - start with upstream make install
727        $(MAKE) install prefix=$(CURDIR)/debian/$(PACKAGE_NAME)/usr mandir=$(CURDIR)/debian/$(PACKAGE_NAME)/us
728r/share/man
729        # - copy html manual to temporary location for renaming
730        mkdir -p debian/doc-temp
731        dh_install -s
732
733# Install architecture independent
734install-indep: build-indep
735        dh_testdir
736        dh_testroot
737        dh_clean -k -i
738        dh_installdirs -i
739        dh_install -i
740
741# Must not depend on anything. This is to be called by
742# binary-arch/binary-indep
743# in another 'make' thread.
744binary-common:
745        dh_testdir
746        dh_testroot
747        dh_installchangelogs ChangeLog
748        dh_installdocs
749        dh_installman
750        dh_link
751        dh_strip
752        dh_compress
753        dh_fixperms
754        dh_installdeb
755        dh_shlibdeps
756        dh_gencontrol
757        dh_md5sums
758        dh_builddeb
759
760# Build architecture independant packages using the common target.
761binary-indep: build-indep install-indep
762        $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
763
764# Build architecture dependant packages using the common target.
765binary-arch: build-arch install-arch
766        $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
767
768# Build architecture depdendent and independent packages
769binary: binary-arch binary-indep
770.PHONY: clean binary
771
772EOF
773            close(CONF);
774            pb_mkdir_p("$ENV{'PBROOT'}/$pp/rpm") || die "Unable to create $ENV{'PBROOT'}/$pp/rpm";
775            open(CONF,"> $ENV{'PBROOT'}/$pp/rpm/$pp.spec") || die "Unable to create $ENV{'PBROOT'}/$pp/rpm/$pp.spec";
776            print CONF << 'EOF';
777#
778# $Id$
779#
780
781Summary:        bla-bla
782Summary(fr):    french bla-bla
783
784Name:           PBPKG
785Version:        PBVER
786Release:        PBTAGPBSUF
787License:        PBLIC
788Group:          PBGRP
789Url:            PBURL
790Source:         PBSRC
791BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -u -n)
792Requires:       PBDEP
793
794%description
795PBDESC
796
797%description -l fr
798french desc
799
800%prep
801%setup -q
802
803%build
804%configure
805make %{?_smp_mflags}
806
807%install
808%{__rm} -rf $RPM_BUILD_ROOT
809make DESTDIR=$RPM_BUILD_ROOT install
810
811%clean
812%{__rm} -rf $RPM_BUILD_ROOT
813
814%files
815%defattr(-,root,root)
816%doc ChangeLog
817%doc INSTALL COPYING README AUTHORS NEWS
818
819%changelog
820PBLOG
821
822EOF
823            close(CONF);
824            pb_mkdir_p("$ENV{'PBROOT'}/$pp/pbfilter") || die "Unable to create $ENV{'PBROOT'}/$pp/pbfilter";
825
826            pb_log(0,"\nDo not to forget to commit the pbconf directory in your CMS if needed\n");
827        }
828    } else {
829        die "Unable to open $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb";
830    }
831}
832umask 0022;
833return(\%filteredfiles, \%supfiles, \%defpkgdir, \%extpkgdir);
834}
835
836# Internal mkdir -p function
837sub pb_mkdir_p {
838my @dir = @_;
839my $ret = mkpath(@dir, 0, 0755);
840return($ret);
841}
842
843# Internal rm -rf function
844sub pb_rm_rf {
845my @dir = @_;
846my $ret = rmtree(@dir, 0, 0);
847return($ret);
848}
849
850# Internal system function
851sub pb_system {
852
853my $cmd=shift;
854my $cmt=shift || $cmd;
855
856pb_log(0,"$cmt... ");
857#system("$cmd 2>&1 > $ENV{'PBTMP'}/system.log");
858system($cmd);
859if ($? == -1) {
860    pb_log(0,"failed to execute ($cmd) : $!\n");
861    pb_display_file("$ENV{'PBTMP'}/system.log");
862} elsif ($? & 127) {
863    pb_log(0, "child ($cmd) died with signal ".($? & 127).", ".($? & 128) ? 'with' : 'without'." coredump\n");
864    pb_display_file("$ENV{'PBTMP'}/system.log");
865} elsif ($? == 0) {
866    pb_log(0,"OK\n");
867} else {
868    pb_log(0, "child ($cmd) exited with value ".($? >> 8)."\n");
869    pb_display_file("$ENV{'PBTMP'}/system.log");
870}
871}
872
873sub pb_display_file {
874
875my $file=shift;
876
877return if (not -f $file);
878open(FILE,"$file");
879while (<FILE>) {
880    print $_;
881}
882close(FILE);
883}
884
885# Function which returns a pointer on a table
886# corresponding to a set of values queried in the conf file
887# and test the returned vaue as they need to exist in that case
888sub pb_conf_get {
889
890my @param = @_;
891my @return = pb_conf_get_if(@param);
892
893die "No params found for $ENV{'PBPROJ'}" if (not @return);
894
895foreach my $i (0..$#param) {
896    die "No $param[$i] defined for $ENV{'PBPROJ'}" if (not defined $return[$i]);
897}
898return(@return);
899}
900
901# Function which returns a pointer on a table
902# corresponding to a set of values queried in the conf file
903# Those value may be undef if they do not exist
904sub pb_conf_get_if {
905
906my @param = @_;
907
908# Everything is returned via ptr1
909my @ptr1 = ();
910my @ptr2 = ();
911@ptr1 = pb_conf_read_if("$ENV{'PBETC'}", @param) if (defined $ENV{'PBETC'});
912@ptr2 = pb_conf_read_if("$ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb", @param) if ((defined $ENV{'PBROOT'}) and (defined $ENV{'PBPROJ'}));
913
914my $p1;
915my $p2;
916
917pb_log(2,"DEBUG: param1: ".Dumper(@ptr1)."\n");
918pb_log(2,"DEBUG: param2: ".Dumper(@ptr2)."\n");
919
920foreach my $i (0..$#param) {
921    $p1 = $ptr1[$i];
922    $p2 = $ptr2[$i];
923    # Always try to take the param from the home dir conf file in priority
924    # in order to mask what could be defined under the CMS to allow for overloading
925    if (not defined $p2) {
926        # No ref in CMS project conf file so use the home dir one.
927        $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if (not defined $p1->{$ENV{'PBPROJ'}});
928    } else {
929        # Ref found in CMS project conf file
930        if (not defined $p1) {
931            # No ref in home dir project conf file so use the CMS one.
932            $p2->{$ENV{'PBPROJ'}} = $p2->{'default'} if (not defined $p2->{$ENV{'PBPROJ'}});
933            $p1->{$ENV{'PBPROJ'}} = $p2->{$ENV{'PBPROJ'}};
934        } else {
935            # Both are defined - handling the overloading
936            if (not defined $p1->{'default'}) {
937                if (defined $p2->{'default'}) {
938                    $p1->{'default'} = $p2->{'default'};
939                }
940            }
941
942            if (not defined $p1->{$ENV{'PBPROJ'}}) {
943                if (defined $p2->{$ENV{'PBPROJ'}}) {
944                    $p1->{$ENV{'PBPROJ'}} = $p2->{$ENV{'PBPROJ'}};
945                } else {
946                    $p1->{$ENV{'PBPROJ'}} = $p1->{'default'};
947                }
948            }
949        }
950    }
951    $ptr1[$i] = $p1;
952    pb_log(2,"DEBUG: param ptr1: ".Dumper(@ptr1)."\n");
953}
954return(@ptr1);
955}
956
957# Function which returns a pointer on a hash
958# corresponding to a declaration (arg2) in a conf file (arg1)
959# if that conf file doesn't exist returns undef
960sub pb_conf_read_if {
961
962my $conffile = shift;
963my @param = @_;
964
965open(CONF,$conffile) || return((undef));
966close(CONF);
967return(pb_conf_read($conffile,@param));
968}
969
970# Function which returns a pointer on a hash
971# corresponding to a declaration (arg2) in a conf file (arg1)
972sub pb_conf_read {
973
974my $conffile = shift;
975my @param = @_;
976my $trace;
977my @ptr;
978my %h;
979
980open(CONF,$conffile) || die "Unable to open $conffile";
981while(<CONF>) {
982    if (/^\s*([A-z0-9-_]+)\s+([[A-z0-9-_]+)\s*=\s*(.+)$/) {
983        pb_log(2,"DEBUG: 1:$1 2:$2 3:$3\n");
984        $h{$1}{$2}=$3;
985    }
986}
987close(CONF);
988
989for my $param (@param) {
990    push @ptr,$h{$param};
991}
992return(@ptr);
993}
994
995# Analyze a url passed and return protocol, account, password, server, port, path
996sub pb_get_uri {
997
998my $uri = shift || undef;
999
1000pb_log(2,"DEBUG: uri:$uri\n");
1001# A URL has the format protocol://[ac@]host[:port][path[?query][#fragment]].
1002# Cf man URI
1003my ($scheme, $authority, $path, $query, $fragment) =
1004         $uri =~ m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?| if (defined $uri);
1005my ($account,$host,$port) = $authority =~ m|(?:([^\@]+)\@)?([^:]+)(:(?:[0-9]+))?| if (defined $authority);
1006
1007$scheme = "" if (not defined $scheme);
1008$authority = "" if (not defined $authority);
1009$path = "" if (not defined $path);
1010$account = "" if (not defined $account);
1011$host = "" if (not defined $host);
1012$port = "" if (not defined $port);
1013
1014pb_log(2,"DEBUG: scheme:$scheme ac:$account host:$host port:$port path:$path\n");
1015return($scheme, $account, $host, $port, $path);
1016}
1017
1018
1019# Setup environment for CMS system for URL passed
1020sub pb_cms_init {
1021
1022my $proj = shift || undef;
1023
1024# Use the project URI
1025my ($uri) = pb_conf_get("pburl");
1026
1027# Extract values from that URI
1028my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri->{$ENV{'PBPROJ'}});
1029
1030if ($scheme =~ /^svn/) {
1031    $ENV{'PBREVISION'}= pb_cms_getinfo($scheme,$uri->{$ENV{'PBPROJ'}},"Revision:");
1032    #$ENV{'PBREVISION'}=`(cd "$ENV{'PBDEVDIR'}" ; svnversion .)`;
1033    $ENV{'PBCMSLOGFILE'}="svn.log";
1034} elsif (($scheme eq "file") || ($scheme eq "ftp") || ($scheme eq "http")) {
1035    $ENV{'PBREVISION'}="flat";
1036    $ENV{'PBCMSLOGFILE'}="flat.log";
1037} elsif ($scheme eq "cvs") {
1038    # Way too slow
1039    #$ENV{'PBREVISION'}=`(cd "$ENV{'PBROOT'}" ; cvs rannotate  -f . 2>&1 | awk '{print \$1}' | grep -E '^[0-9]' | cut -d. -f2 |sort -nu | tail -1)`;
1040    #chomp($ENV{'PBREVISION'});
1041    $ENV{'PBREVISION'}="CVS";
1042    $ENV{'PBCMSLOGFILE'}="cvs.log";
1043    #
1044    # Export content if needed
1045    #
1046    my ($cvsrsh) = pb_conf_get_if("cvsrsh");
1047    $ENV{'CVS_RSH'} = $cvsrsh->{$proj} if (defined $cvsrsh->{$proj});
1048} else {
1049    die "cms $scheme unknown";
1050}
1051
1052#
1053#if (not defined $scheme) {
1054    # We're an upstream guy
1055    # Try to make it easy for us
1056    #pb_log(2,"WARNING: Assuming a local project under $ENV{'PBDIR'}/$ENV{'PBPROJ'}:\n");
1057    #pb_log(2,"         If not, pleaase setup a pbproj entry in $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb\n");
1058    #return("");
1059#}
1060
1061return($scheme,$uri->{$ENV{'PBPROJ'}});
1062}
1063
1064sub pb_get_date {
1065   
1066return(localtime->sec(), localtime->min(), localtime->hour(), localtime->mday(), localtime->mon(), localtime->year(), localtime->wday(), localtime->yday(), localtime->isdst());
1067}
1068
1069sub pb_cms_export {
1070
1071my $uri = shift;
1072my $source = shift;
1073my $destdir = shift;
1074my $tmp;
1075my $tmp1;
1076
1077my @date = pb_get_date();
1078# If it's not flat, then we have a real uri as source
1079my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
1080
1081if ($scheme =~ /^svn/) {
1082    if (-d $source) {
1083        $tmp = $destdir;
1084    } else {
1085        $tmp = $destdir."/".basename($source);
1086        pb_mkdir_p($destdir);
1087    }
1088    pb_system("svn export $source $tmp","Exporting $source from SVN to $tmp");
1089} elsif ($scheme eq "dir") {
1090    pb_system("cp -a $path $destdir","Copying $uri from DIR to $destdir");
1091} elsif (($scheme eq "http") || ($scheme eq "ftp")) {
1092    my $f = basename($path);
1093    unlink "$ENV{'PBTMP'}/$f";
1094    if (-x "/usr/bin/wget") {
1095        pb_system("/usr/bin/wget -nv -O $ENV{'PBTMP'}/$f $uri"," ");
1096    } elsif (-x "/usr/bin/curl") {
1097        pb_system("/usr/bin/curl $uri -o $ENV{'PBTMP'}/$f","Downloading $uri with curl to $ENV{'PBTMP'}/$f\n");
1098    } else {
1099        die "Unable to download $uri.\nNo wget/curl available, please install one of those";
1100    }
1101    pb_cms_export("file://$ENV{'PBTMP'}/$f",$source,$destdir);
1102} elsif ($scheme eq "file") {
1103    use File::MimeInfo;
1104    my $mm = mimetype($path);
1105    pb_log(2,"mimetype: $mm\n");
1106    pb_mkdir_p($destdir);
1107
1108    if ($mm =~ /\/x-bzip-compressed-tar$/) {
1109        # tar+bzip2
1110        pb_system("cd $destdir ; tar xfj $path","Extracting $path in $destdir");
1111    } elsif ($mm =~ /\/x-lzma-compressed-tar$/) {
1112        # tar+lzma
1113        pb_system("cd $destdir ; tar xfY $path","Extracting $path in $destdir");
1114    } elsif ($mm =~ /\/x-compressed-tar$/) {
1115        # tar+gzip
1116        pb_system("cd $destdir ; tar xfz $path","Extracting $path in $destdir");
1117    } elsif ($mm =~ /\/x-tar$/) {
1118        # tar
1119        pb_system("cd $destdir ; tar xf $path","Extracting $path in $destdir");
1120    } elsif ($mm =~ /\/zip$/) {
1121        # zip
1122        pb_system("cd $destdir ; unzip $path","Extracting $path in $destdir");
1123    }
1124    # Maybe we created an extra level of dir under destdir
1125    opendir(DIR,$destdir) || die "Unable to open $destdir";
1126    my $cnt = 0;
1127    my $d0;
1128    foreach my $d (readdir(DIR)) {
1129        pb_log(3,"Looking at \'$d\'...");
1130        next if ($d =~ /^\./);
1131        $cnt++;
1132        $d0 = $d;
1133    }
1134    closedir(DIR);
1135    # Fix that by moving everything below that extra dir under destdir
1136    # and remove the extra dir
1137    if ($cnt == 1) {
1138        pb_system("cd $destdir/$d0 ; mv * .??* .. 2>/dev/null");
1139        pb_rm_rf("$destdir/$d0");
1140    }
1141} elsif ($scheme eq "cvs") {
1142    my $dir=dirname($destdir);
1143    my $base=basename($destdir);
1144    if (-d $source) {
1145        $tmp1 = $source;
1146        $tmp1 =~ s|$ENV{'PBROOT'}/||;
1147    } else {
1148        $tmp1 = dirname($source);
1149        $tmp1 =~ s|$ENV{'PBROOT'}/||;
1150        $tmp1 = $tmp1."/".basename($source);
1151    }
1152    # CVS needs a relative path !
1153    my ($cvsroot) = pb_conf_get("cvsroot");
1154    my $pbdate = strftime("%Y-%m-%d %H:%M:%S", @date);
1155    pb_system("cd $dir ; cvs -d $cvsroot->{$ENV{'PBPROJ'}} export -D \"$pbdate\" -d $base $tmp1","Exporting $source from CVS to $destdir");
1156} else {
1157    die "cms $scheme unknown";
1158}
1159}
1160
1161
1162sub pb_create_authors {
1163
1164my $authors=shift;
1165my $dest=shift;
1166my $scheme=shift;
1167
1168return if ($authors eq "/dev/null");
1169open(SAUTH,$authors) || die "Unable to open $authors";
1170# Save a potentially existing AUTHORS file and write instead toi AUTHORS.pb
1171my $ext = "";
1172if (-f "$dest/AUTHORS") {
1173    $ext = ".pb";
1174}
1175open(DAUTH,"> $dest/AUTHORS$ext") || die "Unable to create $dest/AUTHORS$ext";
1176print DAUTH "Authors of the project are:\n";
1177print DAUTH "===========================\n";
1178while (<SAUTH>) {
1179    my ($nick,$gcos) = split(/:/);
1180    chomp($gcos);
1181    print DAUTH "$gcos";
1182    if (defined $scheme) {
1183        # Do not give a scheme for flat types
1184        my $endstr="";
1185        if ("$ENV{'PBREVISION'}" ne "flat") {
1186            $endstr = " under $scheme";
1187        }
1188        print DAUTH " ($nick$endstr)\n";
1189    } else {
1190        print DAUTH "\n";
1191    }
1192}
1193close(DAUTH);
1194close(SAUTH);
1195}
1196
1197sub pb_cms_log {
1198
1199my $scheme = shift;
1200my $pkgdir = shift;
1201my $dest = shift;
1202my $chglog = shift;
1203my $authors = shift;
1204
1205pb_create_authors($authors,$dest,$scheme);
1206
1207if ($scheme =~ /^svn/) {
1208    if (! -f "$dest/ChangeLog") {
1209        if (-x "/usr/bin/svn2cl") {
1210            pb_system("/usr/bin/svn2cl --group-by-day --authors=$authors -i -o $dest/ChangeLog $pkgdir","Generating ChangeLog from SVN with svn2cl");
1211        } else {
1212            # To be written from pbcl
1213            pb_system("svn log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVN");
1214        }
1215    }
1216} elsif (($scheme eq "file") || ($scheme eq "dir") || ($scheme eq "http") || ($scheme eq "ftp")) {
1217    if (! -f "$dest/ChangeLog") {
1218        pb_system("echo ChangeLog for $pkgdir > $dest/ChangeLog","Empty ChangeLog file created");
1219    }
1220} elsif ($scheme eq "cvs") {
1221    my $tmp=basename($pkgdir);
1222    # CVS needs a relative path !
1223    if (! -f "$dest/ChangeLog") {
1224        if (-x "/usr/bin/cvs2cl") {
1225            pb_system("/usr/bin/cvs2cl --group-by-day -U $authors -f $dest/ChangeLog $pkgdir","Generating ChangeLog from CVS with cvs2cl");
1226        } else {
1227            # To be written from pbcl
1228            pb_system("cvs log $tmp > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from CVS");
1229        }
1230    }
1231} else {
1232    die "cms $scheme unknown";
1233}
1234}
1235
1236sub pb_cms_getinfo {
1237
1238my $scheme = shift;
1239my $dir = shift;
1240my $info = shift || "URL:";
1241
1242my $res = "";
1243my $void = "";
1244
1245if ($scheme =~ /^svn/) {
1246    open(PIPE,"LANGUAGE=C svn info $dir |") || return("");
1247    while (<PIPE>) {
1248        ($void,$res) = split(/^$info/) if (/^$info/);
1249    }
1250    $res =~ s/^\s*//;
1251    close(PIPE);
1252    chomp($res);
1253} elsif ($scheme eq "flat") {
1254} elsif ($scheme eq "cvs") {
1255} else {
1256    die "cms $scheme unknown";
1257}
1258pb_log(2,"Found CMS info: $res\n");
1259return($res);
1260}
1261
1262sub pb_cms_copy {
1263my $scheme = shift;
1264my $oldurl = shift;
1265my $newurl = shift;
1266
1267if ($scheme eq "svn") {
1268    pb_system("svn copy -m \"Creation of $newurl from $oldurl\" $oldurl $newurl","Copying $oldurl to $newurl ");
1269} elsif ($scheme eq "flat") {
1270} elsif ($scheme eq "cvs") {
1271} else {
1272    die "cms $scheme unknown";
1273}
1274}
1275
1276sub pb_cms_checkout {
1277my $scheme = shift;
1278my $url = shift;
1279my $destination = shift;
1280
1281if ($scheme =~ /^svn/) {
1282    pb_system("svn co $url $destination","Checking out $url to $destination ");
1283} elsif ($scheme eq "flat") {
1284} elsif ($scheme eq "cvs") {
1285} else {
1286    die "cms $scheme unknown";
1287}
1288}
1289
1290sub pb_cms_checkin {
1291my $scheme = shift;
1292my $dir = shift;
1293
1294my $ver = basename($dir);
1295if ($scheme eq "svn") {
1296    pb_system("svn ci -m \"Updated to $ver\" $dir","Checking in $dir");
1297    pb_system("svn up $dir","Updating $dir");
1298} elsif ($scheme eq "flat") {
1299} elsif ($scheme eq "cvs") {
1300} else {
1301    die "cms $scheme unknown";
1302}
1303}
1304
1305sub pb_cms_isdiff {
1306my $scheme = shift;
1307
1308if ($scheme eq "svn") {
1309    open(PIPE,"svn diff $ENV{'PBROOT'} |") || die "Unable to get svn diff from $ENV{'PBROOT'}";
1310    my $l = 0;
1311    while (<PIPE>) {
1312        $l++;
1313    }
1314    return($l);
1315} elsif ($scheme eq "flat") {
1316} elsif ($scheme eq "cvs") {
1317} else {
1318    die "cms $scheme unknown";
1319}
1320}
1321
1322# Get all filters to apply
1323# They're cumulative from less specific to most specific
1324# suffix is .pbf
1325
1326sub pb_get_filters {
1327
1328my @ffiles;
1329my ($ffile00, $ffile0, $ffile1, $ffile2, $ffile3);
1330my ($mfile00, $mfile0, $mfile1, $mfile2, $mfile3);
1331my $pbpkg = shift || die "No package specified";
1332my $dtype = shift || "";
1333my $dfam = shift || "";
1334my $ddir = shift || "";
1335my $dver = shift || "";
1336my $ptr; # returned value pointer on the hash of filters
1337my %ptr;
1338my %h;
1339
1340# Global filter files first, then package specificities
1341if (-d "$ENV{'PBROOT'}/pbfilter") {
1342    $mfile00 = "$ENV{'PBROOT'}/pbfilter/all.pbf" if (-f "$ENV{'PBROOT'}/pbfilter/all.pbf");
1343    $mfile0 = "$ENV{'PBROOT'}/pbfilter/$dtype.pbf" if (-f "$ENV{'PBROOT'}/pbfilter/$dtype.pbf");
1344    $mfile1 = "$ENV{'PBROOT'}/pbfilter/$dfam.pbf" if (-f "$ENV{'PBROOT'}/pbfilter/$dfam.pbf");
1345    $mfile2 = "$ENV{'PBROOT'}/pbfilter/$ddir.pbf" if (-f "$ENV{'PBROOT'}/pbfilter/$ddir.pbf");
1346    $mfile3 = "$ENV{'PBROOT'}/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBROOT'}/pbfilter/$ddir-$dver.pbf");
1347
1348    push @ffiles,$mfile00 if (defined $mfile00);
1349    push @ffiles,$mfile0 if (defined $mfile0);
1350    push @ffiles,$mfile1 if (defined $mfile1);
1351    push @ffiles,$mfile2 if (defined $mfile2);
1352    push @ffiles,$mfile3 if (defined $mfile3);
1353}
1354
1355if (-d "$ENV{'PBROOT'}/$pbpkg/pbfilter") {
1356    $ffile00 = "$ENV{'PBROOT'}/$pbpkg/pbfilter/all.pbf" if (-f "$ENV{'PBROOT'}/$pbpkg/pbfilter/all.pbf");
1357    $ffile0 = "$ENV{'PBROOT'}/$pbpkg/pbfilter/$dtype.pbf" if (-f "$ENV{'PBROOT'}/$pbpkg/pbfilter/$dtype.pbf");
1358    $ffile1 = "$ENV{'PBROOT'}/$pbpkg/pbfilter/$dfam.pbf" if (-f "$ENV{'PBROOT'}/$pbpkg/pbfilter/$dfam.pbf");
1359    $ffile2 = "$ENV{'PBROOT'}/$pbpkg/pbfilter/$ddir.pbf" if (-f "$ENV{'PBROOT'}/$pbpkg/pbfilter/$ddir.pbf");
1360    $ffile3 = "$ENV{'PBROOT'}/$pbpkg/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBROOT'}/$pbpkg/pbfilter/$ddir-$dver.pbf");
1361
1362    push @ffiles,$ffile00 if (defined $ffile00);
1363    push @ffiles,$ffile0 if (defined $ffile0);
1364    push @ffiles,$ffile1 if (defined $ffile1);
1365    push @ffiles,$ffile2 if (defined $ffile2);
1366    push @ffiles,$ffile3 if (defined $ffile3);
1367}
1368if (@ffiles) {
1369    pb_log(2,"DEBUG ffiles: ".Dumper(\@ffiles)."\n");
1370
1371    foreach my $f (@ffiles) {
1372        open(CONF,$f) || next;
1373        while(<CONF>)  {
1374            if (/^\s*([A-z0-9-_]+)\s+([[A-z0-9-_]+)\s*=\s*(.+)$/) {
1375                $h{$1}{$2}=$3;
1376            }
1377        }
1378        close(CONF);
1379
1380        $ptr = $h{"filter"};
1381        pb_log(2,"DEBUG f:".Dumper($ptr)."\n");
1382    }
1383} else {
1384    $ptr = { };
1385}
1386%ptr = %$ptr;
1387return(\%ptr);
1388}
1389
1390# Function which applies filter on pb build files
1391sub pb_filter_file_pb {
1392
1393my $f=shift;
1394my $ptr=shift;
1395my %filter=%$ptr;
1396my $destfile=shift;
1397my $dtype=shift;
1398my $pbsuf=shift;
1399my $pbproj=shift;
1400my $pbpkg=shift;
1401my $pbver=shift;
1402my $pbtag=shift;
1403my $pbrev=shift;
1404my $pbdate=shift;
1405my $defpkgdir = shift;
1406my $extpkgdir = shift;
1407my $pbpackager = shift;
1408my $chglog = shift || undef;
1409
1410pb_log(2,"DEBUG: From $f to $destfile\n");
1411pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
1412open(DEST,"> $destfile") || die "Unable to create $destfile";
1413open(FILE,"$f") || die "Unable to open $f: $!";
1414while (<FILE>) {
1415    my $line = $_;
1416    foreach my $s (keys %filter) {
1417        # Process single variables
1418        pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
1419        my $tmp = $filter{$s};
1420        next if (not defined $tmp);
1421        # Expand variables if any single one found
1422        pb_log(2,"DEBUG tmp: $tmp\n");
1423        if ($tmp =~ /\$/) {
1424            eval { $tmp =~ s/(\$\w+)/$1/eeg };
1425        # special case for ChangeLog only for pb
1426        } elsif (($s =~ /^PBLOG$/) && ($line =~ /^PBLOG$/)) {
1427            my $p = $defpkgdir->{$pbpkg};
1428            $p = $extpkgdir->{$pbpkg} if (not defined $p);
1429            pb_changelog($dtype, $pbpkg, $pbver, $pbtag, $pbsuf, $p, \*DEST, $tmp, $chglog);
1430            $tmp = "";
1431        }
1432        $line =~ s|$s|$tmp|;
1433    }
1434    print DEST $line;
1435}
1436close(FILE);
1437close(DEST);
1438}
1439
1440# Function which applies filter on files (external call)
1441sub pb_filter_file_inplace {
1442
1443my $ptr=shift;
1444my %filter=%$ptr;
1445my $destfile=shift;
1446my $pbproj=shift;
1447my $pbpkg=shift;
1448my $pbver=shift;
1449my $pbtag=shift;
1450my $pbrev=shift;
1451my $pbdate=shift;
1452my $pbpackager=shift;
1453
1454my $cp = "$ENV{'PBTMP'}/".basename($destfile);
1455copy($destfile,$cp) || die "Unable to create $cp";
1456
1457pb_filter_file($cp,$ptr,$destfile,$pbproj,$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$pbpackager);
1458unlink $cp;
1459}
1460
1461# Function which applies filter on files (external call)
1462sub pb_filter_file {
1463
1464my $f=shift;
1465my $ptr=shift;
1466my %filter=%$ptr;
1467my $destfile=shift;
1468my $pbproj=shift;
1469my $pbpkg=shift;
1470my $pbver=shift;
1471my $pbtag=shift;
1472my $pbrev=shift;
1473my $pbdate=shift;
1474my $pbpackager=shift;
1475
1476pb_log(2,"DEBUG: From $f to $destfile\n");
1477pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
1478open(DEST,"> $destfile") || die "Unable to create $destfile";
1479open(FILE,"$f") || die "Unable to open $f: $!";
1480while (<FILE>) {
1481    my $line = $_;
1482    foreach my $s (keys %filter) {
1483        # Process single variables
1484        pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
1485        my $tmp = $filter{$s};
1486        next if (not defined $tmp);
1487        # Expand variables if any single one found
1488        if ($tmp =~ /\$/) {
1489            eval { $tmp =~ s/(\$\w+)/$1/eeg };
1490        }
1491        $line =~ s|$s|$tmp|;
1492    }
1493    print DEST $line;
1494}
1495close(FILE);
1496close(DEST);
1497}
1498
1499sub pb_log_init {
1500
1501$debug = shift || 0;
1502$LOG = shift || \*STDOUT;
1503
1504} 
1505
1506sub pb_log {
1507
1508my $dlevel = shift;
1509my $msg = shift;
1510
1511print $LOG "$msg" if ($dlevel <= $debug);
1512}
1513
1514#
1515# Return the list of packages we are working on
1516#
1517sub pb_get_pkg {
1518
1519my @pkgs = ();
1520my $defpkgdir = shift || undef;
1521my $extpkgdir = shift || undef;
1522
1523# Get packages list
1524if (not defined $ARGV[0]) {
1525    @pkgs = keys %$defpkgdir if (defined $defpkgdir);
1526} elsif ($ARGV[0] =~ /^all$/) {
1527    @pkgs = keys %$defpkgdir if (defined $defpkgdir);
1528    push(@pkgs, keys %$extpkgdir) if (defined $extpkgdir);
1529} else {
1530    @pkgs = @ARGV;
1531}
1532pb_log(0,"Packages: ".join(',',@pkgs)."\n");
1533return(\@pkgs);
1534}
1535
15361;
Note: See TracBrowser for help on using the repository browser.