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

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

Lots of fixes in order to make it work for netperf from scratch (newver, cms2build, build2pkg, pbcl)

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