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

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

setupvm seems better now

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);
834my $res = $?;
835if ($res == -1) {
836 pb_log(0,"failed to execute ($cmd) : $!\n");
837 pb_display_file("$ENV{'PBTMP'}/system.log");
838} elsif ($res & 127) {
839 pb_log(0, "child ($cmd) died with signal ".($? & 127).", ".($? & 128) ? 'with' : 'without'." coredump\n");
840 pb_display_file("$ENV{'PBTMP'}/system.log");
841} elsif ($res == 0) {
842 pb_log(0,"OK\n");
843} else {
844 pb_log(0, "child ($cmd) exited with value ".($? >> 8)."\n");
845 pb_display_file("$ENV{'PBTMP'}/system.log");
846}
847return($res);
848}
849
850sub pb_display_file {
851
852my $file=shift;
853
854return if (not -f $file);
855open(FILE,"$file");
856while (<FILE>) {
857 print $_;
858}
859close(FILE);
860}
861
862# Function which returns a pointer on a table
863# corresponding to a set of values queried in the conf file
864# and test the returned vaue as they need to exist in that case
865sub pb_conf_get {
866
867my @param = @_;
868my @return = pb_conf_get_if(@param);
869
870die "No params found for $ENV{'PBPROJ'}" if (not @return);
871
872foreach my $i (0..$#param) {
873 die "No $param[$i] defined for $ENV{'PBPROJ'}" if (not defined $return[$i]);
874}
875return(@return);
876}
877
878# Function which returns a pointer on a table
879# corresponding to a set of values queried in the conf file
880# Those value may be undef if they do not exist
881sub pb_conf_get_if {
882
883my @param = @_;
884
885# Everything is returned via ptr1
886my @ptr1 = ();
887my @ptr2 = ();
888@ptr1 = pb_conf_read_if("$ENV{'PBETC'}", @param) if (defined $ENV{'PBETC'});
889@ptr2 = pb_conf_read_if("$ENV{'PBROOTDIR'}/$ENV{'PBPROJ'}.pb", @param) if ((defined $ENV{'PBROOTDIR'}) and (defined $ENV{'PBPROJ'}));
890
891my $p1;
892my $p2;
893
894pb_log(2,"DEBUG: param1: ".Dumper(@ptr1)."\n");
895pb_log(2,"DEBUG: param2: ".Dumper(@ptr2)."\n");
896
897foreach my $i (0..$#param) {
898 $p1 = $ptr1[$i];
899 $p2 = $ptr2[$i];
900 # Always try to take the param from the home dir conf file in priority
901 # in order to mask what could be defined under the CMS to allow for overloading
902 if (not defined $p2) {
903 # No ref in CMS project conf file so use the home dir one.
904 $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if ((not defined $p1->{$ENV{'PBPROJ'}}) && (defined $p1->{'default'}));
905 } else {
906 # Ref found in CMS project conf file
907 if (not defined $p1) {
908 # No ref in home dir project conf file so use the CMS one.
909 $p2->{$ENV{'PBPROJ'}} = $p2->{'default'} if ((not defined $p2->{$ENV{'PBPROJ'}}) && (defined $p2->{'default'}));
910 $p1 = $p2;
911 } else {
912 # Both are defined - handling the overloading
913 if (not defined $p1->{'default'}) {
914 if (defined $p2->{'default'}) {
915 $p1->{'default'} = $p2->{'default'};
916 }
917 }
918
919 if (not defined $p1->{$ENV{'PBPROJ'}}) {
920 if (defined $p2->{$ENV{'PBPROJ'}}) {
921 $p1->{$ENV{'PBPROJ'}} = $p2->{$ENV{'PBPROJ'}} if (defined $p2->{$ENV{'PBPROJ'}});
922 } else {
923 $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if (defined $p1->{'default'});
924 }
925 }
926 # Now copy back into p1 all p2 content which doesn't exist in p1
927 # p1 content (local) always has priority over p2 (project)
928 foreach my $k (keys %$p2) {
929 $p1->{$k} = $p2->{$k} if (not defined $p1->{$k});
930 }
931 }
932 }
933 $ptr1[$i] = $p1;
934 pb_log(2,"DEBUG: param ptr1: ".Dumper(@ptr1)."\n");
935}
936return(@ptr1);
937}
938
939# Function which returns a pointer on a hash
940# corresponding to a declaration (arg2) in a conf file (arg1)
941# if that conf file doesn't exist returns undef
942sub pb_conf_read_if {
943
944my $conffile = shift;
945my @param = @_;
946
947open(CONF,$conffile) || return((undef));
948close(CONF);
949return(pb_conf_read($conffile,@param));
950}
951
952# Function which returns a pointer on a hash
953# corresponding to a declaration (arg2) in a conf file (arg1)
954sub pb_conf_read {
955
956my $conffile = shift;
957my @param = @_;
958my $trace;
959my @ptr;
960my %h;
961
962open(CONF,$conffile) || die "Unable to open $conffile";
963while(<CONF>) {
964 if (/^\s*([A-z0-9-_]+)\s+([[A-z0-9-_]+)\s*=\s*(.+)$/) {
965 pb_log(3,"DEBUG: 1:$1 2:$2 3:$3\n");
966 $h{$1}{$2}=$3;
967 }
968}
969close(CONF);
970
971for my $param (@param) {
972 push @ptr,$h{$param};
973}
974return(@ptr);
975}
976
977# Analyze a url passed and return protocol, account, password, server, port, path
978sub pb_get_uri {
979
980my $uri = shift || undef;
981
982pb_log(2,"DEBUG: uri:$uri\n");
983# A URL has the format protocol://[ac@]host[:port][path[?query][#fragment]].
984# Cf man URI
985my ($scheme, $authority, $path, $query, $fragment) =
986 $uri =~ m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?| if (defined $uri);
987my ($account,$host,$port) = $authority =~ m|(?:([^\@]+)\@)?([^:]+)(:(?:[0-9]+))?| if (defined $authority);
988
989$scheme = "" if (not defined $scheme);
990$authority = "" if (not defined $authority);
991$path = "" if (not defined $path);
992$account = "" if (not defined $account);
993$host = "" if (not defined $host);
994$port = "" if (not defined $port);
995
996pb_log(2,"DEBUG: scheme:$scheme ac:$account host:$host port:$port path:$path\n");
997return($scheme, $account, $host, $port, $path);
998}
999
1000
1001# Setup environment for CMS system for URL passed
1002sub pb_cms_init {
1003
1004my $pbinit = shift || undef;
1005
1006my ($pburl) = pb_conf_get("pburl");
1007pb_log(2,"DEBUG: Project URL of $ENV{'PBPROJ'}: $pburl->{$ENV{'PBPROJ'}}\n");
1008my ($scheme, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
1009
1010my ($pbprojdir) = pb_conf_get_if("pbprojdir");
1011
1012if ((defined $pbprojdir) && (defined $pbprojdir->{$ENV{'PBPROJ'}})) {
1013 $ENV{'PBPROJDIR'} = $pbprojdir->{$ENV{'PBPROJ'}};
1014} else {
1015 $ENV{'PBPROJDIR'} = "$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}";
1016}
1017
1018# Computing the default dir for PBDIR.
1019# what we have is PBPROJDIR so work from that.
1020# Tree identical between PBCONFDIR and PBROOTDIR on one side and
1021# PBPROJDIR and PBDIR on the other side.
1022
1023my $tmp = $ENV{'PBROOTDIR'};
1024$tmp =~ s|^$ENV{'PBCONFDIR'}||;
1025
1026#
1027# Check project cms compliance
1028#
1029pb_cms_compliant(undef,'PBDIR',"$ENV{'PBPROJDIR'}/$tmp",$pburl->{$ENV{'PBPROJ'}},$pbinit);
1030
1031if ($scheme =~ /^svn/) {
1032 # svnversion more precise than svn info
1033 $tmp = `(cd "$ENV{'PBDIR'}" ; svnversion .)`;
1034 chomp($tmp);
1035 $ENV{'PBREVISION'}=$tmp;
1036 $ENV{'PBCMSLOGFILE'}="svn.log";
1037} elsif (($scheme eq "file") || ($scheme eq "ftp") || ($scheme eq "http")) {
1038 $ENV{'PBREVISION'}="flat";
1039 $ENV{'PBCMSLOGFILE'}="flat.log";
1040} elsif ($scheme =~ /^cvs/) {
1041 # Way too slow
1042 #$ENV{'PBREVISION'}=`(cd "$ENV{'PBROOTDIR'}" ; cvs rannotate -f . 2>&1 | awk '{print \$1}' | grep -E '^[0-9]' | cut -d. -f2 |sort -nu | tail -1)`;
1043 #chomp($ENV{'PBREVISION'});
1044 $ENV{'PBREVISION'}="cvs";
1045 $ENV{'PBCMSLOGFILE'}="cvs.log";
1046 $ENV{'CVS_RSH'} = "ssh" if ($scheme =~ /ssh/);
1047} else {
1048 die "cms $scheme unknown";
1049}
1050
1051return($scheme,$pburl->{$ENV{'PBPROJ'}});
1052}
1053
1054sub pb_get_date {
1055
1056return(localtime->sec(), localtime->min(), localtime->hour(), localtime->mday(), localtime->mon(), localtime->year(), localtime->wday(), localtime->yday(), localtime->isdst());
1057}
1058
1059sub pb_cms_export {
1060
1061my $uri = shift;
1062my $source = shift;
1063my $destdir = shift;
1064my $tmp;
1065my $tmp1;
1066
1067my @date = pb_get_date();
1068# If it's not flat, then we have a real uri as source
1069my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
1070
1071if ($scheme =~ /^svn/) {
1072 if (-d $source) {
1073 $tmp = $destdir;
1074 } else {
1075 $tmp = "$destdir/".basename($source);
1076 }
1077 pb_system("svn export $source $tmp","Exporting $source from SVN to $tmp");
1078} elsif ($scheme eq "dir") {
1079 pb_system("cp -a $path $destdir","Copying $uri from DIR to $destdir");
1080} elsif (($scheme eq "http") || ($scheme eq "ftp")) {
1081 my $f = basename($path);
1082 unlink "$ENV{'PBTMP'}/$f";
1083 if (-x "/usr/bin/wget") {
1084 pb_system("/usr/bin/wget -nv -O $ENV{'PBTMP'}/$f $uri"," ");
1085 } elsif (-x "/usr/bin/curl") {
1086 pb_system("/usr/bin/curl $uri -o $ENV{'PBTMP'}/$f","Downloading $uri with curl to $ENV{'PBTMP'}/$f\n");
1087 } else {
1088 die "Unable to download $uri.\nNo wget/curl available, please install one of those";
1089 }
1090 pb_cms_export("file://$ENV{'PBTMP'}/$f",$source,$destdir);
1091} elsif ($scheme eq "file") {
1092 use File::MimeInfo;
1093 my $mm = mimetype($path);
1094 pb_log(2,"mimetype: $mm\n");
1095 pb_mkdir_p($destdir);
1096
1097 # Check whether the file is well formed
1098 # (containing already a directory with the project-version name)
1099 my ($pbwf) = pb_conf_get_if("pbwf");
1100 if ((defined $pbwf) && (defined $pbwf->{$ENV{'PBPROJ'}})) {
1101 $destdir = dirname($destdir);
1102 }
1103
1104 if ($mm =~ /\/x-bzip-compressed-tar$/) {
1105 # tar+bzip2
1106 pb_system("cd $destdir ; tar xfj $path","Extracting $path in $destdir");
1107 } elsif ($mm =~ /\/x-lzma-compressed-tar$/) {
1108 # tar+lzma
1109 pb_system("cd $destdir ; tar xfY $path","Extracting $path in $destdir");
1110 } elsif ($mm =~ /\/x-compressed-tar$/) {
1111 # tar+gzip
1112 pb_system("cd $destdir ; tar xfz $path","Extracting $path in $destdir");
1113 } elsif ($mm =~ /\/x-tar$/) {
1114 # tar
1115 pb_system("cd $destdir ; tar xf $path","Extracting $path in $destdir");
1116 } elsif ($mm =~ /\/zip$/) {
1117 # zip
1118 pb_system("cd $destdir ; unzip $path","Extracting $path in $destdir");
1119 }
1120} elsif ($scheme =~ /^cvs/) {
1121 # CVS needs a relative path !
1122 my $dir=dirname($destdir);
1123 my $base=basename($destdir);
1124 # CVS also needs a modules name not a dir
1125 #if (-d $source) {
1126 $tmp1 = basename($source);
1127 #} else {
1128 #$tmp1 = dirname($source);
1129 #$tmp1 = basename($tmp1);
1130 #}
1131 my $optcvs = "";
1132
1133 # If we're working on the CVS itself
1134 my $cvstag = basename($ENV{'PBROOTDIR'});
1135 my $cvsopt = "";
1136 if ($cvstag eq "cvs") {
1137 my $pbdate = strftime("%Y-%m-%d %H:%M:%S", @date);
1138 $cvsopt = "-D \"$pbdate\"";
1139 } else {
1140 # we're working on a tag which should be the last part of PBROOTDIR
1141 $cvsopt = "-r $cvstag";
1142 }
1143 pb_system("cd $dir ; cvs -d $account\@$host:$path export $cvsopt -d $base $tmp1","Exporting $tmp1 from $source under CVS to $destdir");
1144} else {
1145 die "cms $scheme unknown";
1146}
1147}
1148
1149
1150sub pb_create_authors {
1151
1152my $authors=shift;
1153my $dest=shift;
1154my $scheme=shift;
1155
1156return if ($authors eq "/dev/null");
1157open(SAUTH,$authors) || die "Unable to open $authors";
1158# Save a potentially existing AUTHORS file and write instead toi AUTHORS.pb
1159my $ext = "";
1160if (-f "$dest/AUTHORS") {
1161 $ext = ".pb";
1162}
1163open(DAUTH,"> $dest/AUTHORS$ext") || die "Unable to create $dest/AUTHORS$ext";
1164print DAUTH "Authors of the project are:\n";
1165print DAUTH "===========================\n";
1166while (<SAUTH>) {
1167 my ($nick,$gcos) = split(/:/);
1168 chomp($gcos);
1169 print DAUTH "$gcos";
1170 if (defined $scheme) {
1171 # Do not give a scheme for flat types
1172 my $endstr="";
1173 if ("$ENV{'PBREVISION'}" ne "flat") {
1174 $endstr = " under $scheme";
1175 }
1176 print DAUTH " ($nick$endstr)\n";
1177 } else {
1178 print DAUTH "\n";
1179 }
1180}
1181close(DAUTH);
1182close(SAUTH);
1183}
1184
1185sub pb_cms_log {
1186
1187my $scheme = shift;
1188my $pkgdir = shift;
1189my $dest = shift;
1190my $chglog = shift;
1191my $authors = shift;
1192
1193pb_create_authors($authors,$dest,$scheme);
1194
1195if ($scheme =~ /^svn/) {
1196 if (! -f "$dest/ChangeLog") {
1197 if (-x "/usr/bin/svn2cl") {
1198 # In case we have no network, just create an empty one before to allow correct build
1199 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
1200 close(CL);
1201 pb_system("/usr/bin/svn2cl --group-by-day --authors=$authors -i -o $dest/ChangeLog $pkgdir","Generating ChangeLog from SVN with svn2cl");
1202 } else {
1203 # To be written from pbcl
1204 pb_system("svn log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVN");
1205 }
1206 }
1207} elsif (($scheme eq "file") || ($scheme eq "dir") || ($scheme eq "http") || ($scheme eq "ftp")) {
1208 if (! -f "$dest/ChangeLog") {
1209 pb_system("echo ChangeLog for $pkgdir > $dest/ChangeLog","Empty ChangeLog file created");
1210 }
1211} elsif ($scheme =~ /^cvs/) {
1212 my $tmp=basename($pkgdir);
1213 # CVS needs a relative path !
1214 if (! -f "$dest/ChangeLog") {
1215 if (-x "/usr/bin/cvs2cl") {
1216 # In case we have no network, just create an empty one before to allow correct build
1217 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
1218 close(CL);
1219 pb_system("/usr/bin/cvs2cl --group-by-day -U $authors -f $dest/ChangeLog $pkgdir","Generating ChangeLog from CVS with cvs2cl");
1220 } else {
1221 # To be written from pbcl
1222 pb_system("cvs log $tmp > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from CVS");
1223 }
1224 }
1225} else {
1226 die "cms $scheme unknown";
1227}
1228}
1229
1230# This function is only called with a real CMS system
1231sub pb_cms_get_uri {
1232
1233my $scheme = shift;
1234my $dir = shift;
1235
1236my $res = "";
1237my $void = "";
1238
1239if ($scheme =~ /^svn/) {
1240 open(PIPE,"LANGUAGE=C svn info $dir |") || return("");
1241 while (<PIPE>) {
1242 ($void,$res) = split(/^URL:/) if (/^URL:/);
1243 }
1244 $res =~ s/^\s*//;
1245 close(PIPE);
1246 chomp($res);
1247} elsif ($scheme =~ /^cvs/) {
1248 # This path is always the root path of CVS, but we may be below
1249 open(FILE,"$dir/CVS/Root") || die "$dir isn't CVS controlled";
1250 $res = <FILE>;
1251 chomp($res);
1252 close(FILE);
1253 # Find where we are in the tree
1254 my $rdir = $dir;
1255 while ((! -d "$rdir/CVSROOT") && ($rdir ne "/")) {
1256 $rdir = dirname($rdir);
1257 }
1258 die "Unable to find a CVSROOT dir in the parents of $dir" if (! -d "$rdir/CVSROOT");
1259 #compute our place under that root dir - should be a relative path
1260 $dir =~ s|^$rdir||;
1261 my $suffix = "";
1262 $suffix = "$dir" if ($dir ne "");
1263
1264 my $prefix = "";
1265 if ($scheme =~ /ssh/) {
1266 $prefix = "cvs+ssh://";
1267 } else {
1268 $prefix = "cvs://";
1269 }
1270 $res = $prefix.$res.$suffix;
1271} else {
1272 die "cms $scheme unknown";
1273}
1274pb_log(2,"Found CMS info: $res\n");
1275return($res);
1276}
1277
1278sub pb_cms_copy {
1279my $scheme = shift;
1280my $oldurl = shift;
1281my $newurl = shift;
1282
1283if ($scheme =~ /^svn/) {
1284 pb_system("svn copy -m \"Creation of $newurl from $oldurl\" $oldurl $newurl","Copying $oldurl to $newurl ");
1285} elsif ($scheme eq "flat") {
1286} elsif ($scheme =~ /^cvs/) {
1287} else {
1288 die "cms $scheme unknown";
1289}
1290}
1291
1292sub pb_cms_checkout {
1293my $scheme = shift;
1294my $url = shift;
1295my $destination = shift;
1296
1297if ($scheme =~ /^svn/) {
1298 pb_system("svn co $url $destination","Checking out $url to $destination ");
1299} elsif (($scheme eq "ftp") || ($scheme eq "http")) {
1300 return;
1301} elsif ($scheme =~ /^cvs/) {
1302 pb_system("cvs co $url $destination","Checking out $url to $destination ");
1303} else {
1304 die "cms $scheme unknown";
1305}
1306}
1307
1308sub pb_cms_checkin {
1309my $scheme = shift;
1310my $dir = shift;
1311
1312my $ver = basename($dir);
1313if ($scheme =~ /^svn/) {
1314 pb_system("svn ci -m \"Updated to $ver\" $dir","Checking in $dir");
1315 pb_system("svn up $dir","Updating $dir");
1316} elsif ($scheme eq "flat") {
1317} elsif ($scheme =~ /^cvs/) {
1318} else {
1319 die "cms $scheme unknown";
1320}
1321}
1322
1323sub pb_cms_isdiff {
1324my $scheme = shift;
1325
1326if ($scheme =~ /^svn/) {
1327 open(PIPE,"svn diff $ENV{'PBROOTDIR'} |") || die "Unable to get svn diff from $ENV{'PBROOTDIR'}";
1328 my $l = 0;
1329 while (<PIPE>) {
1330 $l++;
1331 }
1332 return($l);
1333} elsif ($scheme eq "flat") {
1334} elsif ($scheme =~ /^cvs/) {
1335} else {
1336 die "cms $scheme unknown";
1337}
1338}
1339
1340# Get all filters to apply
1341# They're cumulative from less specific to most specific
1342# suffix is .pbf
1343
1344sub pb_get_filters {
1345
1346my @ffiles;
1347my ($ffile00, $ffile0, $ffile1, $ffile2, $ffile3);
1348my ($mfile00, $mfile0, $mfile1, $mfile2, $mfile3);
1349my $pbpkg = shift || die "No package specified";
1350my $dtype = shift || "";
1351my $dfam = shift || "";
1352my $ddir = shift || "";
1353my $dver = shift || "";
1354my $ptr = undef; # returned value pointer on the hash of filters
1355my %h;
1356
1357# Global filter files first, then package specificities
1358if (-d "$ENV{'PBROOTDIR'}/pbfilter") {
1359 $mfile00 = "$ENV{'PBROOTDIR'}/pbfilter/all.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/all.pbf");
1360 $mfile0 = "$ENV{'PBROOTDIR'}/pbfilter/$dtype.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$dtype.pbf");
1361 $mfile1 = "$ENV{'PBROOTDIR'}/pbfilter/$dfam.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$dfam.pbf");
1362 $mfile2 = "$ENV{'PBROOTDIR'}/pbfilter/$ddir.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$ddir.pbf");
1363 $mfile3 = "$ENV{'PBROOTDIR'}/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBROOTDIR'}/pbfilter/$ddir-$dver.pbf");
1364
1365 push @ffiles,$mfile00 if (defined $mfile00);
1366 push @ffiles,$mfile0 if (defined $mfile0);
1367 push @ffiles,$mfile1 if (defined $mfile1);
1368 push @ffiles,$mfile2 if (defined $mfile2);
1369 push @ffiles,$mfile3 if (defined $mfile3);
1370}
1371
1372if (-d "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter") {
1373 $ffile00 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/all.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/all.pbf");
1374 $ffile0 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dtype.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dtype.pbf");
1375 $ffile1 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dfam.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$dfam.pbf");
1376 $ffile2 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir.pbf");
1377 $ffile3 = "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir-$dver.pbf" if (-f "$ENV{'PBROOTDIR'}/$pbpkg/pbfilter/$ddir-$dver.pbf");
1378
1379 push @ffiles,$ffile00 if (defined $ffile00);
1380 push @ffiles,$ffile0 if (defined $ffile0);
1381 push @ffiles,$ffile1 if (defined $ffile1);
1382 push @ffiles,$ffile2 if (defined $ffile2);
1383 push @ffiles,$ffile3 if (defined $ffile3);
1384}
1385if (@ffiles) {
1386 pb_log(2,"DEBUG ffiles: ".Dumper(\@ffiles)."\n");
1387
1388 foreach my $f (@ffiles) {
1389 open(CONF,$f) || next;
1390 while(<CONF>) {
1391 if (/^\s*([A-z0-9-_]+)\s+([[A-z0-9-_]+)\s*=\s*(.+)$/) {
1392 $h{$1}{$2}=$3;
1393 }
1394 }
1395 close(CONF);
1396
1397 $ptr = $h{"filter"};
1398 pb_log(2,"DEBUG f:".Dumper($ptr)."\n");
1399 }
1400}
1401return($ptr);
1402}
1403
1404# Function which applies filter on pb build files
1405sub pb_filter_file_pb {
1406
1407my $f=shift;
1408my $ptr=shift;
1409my %filter=%$ptr;
1410my $destfile=shift;
1411my $dtype=shift;
1412my $pbsuf=shift;
1413my $pbproj=shift;
1414my $pbpkg=shift;
1415my $pbver=shift;
1416my $pbtag=shift;
1417my $pbrev=shift;
1418my $pbdate=shift;
1419my $defpkgdir = shift;
1420my $extpkgdir = shift;
1421my $pbpackager = shift;
1422my $chglog = shift || undef;
1423
1424pb_log(2,"DEBUG: From $f to $destfile\n");
1425pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
1426open(DEST,"> $destfile") || die "Unable to create $destfile";
1427open(FILE,"$f") || die "Unable to open $f: $!";
1428while (<FILE>) {
1429 my $line = $_;
1430 foreach my $s (keys %filter) {
1431 # Process single variables
1432 pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
1433 my $tmp = $filter{$s};
1434 next if (not defined $tmp);
1435 # Expand variables if any single one found
1436 pb_log(2,"DEBUG tmp: $tmp\n");
1437 if ($tmp =~ /\$/) {
1438 eval { $tmp =~ s/(\$\w+)/$1/eeg };
1439 # special case for ChangeLog only for pb
1440 } elsif (($s =~ /^PBLOG$/) && ($line =~ /^PBLOG$/)) {
1441 my $p = $defpkgdir->{$pbpkg};
1442 $p = $extpkgdir->{$pbpkg} if (not defined $p);
1443 pb_changelog($dtype, $pbpkg, $pbver, $pbtag, $pbsuf, $p, \*DEST, $tmp, $chglog);
1444 $tmp = "";
1445 }
1446 $line =~ s|$s|$tmp|;
1447 }
1448 print DEST $line;
1449}
1450close(FILE);
1451close(DEST);
1452}
1453
1454# Function which applies filter on files (external call)
1455sub pb_filter_file_inplace {
1456
1457my $ptr=shift;
1458my %filter=%$ptr;
1459my $destfile=shift;
1460my $pbproj=shift;
1461my $pbpkg=shift;
1462my $pbver=shift;
1463my $pbtag=shift;
1464my $pbrev=shift;
1465my $pbdate=shift;
1466my $pbpackager=shift;
1467
1468my $cp = "$ENV{'PBTMP'}/".basename($destfile);
1469copy($destfile,$cp) || die "Unable to create $cp";
1470
1471pb_filter_file($cp,$ptr,$destfile,$pbproj,$pbpkg,$pbver,$pbtag,$pbrev,$pbdate,$pbpackager);
1472unlink $cp;
1473}
1474
1475# Function which applies filter on files (external call)
1476sub pb_filter_file {
1477
1478my $f=shift;
1479my $ptr=shift;
1480my %filter=%$ptr;
1481my $destfile=shift;
1482my $pbproj=shift;
1483my $pbpkg=shift;
1484my $pbver=shift;
1485my $pbtag=shift;
1486my $pbrev=shift;
1487my $pbdate=shift;
1488my $pbpackager=shift;
1489
1490pb_log(2,"DEBUG: From $f to $destfile\n");
1491pb_mkdir_p(dirname($destfile)) if (! -d dirname($destfile));
1492open(DEST,"> $destfile") || die "Unable to create $destfile";
1493open(FILE,"$f") || die "Unable to open $f: $!";
1494while (<FILE>) {
1495 my $line = $_;
1496 foreach my $s (keys %filter) {
1497 # Process single variables
1498 pb_log(2,"DEBUG filter{$s}: $filter{$s}\n");
1499 my $tmp = $filter{$s};
1500 next if (not defined $tmp);
1501 # Expand variables if any single one found
1502 if ($tmp =~ /\$/) {
1503 eval { $tmp =~ s/(\$\w+)/$1/eeg };
1504 }
1505 $line =~ s|$s|$tmp|;
1506 }
1507 print DEST $line;
1508}
1509close(FILE);
1510close(DEST);
1511}
1512
1513sub pb_log_init {
1514
1515$debug = shift || 0;
1516$LOG = shift || \*STDOUT;
1517
1518}
1519
1520sub pb_log {
1521
1522my $dlevel = shift;
1523my $msg = shift;
1524
1525print $LOG "$msg" if ($dlevel <= $debug);
1526}
1527
1528#
1529# Return the list of packages we are working on
1530#
1531sub pb_get_pkg {
1532
1533my @pkgs = ();
1534my $defpkgdir = shift || undef;
1535my $extpkgdir = shift || undef;
1536
1537# Get packages list
1538if (not defined $ARGV[0]) {
1539 @pkgs = keys %$defpkgdir if (defined $defpkgdir);
1540} elsif ($ARGV[0] =~ /^all$/) {
1541 @pkgs = keys %$defpkgdir if (defined $defpkgdir);
1542 push(@pkgs, keys %$extpkgdir) if (defined $extpkgdir);
1543} else {
1544 @pkgs = @ARGV;
1545}
1546pb_log(0,"Packages: ".join(',',@pkgs)."\n");
1547return(\@pkgs);
1548}
1549
1550#
1551# Check pbconf/project cms compliance
1552#
1553sub pb_cms_compliant {
1554
1555my $param = shift;
1556my $envar = shift;
1557my $defdir = shift;
1558my $uri = shift;
1559my $pbinit = shift;
1560my %pdir;
1561
1562my ($pdir) = pb_conf_get_if($param) if (defined $param);
1563if (defined $pdir) {
1564 %pdir = %$pdir;
1565}
1566
1567
1568if ((defined $pdir) && (%pdir) && (defined $pdir{$ENV{'PBPROJ'}})) {
1569 # That's always the environment variable that will be used
1570 $ENV{$envar} = $pdir{$ENV{'PBPROJ'}};
1571} else {
1572 if (defined $param) {
1573 pb_log(1,"WARNING: no $param defined, using $defdir\n");
1574 pb_log(1," Please create a $param reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
1575 pb_log(1," if you want to use another directory\n");
1576 }
1577 $ENV{$envar} = "$defdir";
1578}
1579
1580# Expand potential env variable in it
1581eval { $ENV{$envar} =~ s/(\$ENV.+\})/$1/eeg };
1582pb_log(2,"$envar: $ENV{$envar}\n");
1583
1584my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
1585
1586if ((! -d "$ENV{$envar}") || (defined $pbinit)) {
1587 if (defined $pbinit) {
1588 pb_mkdir_p("$ENV{$envar}");
1589 } else {
1590 pb_log(1,"Checking out $uri\n");
1591 pb_cms_checkout($scheme,$uri,$ENV{$envar});
1592 }
1593} elsif (($scheme !~ /^cvs/) || ($scheme !~ /^svn/)) {
1594 # Do not compare if it's not a real cms
1595 return;
1596} else {
1597 pb_log(1,"$uri found locally, checking content\n");
1598 my $cmsurl = pb_cms_get_uri($scheme,$ENV{$envar});
1599 my ($scheme2, $account2, $host2, $port2, $path2) = pb_get_uri($cmsurl);
1600 if ($cmsurl ne $uri) {
1601 # The local content doesn't correpond to the repository
1602 pb_log(0,"ERROR: Inconsistency detected:\n");
1603 pb_log(0," * $ENV{$envar} refers to $cmsurl but\n");
1604 pb_log(0," * $ENV{'PBETC'} refers to $uri\n");
1605 die "Project $ENV{'PBPROJ'} is not Project-Builder compliant.";
1606 } else {
1607 pb_log(1,"Content correct - doing nothing - you may want to update your repository however\n");
1608 # they match - do nothing - there may be local changes
1609 }
1610}
1611}
1612
1613sub pb_changelog {
1614
1615my $dtype = shift;
1616my $pkg = shift;
1617my $pbver = shift;
1618my $pbtag = shift;
1619my $dsuf = shift;
1620my $path = shift;
1621my $OUTPUT = shift;
1622my $doit = shift;
1623my $chglog = shift || undef;
1624
1625my $log = "";
1626
1627# For date handling
1628$ENV{LANG}="C";
1629
1630if ((not (defined $dtype)) || ($dtype eq "") ||
1631 (not (defined $pkg)) || ($pkg eq "") ||
1632 (not (defined $pbver)) || ($pbver eq "") ||
1633 (not (defined $pbtag)) || ($pbtag eq "") ||
1634 (not (defined $dsuf)) || ($dsuf eq "") ||
1635 (not (defined $path)) || ($path eq "") ||
1636 (not (defined $OUTPUT)) || ($OUTPUT eq "") ||
1637 (not (defined $doit)) || ($doit eq "")) {
1638 print $OUTPUT "\n";
1639 return;
1640}
1641
1642if (((not defined $chglog) || (! -f $chglog)) && ($doit eq "yes")) {
1643 #pb_log(2,"No ChangeLog file ($chglog) for $pkg\n";
1644 print $OUTPUT "\n";
1645 return;
1646}
1647
1648my $date;
1649my $ndate;
1650my $n2date;
1651my $ver;
1652my $ver2;
1653my ($pbpackager) = pb_conf_get("pbpackager");
1654
1655if (not defined $pbpackager->{$ENV{'PBPROJ'}}) {
1656 $pbpackager->{$ENV{'PBPROJ'}} = "undefined\@noproject.noorg";
1657}
1658
1659# If we don't need to do it, or don't have it fake something
1660if (((not defined $chglog) || (! -f $chglog)) && ($doit ne "yes")) {
1661 my @date=(localtime->sec(), localtime->min(), localtime->hour(), localtime->mday(), localtime->mon(), localtime->year(), localtime->wday(), localtime->yday(), localtime->isdst());
1662 $date = strftime("%Y-%m-%d", @date);
1663 $ndate = UnixDate($date,"%a", "%b", "%d", "%Y");
1664 $n2date = &UnixDate($date,"%a, %d %b %Y %H:%M:%S %z");
1665 if (($dtype eq "rpm") || ($dtype eq "fc")) {
1666 $ver2 = "$pbver-$pbtag$dsuf";
1667 print $OUTPUT "* $ndate $pbpackager->{$ENV{'PBPROJ'}} $ver2\n";
1668 print $OUTPUT "- Updated to $pbver\n";
1669 }
1670 if ($dtype eq "deb") {
1671 print $OUTPUT "$pkg ($pbver) unstable; urgency=low\n";
1672 print $OUTPUT "\n";
1673 print $OUTPUT " -- $pbpackager->{$ENV{'PBPROJ'}} $n2date\n\n\n";
1674 }
1675 return;
1676}
1677
1678open(INPUT,"$chglog") || die "Unable to open $chglog (read)";
1679
1680# Skip first 4 lines
1681my $tmp = <INPUT>;
1682$tmp = <INPUT>;
1683$tmp = <INPUT>;
1684if ($dtype eq "announce") {
1685 print $OUTPUT $tmp;
1686}
1687$tmp = <INPUT>;
1688if ($dtype eq "announce") {
1689 print $OUTPUT $tmp;
1690}
1691
1692my $first=1;
1693
1694# Handle each block separated by newline
1695while (<INPUT>) {
1696 ($ver, $date) = split(/ /);
1697 $ver =~ s/^v//;
1698 chomp($date);
1699 $date =~ s/\(([0-9-]+)\)/$1/;
1700 #pb_log(2,"**$date**\n";
1701 $ndate = UnixDate($date,"%a", "%b", "%d", "%Y");
1702 $n2date = &UnixDate($date,"%a, %d %b %Y %H:%M:%S %z");
1703 #pb_log(2,"**$ndate**\n";
1704
1705 if (($dtype eq "rpm") || ($dtype eq "fc")) {
1706 if ($ver !~ /-/) {
1707 if ($first eq 1) {
1708 $ver2 = "$ver-$pbtag$dsuf";
1709 $first=0;
1710 } else {
1711 $ver2 = "$ver-1$dsuf";
1712 }
1713 } else {
1714 $ver2 = "$ver$dsuf";
1715 }
1716 print $OUTPUT "* $ndate $pbpackager->{$ENV{'PBPROJ'}} $ver2\n";
1717 print $OUTPUT "- Updated to $ver\n";
1718 }
1719 if ($dtype eq "deb") {
1720 print $OUTPUT "$pkg ($ver) unstable; urgency=low\n";
1721 print $OUTPUT "\n";
1722 }
1723
1724 $tmp = <INPUT>;
1725 while ($tmp !~ /^$/) {
1726 if ($dtype eq "deb") {
1727 $tmp =~ s/^- //;
1728 print $OUTPUT " * $tmp";
1729 } elsif ($dtype eq "rpm") {
1730 print $OUTPUT "$tmp";
1731 } else {
1732 print $OUTPUT "$tmp";
1733 }
1734 last if (eof(INPUT));
1735 $tmp = <INPUT>;
1736 }
1737 print $OUTPUT "\n";
1738
1739 if ($dtype eq "deb") {
1740 # Cf: http://www.debian.org/doc/debian-policy/ch-source.html#s-dpkgchangelog
1741 print $OUTPUT " -- $pbpackager->{$ENV{'PBPROJ'}} $n2date\n\n\n";
1742 }
1743
1744 last if (eof(INPUT));
1745 last if ($dtype eq "announce");
1746}
1747close(INPUT);
1748}
17491;
Note: See TracBrowser for help on using the repository browser.