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

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

r3072@localhost: bruno | 2009-05-17 19:39:56 +0200
Adds support for SVK as a DVCS/CMS to project builder

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