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
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# 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
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#
192
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 {
200 pb_log(0,"WARNING: no pbconfdir defined, using $ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/pbconf\n");
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");
203 $ENV{'PBCONF'} = "$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}/pbconf";
204}
205
206# Expand potential env variable in it
207eval { $ENV{'PBCONF'} =~ s/(\$ENV.+\})/$1/eeg };
208pb_log(2,"PBCONF: $ENV{'PBCONF'}\n");
209
210my ($scheme, $account, $host, $port, $path) = pb_get_uri($pbconf{$ENV{'PBPROJ'}});
211
212if ((! -d "$ENV{'PBCONF'}") || (defined $pbinit)) {
213 pb_log(1,"Checking out pbconf\n");
214 pb_cms_checkout($scheme,$pbconf{$ENV{'PBPROJ'}},$ENV{'PBCONF'});
215} else {
216 pb_log(1,"pbconf found, checking content\n");
217 my $cmsurl = pb_cms_getinfo($scheme,$ENV{'PBCONF'},"URL:");
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");
221 pb_rm_rf("$ENV{'PBCONF'}");
222 pb_cms_checkout($scheme,$pbconf{$ENV{'PBPROJ'}},$ENV{'PBCONF'});
223 } elsif ($cmsurl ne $pbconf{$ENV{'PBPROJ'}}) {
224 # The local content doesn't correpond to the repository
225 pb_log(0,"ERROR: Inconsistency detected:\n");
226 pb_log(0," * $ENV{'PBCONF'} refers to $cmsurl but\n");
227 pb_log(0," * $ENV{'PBETC'} refers to $pbconf{$ENV{'PBPROJ'}}\n");
228 die "Project $ENV{'PBPROJ'} is not Project-Builder compliant.";
229 } else {
230 pb_log(1,"Content correct - doing nothing - you may want to update your repository however\n");
231 # they match - do nothing - there may be local changes
232 }
233}
234
235# Check where is our PBROOT (release tag name can't be guessed the first time)
236#
237if (not defined $ENV{'PBROOT'}) {
238 if (! -f ("$ENV{'PBDESTDIR'}/pbrc")) {
239 opendir(DIR,$ENV{'PBCONF'}) || die "Unable to open directory $ENV{'PBCONF'}: $!";
240 my $maxmtime = 0;
241 foreach my $d (readdir(DIR)) {
242 pb_log(3,"Looking at \'$d\'...");
243 next if ($d =~ /^\./);
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");
248 # Keep the most recent
249 pb_log(2," $s->mtime\n");
250 if ($s->mtime > $maxmtime) {
251 $ENV{'PBROOT'} = "$ENV{'PBCONF'}/$d";
252 $maxmtime = $s->mtime;
253 }
254 }
255 closedir(DIR);
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");
258 pb_log(0," Please use -r release if you want to use another release\n");
259 } else {
260 my ($pbroot) = pb_conf_read_if("$ENV{'PBDESTDIR'}/pbrc","pbroot");
261 # That's always the environment variable that will be used
262 die "Please remove inconsistent $ENV{'PBDESTDIR'}/pbrc" if ((not defined $pbroot) || (not defined $pbroot->{$ENV{'PBPROJ'}}));
263 $ENV{'PBROOT'} = $pbroot->{$ENV{'PBPROJ'}};
264 }
265} else {
266 # transform in full path if relative
267 $ENV{'PBROOT'} = "$ENV{'PBCONF'}/$ENV{'PBROOT'}" if ($ENV{'PBROOT'} !~ /^\//);
268 die "$ENV{'PBROOT'} is not a directory" if (not -d $ENV{'PBROOT'});
269}
270
271my %version = ();
272my %defpkgdir = ();
273my %extpkgdir = ();
274my %filteredfiles = ();
275my %supfiles = ();
276
277if ((-f "$ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb") and (not defined $pbinit)) {
278 # List of pkg to build by default (mandatory)
279 my ($defpkgdir,$pbpackager) = pb_conf_get("defpkgdir","pbpackager");
280 # List of additional pkg to build when all is called (optional)
281 # Valid version names (optional)
282 # List of files to filter (optional)
283 # Project version and tag (optional)
284 my ($extpkgdir, $version, $filteredfiles, $supfiles, $pkgv, $pkgt) = pb_conf_get_if("extpkgdir","version","filteredfiles","supfiles","projver","projtag");
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");
290 # Global
291 %defpkgdir = %$defpkgdir;
292 %extpkgdir = %$extpkgdir if (defined $extpkgdir);
293 %version = %$version if (defined $version);
294 %filteredfiles = %$filteredfiles if (defined $filteredfiles);
295 %supfiles = %$supfiles if (defined $supfiles);
296 #
297 # Get global Version/Tag
298 #
299 if (not defined $ENV{'PBVER'}) {
300 if ((defined $pkgv) && (defined $pkgv->{$ENV{'PBPROJ'}})) {
301 $ENV{'PBVER'}=$pkgv->{$ENV{'PBPROJ'}};
302 } else {
303 die "No projver found in $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb";
304 }
305 }
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'}}/));
307
308 if (not defined $ENV{'PBTAG'}) {
309 if ((defined $pkgt) && (defined $pkgt->{$ENV{'PBPROJ'}})) {
310 $ENV{'PBTAG'}=$pkgt->{$ENV{'PBPROJ'}};
311 } else {
312 die "No projtag found in $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb";
313 }
314 }
315 die "Invalid tag name $ENV{'PBTAG'} in $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb" if ($ENV{'PBTAG'} !~ /[0-9.]+/);
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 }
325} else {
326 if (defined $pbinit) {
327 my $ptr = pb_get_pkg();
328 my @pkgs = @$ptr;
329 @pkgs = ("pkg1") if (not @pkgs);
330
331 open(CONF,"> $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb") || die "Unable to create $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb";
332 print CONF << "EOF";
333#
334# Project Builder configuration file
335# For project $ENV{'PBPROJ'}
336#
337# \$Id\$
338#
339
340#
341# What is the project URL
342#
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
349#pbproj $ENV{'PBPROJ'} = dir:///src/$ENV{'PBPROJ'}-devel
350
351#
352# Packager label
353#
354#pbpackager $ENV{'PBPROJ'} = "William Porte <bill\@$ENV{'PBPROJ'}.org>"
355#
356
357# For delivery to a machine by SSH (potentially the FTP server)
358# Needs hostname, account and directory
359#
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
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#
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
373
374#
375# Valid values for vmtype are
376# qemu, (vmware, xen, ... TBD)
377#vmtype $ENV{'PBPROJ'} = qemu
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
383#vmhost $ENV{'PBPROJ'} = localhost
384#vmlogin $ENV{'PBPROJ'} = pb
385#vmport $ENV{'PBPROJ'} = 2222
386
387# Timeout to wait when VM is launched/stopped
388#vmtmout default = 120
389
390# per VMs needed paramaters
391#vmopt $ENV{'PBPROJ'} = -m 384 -daemonize
392#vmpath $ENV{'PBPROJ'} = /home/qemu
393#vmsize $ENV{'PBPROJ'} = 5G
394
395#
396# Global version/tag for the project
397#
398#projver $ENV{'PBPROJ'} = devel
399#projtag $ENV{'PBPROJ'} = 1
400
401# Hash of valid version names
402#version $ENV{'PBPROJ'} = devel,stable
403
404# Adapt to your needs:
405# Optional if you need to overwrite the global values above
406#
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";
417# Hash of default package/package directory
418#defpkgdir $pp = dir-$pp
419EOF
420 }
421
422 print CONF << "EOF";
423# Hash of additional package/package directory
424#extpkgdir minor-pkg = dir-minor-pkg
425
426# List of files per pkg on which to apply filters
427# Files are mentioned relatively to pbroot/defpkgdir
428EOF
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 }
435 close(CONF);
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";
438 print CONF << "EOF";
439#
440# \$Id\$
441#
442# Filter for all files
443#
444# PBSRC is replaced by the source package format
445#filter PBSRC = ftp://ftp.$ENV{'PBPROJ'}.org/src/%{name}-%{version}.tar.gz
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
472#filter PBURL = http://www.$ENV{'PBPROJ'}.org
473EOF
474 close(CONF);
475 open(CONF,"> $ENV{'PBROOT'}/pbfilter/rpm.pbf") || die "Unable to create $ENV{'PBROOT'}/pbfilter/rpm.pbf";
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
484# Cf: http://fedoraproject.org/wiki/RPMGroups
485#filter PBGRP = Applications/Archiving
486
487# PBLIC is replaced by the license of the application
488# Cf: http://fedoraproject.org/wiki/Licensing
489#filter PBLIC = GPL
490
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);
502 open(CONF,"> $ENV{'PBROOT'}/pbfilter/deb.pbf") || die "Unable to create $ENV{'PBROOT'}/pbfilter/deb.pbf";
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
512# PBLIC is replaced by the license of the application
513# Cf:
514#filter PBLIC = GPL
515
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);
539 open(CONF,"> $ENV{'PBROOT'}/pbfilter/md.pbf") || die "Unable to create $ENV{'PBROOT'}/pbfilter/md.pbf";
540 print CONF << "EOF";
541# Specific group for Mandriva for $ENV{'PBPROJ'}
542# Cf: http://wiki.mandriva.com/en/Development/Packaging/Groups
543filter PBGRP = Archiving/Backup
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
549EOF
550 close(CONF);
551 open(CONF,"> $ENV{'PBROOT'}/pbfilter/novell.pbf") || die "Unable to create $ENV{'PBROOT'}/pbfilter/novell.pbf";
552 print CONF << "EOF";
553# Specific group for SuSE for $ENV{'PBPROJ'}
554# Cf: http://en.opensuse.org/SUSE_Package_Conventions/RPM_Groups
555filter PBGRP = Productivity/Archiving/Backup
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
561EOF
562 close(CONF);
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";
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
587 close(CONF);
588 open(CONF,"> $ENV{'PBROOT'}/$pp/deb/copyright") || die "Unable to create $ENV{'PBROOT'}/$pp/deb/copyright";
589 print CONF << "EOF";
590This package is debianized by PBPACKAGER
591`date`
592
593The current upstream source was downloaded from
594ftp://ftp.$ENV{'PBPROJ'}.org/src/.
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
618 close(CONF);
619 open(CONF,"> $ENV{'PBROOT'}/$pp/deb/changelog") || die "Unable to create $ENV{'PBROOT'}/$pp/deb/changelog";
620 print CONF << "EOF";
621PBLOG
622EOF
623 close(CONF);
624 open(CONF,"> $ENV{'PBROOT'}/$pp/deb/compat") || die "Unable to create $ENV{'PBROOT'}/$pp/deb/compat";
625 print CONF << "EOF";
6264
627EOF
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";
631EOF
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";
635INSTALL
636COPYING
637AUTHORS
638NEWS
639README
640EOF
641 close(CONF);
642 open(CONF,"> $ENV{'PBROOT'}/$pp/deb/rules") || die "Unable to create $ENV{'PBROOT'}/$pp/deb/rules";
643 print CONF << 'EOF';
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
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';
782#
783# $Id$
784#
785
786Summary: bla-bla
787Summary(fr): french bla-bla
788
789Name: PBPKG
790Version: PBVER
791Release: PBTAGPBSUF
792License: PBLIC
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
810make %{?_smp_mflags}
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
828 close(CONF);
829 pb_mkdir_p("$ENV{'PBROOT'}/$pp/pbfilter") || die "Unable to create $ENV{'PBROOT'}/$pp/pbfilter";
830
831 pb_log(0,"\nDo not to forget to commit the pbconf directory in your CMS if needed\n");
832 }
833 } else {
834 die "Unable to open $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb";
835 }
836}
837umask 0022;
838return(\%filteredfiles, \%supfiles, \%defpkgdir, \%extpkgdir);
839}
840
841# Internal mkdir -p function
842sub pb_mkdir_p {
843my @dir = @_;
844my $ret = mkpath(@dir, 0, 0755);
845return($ret);
846}
847
848# Internal rm -rf function
849sub pb_rm_rf {
850my @dir = @_;
851my $ret = rmtree(@dir, 0, 0);
852return($ret);
853}
854
855# Internal system function
856sub pb_system {
857
858my $cmd=shift;
859my $cmt=shift || $cmd;
860
861pb_log(0,"$cmt... ");
862#system("$cmd 2>&1 > $ENV{'PBTMP'}/system.log");
863system($cmd);
864if ($? == -1) {
865 pb_log(0,"failed to execute ($cmd) : $!\n");
866 pb_display_file("$ENV{'PBTMP'}/system.log");
867} elsif ($? & 127) {
868 pb_log(0, "child ($cmd) died with signal ".($? & 127).", ".($? & 128) ? 'with' : 'without'." coredump\n");
869 pb_display_file("$ENV{'PBTMP'}/system.log");
870} elsif ($? == 0) {
871 pb_log(0,"OK\n");
872} else {
873 pb_log(0, "child ($cmd) exited with value ".($? >> 8)."\n");
874 pb_display_file("$ENV{'PBTMP'}/system.log");
875}
876}
877
878sub pb_display_file {
879
880my $file=shift;
881
882return if (not -f $file);
883open(FILE,"$file");
884while (<FILE>) {
885 print $_;
886}
887close(FILE);
888}
889
890# Function which returns a pointer on a table
891# corresponding to a set of values queried in the conf file
892# and test the returned vaue as they need to exist in that case
893sub pb_conf_get {
894
895my @param = @_;
896my @return = pb_conf_get_if(@param);
897
898die "No params found for $ENV{'PBPROJ'}" if (not @return);
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
913# Everything is returned via ptr1
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'}));
918
919my $p1;
920my $p2;
921
922pb_log(2,"DEBUG: param1: ".Dumper(@ptr1)."\n");
923pb_log(2,"DEBUG: param2: ".Dumper(@ptr2)."\n");
924
925foreach my $i (0..$#param) {
926 $p1 = $ptr1[$i];
927 $p2 = $ptr2[$i];
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 }
956 $ptr1[$i] = $p1;
957 pb_log(2,"DEBUG: param ptr1: ".Dumper(@ptr1)."\n");
958}
959return(@ptr1);
960}
961
962# Function which returns a pointer on a hash
963# corresponding to a declaration (arg2) in a conf file (arg1)
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)
977sub pb_conf_read {
978
979my $conffile = shift;
980my @param = @_;
981my $trace;
982my @ptr;
983my %h;
984
985open(CONF,$conffile) || die "Unable to open $conffile";
986while(<CONF>) {
987 if (/^\s*([A-z0-9-_]+)\s+([[A-z0-9-_]+)\s*=\s*(.+)$/) {
988 pb_log(2,"DEBUG: 1:$1 2:$2 3:$3\n");
989 $h{$1}{$2}=$3;
990 }
991}
992close(CONF);
993
994for my $param (@param) {
995 push @ptr,$h{$param};
996}
997return(@ptr);
998}
999
1000# Analyze a url passed and return protocol, account, password, server, port, path
1001sub pb_get_uri {
1002
1003my $uri = shift || undef;
1004
1005pb_log(2,"DEBUG: uri:$uri\n");
1006# A URL has the format protocol://[ac@]host[:port][path[?query][#fragment]].
1007# Cf man URI
1008my ($scheme, $authority, $path, $query, $fragment) =
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
1019pb_log(2,"DEBUG: scheme:$scheme ac:$account host:$host port:$port path:$path\n");
1020return($scheme, $account, $host, $port, $path);
1021}
1022
1023
1024# Setup environment for CMS system for URL passed
1025sub pb_cms_init {
1026
1027my $proj = shift || undef;
1028
1029# Use the project URI
1030my ($uri) = pb_conf_get("pburl");
1031
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 .)`;
1038 $ENV{'PBCMSLOGFILE'}="svn.log";
1039} elsif (($scheme eq "file") || ($scheme eq "ftp") || ($scheme eq "http")) {
1040 $ENV{'PBREVISION'}="flat";
1041 $ENV{'PBCMSLOGFILE'}="flat.log";
1042} elsif ($scheme eq "cvs") {
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";
1047 $ENV{'PBCMSLOGFILE'}="cvs.log";
1048 #
1049 # Export content if needed
1050 #
1051 my ($cvsrsh) = pb_conf_get_if("cvsrsh");
1052 $ENV{'CVS_RSH'} = $cvsrsh->{$proj} if (defined $cvsrsh->{$proj});
1053} else {
1054 die "cms $scheme unknown";
1055}
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");
1062 #pb_log(2," If not, pleaase setup a pbproj entry in $ENV{'PBROOT'}/$ENV{'PBPROJ'}.pb\n");
1063 #return("");
1064#}
1065
1066return($scheme,$uri->{$ENV{'PBPROJ'}});
1067}
1068
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
1074sub pb_cms_export {
1075
1076my $uri = shift;
1077my $source = shift;
1078my $destdir = shift;
1079my $tmp;
1080my $tmp1;
1081
1082my @date = pb_get_date();
1083# If it's not flat, then we have a real uri as source
1084my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
1085
1086if ($scheme =~ /^svn/) {
1087 if (-d $source) {
1088 $tmp = $destdir;
1089 } else {
1090 $tmp = $destdir."/".basename($source);
1091 pb_mkdir_p($destdir);
1092 }
1093 pb_system("svn export $source $tmp","Exporting $source from SVN to $tmp");
1094} elsif ($scheme eq "dir") {
1095 pb_system("cp -a $path $destdir","Copying $uri from DIR to $destdir");
1096} elsif (($scheme eq "http") || ($scheme eq "ftp")) {
1097 my $f = basename($path);
1098 unlink "$ENV{'PBTMP'}/$f";
1099 if (-x "/usr/bin/wget") {
1100 pb_system("/usr/bin/wget -nv -O $ENV{'PBTMP'}/$f $uri"," ");
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");
1111 pb_mkdir_p($destdir);
1112
1113 if ($mm =~ /\/x-bzip-compressed-tar$/) {
1114 # tar+bzip2
1115 pb_system("cd $destdir ; tar xfj $path","Extracting $path in $destdir");
1116 } elsif ($mm =~ /\/x-lzma-compressed-tar$/) {
1117 # tar+lzma
1118 pb_system("cd $destdir ; tar xfY $path","Extracting $path in $destdir");
1119 } elsif ($mm =~ /\/x-compressed-tar$/) {
1120 # tar+gzip
1121 pb_system("cd $destdir ; tar xfz $path","Extracting $path in $destdir");
1122 } elsif ($mm =~ /\/x-tar$/) {
1123 # tar
1124 pb_system("cd $destdir ; tar xf $path","Extracting $path in $destdir");
1125 } elsif ($mm =~ /\/zip$/) {
1126 # zip
1127 pb_system("cd $destdir ; unzip $path","Extracting $path in $destdir");
1128 }
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 }
1146} elsif ($scheme eq "cvs") {
1147 my $dir=dirname($destdir);
1148 my $base=basename($destdir);
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 }
1157 # CVS needs a relative path !
1158 my ($cvsroot) = pb_conf_get("cvsroot");
1159 my $pbdate = strftime("%Y-%m-%d %H:%M:%S", @date);
1160 pb_system("cd $dir ; cvs -d $cvsroot->{$ENV{'PBPROJ'}} export -D \"$pbdate\" -d $base $tmp1","Exporting $source from CVS to $destdir");
1161} else {
1162 die "cms $scheme unknown";
1163}
1164}
1165
1166
1167sub pb_create_authors {
1168
1169my $authors=shift;
1170my $dest=shift;
1171my $scheme=shift;
1172
1173return if ($authors eq "/dev/null");
1174open(SAUTH,$authors) || die "Unable to open $authors";
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";
1181print DAUTH "Authors of the project are:\n";
1182print DAUTH "===========================\n";
1183while (<SAUTH>) {
1184 my ($nick,$gcos) = split(/:/);
1185 chomp($gcos);
1186 print DAUTH "$gcos";
1187 if (defined $scheme) {
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";
1194 } else {
1195 print DAUTH "\n";
1196 }
1197}
1198close(DAUTH);
1199close(SAUTH);
1200}
1201
1202sub pb_cms_log {
1203
1204my $scheme = shift;
1205my $pkgdir = shift;
1206my $dest = shift;
1207my $chglog = shift;
1208my $authors = shift;
1209
1210pb_create_authors($authors,$dest,$scheme);
1211
1212if ($scheme =~ /^svn/) {
1213 if (! -f "$dest/ChangeLog") {
1214 if (-x "/usr/bin/svn2cl") {
1215 pb_system("/usr/bin/svn2cl --group-by-day --authors=$authors -i -o $dest/ChangeLog $pkgdir","Generating ChangeLog from SVN with svn2cl");
1216 } else {
1217 # To be written from pbcl
1218 pb_system("svn log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVN");
1219 }
1220 }
1221} elsif (($scheme eq "file") || ($scheme eq "dir") || ($scheme eq "http") || ($scheme eq "ftp")) {
1222 if (! -f "$dest/ChangeLog") {
1223 pb_system("echo ChangeLog for $pkgdir > $dest/ChangeLog","Empty ChangeLog file created");
1224 }
1225} elsif ($scheme eq "cvs") {
1226 my $tmp=basename($pkgdir);
1227 # CVS needs a relative path !
1228 if (! -f "$dest/ChangeLog") {
1229 if (-x "/usr/bin/cvs2cl") {
1230 pb_system("/usr/bin/cvs2cl --group-by-day -U $authors -f $dest/ChangeLog $pkgdir","Generating ChangeLog from CVS with cvs2cl");
1231 } else {
1232 # To be written from pbcl
1233 pb_system("cvs log $tmp > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from CVS");
1234 }
1235 }
1236} else {
1237 die "cms $scheme unknown";
1238}
1239}
1240
1241sub pb_cms_getinfo {
1242
1243my $scheme = shift;
1244my $dir = shift;
1245my $info = shift || "URL:";
1246
1247my $res = "";
1248my $void = "";
1249
1250if ($scheme =~ /^svn/) {
1251 open(PIPE,"LANGUAGE=C svn info $dir |") || return("");
1252 while (<PIPE>) {
1253 ($void,$res) = split(/^$info/) if (/^$info/);
1254 }
1255 $res =~ s/^\s*//;
1256 close(PIPE);
1257 chomp($res);
1258} elsif ($scheme eq "flat") {
1259} elsif ($scheme eq "cvs") {
1260} else {
1261 die "cms $scheme unknown";
1262}
1263pb_log(2,"Found CMS info: $res\n");
1264return($res);
1265}
1266
1267sub pb_cms_copy {
1268my $scheme = shift;
1269my $oldurl = shift;
1270my $newurl = shift;
1271
1272if ($scheme eq "svn") {
1273 pb_system("svn copy -m \"Creation of $newurl from $oldurl\" $oldurl $newurl","Copying $oldurl to $newurl ");
1274} elsif ($scheme eq "flat") {
1275} elsif ($scheme eq "cvs") {
1276} else {
1277 die "cms $scheme unknown";
1278}
1279}
1280
1281sub pb_cms_checkout {
1282my $scheme = shift;
1283my $url = shift;
1284my $destination = shift;
1285
1286if ($scheme =~ /^svn/) {
1287 pb_system("svn co $url $destination","Checking out $url to $destination ");
1288} elsif ($scheme eq "flat") {
1289} elsif ($scheme eq "cvs") {
1290} else {
1291 die "cms $scheme unknown";
1292}
1293}
1294
1295sub pb_cms_checkin {
1296my $scheme = shift;
1297my $dir = shift;
1298
1299my $ver = basename($dir);
1300if ($scheme eq "svn") {
1301 pb_system("svn ci -m \"Updated to $ver\" $dir","Checking in $dir");
1302 pb_system("svn up $dir","Updating $dir");
1303} elsif ($scheme eq "flat") {
1304} elsif ($scheme eq "cvs") {
1305} else {
1306 die "cms $scheme unknown";
1307}
1308}
1309
1310sub pb_cms_isdiff {
1311my $scheme = shift;
1312
1313if ($scheme eq "svn") {
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);
1320} elsif ($scheme eq "flat") {
1321} elsif ($scheme eq "cvs") {
1322} else {
1323 die "cms $scheme unknown";
1324}
1325}
1326
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;
1334my ($ffile00, $ffile0, $ffile1, $ffile2, $ffile3);
1335my ($mfile00, $mfile0, $mfile1, $mfile2, $mfile3);
1336my $pbpkg = shift || die "No package specified";
1337my $dtype = shift || "";
1338my $dfam = shift || "";
1339my $ddir = shift || "";
1340my $dver = shift || "";
1341my $ptr; # returned value pointer on the hash of filters
1342my %ptr;
1343my %h;
1344
1345# Global filter files first, then package specificities
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");
1352
1353 push @ffiles,$mfile00 if (defined $mfile00);
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
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");
1366
1367 push @ffiles,$ffile00 if (defined $ffile00);
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) {
1374 pb_log(2,"DEBUG ffiles: ".Dumper(\@ffiles)."\n");
1375
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 }
1382 }
1383 close(CONF);
1384
1385 $ptr = $h{"filter"};
1386 pb_log(2,"DEBUG f:".Dumper($ptr)."\n");
1387 }
1388} else {
1389 $ptr = { };
1390}
1391%ptr = %$ptr;
1392return(\%ptr);
1393}
1394
1395# Function which applies filter on pb build files
1396sub pb_filter_file_pb {
1397
1398my $f=shift;
1399my $ptr=shift;
1400my %filter=%$ptr;
1401my $destfile=shift;
1402my $dtype=shift;
1403my $pbsuf=shift;
1404my $pbproj=shift;
1405my $pbpkg=shift;
1406my $pbver=shift;
1407my $pbtag=shift;
1408my $pbrev=shift;
1409my $pbdate=shift;
1410my $defpkgdir = shift;
1411my $extpkgdir = shift;
1412my $pbpackager = shift;
1413my $chglog = shift || undef;
1414
1415pb_log(2,"DEBUG: From $f to $destfile\n");
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
1423 pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
1424 my $tmp = $filter{$s};
1425 next if (not defined $tmp);
1426 # Expand variables if any single one found
1427 pb_log(2,"DEBUG tmp: $tmp\n");
1428 if ($tmp =~ /\$/) {
1429 eval { $tmp =~ s/(\$\w+)/$1/eeg };
1430 # special case for ChangeLog only for pb
1431 } elsif (($s =~ /^PBLOG$/) && ($line =~ /^PBLOG$/)) {
1432 my $p = $defpkgdir->{$pbpkg};
1433 $p = $extpkgdir->{$pbpkg} if (not defined $p);
1434 pb_changelog($dtype, $pbpkg, $pbver, $pbtag, $pbsuf, $p, \*DEST, $tmp, $chglog);
1435 $tmp = "";
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)
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)
1467sub pb_filter_file {
1468
1469my $f=shift;
1470my $ptr=shift;
1471my %filter=%$ptr;
1472my $destfile=shift;
1473my $pbproj=shift;
1474my $pbpkg=shift;
1475my $pbver=shift;
1476my $pbtag=shift;
1477my $pbrev=shift;
1478my $pbdate=shift;
1479my $pbpackager=shift;
1480
1481pb_log(2,"DEBUG: From $f to $destfile\n");
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
1489 pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
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
1504sub pb_log_init {
1505
1506$debug = shift || 0;
1507$LOG = shift || \*STDOUT;
1508
1509}
1510
1511sub pb_log {
1512
1513my $dlevel = shift;
1514my $msg = shift;
1515
1516print $LOG "$msg" if ($dlevel <= $debug);
1517}
1518
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$/) {
1532 @pkgs = keys %$defpkgdir if (defined $defpkgdir);
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
15411;
Note: See TracBrowser for help on using the repository browser.