source: ProjectBuilder/devel/pb/lib/ProjectBuilder/CMS.pm@ 537

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

Fix #31: pb now preserves by default original tar files got by http or ftp to allow for checksum consistency.

File size: 19.7 KB
Line 
1#!/usr/bin/perl -w
2#
3# Project Builder CMS module
4# CMS subroutines brought by the the Project-Builder project
5# which can be easily used by pbinit scripts
6#
7# $Id$
8#
9# Copyright B. Cornec 2007
10# Provided under the GPL v2
11
12package ProjectBuilder::CMS;
13
14use strict 'vars';
15use Data::Dumper;
16use English;
17use File::Basename;
18use File::Copy;
19use POSIX qw(strftime);
20use lib qw (lib);
21use ProjectBuilder::Base;
22use ProjectBuilder::Conf;
23
24# Inherit from the "Exporter" module which handles exporting functions.
25
26use Exporter;
27
28# Export, by default, all the functions into the namespace of
29# any code which uses this module.
30
31our @ISA = qw(Exporter);
32our @EXPORT = qw(pb_cms_init pb_cms_export pb_cms_get_uri pb_cms_copy pb_cms_checkout pb_cms_up pb_cms_checkin pb_cms_isdiff pb_cms_get_pkg pb_cms_compliant pb_cms_log pb_cms_add);
33
34=pod
35
36=head1 NAME
37
38ProjectBuilder::CMS, part of the project-builder.org
39
40=head1 DESCRIPTION
41
42This modules provides configuration management system functions suitable for pbinit calls.
43
44=head1 USAGE
45
46=over 4
47
48=item B<pb_cms_init>
49
50This function setup the environment for the CMS system related to the URL given by the pburl configuration parameter.
51The potential parameter indicates whether we should inititate the context or not.
52It sets up environement variables (PBPROJDIR, PBDIR, PBREVISION, PBCMSLOGFILE)
53
54=cut
55
56sub pb_cms_init {
57
58my $pbinit = shift || undef;
59
60my ($pburl) = pb_conf_get("pburl");
61pb_log(2,"DEBUG: Project URL of $ENV{'PBPROJ'}: $pburl->{$ENV{'PBPROJ'}}\n");
62my ($scheme, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
63
64my ($pbprojdir) = pb_conf_get_if("pbprojdir");
65
66if ((defined $pbprojdir) && (defined $pbprojdir->{$ENV{'PBPROJ'}})) {
67 $ENV{'PBPROJDIR'} = $pbprojdir->{$ENV{'PBPROJ'}};
68} else {
69 $ENV{'PBPROJDIR'} = "$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}";
70}
71
72# Computing the default dir for PBDIR.
73# what we have is PBPROJDIR so work from that.
74# Tree identical between PBCONFDIR and PBROOTDIR on one side and
75# PBPROJDIR and PBDIR on the other side.
76
77my $tmp = $ENV{'PBROOTDIR'};
78$tmp =~ s|^$ENV{'PBCONFDIR'}||;
79
80#
81# Check project cms compliance
82#
83pb_cms_compliant(undef,'PBDIR',"$ENV{'PBPROJDIR'}/$tmp",$pburl->{$ENV{'PBPROJ'}},$pbinit);
84
85if ($scheme =~ /^svn/) {
86 # svnversion more precise than svn info
87 $tmp = `(cd "$ENV{'PBDIR'}" ; svnversion .)`;
88 chomp($tmp);
89 $ENV{'PBREVISION'}=$tmp;
90 $ENV{'PBCMSLOGFILE'}="svn.log";
91} elsif (($scheme eq "file") || ($scheme eq "ftp") || ($scheme eq "http")) {
92 $ENV{'PBREVISION'}="flat";
93 $ENV{'PBCMSLOGFILE'}="flat.log";
94} elsif ($scheme =~ /^cvs/) {
95 # Way too slow
96 #$ENV{'PBREVISION'}=`(cd "$ENV{'PBROOTDIR'}" ; cvs rannotate -f . 2>&1 | awk '{print \$1}' | grep -E '^[0-9]' | cut -d. -f2 |sort -nu | tail -1)`;
97 #chomp($ENV{'PBREVISION'});
98 $ENV{'PBREVISION'}="cvs";
99 $ENV{'PBCMSLOGFILE'}="cvs.log";
100 $ENV{'CVS_RSH'} = "ssh" if ($scheme =~ /ssh/);
101} else {
102 die "cms $scheme unknown";
103}
104
105return($scheme,$pburl->{$ENV{'PBPROJ'}});
106}
107
108=item B<pb_cms_export>
109
110This function exports a CMS content to a directory.
111The first parameter is the URL of the CMS content.
112The second parameter is the directory in which it is locally exposed (result of a checkout). If undef, then use the original CMS content.
113The third parameter is the directory where we want to deliver it (result of export).
114It returns the original tar file if we need to preserve it and undef if we use the produced one.
115
116=cut
117
118sub pb_cms_export {
119
120my $uri = shift;
121my $source = shift;
122my $destdir = shift;
123my $tmp;
124my $tmp1;
125
126my @date = pb_get_date();
127# If it's not flat, then we have a real uri as source
128my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
129
130if ($scheme =~ /^svn/) {
131 if (defined $source) {
132 if (-d $source) {
133 $tmp = $destdir;
134 } else {
135 $tmp = "$destdir/".basename($source);
136 }
137 pb_system("svn export $source $tmp","Exporting $source from SVN to $tmp");
138 } else {
139 pb_system("svn export $uri $destdir","Exporting $uri from SVN to $destdir");
140 }
141} elsif ($scheme eq "dir") {
142 pb_system("cp -a $path $destdir","Copying $uri from DIR to $destdir");
143} elsif (($scheme eq "http") || ($scheme eq "ftp")) {
144 my $f = basename($path);
145 unlink "$ENV{'PBTMP'}/$f";
146 if (-x "/usr/bin/wget") {
147 pb_system("/usr/bin/wget -nv -O $ENV{'PBTMP'}/$f $uri"," ");
148 } elsif (-x "/usr/bin/curl") {
149 pb_system("/usr/bin/curl $uri -o $ENV{'PBTMP'}/$f","Downloading $uri with curl to $ENV{'PBTMP'}/$f\n");
150 } else {
151 die "Unable to download $uri.\nNo wget/curl available, please install one of those";
152 }
153 # We want to preserve the original tar file
154 pb_cms_export("file://$ENV{'PBTMP'}/$f",$source,$destdir);
155 return("$ENV{'PBTMP'}/$f");
156} elsif ($scheme eq "file") {
157 use File::MimeInfo;
158 my $mm = mimetype($path);
159 pb_log(2,"mimetype: $mm\n");
160
161 if (defined $source) {
162 # Check whether the file is well formed
163 # (containing already a directory with the project-version name)
164 #
165 # If it's not the case, we try to adapt, but distro needing
166 # to verify the checksum will have issues (Fedora)
167 # Then upstream should be notified that they need to change their rules
168 my ($pbwf) = pb_conf_get_if("pbwf");
169 if ((defined $pbwf) && (defined $pbwf->{$ENV{'PBPROJ'}})) {
170 $destdir = dirname($destdir);
171 }
172 }
173 pb_mkdir_p($destdir);
174
175 if ($mm =~ /\/x-bzip-compressed-tar$/) {
176 # tar+bzip2
177 pb_system("cd $destdir ; tar xfj $path","Extracting $path in $destdir");
178 } elsif ($mm =~ /\/x-lzma-compressed-tar$/) {
179 # tar+lzma
180 pb_system("cd $destdir ; tar xfY $path","Extracting $path in $destdir");
181 } elsif ($mm =~ /\/x-compressed-tar$/) {
182 # tar+gzip
183 pb_system("cd $destdir ; tar xfz $path","Extracting $path in $destdir");
184 } elsif ($mm =~ /\/x-tar$/) {
185 # tar
186 pb_system("cd $destdir ; tar xf $path","Extracting $path in $destdir");
187 } elsif ($mm =~ /\/zip$/) {
188 # zip
189 pb_system("cd $destdir ; unzip $path","Extracting $path in $destdir");
190 } else {
191 # simple file: copy it (patch e.g.)
192 copy($path,$destdir);
193 }
194} elsif ($scheme =~ /^cvs/) {
195 # CVS needs a relative path !
196 my $dir=dirname($destdir);
197 my $base=basename($destdir);
198 if (defined $source) {
199 # CVS also needs a modules name not a dir
200 $tmp1 = basename($source);
201 } else {
202 # Probably not right, should be checked, but that way I'll notice it :-)
203 $tmp1 = $uri;
204 }
205 # If we're working on the CVS itself
206 my $cvstag = basename($ENV{'PBROOTDIR'});
207 my $cvsopt = "";
208 if ($cvstag eq "cvs") {
209 my $pbdate = strftime("%Y-%m-%d %H:%M:%S", @date);
210 $cvsopt = "-D \"$pbdate\"";
211 } else {
212 # we're working on a tag which should be the last part of PBROOTDIR
213 $cvsopt = "-r $cvstag";
214 }
215 pb_system("cd $dir ; cvs -d $account\@$host:$path export $cvsopt -d $base $tmp1","Exporting $tmp1 from $source under CVS to $destdir");
216} else {
217 die "cms $scheme unknown";
218}
219return(undef);
220}
221
222=item B<pb_cms_get_uri>
223
224This function is only called with a real CMS system and gives the URL stored in the checked out directory.
225The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
226The second parameter is the directory in which it is locally exposed (result of a checkout).
227
228=cut
229
230sub pb_cms_get_uri {
231
232my $scheme = shift;
233my $dir = shift;
234
235my $res = "";
236my $void = "";
237
238if ($scheme =~ /^svn/) {
239 open(PIPE,"LANGUAGE=C svn info $dir |") || return("");
240 while (<PIPE>) {
241 ($void,$res) = split(/^URL:/) if (/^URL:/);
242 }
243 $res =~ s/^\s*//;
244 close(PIPE);
245 chomp($res);
246} elsif ($scheme =~ /^cvs/) {
247 # This path is always the root path of CVS, but we may be below
248 open(FILE,"$dir/CVS/Root") || die "$dir isn't CVS controlled";
249 $res = <FILE>;
250 chomp($res);
251 close(FILE);
252 # Find where we are in the tree
253 my $rdir = $dir;
254 while ((! -d "$rdir/CVSROOT") && ($rdir ne "/")) {
255 $rdir = dirname($rdir);
256 }
257 die "Unable to find a CVSROOT dir in the parents of $dir" if (! -d "$rdir/CVSROOT");
258 #compute our place under that root dir - should be a relative path
259 $dir =~ s|^$rdir||;
260 my $suffix = "";
261 $suffix = "$dir" if ($dir ne "");
262
263 my $prefix = "";
264 if ($scheme =~ /ssh/) {
265 $prefix = "cvs+ssh://";
266 } else {
267 $prefix = "cvs://";
268 }
269 $res = $prefix.$res.$suffix;
270} else {
271 die "cms $scheme unknown";
272}
273pb_log(2,"Found CMS info: $res\n");
274return($res);
275}
276
277=item B<pb_cms_copy>
278
279This function copies a CMS content to another.
280The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
281The second parameter is the URL of the original CMS content.
282The third parameter is the URL of the destination CMS content.
283
284Only coded for SVN now.
285
286=cut
287
288sub pb_cms_copy {
289my $scheme = shift;
290my $oldurl = shift;
291my $newurl = shift;
292
293if ($scheme =~ /^svn/) {
294 pb_system("svn copy -m \"Creation of $newurl from $oldurl\" $oldurl $newurl","Copying $oldurl to $newurl ");
295} elsif ($scheme eq "flat") {
296} elsif ($scheme =~ /^cvs/) {
297} else {
298 die "cms $scheme unknown";
299}
300}
301
302=item B<pb_cms_checkout>
303
304This function checks a CMS content out to a directory.
305The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
306The second parameter is the URL of the CMS content.
307The third parameter is the directory where we want to deliver it (result of export).
308
309=cut
310
311sub pb_cms_checkout {
312my $scheme = shift;
313my $url = shift;
314my $destination = shift;
315
316if ($scheme =~ /^svn/) {
317 pb_system("svn co $url $destination","Checking out $url to $destination ");
318} elsif (($scheme eq "ftp") || ($scheme eq "http")) {
319 return;
320} elsif ($scheme =~ /^cvs/) {
321 my ($scheme, $account, $host, $port, $path) = pb_get_uri($url);
322
323 # If we're working on the CVS itself
324 my $cvstag = basename($ENV{'PBROOTDIR'});
325 my $cvsopt = "";
326 if ($cvstag eq "cvs") {
327 my @date = pb_get_date();
328 my $pbdate = strftime("%Y-%m-%d %H:%M:%S", @date);
329 $cvsopt = "-D \"$pbdate\"";
330 } else {
331 # we're working on a tag which should be the last part of PBROOTDIR
332 $cvsopt = "-r $cvstag";
333 }
334 pb_mkdir_p("$destination");
335 pb_system("cd $destination ; cvs -d $account\@$host:$path co $cvsopt .","Checking out $url to $destination");
336} elsif ($scheme =~ /^file/) {
337 pb_cms_export($url,undef,$destination);
338} else {
339 die "cms $scheme unknown";
340}
341}
342
343=item B<pb_cms_up>
344
345This function updates a local directory with the CMS content.
346The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
347The second parameter is the directory to update.
348
349=cut
350
351sub pb_cms_up {
352my $scheme = shift;
353my $dir = shift;
354
355if ($scheme =~ /^svn/) {
356 pb_system("svn up $dir","Updating $dir");
357} elsif ($scheme eq "flat") {
358} elsif ($scheme =~ /^cvs/) {
359 pb_system("cvs up $dir","Updating $dir");
360} else {
361 die "cms $scheme unknown";
362}
363}
364
365=item B<pb_cms_checkin>
366
367This function updates a CMS content from a local directory.
368The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
369The second parameter is the directory to update from.
370The third parameter indicates if we are in a new version creation (undef) or in a new project creation (1)
371
372=cut
373
374sub pb_cms_checkin {
375my $scheme = shift;
376my $dir = shift;
377my $pbinit = shift || undef;
378
379my $ver = basename($dir);
380my $msg = "updated to $ver";
381$msg = "Project $ENV{PBPROJ} creation" if (defined $pbinit);
382
383if ($scheme =~ /^svn/) {
384 pb_system("svn ci -m \"$msg\" $dir","Checking in $dir");
385} elsif ($scheme eq "flat") {
386} elsif ($scheme =~ /^cvs/) {
387 pb_system("cvs ci -m \"$msg\" $dir","Checking in $dir");
388} else {
389 die "cms $scheme unknown";
390}
391pb_cms_up($scheme,$dir);
392}
393
394=item B<pb_cms_add>
395
396This function adds to a CMS content from a local directory.
397The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
398The second parameter is the directory/file to add.
399
400=cut
401
402sub pb_cms_add {
403my $scheme = shift;
404my $f = shift;
405
406if ($scheme =~ /^svn/) {
407 pb_system("svn add $f","Adding $f to SVN");
408} elsif ($scheme eq "flat") {
409} elsif ($scheme =~ /^cvs/) {
410 pb_system("cvs add $f","Adding $f to CVS");
411} else {
412 die "cms $scheme unknown";
413}
414pb_cms_up($scheme,$f);
415}
416
417=item B<pb_cms_isdiff>
418
419This function returns a integer indicating the number f differences between the CMS content and the local directory where it's checked out.
420The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
421The second parameter is the directory to consider.
422
423=cut
424
425sub pb_cms_isdiff {
426my $scheme = shift;
427my $dir =shift;
428
429if ($scheme =~ /^svn/) {
430 open(PIPE,"svn diff $dir |") || die "Unable to get svn diff from $dir";
431 my $l = 0;
432 while (<PIPE>) {
433 $l++;
434 }
435 return($l);
436} elsif ($scheme eq "flat") {
437} elsif ($scheme =~ /^cvs/) {
438 open(PIPE,"cvs diff $dir |") || die "Unable to get svn diff from $dir";
439 my $l = 0;
440 while (<PIPE>) {
441 # Skipping normal messages
442 next if (/^cvs diff:/);
443 $l++;
444 }
445 return($l);
446} else {
447 die "cms $scheme unknown";
448}
449}
450
451=item B<pb_cms_getpkg>
452
453This function returns the list of packages we are working on in a CMS action.
454The first parameter is the default list of packages from the configuration file.
455The second parameter is the optional list of packages from the configuration file.
456
457=cut
458
459sub pb_cms_get_pkg {
460
461my @pkgs = ();
462my $defpkgdir = shift || undef;
463my $extpkgdir = shift || undef;
464
465# Get packages list
466if (not defined $ARGV[0]) {
467 @pkgs = keys %$defpkgdir if (defined $defpkgdir);
468} elsif ($ARGV[0] =~ /^all$/) {
469 @pkgs = keys %$defpkgdir if (defined $defpkgdir);
470 push(@pkgs, keys %$extpkgdir) if (defined $extpkgdir);
471} else {
472 @pkgs = @ARGV;
473}
474pb_log(0,"Packages: ".join(',',@pkgs)."\n");
475return(\@pkgs);
476}
477
478=item B<pb_cms_compliant>
479
480This function checks the compliance of the project and the pbconf directory.
481The first parameter is the key name of the value that needs to be read in the configuration file.
482The second parameter is the environment variable this key will populate.
483The third parameter is the location of the pbconf dir.
484The fourth parameter is the URI of the CMS content related to the pbconf dir.
485The fifth parameter indicates whether we should inititate the context or not.
486
487=cut
488
489sub pb_cms_compliant {
490
491my $param = shift;
492my $envar = shift;
493my $defdir = shift;
494my $uri = shift;
495my $pbinit = shift;
496my %pdir;
497
498my ($pdir) = pb_conf_get_if($param) if (defined $param);
499if (defined $pdir) {
500 %pdir = %$pdir;
501}
502
503
504if ((defined $pdir) && (%pdir) && (defined $pdir{$ENV{'PBPROJ'}})) {
505 # That's always the environment variable that will be used
506 $ENV{$envar} = $pdir{$ENV{'PBPROJ'}};
507} else {
508 if (defined $param) {
509 pb_log(1,"WARNING: no $param defined, using $defdir\n");
510 pb_log(1," Please create a $param reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
511 pb_log(1," if you want to use another directory\n");
512 }
513 $ENV{$envar} = "$defdir";
514}
515
516# Expand potential env variable in it
517eval { $ENV{$envar} =~ s/(\$ENV.+\})/$1/eeg };
518pb_log(2,"$envar: $ENV{$envar}\n");
519
520my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
521
522if ((! -d "$ENV{$envar}") || (defined $pbinit)) {
523 if (defined $pbinit) {
524 pb_mkdir_p("$ENV{$envar}");
525 } else {
526 pb_log(1,"Checking out $uri\n");
527 pb_cms_checkout($scheme,$uri,$ENV{$envar});
528 }
529} elsif (($scheme !~ /^cvs/) || ($scheme !~ /^svn/)) {
530 # Do not compare if it's not a real cms
531 return;
532} else {
533 pb_log(1,"$uri found locally, checking content\n");
534 my $cmsurl = pb_cms_get_uri($scheme,$ENV{$envar});
535 my ($scheme2, $account2, $host2, $port2, $path2) = pb_get_uri($cmsurl);
536 if ($cmsurl ne $uri) {
537 # The local content doesn't correpond to the repository
538 pb_log(0,"ERROR: Inconsistency detected:\n");
539 pb_log(0," * $ENV{$envar} refers to $cmsurl but\n");
540 pb_log(0," * $ENV{'PBETC'} refers to $uri\n");
541 die "Project $ENV{'PBPROJ'} is not Project-Builder compliant.";
542 } else {
543 pb_log(1,"Content correct - doing nothing - you may want to update your repository however\n");
544 # they match - do nothing - there may be local changes
545 }
546}
547}
548
549=item B<pb_cms_create_authors>
550
551This function creates a AUTHORS files for the project. It call it AUTHORS.pb if an AUTHORS file already exists.
552The first parameter is the source file for authors information.
553The second parameter is the directory where to create the final AUTHORS file.
554The third parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
555
556=cut
557
558sub pb_cms_create_authors {
559
560my $authors=shift;
561my $dest=shift;
562my $scheme=shift;
563
564return if ($authors eq "/dev/null");
565open(SAUTH,$authors) || die "Unable to open $authors";
566# Save a potentially existing AUTHORS file and write instead to AUTHORS.pb
567my $ext = "";
568if (-f "$dest/AUTHORS") {
569 $ext = ".pb";
570}
571open(DAUTH,"> $dest/AUTHORS$ext") || die "Unable to create $dest/AUTHORS$ext";
572print DAUTH "Authors of the project are:\n";
573print DAUTH "===========================\n";
574while (<SAUTH>) {
575 my ($nick,$gcos) = split(/:/);
576 chomp($gcos);
577 print DAUTH "$gcos";
578 if (defined $scheme) {
579 # Do not give a scheme for flat types
580 my $endstr="";
581 if ("$ENV{'PBREVISION'}" ne "flat") {
582 $endstr = " under $scheme";
583 }
584 print DAUTH " ($nick$endstr)\n";
585 } else {
586 print DAUTH "\n";
587 }
588}
589close(DAUTH);
590close(SAUTH);
591}
592
593=item B<pb_cms_log>
594
595This function creates a ChangeLog file for the project.
596The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
597The second parameter is the directory where the CMS content was checked out.
598The third parameter is the directory where to create the final ChangeLog file.
599The fourth parameter is unused.
600The fifth parameter is the source file for authors information.
601
602It may use a tool like svn2cl or cvs2cl to generate it if present, or the log file from the CMS if not.
603
604=cut
605
606
607sub pb_cms_log {
608
609my $scheme = shift;
610my $pkgdir = shift;
611my $dest = shift;
612my $chglog = shift;
613my $authors = shift;
614my $testver = shift || undef;
615
616pb_cms_create_authors($authors,$dest,$scheme);
617
618if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
619 if (! -f "$dest/ChangeLog") {
620 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
621 # We need a minimal version for debian type of build
622 print CL "\n";
623 print CL "\n";
624 print CL "\n";
625 print CL "\n";
626 print CL "1990-01-01 none\n";
627 print CL "\n";
628 print CL " * test version\n";
629 print CL "\n";
630 close(CL);
631 pb_log(0,"Generating fake ChangeLog for test version\n");
632 open(CL,"> $dest/$ENV{'PBCMSLOGFILE'}") || die "Unable to create $dest/$ENV{'PBCMSLOGFILE'}";
633 close(CL);
634 }
635}
636
637if ($scheme =~ /^svn/) {
638 if (! -f "$dest/ChangeLog") {
639 # In case we have no network, just create an empty one before to allow correct build
640 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
641 close(CL);
642 if (-x "/usr/bin/svn2cl") {
643 pb_system("/usr/bin/svn2cl --group-by-day --authors=$authors -i -o $dest/ChangeLog $pkgdir","Generating ChangeLog from SVN with svn2cl");
644 } else {
645 # To be written from pbcl
646 pb_system("svn log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVN");
647 }
648 }
649} elsif (($scheme eq "file") || ($scheme eq "dir") || ($scheme eq "http") || ($scheme eq "ftp")) {
650 if (! -f "$dest/ChangeLog") {
651 pb_system("echo ChangeLog for $pkgdir > $dest/ChangeLog","Empty ChangeLog file created");
652 }
653} elsif ($scheme =~ /^cvs/) {
654 my $tmp=basename($pkgdir);
655 # CVS needs a relative path !
656 if (! -f "$dest/ChangeLog") {
657 # In case we have no network, just create an empty one before to allow correct build
658 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
659 close(CL);
660 if (-x "/usr/bin/cvs2cl") {
661 pb_system("/usr/bin/cvs2cl --group-by-day -U $authors -f $dest/ChangeLog $pkgdir","Generating ChangeLog from CVS with cvs2cl");
662 } else {
663 # To be written from pbcl
664 pb_system("cvs log $tmp > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from CVS");
665 }
666 }
667} else {
668 die "cms $scheme unknown";
669}
670}
671
672=back
673
674=head1 WEB SITES
675
676The main Web site of the project is available at L<http://www.project-builder.org/>. Bug reports should be filled using the trac instance of the project at L<http://trac.project-builder.org/>.
677
678=head1 USER MAILING LIST
679
680None exists for the moment.
681
682=head1 AUTHORS
683
684The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
685
686=head1 COPYRIGHT
687
688Project-Builder.org is distributed under the GPL v2.0 license
689described in the file C<COPYING> included with the distribution.
690
691=cut
692
6931;
Note: See TracBrowser for help on using the repository browser.