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

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

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

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