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

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

Adds support for supplemental files in projects (such as init scripts different for different distributions such as in collectl)

File size: 31.3 KB
RevLine 
[2]1#!/usr/bin/perl -w
2#
[74]3# Base subroutines for the Project-Builder project
[2]4#
5# $Id$
6#
7
[18]8use strict;
[5]9use lib qw (lib);
[2]10use File::Basename;
[9]11use File::Path;
[2]12use File::Temp qw /tempdir/;
[8]13use Data::Dumper;
[2]14
[199]15use ProjectBuilder::Changelog qw (pb_changelog);
16
[49]17$ENV{'PBETC'} = "$ENV{'HOME'}/.pbrc";
[5]18
[74]19sub pb_env_init {
[2]20
[273]21my $proj=shift || undef;
22my $pbinit=shift || undef;
[5]23my $ver;
24my $tag;
[2]25
[107]26# For the moment not dynamic
27my $debug = 0; # Debug level
28my $LOG = *STDOUT; # Where to log
29
[8]30#
[5]31# Check project name
[49]32# Could be with env var PBPROJ
33# or option -p
34# if not define take the first in conf file
[8]35#
[5]36if ((defined $ENV{'PBPROJ'}) &&
37 (not (defined $proj))) {
38 $proj = $ENV{'PBPROJ'};
39}
[69]40
[49]41#
[69]42# We get the pbrc file for that project
43# and use its content
44#
[89]45my ($pbrc) = pb_conf_read("$ENV{'PBETC'}","pbrc");
[74]46print "DEBUG pbrc: ".Dumper($pbrc)."\n" if ($debug >= 1);
[69]47
[108]48my %pbrc = %$pbrc;
[69]49if (not defined $proj) {
50 # Take the first as the default project
51 $proj = (keys %pbrc)[0];
52 print $LOG "Using $proj as default project as none has been specified\n" if (($debug >= 0) and (defined $proj));
53}
54die "No project defined - use env var PBPROJ or -p proj" if (not (defined $proj));
55
56#
57# Set delivery directory
58#
[273]59if (not defined ($pbrc{$proj})) {
60 die "Please create a pbrc reference for project $proj in $ENV{'PBETC'}\n";
61}
62
[71]63my $topdir=dirname($pbrc{$proj});
[108]64# Expand potential env variable in it
65eval { $topdir =~ s/(\$ENV.+\})/$1/eeg };
[69]66chdir $topdir || die "Unable to change directory to $topdir";
[108]67$pbrc{$proj} = $topdir."/pbrc";
[69]68$ENV{'PBDESTDIR'}=$topdir."/delivery";
69
70#
[67]71# Use project configuration file if needed
[49]72#
[67]73if (not defined $ENV{'PBROOT'}) {
[69]74 if (-f $pbrc{$proj}) {
[89]75 my ($pbroot) = pb_conf_read($pbrc{$proj},"pbroot");
[71]76 my %pbroot = %$pbroot;
[77]77 # All lines should point to the same pbroot so take the first
[69]78 $ENV{'PBROOT'} = (values %$pbroot)[0] if (defined $pbroot);
79 print $LOG "Using $ENV{'PBROOT'} as default pbroot from $pbrc{$proj}\n" if (($debug >= 0) and (defined $ENV{'PBROOT'}));
[67]80 }
[69]81 die "No pbroot defined - use env var PBROOT or -r pbroot " if (not defined $ENV{'PBROOT'});
[49]82}
[2]83
[8]84#
[49]85# Check pb conf compliance
[8]86#
[49]87$ENV{'PBCONF'} = "$ENV{'PBROOT'}/pbconf";
[273]88if (defined $pbinit) {
89 print $LOG "Creating $ENV{'PBCONF'} directory\n";
90 pb_mkdir_p("$ENV{'PBCONF'}");
91 }
[49]92die "Project $proj not Project-Builder compliant. Please populate $ENV{'PBCONF'}" if ( not -d "$ENV{'PBCONF'}");
[2]93
[74]94my %version = ();
[108]95my %defpkgdir = ();
96my %extpkgdir = ();
97my %filteredfiles = ();
[300]98my %supfiles = ();
[74]99
[273]100if ((-f "$ENV{'PBCONF'}/$proj.pb") and (not defined $pbinit)) {
[74]101 # List of pkg to build by default (mandatory)
102 # List of additional pkg to build when all is called (optional)
103 # Valid version names (optional)
104 # List of files to filter (optional)
[300]105 my ($defpkgdir, $extpkgdir, $version, $filteredfiles, $supfiles, $pkgv, $pkgt) = pb_conf_read("$ENV{'PBCONF'}/$proj.pb","defpkgdir","extpkgdir","version","filteredfiles","supfiles","projver","projtag");
[74]106 print "DEBUG: defpkgdir: ".Dumper($defpkgdir)."\n" if ($debug >= 1);
107 print "DEBUG: extpkgdir: ".Dumper($extpkgdir)."\n" if ($debug >= 1);
108 print "DEBUG: version: ".Dumper($version)."\n" if ($debug >= 1);
109 print "DEBUG: filteredfiles: ".Dumper($filteredfiles)."\n" if ($debug >= 1);
[300]110 print "DEBUG: supfiles: ".Dumper($supfiles)."\n" if ($debug >= 1);
[74]111 die "Unable to find defpkgdir in $ENV{'PBCONF'}/$proj.pb" if (not defined $defpkgdir);
112 # Global
113 %defpkgdir = %$defpkgdir;
114 # Global
[114]115 %extpkgdir = %$extpkgdir if (defined $extpkgdir);
[74]116 %version = %$version if (defined $version);
117 # Global
118 %filteredfiles = %$filteredfiles if (defined $filteredfiles);
[300]119 %supfiles = %$supfiles if (defined $supfiles);
[106]120 #
121 # Get global Version/Tag
122 #
[38]123
[106]124 if (not defined $ENV{'PBVER'}) {
125 if ((defined $pkgv) && (defined $pkgv->{$proj})) {
126 $ENV{'PBVER'}=$pkgv->{$proj};
127 } else {
128 die "No projver found in $ENV{'PBCONF'}/$proj.pb";
129 }
[98]130 }
[291]131 die "Invalid version name $ENV{'PBVER'} in $ENV{'PBCONF'}/$proj.pb" if (($ENV{'PBVER'} !~ /[0-9.]+/) && (not defined $version) && ($ENV{'PBVER'} =~ /$version{$proj}/));
[106]132
133 if (not defined $ENV{'PBTAG'}) {
134 if ((defined $pkgt) && (defined $pkgt->{$proj})) {
135 $ENV{'PBTAG'}=$pkgt->{$proj};
136 } else {
137 die "No projtag found in $ENV{'PBCONF'}/$proj.pb";
138 }
[98]139 }
[106]140 die "Invalid tag name $ENV{'PBTAG'} in $ENV{'PBCONF'}/$proj.pb" if ($ENV{'PBTAG'} !~ /[0-9.]+/);
141} else {
[273]142 if (defined $pbinit) {
143 open(CONF,"> $ENV{'PBCONF'}/$proj.pb") || die "Unable to create $ENV{'PBCONF'}/$proj.pb";
144 print CONF << "EOF";
145#
146# Project Builder configuration file
147# For project $proj
148#
149# \$Id\$
150#
151
152#
153# Which CMS system is used (Subversion, CVS or tar file content extracted)
154#
155#cms $proj = svn
156#cms $proj = cvs
157#cms $proj = flat
158
159#
160# Packager label
161#
162#packager $proj = "William Porte <bill\@$proj.org>"
163#
164
165# For delivery to a machine by SSH (potentially the FTP server)
166# Needs hostname, account and directory
167#
168#sshhost $proj = www.$proj.org
169#sshlogin $proj = bill
170#sshdir $proj = /$proj/ftp
171#sshport $proj = 22
172
173#
174# For Virtual machines management
175# Naming convention to follow: distribution name (as per ProjectBuilder::Distribution)
176# followed by '_' and by release number
177# a .vmtype extension will be added to the resulting string
178# a QEMU rhel_3 here means that the VM will be named rhel_3.qemu
179#
[287]180#vmlist $proj = 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
[273]181
182#
183# Valid values for vmtype are
184# qemu, (vmware, xen, ... TBD)
185#vmtype $proj = qemu
186
187# Hash for VM stuff on vmtype
188#vmntp default = pool.ntp.org
189
190# We suppose we can commmunicate with the VM through SSH
[287]191#vmhost $proj = localhost
192#vmlogin $proj = pb
193#vmport $proj = 2222
[273]194
195# Timeout to wait when VM is launched/stopped
196#vmtmout default = 120
197
198# per VMs needed paramaters
[287]199#vmopt $proj = -m 384 -daemonize
200#vmpath $proj = /home/qemu
201#vmsize $proj = 5G
[273]202
203#
204# Global version/tag for the project
205#
206#projver $proj = devel
207#projtag $proj = 1
208
209# Adapt to your needs:
210# Optional if you need to overwrite the global values above
211#
212#pkgver pkg1 = stable
213#pkgtag pkg1 = 3
214#pkgver nil
215#pkgtag nil
216
217# Hash of default package/package directory
218#defpkgdir pkg1 = pkg1dir
219
220# Hash of additional package/package directory
221#extpkgdir pkg1-doc = pkg1-docdir
222
223# Hash of valid version names
224#version devel
225#version stable
226
227# List of files per pkg on which to apply filters
228# Files are mentioned relatively to pbroot/defpkgdir
229#filteredfiles pkg1 = Makefile.PL
230#filteredfiles pkg1-doc = configure.in
[300]231#supfiles pkg1 = pkg1.init
[273]232EOF
233 close(CONF);
234 pb_mkdir_p("$ENV{'PBCONF'}/pbfilter") || die "Unable to create $ENV{'PBCONF'}/pbfilter";
235 open(CONF,"> $ENV{'PBCONF'}/pbfilter/all.pbf") || die "Unable to create $ENV{'PBCONF'}/pbfilter/all.pbf";
236 print CONF << "EOF";
237#
238# \$Id\$
239#
240# Filter for all files
241#
242# PBSRC is replaced by the source package format
243#filter PBSRC = ftp://ftp.$proj.org/src/%{name}-%{version}.tar.gz
244
245# PBVER is replaced by the version (\$pbver in code)
246#filter PBVER = \$pbver
247
248# PBDATE is replaced by the date (\$pbdate in code)
249#filter PBDATE = \$pbdate
250
251# PBLOG is replaced by the changelog if value is yes
252#filter PBLOG = yes
253
254# PBTAG is replaced by the tag (\$pbtag in code)
255#filter PBTAG = \$pbtag
256
257# PBREV is replaced by the revision (\$pbrev in code)
258#filter PBREV = \$pbrev
259
260# PBPKG is replaced by the package name (\$pbpkg in code)
261#filter PBPKG = \$pbpkg
262
263# PBPACKAGER is replaced by the packager name (\$pbpackager in code)
264#filter PBPACKAGER = \$pbpackager
265
266# PBDESC contains the description of the package
267#filter PBDESC = "Bla-Bla"
268
269# PBURL contains the URL of the Web site of the project
270#filter PBURL = http://www.$proj.org
271EOF
272 close(CONF);
273 open(CONF,"> $ENV{'PBCONF'}/pbfilter/rpm.pbf") || die "Unable to create $ENV{'PBCONF'}/pbfilter/rpm.pbf";
274 print CONF << "EOF";
275#
276# \$Id\$
277#
278# Filter for rpm build
279#
280
281# PBGRP is replaced by the RPM group of apps
[288]282# Cf: http://fedoraproject.org/wiki/RPMGroups
[273]283#filter PBGRP = Applications/Archiving
284
285# PBDEP is replaced by the list of dependencies
286#filter PBDEP =
287
288# PBSUF is replaced by the package name (\$pbpkg in code)
289#filter PBSUF = \$pbsuf
290
291# PBOBS is replaced by the Obsolete line
292#filter PBOBS =
293
294EOF
295 close(CONF);
296 open(CONF,"> $ENV{'PBCONF'}/pbfilter/deb.pbf") || die "Unable to create $ENV{'PBCONF'}/pbfilter/deb.pbf";
297 print CONF << "EOF";
298#
299# \$Id\$
300#
301# Filter for debian build
302#
303# PBGRP is replaced by the group of apps
304#filter PBGRP = utils
305
306# PBVER is replaced by the version (\$pbver in code)
307#filter PBVER = \$pbver
308
309# PBDEP is replaced by the list of dependencies
310#filter PBDEP =
311
312# PBSUG is replaced by the list of suggestions
313#filter PBSUG =
314
315# PBREC is replaced by the list of recommandations
316#filter PBREC =
317
318# PBLOG is replaced by the changelog if value is yes
319#filter PBLOG = yes
320
321# PBPKG is replaced by the package name (\$pbpkg in code)
322#filter PBPKG = \$pbpkg
323
324# PBPACKAGER is replaced by the packager name (\$pbpackager in code)
325#filter PBPACKAGER = \$pbpackager
326
327EOF
328 close(CONF);
329 open(CONF,"> $ENV{'PBCONF'}/pbfilter/md.pbf") || die "Unable to create $ENV{'PBCONF'}/pbfilter/md.pbf";
330 print CONF << "EOF";
331# Specific group for Mandriva for $proj
332filter PBGRP = Archiving/Backup
333EOF
334 close(CONF);
335 open(CONF,"> $ENV{'PBCONF'}/pbfilter/novell.pbf") || die "Unable to create $ENV{'PBCONF'}/pbfilter/novell.pbf";
336 print CONF << "EOF";
337# Specific group for SuSE for $proj
338filter PBGRP = Productivity/Archiving/Backup
339EOF
340 close(CONF);
341 pb_mkdir_p("$ENV{'PBCONF'}/pkg1/deb") || die "Unable to create $ENV{'PBCONF'}/pkg1/deb";
342 open(CONF,"> $ENV{'PBCONF'}/pkg1/deb/control") || die "Unable to create $ENV{'PBCONF'}/pkg1/deb/control";
343 print CONF << "EOF";
344Source: PBPKG
345Section: PBGRP
346Priority: optional
347Maintainer: PBPACKAGER
348Build-Depends: debhelper (>= 4.2.20), PBDEP
349Standards-Version: 3.6.1
350
351Package: PBPKG
352Architecture: amd64 i386 ia64
353Section: PBGRP
354Priority: optional
355Depends: \${shlibs:Depends}, \${misc:Depends}, PBDEP
356Recommends: PBREC
357Suggests: PBSUG
358Description:
359 PBDESC
360 .
361 Homepage: PBURL
362
363EOF
364 close(CONF);
365 open(CONF,"> $ENV{'PBCONF'}/pkg1/deb/copyright") || die "Unable to create $ENV{'PBCONF'}/pkg1/deb/copyright";
366 print CONF << "EOF";
367This package is debianized by PBPACKAGER
368`date`
369
370The current upstream source was downloaded from
371ftp://ftp.$proj.org/src/.
372
373Upstream Authors: Put their name here
374
375Copyright:
376
377 This package is free software; you can redistribute it and/or modify
378 it under the terms of the GNU General Public License as published by
379 the Free Software Foundation; version 2 dated June, 1991.
380
381 This package is distributed in the hope that it will be useful,
382 but WITHOUT ANY WARRANTY; without even the implied warranty of
383 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
384 GNU General Public License for more details.
385
386 You should have received a copy of the GNU General Public License
387 along with this package; if not, write to the Free Software
388 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
389 MA 02110-1301, USA.
390
391On Debian systems, the complete text of the GNU General
392Public License can be found in /usr/share/common-licenses/GPL.
393
394EOF
395 close(CONF);
396 open(CONF,"> $ENV{'PBCONF'}/pkg1/deb/changelog") || die "Unable to create $ENV{'PBCONF'}/pkg1/deb/changelog";
397 print CONF << "EOF";
398PBLOG
399EOF
400 close(CONF);
401 open(CONF,"> $ENV{'PBCONF'}/pkg1/deb/compat") || die "Unable to create $ENV{'PBCONF'}/pkg1/deb/compat";
402 print CONF << "EOF";
4034
404EOF
405 close(CONF);
406 open(CONF,"> $ENV{'PBCONF'}/pkg1/deb/pkg1.dirs") || die "Unable to create $ENV{'PBCONF'}/pkg1/deb/pkg1.dirs";
407 print CONF << "EOF";
408EOF
409 close(CONF);
410 open(CONF,"> $ENV{'PBCONF'}/pkg1/deb/pkg1.docs") || die "Unable to create $ENV{'PBCONF'}/pkg1/deb/pkg1.docs";
411 print CONF << "EOF";
412INSTALL
413COPYING
414AUTHORS
415NEWS
416README
417EOF
418 close(CONF);
419 open(CONF,"> $ENV{'PBCONF'}/pkg1/deb/rules") || die "Unable to create $ENV{'PBCONF'}/pkg1/deb/rules";
420 print CONF << 'EOF';
421#!/usr/bin/make -f
422# -*- makefile -*-
423# Sample debian/rules that uses debhelper.
424# GNU copyright 1997 to 1999 by Joey Hess.
425#
426# $Id$
427#
428
429# Uncomment this to turn on verbose mode.
430#export DH_VERBOSE=1
431
432# Define package name variable for a one-stop change.
433PACKAGE_NAME = PBPKG
434
435# These are used for cross-compiling and for saving the configure script
436# from having to guess our platform (since we know it already)
437DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
438DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
439
440CFLAGS = -Wall -g
441
442ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
443 CFLAGS += -O0
444else
445 CFLAGS += -O2
446endif
447ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
448 INSTALL_PROGRAM += -s
449endif
450config.status: configure
451 dh_testdir
452
453 # Configure the package.
454 CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr
455 --mandir=\$${prefix}/share/man
456
457# Build both architecture dependent and independent
458build: build-arch build-indep
459
460# Build architecture dependent
461build-arch: build-arch-stamp
462
463build-arch-stamp: config.status
464 dh_testdir
465
466 # Compile the package.
467 $(MAKE)
468
469 touch build-stamp
470
471# Build architecture independent
472build-indep: build-indep-stamp
473
474build-indep-stamp: config.status
475 # Nothing to do, the only indep item is the manual which is available as html in original source
476 touch build-indep-stamp
477
478# Clean up
479clean:
480 dh_testdir
481 dh_testroot
482 rm -f build-arch-stamp build-indep-stamp #CONFIGURE-STAMP#
483 # Clean temporary document directory
484 rm -rf debian/doc-temp
485 # Clean up.
486 -$(MAKE) distclean
487 rm -f config.log
488ifneq "$(wildcard /usr/share/misc/config.sub)" ""
489 cp -f /usr/share/misc/config.sub config.sub
490endif
491ifneq "$(wildcard /usr/share/misc/config.guess)" ""
492 cp -f /usr/share/misc/config.guess config.guess
493endif
494
495 dh_clean
496
497# Install architecture dependent and independent
498install: install-arch install-indep
499
500# Install architecture dependent
501install-arch: build-arch
502 dh_testdir
503 dh_testroot
504 dh_clean -k -s
505 dh_installdirs -s
506
507 # Install the package files into build directory:
508 # - start with upstream make install
509 $(MAKE) install prefix=$(CURDIR)/debian/$(PACKAGE_NAME)/usr mandir=$(CURDIR)/debian/$(PACKAGE_NAME)/us
510r/share/man
511 # - copy html manual to temporary location for renaming
512 mkdir -p debian/doc-temp
513 dh_install -s
514
515# Install architecture independent
516install-indep: build-indep
517 dh_testdir
518 dh_testroot
519 dh_clean -k -i
520 dh_installdirs -i
521 dh_install -i
522
523# Must not depend on anything. This is to be called by
524# binary-arch/binary-indep
525# in another 'make' thread.
526binary-common:
527 dh_testdir
528 dh_testroot
529 dh_installchangelogs ChangeLog
530 dh_installdocs
531 dh_installman
532 dh_link
533 dh_strip
534 dh_compress
535 dh_fixperms
536 dh_installdeb
537 dh_shlibdeps
538 dh_gencontrol
539 dh_md5sums
540 dh_builddeb
541
542# Build architecture independant packages using the common target.
543binary-indep: build-indep install-indep
544 $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
545
546# Build architecture dependant packages using the common target.
547binary-arch: build-arch install-arch
548 $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
549
550# Build architecture depdendent and independent packages
551binary: binary-arch binary-indep
552.PHONY: clean binary
553
554EOF
555 close(CONF);
556 pb_mkdir_p("$ENV{'PBCONF'}/pkg1/rpm") || die "Unable to create $ENV{'PBCONF'}/pkg1/rpm";
557 open(CONF,"> $ENV{'PBCONF'}/pkg1/rpm/pkg1.spec") || die "Unable to create $ENV{'PBCONF'}/pkg1/rpm/pkg1.spec";
558 print CONF << 'EOF';
559#
560# $Id$
561#
562
563Summary: bla-bla
564Summary(fr): french bla-bla
565
566Name: PBPKG
567Version: PBVER
568Release: PBTAGPBSUF
569License: GPL
570Group: PBGRP
571Url: PBURL
572Source: PBSRC
573BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -u -n)
574Requires: PBDEP
575
576%description
577PBDESC
578
579%description -l fr
580french desc
581
582%prep
583%setup -q
584
585%build
586%configure
[288]587make %{?_smp_mflags}
[273]588
589%install
590%{__rm} -rf $RPM_BUILD_ROOT
591make DESTDIR=$RPM_BUILD_ROOT install
592
593%clean
594%{__rm} -rf $RPM_BUILD_ROOT
595
596%files
597%defattr(-,root,root)
598%doc ChangeLog
599%doc INSTALL COPYING README AUTHORS NEWS
600
601%changelog
602PBLOG
603
604EOF
605 close(CONF);
606 pb_mkdir_p("$ENV{'PBCONF'}/pkg1/pbfilter") || die "Unable to create $ENV{'PBCONF'}/pkg1/pbfilter";
607
608 print "\nDo not to forget to commit the pbconf directory in your CMS if needed\n";
609 print "After having renamed the pkg1 directory to your package's name \n\n";
610 } else {
611 die "Unable to open $ENV{'PBCONF'}/$proj.pb";
612 }
[98]613}
614
[8]615#
[105]616# Set temp directory
617#
618if (not defined $ENV{'TMPDIR'}) {
619 $ENV{'TMPDIR'}="/tmp";
620}
621$ENV{'PBTMP'} = tempdir( "pb.XXXXXXXXXX", DIR => $ENV{'TMPDIR'}, CLEANUP => 1 );
622
623#
[69]624# Removes all directory existing below the delivery dir
625# as they are temp dir only
[68]626# Files stay and have to be cleaned up manually
[8]627#
[25]628if (-d $ENV{'PBDESTDIR'}) {
629 opendir(DIR,$ENV{'PBDESTDIR'}) || die "Unable to open directory $ENV{'PBDESTDIR'}: $!";
630 foreach my $d (readdir(DIR)) {
631 next if ($d =~ /^\./);
[68]632 next if (-f "$ENV{'PBDESTDIR'}/$d");
[74]633 pb_rm_rf("$ENV{'PBDESTDIR'}/$d") if (-d "$ENV{'PBDESTDIR'}/$d");
[25]634 }
635 closedir(DIR);
636}
637if (! -d "$ENV{'PBDESTDIR'}") {
[74]638 pb_mkdir_p($ENV{'PBDESTDIR'}) || die "Unable to recursively create $ENV{'PBDESTDIR'}";
[25]639}
[5]640
[25]641#
642# Set build directory
643#
[71]644$ENV{'PBBUILDDIR'}=$topdir."/build";
[101]645if (! -d "$ENV{'PBBUILDDIR'}") {
646 pb_mkdir_p($ENV{'PBBUILDDIR'}) || die "Unable to recursively create $ENV{'PBBUILDDIR'}";
647}
[25]648
[8]649umask 0022;
[300]650return($proj,$debug,$LOG,\%pbrc, \%filteredfiles, \%supfiles, \%defpkgdir, \%extpkgdir);
[2]651}
[9]652
[74]653# Internal mkdir -p function
654sub pb_mkdir_p {
[29]655my @dir = @_;
656my $ret = mkpath(@dir, 0, 0755);
657return($ret);
[9]658}
659
[74]660# Internal rm -rf function
661sub pb_rm_rf {
[29]662my @dir = @_;
663my $ret = rmtree(@dir, 0, 0);
664return($ret);
[9]665}
666
[74]667# Internal system function
668sub pb_system {
[29]669
670my $cmd=shift;
[30]671my $cmt=shift || $cmd;
[29]672
[108]673print "$cmt... ";
[117]674#system("$cmd 2>&1 > $ENV{'PBTMP'}/system.log");
[293]675system($cmd);
[29]676if ($? == -1) {
[108]677 print "failed to execute ($cmd) : $!\n";
[106]678 pb_display_file("$ENV{'PBTMP'}/system.log");
[29]679} elsif ($? & 127) {
[108]680 printf "child ($cmd) died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without';
[106]681 pb_display_file("$ENV{'PBTMP'}/system.log");
682} elsif ($? == 0) {
[108]683 print "OK\n";
[29]684} else {
[106]685 printf "child ($cmd) exited with value %d\n", $? >> 8;
686 pb_display_file("$ENV{'PBTMP'}/system.log");
[29]687}
[30]688}
[74]689
[106]690sub pb_display_file {
691
692my $file=shift;
693
[117]694return if (not -f $file);
695open(FILE,"$file");
[106]696while (<FILE>) {
[108]697 print $_;
[106]698}
699close(FILE);
700}
701
[242]702# Function which returns a pointer on a table
703# corresponding to a set of values queried in the conf file
[88]704# and test the returned vaue as they need to exist in that case
705sub pb_conf_get {
706
707my @param = @_;
708
[242]709# Everything is returned via ptr1
710my @ptr1 = pb_conf_read("$ENV{'PBETC'}", @param);
711my @ptr2 = pb_conf_read("$ENV{'PBCONF'}/$ENV{'PBPROJ'}.pb", @param);
[89]712
[242]713my $p1;
714my $p2;
715
[262]716#print "DEBUG: param1: ".Dumper(@ptr1)."\n"; # if ($debug >= 1);
717#print "DEBUG: param2: ".Dumper(@ptr2)."\n"; # if ($debug >= 1);
718
[88]719foreach my $i (0..$#param) {
[262]720 $p1 = $ptr1[$i];
721 $p2 = $ptr2[$i];
[265]722 die "No $param[$i] defined for $ENV{'PBPROJ'}" if ((not @ptr1) && (not @ptr2));
[262]723 die "No $param[$i] defined for $ENV{'PBPROJ'}" if ((not defined $p1) && (not defined $p2));
[242]724 # Always try to take the param from the home dir conf file in priority
725 # in order to mask what could be defined under the CMS to allow for overloading
726 if (not defined $p2) {
727 # No ref in CMS project conf file so use the home dir one.
728 $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if (not defined $p1->{$ENV{'PBPROJ'}});
729 } else {
730 # Ref found in CMS project conf file
731 if (not defined $p1) {
732 # No ref in home dir project conf file so use the CMS one.
733 $p2->{$ENV{'PBPROJ'}} = $p2->{'default'} if (not defined $p2->{$ENV{'PBPROJ'}});
734 $p1->{$ENV{'PBPROJ'}} = $p2->{$ENV{'PBPROJ'}};
735 } else {
736 # Both are defined - handling the overloading
737 if (not defined $p1->{'default'}) {
738 if (defined $p2->{'default'}) {
739 $p1->{'default'} = $p2->{'default'};
740 }
741 }
742
743 if (not defined $p1->{$ENV{'PBPROJ'}}) {
744 if (defined $p2->{$ENV{'PBPROJ'}}) {
745 $p1->{$ENV{'PBPROJ'}} = $p2->{$ENV{'PBPROJ'}};
746 } else {
747 $p1->{$ENV{'PBPROJ'}} = $p1->{'default'};
748 }
749 }
750 }
751 }
752 die "No $param[$i] defined for $ENV{'PBPROJ'}" if (not defined $p1->{$ENV{'PBPROJ'}});
[262]753 $ptr1[$i] = $p1;
754 #print "DEBUG: param ptr1: ".Dumper(@ptr1)."\n"; # if ($debug >= 1);
[88]755}
[242]756return(@ptr1);
[88]757}
758
759# Function which returns a pointer on a hash
[74]760# corresponding to a declaration (arg2) in a conf file (arg1)
761sub pb_conf_read {
762
763my $conffile = shift;
764my @param = @_;
765my $trace;
766my @ptr;
[291]767my %h;
[74]768
[108]769my $debug = 0;
770
[291]771open(CONF,$conffile) || die "Unable to open $conffile";
772while(<CONF>) {
773 if (/^\s*([A-z0-9-_]+)\s+([[A-z0-9-_]+)\s*=\s*(.+)$/) {
774 print "DEBUG: 1:$1 2:$2 3:$3\n" if ($debug >= 1);
775 $h{$1}{$2}=$3;
776 }
[74]777}
[291]778close(CONF);
[74]779
780for my $param (@param) {
[291]781 push @ptr,$h{$param};
[74]782}
[291]783print "DEBUG: h:".Dumper(%h)." param:".Dumper(@param)." ptr:".Dumper(@ptr)."\n" if ($debug >= 1);
[89]784return(@ptr);
[74]785}
786
787# Setup environment for CMS system
788sub pb_cms_init {
789
790my $proj = shift || undef;
791my $ret;
792
[89]793my ($cms) = pb_conf_get("cms");
[74]794
[88]795if ($cms->{$proj} eq "svn") {
[74]796 $ENV{'PBREVISION'}=`(cd "$ENV{'PBROOT'}" ; svnversion .)`;
797 chomp($ENV{'PBREVISION'});
798 $ENV{'PBCMSLOGFILE'}="svn.log";
[226]799} elsif ($cms->{$proj} eq "flat") {
800 $ENV{'PBREVISION'}="flat";
[227]801 $ENV{'PBCMSLOGFILE'}="flat.log";
[88]802} elsif ($cms->{$proj} eq "cvs") {
[106]803 # Way too slow
804 #$ENV{'PBREVISION'}=`(cd "$ENV{'PBROOT'}" ; cvs rannotate -f . 2>&1 | awk '{print \$1}' | grep -E '^[0-9]' | cut -d. -f2 |sort -nu | tail -1)`;
805 #chomp($ENV{'PBREVISION'});
806 $ENV{'PBREVISION'}="CVS";
[74]807 $ENV{'PBCMSLOGFILE'}="cvs.log";
[87]808 #
809 # Export content if needed
810 #
[242]811 my ($cvsroot,$cvsrsh) = pb_conf_get("cvsroot","cvsrsh");
[88]812 $ENV{'CVSROOT'} = $cvsroot->{$proj} if (defined $cvsroot->{$proj});
[299]813 $ENV{'CVS_RSH'} = $cvsrsh->{$proj} if (defined $cvsrsh->{$proj});
[74]814} else {
[88]815 die "cms $cms->{$proj} unknown";
[74]816}
[106]817return($cms);
[74]818}
819
[106]820sub pb_cms_export {
821my $cms = shift;
822my $pbdate = shift || undef;
[108]823my $source = shift;
[106]824my $destdir = shift;
[108]825my $tmp;
[115]826my $tmp1;
[106]827
828if ($cms->{$ENV{'PBPROJ'}} eq "svn") {
[108]829 if (-d $source) {
830 $tmp = $destdir;
831 } else {
832 $tmp = $destdir."/".basename($source);
833 }
[116]834 pb_system("svn export $source $tmp","Exporting $source from SVN to $tmp");
[226]835} elsif ($cms->{$ENV{'PBPROJ'}} eq "flat") {
836 if (-d $source) {
837 $tmp = $destdir;
838 } else {
839 $tmp = $destdir."/".basename($source);
840 }
841 pb_system("cp -a $source $tmp","Exporting $source from DIR to $tmp");
[106]842} elsif ($cms->{$ENV{'PBPROJ'}} eq "cvs") {
843 my $dir=dirname($destdir);
844 my $base=basename($destdir);
[115]845 if (-d $source) {
846 $tmp1 = $source;
847 $tmp1 =~ s|$ENV{'PBROOT'}/||;
848 } else {
849 $tmp1 = dirname($source);
850 $tmp1 =~ s|$ENV{'PBROOT'}/||;
851 $tmp1 = $tmp1."/".basename($source);
852 }
[106]853 # CVS needs a relative path !
[115]854 pb_system("cd $dir ; cvs export -D \"$pbdate\" -d $base $tmp1","Exporting $source from CVS to $destdir");
[106]855} else {
856 die "cms $cms->{$ENV{'PBPROJ'}} unknown";
857}
858}
859
[285]860
861sub pb_create_authors {
862
863my $authors=shift;
864my $dest=shift;
865my $cms=shift;
866
[286]867return if ($authors eq "/dev/null");
868open(SAUTH,$authors) || die "Unable to open $authors";
[285]869open(DAUTH,"> $dest/AUTHORS") || die "Unable to create $dest/AUTHORS";
870print DAUTH "Authors of the project are:\n";
871print DAUTH "===========================\n";
[286]872while (<SAUTH>) {
[285]873 my ($nick,$gcos) = split(/:/);
[286]874 chomp($gcos);
[285]875 print DAUTH "$gcos";
[286]876 if (defined $cms) {
877 print DAUTH " ($nick under $cms)\n";
878 } else {
879 print DAUTH "\n";
880 }
[285]881}
882close(DAUTH);
[286]883close(SAUTH);
[285]884}
885
[106]886sub pb_cms_log {
887my $cms = shift;
888my $pkgdir = shift;
[285]889my $dest = shift;
[286]890my $chglog = shift;
[285]891my $authors = shift;
[106]892
[285]893pb_create_authors($authors,$dest,$cms->{$ENV{'PBPROJ'}});
894
[106]895if ($cms->{$ENV{'PBPROJ'}} eq "svn") {
[286]896 if (! -f "$dest/ChangeLog") {
897 if (-x "/usr/bin/svn2cl") {
898 pb_system("/usr/bin/svn2cl --group-by-day --authors=$authors -i -o $dest/ChangeLog $pkgdir","Generating ChangeLog from SVN");
899 } else {
900 # To be written from pbcl
901 pb_system("svn log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVN");
902 }
[285]903 }
[226]904} elsif ($cms->{$ENV{'PBPROJ'}} eq "flat") {
[288]905 if (! -f "$dest/ChangeLog") {
906 pb_system("echo ChangeLog for $pkgdir > $dest/ChangeLog","Empty ChangeLog file created");
907 }
[106]908} elsif ($cms->{$ENV{'PBPROJ'}} eq "cvs") {
909 my $tmp=basename($pkgdir);
910 # CVS needs a relative path !
[286]911 if (! -f "$dest/ChangeLog") {
912 if (-x "/usr/bin/cvs2cl") {
[288]913 pb_system("/usr/bin/cvs2cl --group-by-day -U $authors -f $dest/ChangeLog $pkgdir","Generating ChangeLog from CVS");
[286]914 } else {
915 # To be written from pbcl
916 pb_system("cvs log $tmp > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from CVS");
917 }
[285]918 }
[106]919} else {
920 die "cms $cms->{$ENV{'PBPROJ'}} unknown";
921}
922}
923
[204]924sub pb_cms_getinfo {
925my $cms = shift;
926my $url = "";
927my $void = "";
[106]928
[204]929if ($cms->{$ENV{'PBPROJ'}} eq "svn") {
930 open(PIPE,"LANGUAGE=C svn info $ENV{'PBROOT'} |") || die "Unable to get svn info from $ENV{'PBROOT'}";
931 while (<PIPE>) {
[206]932 ($void,$url) = split(/^URL:/) if (/^URL:/);
[204]933 }
934 close(PIPE);
[205]935 chomp($url);
[226]936} elsif ($cms->{$ENV{'PBPROJ'}} eq "flat") {
[204]937} elsif ($cms->{$ENV{'PBPROJ'}} eq "cvs") {
938} else {
939 die "cms $cms->{$ENV{'PBPROJ'}} unknown";
940}
941return($url);
942}
943
944sub pb_cms_copy {
945my $cms = shift;
946my $oldurl = shift;
947my $newurl = shift;
948
949if ($cms->{$ENV{'PBPROJ'}} eq "svn") {
[212]950 pb_system("svn copy -m \"Creation of $newurl from $oldurl\" $oldurl $newurl","Copying $oldurl to $newurl ");
[226]951} elsif ($cms->{$ENV{'PBPROJ'}} eq "flat") {
[204]952} elsif ($cms->{$ENV{'PBPROJ'}} eq "cvs") {
953} else {
954 die "cms $cms->{$ENV{'PBPROJ'}} unknown";
955}
956}
957
958sub pb_cms_checkout {
959my $cms = shift;
960my $url = shift;
961my $destination = shift;
962
963if ($cms->{$ENV{'PBPROJ'}} eq "svn") {
964 pb_system("svn co $url $destination","Checking $url to $destination ");
[226]965} elsif ($cms->{$ENV{'PBPROJ'}} eq "flat") {
[204]966} elsif ($cms->{$ENV{'PBPROJ'}} eq "cvs") {
967} else {
968 die "cms $cms->{$ENV{'PBPROJ'}} unknown";
969}
970}
971
[208]972sub pb_cms_checkin {
973my $cms = shift;
974my $dir = shift;
975
[212]976my $ver = basename($dir);
[208]977if ($cms->{$ENV{'PBPROJ'}} eq "svn") {
[212]978 pb_system("svn ci -m \"Updated to $ver\" $dir","Checking in $dir");
[208]979 pb_system("svn up $dir","Updating $dir");
[226]980} elsif ($cms->{$ENV{'PBPROJ'}} eq "flat") {
[208]981} elsif ($cms->{$ENV{'PBPROJ'}} eq "cvs") {
982} else {
983 die "cms $cms->{$ENV{'PBPROJ'}} unknown";
984}
985}
986
[204]987sub pb_cms_isdiff {
988my $cms = shift;
989
990if ($cms->{$ENV{'PBPROJ'}} eq "svn") {
991 open(PIPE,"svn diff $ENV{'PBROOT'} |") || die "Unable to get svn diff from $ENV{'PBROOT'}";
992 my $l = 0;
993 while (<PIPE>) {
994 $l++;
995 }
996 return($l);
[226]997} elsif ($cms->{$ENV{'PBPROJ'}} eq "flat") {
[204]998} elsif ($cms->{$ENV{'PBPROJ'}} eq "cvs") {
999} else {
1000 die "cms $cms->{$ENV{'PBPROJ'}} unknown";
1001}
1002}
1003
[77]1004# Get all filters to apply
1005# They're cumulative from less specific to most specific
1006# suffix is .pbf
1007
1008sub pb_get_filters {
1009
[108]1010# For the moment not dynamic
1011my $debug = 0; # Debug level
1012my $LOG = *STDOUT; # Where to log
1013
[77]1014my @ffiles;
[235]1015my ($ffile00, $ffile0, $ffile1, $ffile2, $ffile3);
1016my ($mfile00, $mfile0, $mfile1, $mfile2, $mfile3);
[77]1017my $pbpkg = shift || die "No package specified";
[236]1018my $dtype = shift || "";
1019my $dfam = shift || "";
1020my $ddir = shift || "";
1021my $dver = shift || "";
[77]1022my $ptr; # returned value pointer on the hash of filters
[79]1023my %ptr;
[291]1024my %h;
[77]1025
[169]1026# Global filter files first, then package specificities
1027if (-d "$ENV{'PBCONF'}/pbfilter") {
[231]1028 $mfile00 = "$ENV{'PBCONF'}/pbfilter/all.pbf" if (-f "$ENV{'PBCONF'}/pbfilter/all.pbf");
[169]1029 $mfile0 = "$ENV{'PBCONF'}/pbfilter/$dtype.pbf" if (-f "$ENV{'PBCONF'}/pbfilter/$dtype.pbf");
1030 $mfile1 = "$ENV{'PBCONF'}/pbfilter/$dfam.pbf" if (-f "$ENV{'PBCONF'}/pbfilter/$dfam.pbf");
1031 $mfile2 = "$ENV{'PBCONF'}/pbfilter/$ddir.pbf" if (-f "$ENV{'PBCONF'}/pbfilter/$ddir.pbf");
1032 $mfile3 = "$ENV{'PBCONF'}/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBCONF'}/pbfilter/$ddir-$dver.pbf");
1033
[231]1034 push @ffiles,$mfile00 if (defined $mfile00);
[169]1035 push @ffiles,$mfile0 if (defined $mfile0);
1036 push @ffiles,$mfile1 if (defined $mfile1);
1037 push @ffiles,$mfile2 if (defined $mfile2);
1038 push @ffiles,$mfile3 if (defined $mfile3);
1039}
1040
[77]1041if (-d "$ENV{'PBCONF'}/$pbpkg/pbfilter") {
[231]1042 $ffile00 = "$ENV{'PBCONF'}/$pbpkg/pbfilter/all.pbf" if (-f "$ENV{'PBCONF'}/$pbpkg/pbfilter/all.pbf");
[77]1043 $ffile0 = "$ENV{'PBCONF'}/$pbpkg/pbfilter/$dtype.pbf" if (-f "$ENV{'PBCONF'}/$pbpkg/pbfilter/$dtype.pbf");
1044 $ffile1 = "$ENV{'PBCONF'}/$pbpkg/pbfilter/$dfam.pbf" if (-f "$ENV{'PBCONF'}/$pbpkg/pbfilter/$dfam.pbf");
1045 $ffile2 = "$ENV{'PBCONF'}/$pbpkg/pbfilter/$ddir.pbf" if (-f "$ENV{'PBCONF'}/$pbpkg/pbfilter/$ddir.pbf");
1046 $ffile3 = "$ENV{'PBCONF'}/$pbpkg/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBCONF'}/$pbpkg/pbfilter/$ddir-$dver.pbf");
1047
[231]1048 push @ffiles,$ffile00 if (defined $ffile00);
[77]1049 push @ffiles,$ffile0 if (defined $ffile0);
1050 push @ffiles,$ffile1 if (defined $ffile1);
1051 push @ffiles,$ffile2 if (defined $ffile2);
1052 push @ffiles,$ffile3 if (defined $ffile3);
1053}
1054if (@ffiles) {
1055 print $LOG "DEBUG ffiles: ".Dumper(\@ffiles)."\n" if ($debug >= 1);
[79]1056
[291]1057 foreach my $f (@ffiles) {
1058 open(CONF,$f) || next;
1059 while(<CONF>) {
1060 if (/^\s*([A-z0-9-_]+)\s+([[A-z0-9-_]+)\s*=\s*(.+)$/) {
1061 $h{$1}{$2}=$3;
1062 }
[79]1063 }
[291]1064 close(CONF);
[79]1065
[291]1066 $ptr = $h{"filter"};
1067 print $LOG "DEBUG f:".Dumper($ptr)."\n" if ($debug >= 1);
1068 }
[77]1069} else {
1070 $ptr = { };
1071}
[79]1072%ptr = %$ptr;
1073return(\%ptr);
[77]1074}
1075
[236]1076# Function which applies filter on pb build files
[77]1077sub pb_filter_file_pb {
1078
1079my $f=shift;
1080my $ptr=shift;
1081my %filter=%$ptr;
1082my $destfile=shift;
1083my $dtype=shift;
[99]1084my $pbsuf=shift;
[297]1085my $pbproj=shift;
[80]1086my $pbpkg=shift;
1087my $pbver=shift;
1088my $pbtag=shift;
1089my $pbrev=shift;
1090my $pbdate=shift;
[108]1091my $defpkgdir = shift;
1092my $extpkgdir = shift;
[174]1093my $pbpackager = shift;
[285]1094my $chglog = shift || undef;
[77]1095
[108]1096# For the moment not dynamic
1097my $debug = 0; # Debug level
1098my $LOG = *STDOUT; # Where to log
1099
[77]1100print $LOG "DEBUG: From $f to $destfile\n" if ($debug >= 1);
1101pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
1102open(DEST,"> $destfile") || die "Unable to create $destfile";
1103open(FILE,"$f") || die "Unable to open $f: $!";
1104while (<FILE>) {
1105 my $line = $_;
1106 foreach my $s (keys %filter) {
1107 # Process single variables
[79]1108 print $LOG "DEBUG filter{$s}: $filter{$s}\n" if ($debug >= 1);
[77]1109 my $tmp = $filter{$s};
1110 next if (not defined $tmp);
1111 # Expand variables if any single one found
[79]1112 print $LOG "DEBUG tmp: $tmp\n" if ($debug >= 1);
[77]1113 if ($tmp =~ /\$/) {
1114 eval { $tmp =~ s/(\$\w+)/$1/eeg };
1115 # special case for ChangeLog only for pb
[259]1116 } elsif (($s =~ /^PBLOG$/) && ($line =~ /^PBLOG$/)) {
[108]1117 my $p = $defpkgdir->{$pbpkg};
1118 $p = $extpkgdir->{$pbpkg} if (not defined $p);
[285]1119 pb_changelog($dtype, $pbpkg, $pbver, $pbtag, $pbsuf, $p, \*DEST, $tmp, $chglog);
[254]1120 $tmp = "";
[77]1121 }
1122 $line =~ s|$s|$tmp|;
1123 }
1124 print DEST $line;
1125}
1126close(FILE);
1127close(DEST);
1128}
1129
1130# Function which applies filter on files (external call)
1131sub pb_filter_file {
1132
1133my $f=shift;
1134my $ptr=shift;
1135my %filter=%$ptr;
1136my $destfile=shift;
[298]1137my $pbproj=shift;
[80]1138my $pbpkg=shift;
1139my $pbver=shift;
1140my $pbtag=shift;
1141my $pbrev=shift;
1142my $pbdate=shift;
[174]1143my $pbpackager=shift;
[77]1144
[108]1145# For the moment not dynamic
1146my $debug = 0; # Debug level
1147my $LOG = *STDOUT; # Where to log
1148
[77]1149print $LOG "DEBUG: From $f to $destfile\n" if ($debug >= 1);
1150pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
1151open(DEST,"> $destfile") || die "Unable to create $destfile";
1152open(FILE,"$f") || die "Unable to open $f: $!";
1153while (<FILE>) {
1154 my $line = $_;
1155 foreach my $s (keys %filter) {
1156 # Process single variables
1157 print $LOG "DEBUG filter{$s}: $filter{$s}\n" if ($debug > 1);
1158 my $tmp = $filter{$s};
1159 next if (not defined $tmp);
1160 # Expand variables if any single one found
1161 if ($tmp =~ /\$/) {
1162 eval { $tmp =~ s/(\$\w+)/$1/eeg };
1163 }
1164 $line =~ s|$s|$tmp|;
1165 }
1166 print DEST $line;
1167}
1168close(FILE);
1169close(DEST);
1170}
1171
1172
[2]11731;
Note: See TracBrowser for help on using the repository browser.