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

Last change on this file since 781 was 781, checked in by Bruno Cornec, 15 years ago

r3085@localhost: bruno | 2009-05-17 20:47:58 +0200

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