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

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

linuxcoe version cvs now builds. Rest to see tags for cvs

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