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

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