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

Last change on this file since 1174 was 1174, checked in by Bruno Cornec, 13 years ago
  • Fix ebuild test name generation (Report Francesco)
  • Fix project package generation from file URL
  • Introduce hpux entry (not working)
  • pb_cms_mod_http renamed pb_cms_mod_htftp and also now handles ftp protocol
  • Fix pb_cms_compliant for file URL build
File size: 28.5 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::Version;
22use ProjectBuilder::Base;
23use ProjectBuilder::Conf;
24
25# Inherit from the "Exporter" module which handles exporting functions.
26
27use vars qw($VERSION $REVISION @ISA @EXPORT);
28use Exporter;
29
30# Export, by default, all the functions into the namespace of
31# any code which uses this module.
32
33our @ISA = qw(Exporter);
34our @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_get_real_pkg pb_cms_compliant pb_cms_log pb_cms_add);
35($VERSION,$REVISION) = pb_version_init();
36
37=pod
38
39=head1 NAME
40
41ProjectBuilder::CMS, part of the project-builder.org
42
43=head1 DESCRIPTION
44
45This modules provides configuration management system functions suitable for pbinit calls.
46
47=head1 USAGE
48
49=over 4
50
51=item B<pb_cms_init>
52
53This function setup the environment for the CMS system related to the URL given by the pburl configuration parameter.
54The potential parameter indicates whether we should inititate the context or not.
55It sets up environement variables (PBPROJDIR, PBDIR, PBREVISION, PBCMSLOGFILE)
56
57=cut
58
59sub pb_cms_init {
60
61my $pbinit = shift || undef;
62my $param = shift || undef;
63
64my ($pburl) = pb_conf_get("pburl");
65pb_log(2,"DEBUG: Project URL of $ENV{'PBPROJ'}: $pburl->{$ENV{'PBPROJ'}}\n");
66my ($scheme, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
67my $vcscmd = pb_cms_cmd($scheme);
68
69my ($pbprojdir) = pb_conf_get_if("pbprojdir");
70
71if ((defined $pbprojdir) && (defined $pbprojdir->{$ENV{'PBPROJ'}})) {
72 $ENV{'PBPROJDIR'} = $pbprojdir->{$ENV{'PBPROJ'}};
73} else {
74 $ENV{'PBPROJDIR'} = "$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}";
75}
76# Expand potential env variable in it to allow string replacement
77eval { $ENV{'PBPROJDIR'} =~ s/(\$ENV.+\})/$1/eeg };
78
79
80# Computing the default dir for PBDIR.
81# what we have is PBPROJDIR so work from that.
82# Tree identical between PBCONFDIR and PBROOTDIR on one side and
83# PBPROJDIR and PBDIR on the other side.
84
85my $tmp = $ENV{'PBROOTDIR'};
86$tmp =~ s|^$ENV{'PBCONFDIR'}/||;
87
88#
89# Check project cms compliance
90#
91my $turl = "$pburl->{$ENV{'PBPROJ'}}/$tmp";
92$turl = $pburl->{$ENV{'PBPROJ'}} if (($scheme =~ /^file/) || ($scheme =~ /^(ht|f)tp/));
93pb_cms_compliant(undef,'PBDIR',"$ENV{'PBPROJDIR'}/$tmp",$turl,$pbinit);
94
95
96if ($scheme =~ /^hg/) {
97 $tmp = `(cd "$ENV{'PBDIR'}" ; $vcscmd identify )`;
98 chomp($tmp);
99 $tmp =~ s/^.* //;
100 $ENV{'PBREVISION'}=$tmp;
101 $ENV{'PBCMSLOGFILE'}="hg.log";
102} elsif ($scheme =~ /^git/) {
103 $tmp = `(cd "$ENV{'PBDIR'}" ; $vcscmd log | head -1 | cut -f2)`;
104 chomp($tmp);
105 $tmp =~ s/^.* //;
106 $ENV{'PBREVISION'}=$tmp;
107 $ENV{'PBCMSLOGFILE'}="git.log";
108} elsif (($scheme =~ /^file/) || ($scheme eq "ftp") || ($scheme eq "http")) {
109 $ENV{'PBREVISION'}="flat";
110 $ENV{'PBCMSLOGFILE'}="flat.log";
111} elsif ($scheme =~ /^svn/) {
112 # svnversion more precise than svn info if sbx
113 if ((defined $param) && ($param eq "CMS")) {
114 $tmp = `(LANGUAGE=C $vcscmd info $pburl->{$ENV{'PBPROJ'}} | grep -E '^Revision:' | cut -d: -f2)`;
115 $tmp =~ s/\s+//;
116 } else {
117 $tmp = `(cd "$ENV{'PBDIR'}" ; $vcscmd"version" .)`;
118 }
119 chomp($tmp);
120 $ENV{'PBREVISION'}=$tmp;
121 $ENV{'PBCMSLOGFILE'}="svn.log";
122} elsif ($scheme =~ /^svk/) {
123 $tmp = `(cd "$ENV{'PBDIR'}" ; LANGUAGE=C $vcscmd info . | grep -E '^Revision:' | cut -d: -f2)`;
124 $tmp =~ s/\s+//;
125 chomp($tmp);
126 $ENV{'PBREVISION'}=$tmp;
127 $ENV{'PBCMSLOGFILE'}="svk.log";
128} elsif ($scheme =~ /^cvs/) {
129 # Way too slow
130 #$ENV{'PBREVISION'}=`(cd "$ENV{'PBROOTDIR'}" ; cvs rannotate -f . 2>&1 | awk '{print \$1}' | grep -E '^[0-9]' | cut -d. -f2 |sort -nu | tail -1)`;
131 #chomp($ENV{'PBREVISION'});
132 $ENV{'PBREVISION'}="cvs";
133 $ENV{'PBCMSLOGFILE'}="cvs.log";
134 $ENV{'CVS_RSH'} = "ssh" if ($scheme =~ /ssh/);
135} else {
136 die "cms $scheme unknown";
137}
138
139pb_log(1,"pb_cms_init returns $scheme,$pburl->{$ENV{'PBPROJ'}}\n");
140return($scheme,$pburl->{$ENV{'PBPROJ'}});
141}
142
143=item B<pb_cms_export>
144
145This function exports a CMS content to a directory.
146The first parameter is the URL of the CMS content.
147The second parameter is the directory in which it is locally exposed (result of a checkout). If undef, then use the original CMS content.
148The third parameter is the directory where we want to deliver it (result of export).
149It returns the original tar file if we need to preserve it and undef if we use the produced one.
150
151=cut
152
153sub pb_cms_export {
154
155my $uri = shift;
156my $source = shift;
157my $destdir = shift;
158my $tmp;
159my $tmp1;
160
161pb_log(1,"pb_cms_export uri: $uri - destdir: $destdir\n");
162pb_log(1,"pb_cms_export source: $source\n") if (defined $source);
163my @date = pb_get_date();
164# If it's not flat, then we have a real uri as source
165my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
166my $vcscmd = pb_cms_cmd($scheme);
167$uri = pb_cms_mod_socks($uri);
168
169if ($scheme =~ /^svn/) {
170 if (defined $source) {
171 if (-d $source) {
172 $tmp = $destdir;
173 } else {
174 $tmp = "$destdir/".basename($source);
175 }
176 $source = pb_cms_mod_htftp($source,"svn");
177 pb_system("$vcscmd export $source $tmp","Exporting $source from $scheme to $tmp ");
178 } else {
179 $uri = pb_cms_mod_htftp($uri,"svn");
180 pb_system("$vcscmd export $uri $destdir","Exporting $uri from $scheme to $destdir ");
181 }
182} elsif ($scheme eq "svk") {
183 my $src = $source;
184 if (defined $source) {
185 if (-d $source) {
186 $tmp = $destdir;
187 } else {
188 $tmp = "$destdir/".basename($source);
189 $src = dirname($source);
190 }
191 $source = pb_cms_mod_htftp($source,"svk");
192 # This doesn't exist !
193 # pb_system("$vcscmd export $path $tmp","Exporting $path from $scheme to $tmp ");
194 pb_log(4,"$uri,$source,$destdir,$scheme, $account, $host, $port, $path,$tmp");
195 if (-d $source) {
196 pb_system("mkdir -p $tmp ; cd $tmp; tar -cf - -C $source . | tar xf -","Exporting $source from $scheme to $tmp ");
197 } else {
198 # If source is file do not use -C with source
199 pb_system("mkdir -p ".dirname($tmp)." ; cd ".dirname($tmp)."; tar -cf - -C $src ".basename($source)." | tar xf -","Exporting $src/".basename($source)." from $scheme to $tmp ");
200 }
201 } else {
202 # Look at svk admin hotcopy
203 die "Unable to export from svk without a source defined";
204 }
205} elsif ($scheme eq "dir") {
206 pb_system("cp -r $path $destdir","Copying $uri from DIR to $destdir ");
207} elsif (($scheme eq "http") || ($scheme eq "ftp")) {
208 my $f = basename($path);
209 unlink "$ENV{'PBTMP'}/$f";
210 pb_system("$vcscmd $ENV{'PBTMP'}/$f $uri","Downloading $uri with $vcscmd to $ENV{'PBTMP'}/$f\n");
211 # We want to preserve the original tar file
212 pb_cms_export("file://$ENV{'PBTMP'}/$f",$source,$destdir);
213 return("$ENV{'PBTMP'}/$f");
214} elsif ($scheme =~ /^file/) {
215 eval
216 {
217 require File::MimeInfo;
218 File::MimeInfo->import();
219 };
220 if ($@) {
221 # File::MimeInfo not found
222 die("ERROR: Install File::MimeInfo to handle scheme $scheme\n");
223 }
224
225 my $mm = mimetype($path);
226 pb_log(2,"mimetype: $mm\n");
227
228 # Check whether the file is well formed
229 (containing already a directory with the project-version name)
230 #
231 # If it's not the case, we try to adapt, but distro needing
232 # to verify the checksum will have issues (Fedora)
233 # Then upstream should be notified that they need to change their rules
234 my ($pbwf) = pb_conf_get_if("pbwf");
235 if ((defined $pbwf) && (defined $pbwf->{$ENV{'PBPROJ'}})) {
236 $destdir = dirname($destdir);
237 pb_log(2,"This is a well-formed file so destdir is now $destdir\n");
238 }
239 pb_mkdir_p($destdir);
240
241 if ($mm =~ /\/x-bzip-compressed-tar$/) {
242 # tar+bzip2
243 pb_system("cd $destdir ; tar xfj $path","Extracting $path in $destdir ");
244 } elsif ($mm =~ /\/x-lzma-compressed-tar$/) {
245 # tar+lzma
246 pb_system("cd $destdir ; tar xfY $path","Extracting $path in $destdir ");
247 } elsif ($mm =~ /\/x-compressed-tar$/) {
248 # tar+gzip
249 pb_system("cd $destdir ; tar xfz $path","Extracting $path in $destdir ");
250 } elsif ($mm =~ /\/x-tar$/) {
251 # tar
252 pb_system("cd $destdir ; tar xf $path","Extracting $path in $destdir ");
253 } elsif ($mm =~ /\/zip$/) {
254 # zip
255 pb_system("cd $destdir ; unzip $path","Extracting $path in $destdir ");
256 } else {
257 # simple file: copy it (patch e.g.)
258 copy($path,$destdir);
259 }
260} elsif ($scheme =~ /^hg/) {
261 if (defined $source) {
262 if (-d $source) {
263 $tmp = $destdir;
264 } else {
265 $tmp = "$destdir/".basename($source);
266 }
267 $source = pb_cms_mod_htftp($source,"hg");
268 pb_system("cd $source ; $vcscmd archive $tmp","Exporting $source from Mercurial to $tmp ");
269 } else {
270 $uri = pb_cms_mod_htftp($uri,"hg");
271 pb_system("$vcscmd clone $uri $destdir","Exporting $uri from Mercurial to $destdir ");
272 }
273} elsif ($scheme =~ /^git/) {
274 if (defined $source) {
275 if (-d $source) {
276 $tmp = $destdir;
277 } else {
278 $tmp = "$destdir/".basename($source);
279 }
280 $source = pb_cms_mod_htftp($source,"git");
281 pb_system("cd $source ; $vcscmd archive --format=tar HEAD | (mkdir $tmp && cd $tmp && tar xf -)","Exporting $source/HEAD from GIT to $tmp ");
282 } else {
283 $uri = pb_cms_mod_htftp($uri,"git");
284 pb_system("$vcscmd clone $uri $destdir","Exporting $uri from GIT to $destdir ");
285 }
286} elsif ($scheme =~ /^cvs/) {
287 # CVS needs a relative path !
288 my $dir=dirname($destdir);
289 my $base=basename($destdir);
290 if (defined $source) {
291 # CVS also needs a modules name not a dir
292 $tmp1 = basename($source);
293 } else {
294 # Probably not right, should be checked, but that way I'll notice it :-)
295 pb_log(0,"You're in an untested part of project-builder.org, please report any result upstream\n");
296 $tmp1 = $uri;
297 }
298 # If we're working on the CVS itself
299 my $cvstag = basename($ENV{'PBROOTDIR'});
300 my $cvsopt = "";
301 if ($cvstag eq "cvs") {
302 my $pbdate = strftime("%Y-%m-%d %H:%M:%S", @date);
303 $cvsopt = "-D \"$pbdate\"";
304 } else {
305 # we're working on a tag which should be the last part of PBROOTDIR
306 $cvsopt = "-r $cvstag";
307 }
308 pb_system("cd $dir ; $vcscmd -d $account\@$host:$path export $cvsopt -d $base $tmp1","Exporting $tmp1 from $source under CVS to $destdir ");
309} else {
310 die "cms $scheme unknown";
311}
312return(undef);
313}
314
315=item B<pb_cms_get_uri>
316
317This function is only called with a real CMS system and gives the URL stored in the checked out directory.
318The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
319The second parameter is the directory in which it is locally exposed (result of a checkout).
320
321=cut
322
323sub pb_cms_get_uri {
324
325my $scheme = shift;
326my $dir = shift;
327
328my $res = "";
329my $void = "";
330my $vcscmd = pb_cms_cmd($scheme);
331
332if ($scheme =~ /^svn/) {
333 open(PIPE,"LANGUAGE=C $vcscmd info $dir |") || return("");
334 while (<PIPE>) {
335 ($void,$res) = split(/^URL:/) if (/^URL:/);
336 }
337 $res =~ s/^\s*//;
338 close(PIPE);
339 chomp($res);
340} elsif ($scheme =~ /^svk/) {
341 open(PIPE,"LANGUAGE=C $vcscmd info $dir |") || return("");
342 my $void2 = "";
343 while (<PIPE>) {
344 ($void,$void2,$res) = split(/ /) if (/^Depot/);
345 }
346 $res =~ s/^\s*//;
347 close(PIPE);
348 chomp($res);
349} elsif ($scheme =~ /^hg/) {
350 open(HGRC,".hg/hgrc/") || return("");
351 while (<HGRC>) {
352 ($void,$res) = split(/^default.*=/) if (/^default.*=/);
353 }
354 close(HGRC);
355 chomp($res);
356} elsif ($scheme =~ /^git/) {
357 open(GITRC,".git/gitrc/") || return("");
358 while (<GITRC>) {
359 ($void,$res) = split(/^default.*=/) if (/^default.*=/);
360 }
361 close(GITRC);
362 chomp($res);
363} elsif ($scheme =~ /^cvs/) {
364 # This path is always the root path of CVS, but we may be below
365 open(FILE,"$dir/CVS/Root") || die "$dir isn't CVS controlled";
366 $res = <FILE>;
367 chomp($res);
368 close(FILE);
369 # Find where we are in the tree
370 my $rdir = $dir;
371 while ((! -d "$rdir/CVSROOT") && ($rdir ne "/")) {
372 $rdir = dirname($rdir);
373 }
374 die "Unable to find a CVSROOT dir in the parents of $dir" if (! -d "$rdir/CVSROOT");
375 #compute our place under that root dir - should be a relative path
376 $dir =~ s|^$rdir||;
377 my $suffix = "";
378 $suffix = "$dir" if ($dir ne "");
379
380 my $prefix = "";
381 if ($scheme =~ /ssh/) {
382 $prefix = "cvs+ssh://";
383 } else {
384 $prefix = "cvs://";
385 }
386 $res = $prefix.$res.$suffix;
387} else {
388 die "cms $scheme unknown";
389}
390pb_log(1,"pb_cms_get_uri returns $res\n");
391return($res);
392}
393
394=item B<pb_cms_copy>
395
396This function copies a CMS content to another.
397The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
398The second parameter is the URL of the original CMS content.
399The third parameter is the URL of the destination CMS content.
400
401Only coded for SVN now as used for pbconf itself not the project
402
403=cut
404
405sub pb_cms_copy {
406my $scheme = shift;
407my $oldurl = shift;
408my $newurl = shift;
409my $vcscmd = pb_cms_cmd($scheme);
410$oldurl = pb_cms_mod_socks($oldurl);
411$newurl = pb_cms_mod_socks($newurl);
412
413if ($scheme =~ /^svn/) {
414 $oldurl = pb_cms_mod_htftp($oldurl,"svn");
415 $newurl = pb_cms_mod_htftp($newurl,"svn");
416 pb_system("$vcscmd copy -m \"Creation of $newurl from $oldurl\" $oldurl $newurl","Copying $oldurl to $newurl ");
417} elsif (($scheme eq "flat") || ($scheme eq "ftp") || ($scheme eq "http")) {
418} else {
419 die "cms $scheme unknown for project management";
420}
421}
422
423=item B<pb_cms_checkout>
424
425This function checks a CMS content out to a directory.
426The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
427The second parameter is the URL of the CMS content.
428The third parameter is the directory where we want to deliver it (result of export).
429
430=cut
431
432sub pb_cms_checkout {
433my $scheme = shift;
434my $url = shift;
435my $destination = shift;
436my $vcscmd = pb_cms_cmd($scheme);
437$url = pb_cms_mod_socks($url);
438
439if ($scheme =~ /^svn/) {
440 $url = pb_cms_mod_htftp($url,"svn");
441 pb_system("$vcscmd co $url $destination","Checking out $url to $destination ");
442} elsif ($scheme =~ /^svk/) {
443 $url = pb_cms_mod_htftp($url,"svk");
444 pb_system("$vcscmd co $url $destination","Checking out $url to $destination ");
445} elsif ($scheme =~ /^hg/) {
446 $url = pb_cms_mod_htftp($url,"hg");
447 pb_system("$vcscmd clone $url $destination","Checking out $url to $destination ");
448} elsif ($scheme =~ /^git/) {
449 $url = pb_cms_mod_htftp($url,"git");
450 pb_system("$vcscmd clone $url $destination","Checking out $url to $destination ");
451} elsif (($scheme eq "ftp") || ($scheme eq "http")) {
452 return;
453} elsif ($scheme =~ /^cvs/) {
454 my ($scheme, $account, $host, $port, $path) = pb_get_uri($url);
455
456 # If we're working on the CVS itself
457 my $cvstag = basename($ENV{'PBROOTDIR'});
458 my $cvsopt = "";
459 if ($cvstag eq "cvs") {
460 my @date = pb_get_date();
461 my $pbdate = strftime("%Y-%m-%d %H:%M:%S", @date);
462 $cvsopt = "-D \"$pbdate\"";
463 } else {
464 # we're working on a tag which should be the last part of PBROOTDIR
465 $cvsopt = "-r $cvstag";
466 }
467 pb_mkdir_p("$destination");
468 pb_system("cd $destination ; $vcscmd -d $account\@$host:$path co $cvsopt .","Checking out $url to $destination ");
469} elsif ($scheme =~ /^file/) {
470 pb_cms_export($url,undef,$destination);
471} else {
472 die "cms $scheme unknown";
473}
474}
475
476=item B<pb_cms_up>
477
478This function updates a local directory with the CMS content.
479The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
480The second parameter is the directory to update.
481
482=cut
483
484sub pb_cms_up {
485my $scheme = shift;
486my $dir = shift;
487my $vcscmd = pb_cms_cmd($scheme);
488
489if (($scheme =~ /^svn/) || ($scheme =~ /^svk/) || ($scheme =~ /^hg/) || ($scheme =~ /^git/) || ($scheme =~ /^cvs/)) {
490 pb_system("$vcscmd up $dir","Updating $dir ");
491} elsif (($scheme eq "flat") || ($scheme eq "ftp") || ($scheme eq "http")) {
492} else {
493 die "cms $scheme unknown";
494}
495}
496
497=item B<pb_cms_checkin>
498
499This function updates a CMS content from a local directory.
500The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
501The second parameter is the directory to update from.
502The third parameter indicates if we are in a new version creation (undef) or in a new project creation (1)
503
504=cut
505
506sub pb_cms_checkin {
507my $scheme = shift;
508my $dir = shift;
509my $pbinit = shift || undef;
510my $vcscmd = pb_cms_cmd($scheme);
511
512my $ver = basename($dir);
513my $msg = "updated to $ver";
514$msg = "Project $ENV{PBPROJ} creation" if (defined $pbinit);
515
516if (($scheme =~ /^svn/) || ($scheme =~ /^svk/) || ($scheme =~ /^hg/) || ($scheme =~ /^git/) || ($scheme =~ /^cvs/)) {
517 pb_system("cd $dir ; $vcscmd ci -m \"$msg\" .","Checking in $dir ");
518} elsif (($scheme eq "flat") || ($scheme eq "ftp") || ($scheme eq "http")) {
519} else {
520 die "cms $scheme unknown";
521}
522pb_cms_up($scheme,$dir);
523}
524
525=item B<pb_cms_add>
526
527This function adds to a CMS content from a local directory.
528The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
529The second parameter is the directory/file to add.
530
531=cut
532
533sub pb_cms_add {
534my $scheme = shift;
535my $f = shift;
536my $vcscmd = pb_cms_cmd($scheme);
537
538if (($scheme =~ /^svn/) || ($scheme =~ /^svk/) || ($scheme =~ /^hg/) || ($scheme =~ /^git/) || ($scheme =~ /^cvs/)) {
539 pb_system("$vcscmd add $f","Adding $f to VCS ");
540} elsif (($scheme eq "flat") || ($scheme eq "ftp") || ($scheme eq "http")) {
541} else {
542 die "cms $scheme unknown";
543}
544pb_cms_up($scheme,$f);
545}
546
547=item B<pb_cms_isdiff>
548
549This function returns a integer indicating the number f differences between the CMS content and the local directory where it's checked out.
550The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
551The second parameter is the directory to consider.
552
553=cut
554
555sub pb_cms_isdiff {
556my $scheme = shift;
557my $dir =shift;
558my $vcscmd = pb_cms_cmd($scheme);
559my $l = undef;
560
561if (($scheme =~ /^svn/) || ($scheme =~ /^svk/) || ($scheme =~ /^hg/) || ($scheme =~ /^git/) || ($scheme =~ /^cvs/)) {
562 open(PIPE,"$vcscmd diff $dir |") || die "Unable to get $vcscmd diff from $dir";
563 $l = 0;
564 while (<PIPE>) {
565 # Skipping normal messages in case of CVS
566 next if (/^cvs diff:/);
567 $l++;
568 }
569} elsif (($scheme eq "flat") || ($scheme eq "ftp") || ($scheme eq "http")) {
570 $l = 0;
571} else {
572 die "cms $scheme unknown";
573}
574pb_log(1,"pb_cms_isdiff returns $l\n");
575return($l);
576}
577
578=item B<pb_cms_get_pkg>
579
580This function returns the list of packages we are working on in a CMS action.
581The first parameter is the default list of packages from the configuration file.
582The second parameter is the optional list of packages from the configuration file.
583
584=cut
585
586sub pb_cms_get_pkg {
587
588my @pkgs = ();
589my $defpkgdir = shift || undef;
590my $extpkgdir = shift || undef;
591
592# Get packages list
593if (not defined $ARGV[0]) {
594 @pkgs = keys %$defpkgdir if (defined $defpkgdir);
595} elsif ($ARGV[0] =~ /^all$/) {
596 @pkgs = keys %$defpkgdir if (defined $defpkgdir);
597 push(@pkgs, keys %$extpkgdir) if (defined $extpkgdir);
598} else {
599 @pkgs = @ARGV;
600}
601pb_log(0,"Packages: ".join(',',@pkgs)."\n");
602return(\@pkgs);
603}
604
605=item B<pb_cms_get_real_pkg>
606
607This function returns the real name of a virtual package we are working on in a CMS action.
608It supports the following types: perl.
609The first parameter is the virtual package name
610
611=cut
612
613sub pb_cms_get_real_pkg {
614
615my $pbpkg = shift || undef;
616my $dtype = shift;
617my $pbpkgreal = $pbpkg;
618
619my @nametype = pb_conf_get_if("namingtype");
620my $type = $nametype[0]->{$pbpkg};
621if (defined $type) {
622 if ($type eq "perl") {
623 if ($dtype eq "rpm") {
624 $pbpkgreal = "perl-".$pbpkg;
625 } elsif ($dtype eq "deb") {
626 # Only lower case allowed in Debian
627 # Cf: http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Package
628 $pbpkgreal = "lib".lc($pbpkg)."-perl";
629 } elsif ($dtype eq "ebuild") {
630 $pbpkgreal = $pbpkg;
631 } elsif ($dtype eq "hpux") {
632 $pbpkgreal = $pbpkg;
633 } elsif ($dtype eq "pkg") {
634 $pbpkgreal = "PB$pbpkg";
635 } else {
636 die "pb_cms_get_real_pkg not implemented for $dtype yet";
637 }
638 } else {
639 die "nametype $type not implemented yet";
640 }
641}
642
643pb_log(1,"pb_cms_get_real_pkg returns $pbpkgreal\n");
644return($pbpkgreal);
645}
646
647=item B<pb_cms_compliant>
648
649This function checks the compliance of the project and the pbconf directory.
650The first parameter is the key name of the value that needs to be read in the configuration file.
651The second parameter is the environment variable this key will populate.
652The third parameter is the location of the pbconf dir.
653The fourth parameter is the URI of the CMS content related to the pbconf dir.
654The fifth parameter indicates whether we should inititate the context or not.
655
656=cut
657
658sub pb_cms_compliant {
659
660my $param = shift;
661my $envar = shift;
662my $defdir = shift;
663my $uri = shift;
664my $pbinit = shift;
665my %pdir;
666
667pb_log(1,"pb_cms_compliant: envar: $envar - defdir: $defdir - uri: $uri\n");
668my ($pdir) = pb_conf_get_if($param) if (defined $param);
669if (defined $pdir) {
670 %pdir = %$pdir;
671}
672
673
674if ((defined $pdir) && (%pdir) && (defined $pdir{$ENV{'PBPROJ'}})) {
675 # That's always the environment variable that will be used
676 $ENV{$envar} = $pdir{$ENV{'PBPROJ'}};
677} else {
678 if (defined $param) {
679 pb_log(1,"WARNING: no $param defined, using $defdir\n");
680 pb_log(1," Please create a $param reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
681 pb_log(1," if you want to use another directory\n");
682 }
683 $ENV{$envar} = "$defdir";
684}
685
686# Expand potential env variable in it
687eval { $ENV{$envar} =~ s/(\$ENV.+\})/$1/eeg };
688pb_log(2,"$envar: $ENV{$envar}\n");
689
690my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
691
692if (($scheme !~ /^cvs/) && ($scheme !~ /^svn/) && ($scheme !~ /^svk/) && ($scheme !~ /^hg/) && ($scheme !~ /^git/)) {
693 # Do not compare if it's not a real cms
694 pb_log(1,"pb_cms_compliant useless\n");
695 return;
696} elsif (defined $pbinit) {
697 pb_mkdir_p("$ENV{$envar}");
698} elsif (! -d "$ENV{$envar}") {
699 # Either we have a version in the uri, and it should be the same
700 # as the one in the envar. Or we should add the version to the uri
701 if (basename($uri) ne basename($ENV{$envar})) {
702 $uri .= "/".basename($ENV{$envar})
703 }
704 pb_log(1,"Checking out $uri\n");
705 # Create structure and remove end dir before exporting
706 pb_mkdir_p("$ENV{$envar}");
707 rm_rf($ENV{$envar});
708 pb_cms_checkout($scheme,$uri,$ENV{$envar});
709} else {
710 pb_log(1,"$uri found locally, checking content\n");
711 my $cmsurl = pb_cms_get_uri($scheme,$ENV{$envar});
712 my ($scheme2, $account2, $host2, $port2, $path2) = pb_get_uri($cmsurl);
713 if ($cmsurl ne $uri) {
714 # The local content doesn't correpond to the repository
715 pb_log(0,"ERROR: Inconsistency detected:\n");
716 pb_log(0," * $ENV{$envar} ($envar) refers to $cmsurl but\n");
717 pb_log(0," * $ENV{'PBETC'} refers to $uri\n");
718 die "Project $ENV{'PBPROJ'} is not Project-Builder compliant.";
719 } else {
720 pb_log(1,"Content correct - doing nothing - you may want to update your repository however\n");
721 # they match - do nothing - there may be local changes
722 }
723}
724pb_log(1,"pb_cms_compliant end\n");
725}
726
727=item B<pb_cms_create_authors>
728
729This function creates a AUTHORS files for the project. It call it AUTHORS.pb if an AUTHORS file already exists.
730The first parameter is the source file for authors information.
731The second parameter is the directory where to create the final AUTHORS file.
732The third parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
733
734=cut
735
736sub pb_cms_create_authors {
737
738my $authors=shift;
739my $dest=shift;
740my $scheme=shift;
741
742return if ($authors eq "/dev/null");
743open(SAUTH,$authors) || die "Unable to open $authors";
744# Save a potentially existing AUTHORS file and write instead to AUTHORS.pb
745my $ext = "";
746if (-f "$dest/AUTHORS") {
747 $ext = ".pb";
748}
749open(DAUTH,"> $dest/AUTHORS$ext") || die "Unable to create $dest/AUTHORS$ext";
750print DAUTH "Authors of the project are:\n";
751print DAUTH "===========================\n";
752while (<SAUTH>) {
753 my ($nick,$gcos) = split(/:/);
754 chomp($gcos);
755 print DAUTH "$gcos";
756 if (defined $scheme) {
757 # Do not give a scheme for flat types
758 my $endstr="";
759 if ("$ENV{'PBREVISION'}" ne "flat") {
760 $endstr = " under $scheme";
761 }
762 print DAUTH " ($nick$endstr)\n";
763 } else {
764 print DAUTH "\n";
765 }
766}
767close(DAUTH);
768close(SAUTH);
769}
770
771=item B<pb_cms_log>
772
773This function creates a ChangeLog file for the project.
774The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
775The second parameter is the directory where the CMS content was checked out.
776The third parameter is the directory where to create the final ChangeLog file.
777The fourth parameter is unused.
778The fifth parameter is the source file for authors information.
779
780It may use a tool like svn2cl or cvs2cl to generate it if present, or the log file from the CMS if not.
781
782=cut
783
784
785sub pb_cms_log {
786
787my $scheme = shift;
788my $pkgdir = shift;
789my $dest = shift;
790my $chglog = shift;
791my $authors = shift;
792my $testver = shift || undef;
793
794pb_cms_create_authors($authors,$dest,$scheme);
795my $vcscmd = pb_cms_cmd($scheme);
796
797if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
798 if (! -f "$dest/ChangeLog") {
799 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
800 # We need a minimal version for debian type of build
801 print CL "\n";
802 print CL "\n";
803 print CL "\n";
804 print CL "\n";
805 print CL "1990-01-01 none\n";
806 print CL "\n";
807 print CL " * test version\n";
808 print CL "\n";
809 close(CL);
810 pb_log(0,"Generating fake ChangeLog for test version\n");
811 open(CL,"> $dest/$ENV{'PBCMSLOGFILE'}") || die "Unable to create $dest/$ENV{'PBCMSLOGFILE'}";
812 close(CL);
813 }
814}
815
816if (! -f "$dest/ChangeLog") {
817 if ($scheme =~ /^svn/) {
818 # In case we have no network, just create an empty one before to allow correct build
819 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
820 close(CL);
821 my $command = pb_check_req("svn2cl",1);
822 if (-x $command) {
823 pb_system("$command --group-by-day --authors=$authors -i -o $dest/ChangeLog $pkgdir","Generating ChangeLog from SVN with svn2cl");
824 } else {
825 # To be written from pbcl
826 pb_system("$vcscmd log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVN");
827 }
828 } elsif ($scheme =~ /^svk/) {
829 pb_system("$vcscmd log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVK");
830 } elsif ($scheme =~ /^hg/) {
831 # In case we have no network, just create an empty one before to allow correct build
832 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
833 close(CL);
834 pb_system("$vcscmd log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from Mercurial");
835 } elsif ($scheme =~ /^git/) {
836 # In case we have no network, just create an empty one before to allow correct build
837 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
838 close(CL);
839 pb_system("$vcscmd log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from GIT");
840 } elsif (($scheme =~ /^file/) || ($scheme eq "dir") || ($scheme eq "http") || ($scheme eq "ftp")) {
841 pb_system("echo ChangeLog for $pkgdir > $dest/ChangeLog","Empty ChangeLog file created");
842 } elsif ($scheme =~ /^cvs/) {
843 my $tmp=basename($pkgdir);
844 # CVS needs a relative path !
845 # In case we have no network, just create an empty one before to allow correct build
846 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
847 close(CL);
848 my $command = pb_check_req("cvs2cl",1);
849 if (-x $command) {
850 pb_system("$command --group-by-day -U $authors -f $dest/ChangeLog $pkgdir","Generating ChangeLog from CVS with cvs2cl");
851 } else {
852 # To be written from pbcl
853 pb_system("$vcscmd log $tmp > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from CVS");
854 }
855 } else {
856 die "cms $scheme unknown";
857 }
858}
859if (! -f "$dest/ChangeLog") {
860 copy("$dest/$ENV{'PBCMSLOGFILE'}","$dest/ChangeLog");
861}
862}
863
864sub pb_cms_mod_htftp {
865
866my $url = shift;
867my $proto = shift;
868
869$url =~ s/^$proto\+((ht|f)tp[s]*):/$1:/;
870pb_log(1,"pb_cms_mod_htftp returns $url\n");
871return($url);
872}
873
874sub pb_cms_mod_socks {
875
876my $url = shift;
877
878$url =~ s/^([A-z0-9]+)\+(socks):/$1:/;
879pb_log(1,"pb_cms_mod_socks returns $url\n");
880return($url);
881}
882
883
884sub pb_cms_cmd {
885
886my $scheme = shift;
887my $cmd = "";
888
889# If there is a socks proxy to use
890if ($scheme =~ /socks/) {
891 # Get the socks proxy command from the conf file
892 my ($pbsockscmd) = pb_conf_get("pbsockscmd");
893 $cmd = "$pbsockscmd->{$ENV{'PBPROJ'}} ";
894}
895
896if ($scheme =~ /hg/) {
897 return($cmd."hg")
898} elsif ($scheme =~ /git/) {
899 return($cmd."git")
900} elsif ($scheme =~ /svn/) {
901 return($cmd."svn")
902} elsif ($scheme =~ /svk/) {
903 return($cmd."svk")
904} elsif ($scheme =~ /cvs/) {
905 return($cmd."cvs")
906} elsif (($scheme =~ /http/) || ($scheme =~ /ftp/)) {
907 my $command = pb_check_req("wget",1);
908 if (-x $command) {
909 return($cmd."$command -nv -O ");
910 } else {
911 $command = pb_check_req("curl",1);
912 if (-x $command) {
913 return($cmd."$command -o ");
914 } else {
915 die "Unable to handle $scheme.\nNo wget/curl available, please install one of those";
916 }
917 }
918} else {
919 return($cmd);
920}
921}
922
923
924
925=back
926
927=head1 WEB SITES
928
929The 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/>.
930
931=head1 USER MAILING LIST
932
933None exists for the moment.
934
935=head1 AUTHORS
936
937The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
938
939=head1 COPYRIGHT
940
941Project-Builder.org is distributed under the GPL v2.0 license
942described in the file C<COPYING> included with the distribution.
943
944=cut
945
9461;
Note: See TracBrowser for help on using the repository browser.