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

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

Small fixes for CMS support

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