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

Last change on this file since 661 was 661, checked in by Bruno Cornec, 15 years ago
  • Adds GIT support for schroot (initial, works for cms2build)
  • Adds SOCKS support for all VCS commands by adding a new pbsockscmd option in .pbrc (tested with git access behind proxy)
File size: 24.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 =~ /^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 -a $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 pb_log(1,"Checking out $uri\n");
623 pb_cms_checkout($scheme,$uri,$ENV{$envar});
624 }
625} elsif (($scheme !~ /^cvs/) || ($scheme !~ /^svn/) || ($scheme !~ /^hg/) || ($scheme !~ /^git/) ) {
626 # Do not compare if it's not a real cms
627 return;
628} else {
629 pb_log(1,"$uri found locally, checking content\n");
630 my $cmsurl = pb_cms_get_uri($scheme,$ENV{$envar});
631 my ($scheme2, $account2, $host2, $port2, $path2) = pb_get_uri($cmsurl);
632 if ($cmsurl ne $uri) {
633 # The local content doesn't correpond to the repository
634 pb_log(0,"ERROR: Inconsistency detected:\n");
635 pb_log(0," * $ENV{$envar} refers to $cmsurl but\n");
636 pb_log(0," * $ENV{'PBETC'} refers to $uri\n");
637 die "Project $ENV{'PBPROJ'} is not Project-Builder compliant.";
638 } else {
639 pb_log(1,"Content correct - doing nothing - you may want to update your repository however\n");
640 # they match - do nothing - there may be local changes
641 }
642}
643}
644
645=item B<pb_cms_create_authors>
646
647This function creates a AUTHORS files for the project. It call it AUTHORS.pb if an AUTHORS file already exists.
648The first parameter is the source file for authors information.
649The second parameter is the directory where to create the final AUTHORS file.
650The third parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
651
652=cut
653
654sub pb_cms_create_authors {
655
656my $authors=shift;
657my $dest=shift;
658my $scheme=shift;
659
660return if ($authors eq "/dev/null");
661open(SAUTH,$authors) || die "Unable to open $authors";
662# Save a potentially existing AUTHORS file and write instead to AUTHORS.pb
663my $ext = "";
664if (-f "$dest/AUTHORS") {
665 $ext = ".pb";
666}
667open(DAUTH,"> $dest/AUTHORS$ext") || die "Unable to create $dest/AUTHORS$ext";
668print DAUTH "Authors of the project are:\n";
669print DAUTH "===========================\n";
670while (<SAUTH>) {
671 my ($nick,$gcos) = split(/:/);
672 chomp($gcos);
673 print DAUTH "$gcos";
674 if (defined $scheme) {
675 # Do not give a scheme for flat types
676 my $endstr="";
677 if ("$ENV{'PBREVISION'}" ne "flat") {
678 $endstr = " under $scheme";
679 }
680 print DAUTH " ($nick$endstr)\n";
681 } else {
682 print DAUTH "\n";
683 }
684}
685close(DAUTH);
686close(SAUTH);
687}
688
689=item B<pb_cms_log>
690
691This function creates a ChangeLog file for the project.
692The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
693The second parameter is the directory where the CMS content was checked out.
694The third parameter is the directory where to create the final ChangeLog file.
695The fourth parameter is unused.
696The fifth parameter is the source file for authors information.
697
698It may use a tool like svn2cl or cvs2cl to generate it if present, or the log file from the CMS if not.
699
700=cut
701
702
703sub pb_cms_log {
704
705my $scheme = shift;
706my $pkgdir = shift;
707my $dest = shift;
708my $chglog = shift;
709my $authors = shift;
710my $testver = shift || undef;
711
712pb_cms_create_authors($authors,$dest,$scheme);
713my $vcscmd = pb_cms_cmd($scheme);
714
715if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
716 if (! -f "$dest/ChangeLog") {
717 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
718 # We need a minimal version for debian type of build
719 print CL "\n";
720 print CL "\n";
721 print CL "\n";
722 print CL "\n";
723 print CL "1990-01-01 none\n";
724 print CL "\n";
725 print CL " * test version\n";
726 print CL "\n";
727 close(CL);
728 pb_log(0,"Generating fake ChangeLog for test version\n");
729 open(CL,"> $dest/$ENV{'PBCMSLOGFILE'}") || die "Unable to create $dest/$ENV{'PBCMSLOGFILE'}";
730 close(CL);
731 }
732}
733
734if ($scheme =~ /^svn/) {
735 if (! -f "$dest/ChangeLog") {
736 # In case we have no network, just create an empty one before to allow correct build
737 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
738 close(CL);
739 if (-x "/usr/bin/svn2cl") {
740 pb_system("/usr/bin/svn2cl --group-by-day --authors=$authors -i -o $dest/ChangeLog $pkgdir","Generating ChangeLog from SVN with svn2cl");
741 } else {
742 # To be written from pbcl
743 pb_system("$vcscmd log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVN");
744 }
745 }
746} elsif ($scheme =~ /^hg/) {
747 if (! -f "$dest/ChangeLog") {
748 # In case we have no network, just create an empty one before to allow correct build
749 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
750 close(CL);
751 pb_system("$vcscmd log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVN");
752 }
753} elsif ($scheme =~ /^git/) {
754 if (! -f "$dest/ChangeLog") {
755 # In case we have no network, just create an empty one before to allow correct build
756 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
757 close(CL);
758 pb_system("$vcscmd log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from GIT");
759 }
760} elsif (($scheme eq "file") || ($scheme eq "dir") || ($scheme eq "http") || ($scheme eq "ftp")) {
761 if (! -f "$dest/ChangeLog") {
762 pb_system("echo ChangeLog for $pkgdir > $dest/ChangeLog","Empty ChangeLog file created");
763 }
764} elsif ($scheme =~ /^cvs/) {
765 my $tmp=basename($pkgdir);
766 # CVS needs a relative path !
767 if (! -f "$dest/ChangeLog") {
768 # In case we have no network, just create an empty one before to allow correct build
769 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
770 close(CL);
771 if (-x "/usr/bin/cvs2cl") {
772 pb_system("/usr/bin/cvs2cl --group-by-day -U $authors -f $dest/ChangeLog $pkgdir","Generating ChangeLog from CVS with cvs2cl");
773 } else {
774 # To be written from pbcl
775 pb_system("$vcscmd log $tmp > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from CVS");
776 }
777 }
778} else {
779 die "cms $scheme unknown";
780}
781}
782
783sub pb_cms_mod_http {
784
785my $url = shift;
786my $proto = shift;
787
788$url =~ s/^$proto\+(http[s]*):/$1:/;
789return($url);
790}
791
792sub pb_cms_mod_socks {
793
794my $url = shift;
795
796$url =~ s/^([A-z0-9]+)\+(socks):/$1:/;
797return($url);
798}
799
800
801sub pb_cms_cmd {
802
803my $scheme = shift;
804my $cmd = "";
805
806# If there is a socks proxy to use
807if ($scheme =~ /socks/) {
808 # Get the socks proxy command from the conf file
809 my ($pbsockcmd) = pb_conf_get("pbsockscmd");
810 $cmd = "$pbsockcmd->{$ENV{'PBPROJ'}} ";
811}
812
813if ($scheme =~ /hg/) {
814 return($cmd."hg")
815} elsif ($scheme =~ /git/) {
816 return($cmd."git")
817} elsif ($scheme =~ /svn/) {
818 return($cmd."svn")
819} elsif ($scheme =~ /cvs/) {
820 return($cmd."cvs")
821} elsif (($scheme =~ /http/) || ($scheme =~ /ftp/)) {
822 if (-x "/usr/bin/wget") {
823 return($cmd."/usr/bin/wget -nv -O ");
824 } elsif (-x "/usr/bin/curl") {
825 return($cmd."/usr/bin/curl -o ");
826 } else {
827 die "Unable to handle $scheme.\nNo wget/curl available, please install one of those";
828 }
829} else {
830 return($cmd);
831}
832}
833
834
835
836=back
837
838=head1 WEB SITES
839
840The 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/>.
841
842=head1 USER MAILING LIST
843
844None exists for the moment.
845
846=head1 AUTHORS
847
848The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
849
850=head1 COPYRIGHT
851
852Project-Builder.org is distributed under the GPL v2.0 license
853described in the file C<COPYING> included with the distribution.
854
855=cut
856
8571;
Note: See TracBrowser for help on using the repository browser.