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

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

Fix #35 by forcing the usage of a -r release option, and by exporting only that version tree from the VCS.

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