source: ProjectBuilder/devel/pb-modules/lib/ProjectBuilder/VCS.pm@ 2025

Last change on this file since 2025 was 2025, checked in by Bruno Cornec, 8 years ago

improve git support by archiving HEAD if no modif in progress and removing git+ on uri when needed

File size: 22.1 KB
Line 
1#!/usr/bin/perl -w
2#
3# Project Builder VCS module
4# VCS subroutines brought by the the Project-Builder project
5# which can be easily used across projects needing to perform
6# VCS related operations
7#
8# $Id$
9#
10# Copyright B. Cornec 2007-2015
11# Eric Anderson's changes are (c) Copyright 2012 Hewlett Packard
12# Provided under the GPL v2
13
14package ProjectBuilder::VCS;
15
16use strict 'vars';
17use Carp 'confess';
18use Cwd 'abs_path';
19use Data::Dumper;
20use English;
21use File::Basename;
22use File::Copy;
23use POSIX qw(strftime);
24use lib qw (lib);
25use ProjectBuilder::Version;
26use ProjectBuilder::Base;
27use ProjectBuilder::Conf;
28
29# Inherit from the "Exporter" module which handles exporting functions.
30
31use vars qw($VERSION $REVISION @ISA @EXPORT);
32use Exporter;
33
34# Export, by default, all the functions into the namespace of
35# any code which uses this module.
36
37our @ISA = qw(Exporter);
38our @EXPORT = qw(pb_vcs_export pb_vcs_get_uri pb_vcs_copy pb_vcs_checkout pb_vcs_up pb_vcs_checkin pb_vcs_isdiff pb_vcs_add pb_vcs_add_if_not_in pb_vcs_cmd pb_vcs_compliant);
39($VERSION,$REVISION) = pb_version_init();
40
41=pod
42
43=head1 NAME
44
45ProjectBuilder::VCS, part of the project-builder.org
46
47=head1 DESCRIPTION
48
49This modules provides version control system functions.
50
51=head1 USAGE
52
53=over 4
54
55=item B<pb_vcs_export>
56
57This function exports a VCS content to a directory.
58The first parameter is the URL of the VCS content.
59The second parameter is the directory in which it is locally exposed (result of a checkout). If undef, then use the original VCS content.
60The third parameter is the directory where we want to deliver it (result of export).
61It returns the original tar file if we need to preserve it and undef if we use the produced one.
62
63=cut
64
65sub pb_vcs_export {
66
67my $uri = shift;
68my $source = shift;
69my $destdir = shift;
70my $tmp;
71my $tmp1;
72
73pb_log(1,"pb_vcs_export uri: $uri - destdir: $destdir\n");
74pb_log(1,"pb_vcs_export source: $source\n") if (defined $source);
75my @date = pb_get_date();
76# If it's not flat, then we have a real uri as source
77my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
78my $vcscmd = pb_vcs_cmd($scheme);
79$uri = pb_vcs_mod_socks($uri);
80
81if ($scheme =~ /^svn/) {
82 if (defined $source) {
83 if (-d $source) {
84 $tmp = $destdir;
85 } else {
86 $tmp = "$destdir/".basename($source);
87 }
88 $source = pb_vcs_mod_htftp($source,"svn");
89 pb_system("$vcscmd export $source $tmp","Exporting $source from $scheme to $tmp ");
90 } else {
91 $uri = pb_vcs_mod_htftp($uri,"svn");
92 pb_system("$vcscmd export $uri $destdir","Exporting $uri from $scheme to $destdir ");
93 }
94} elsif ($scheme eq "svk") {
95 my $src = $source;
96 if (defined $source) {
97 if (-d $source) {
98 $tmp = $destdir;
99 } else {
100 $tmp = "$destdir/".basename($source);
101 $src = dirname($source);
102 }
103 $source = pb_vcs_mod_htftp($source,"svk");
104 # This doesn't exist !
105 # pb_system("$vcscmd export $path $tmp","Exporting $path from $scheme to $tmp ");
106 pb_log(4,"$uri,$source,$destdir,$scheme, $account, $host, $port, $path,$tmp");
107 if (-d $source) {
108 pb_system("mkdir -p $tmp ; cd $tmp; tar -cf - -C $source . | tar xf -","Exporting $source from $scheme to $tmp ");
109 } else {
110 # If source is file do not use -C with source
111 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 ");
112 }
113 } else {
114 # Look at svk admin hotcopy
115 confess "Unable to export from svk without a source defined";
116 }
117} elsif ($scheme eq "dir") {
118 pb_system("cp -r $path $destdir","Copying $uri from DIR to $destdir ");
119} elsif (($scheme eq "http") || ($scheme eq "ftp")) {
120 my $f = basename($path);
121 unlink "$ENV{'PBTMP'}/$f";
122 pb_system("$vcscmd $ENV{'PBTMP'}/$f $uri","Downloading $uri with $vcscmd to $ENV{'PBTMP'}/$f\n");
123 # We want to preserve the original tar file
124 pb_vcs_export("file://$ENV{'PBTMP'}/$f",$source,$destdir);
125 return("$ENV{'PBTMP'}/$f");
126} elsif ($scheme =~ /^file/) {
127 eval
128 {
129 require File::MimeInfo;
130 File::MimeInfo->import();
131 };
132 if ($@) {
133 # File::MimeInfo not found
134 confess("ERROR: Install File::MimeInfo to handle scheme $scheme\n");
135 }
136
137 my $mm = mimetype($path);
138 pb_log(2,"mimetype: $mm\n");
139
140 # Check whether the file is well formed
141 # (containing already a directory with the project-version name)
142 #
143 # If it's not the case, we try to adapt, but distro needing
144 # to verify the checksum will have issues (Fedora)
145 # Then upstream should be notified that they need to change their rules
146 # This doesn't apply to patches or additional sources of course.
147 my ($pbwf) = pb_conf_get_if("pbwf");
148 if ((defined $pbwf) && (defined $pbwf->{$ENV{'PBPROJ'}}) && ($path !~ /\/pbpatch\//) && ($path !~ /\/pbsrc\//)) {
149 $destdir = dirname($destdir);
150 pb_log(2,"This is a well-formed file so destdir is now $destdir\n");
151 }
152 pb_mkdir_p($destdir);
153
154 if ($mm =~ /\/x-bzip-compressed-tar$/) {
155 # tar+bzip2
156 pb_system("cd $destdir ; tar xfj $path","Extracting $path in $destdir ");
157 } elsif ($mm =~ /\/x-lzma-compressed-tar$/) {
158 # tar+lzma
159 pb_system("cd $destdir ; tar xfY $path","Extracting $path in $destdir ");
160 } elsif ($mm =~ /\/x-compressed-tar$/) {
161 # tar+gzip
162 pb_system("cd $destdir ; tar xfz $path","Extracting $path in $destdir ");
163 } elsif ($mm =~ /\/x-tar$/) {
164 # tar
165 pb_system("cd $destdir ; tar xf $path","Extracting $path in $destdir ");
166 } elsif ($mm =~ /\/zip$/) {
167 # zip
168 pb_system("cd $destdir ; unzip $path","Extracting $path in $destdir ");
169 } else {
170 # simple file: copy it (patch e.g.)
171 copy($path,$destdir);
172 }
173} elsif ($scheme =~ /^hg/) {
174 if (defined $source) {
175 if (-d $source) {
176 $tmp = $destdir;
177 } else {
178 $tmp = "$destdir/".basename($source);
179 }
180 $source = pb_vcs_mod_htftp($source,"hg");
181 pb_system("cd $source ; $vcscmd archive $tmp","Exporting $source from Mercurial to $tmp ");
182 } else {
183 $uri = pb_vcs_mod_htftp($uri,"hg");
184 pb_system("$vcscmd clone $uri $destdir","Exporting $uri from Mercurial to $destdir ");
185 }
186} elsif ($scheme =~ /^git/) {
187 if ($scheme =~ /svn/) {
188 if (defined $source) {
189 if (-d $source) {
190 $tmp = $destdir;
191 } else {
192 $tmp = "$destdir/".basename($source);
193 }
194 $source = pb_vcs_mod_htftp($source,"git");
195 pb_system("cp -a $source $tmp","Exporting $source from $scheme to $tmp ");
196 } else {
197 $uri = pb_vcs_mod_htftp($uri,"git");
198 pb_system("$vcscmd clone $uri $destdir","Exporting $uri from $scheme to $destdir ");
199 }
200 } else {
201 if (defined $source) {
202 if (-d $source) {
203 $tmp = $destdir;
204 } else {
205 $tmp = "$destdir/".basename($source);
206 }
207 $source = pb_vcs_mod_htftp($source,"git");
208 pb_system("cd $source ; stid=`$vcscmd stash create` ; $vcscmd archive --format=tar \$\{stid:=HEAD\} | (mkdir $tmp && cd $tmp && tar xf -)","Exporting current $source from GIT to $tmp ");
209 } else {
210 $uri = pb_vcs_mod_htftp($uri,"git");
211 pb_system("$vcscmd clone $uri $destdir","Exporting $uri from GIT to $destdir ");
212 }
213 }
214} elsif ($scheme =~ /^cvs/) {
215 # CVS needs a relative path !
216 my $dir=dirname($destdir);
217 my $base=basename($destdir);
218 if (defined $source) {
219 # CVS also needs a modules name not a dir
220 $tmp1 = basename($source);
221 } else {
222 # Probably not right, should be checked, but that way I'll notice it :-)
223 pb_log(0,"You're in an untested part of project-builder.org, please report any result upstream\n");
224 $tmp1 = $uri;
225 }
226 # If we're working on the CVS itself
227 my $cvstag = basename($ENV{'PBROOTDIR'});
228 my $cvsopt = "";
229 if ($cvstag eq "cvs") {
230 my $pbdate = strftime("%Y-%m-%d %H:%M:%S", @date);
231 $cvsopt = "-D \"$pbdate\"";
232 } else {
233 # we're working on a tag which should be the last part of PBROOTDIR
234 $cvsopt = "-r $cvstag";
235 }
236 pb_system("cd $dir ; $vcscmd -d $account\@$host:$path export $cvsopt -d $base $tmp1","Exporting $tmp1 from $source under CVS to $destdir ");
237} else {
238 confess "cms $scheme unknown";
239}
240return(undef);
241}
242
243=item B<pb_vcs_get_uri>
244
245This function is only called with a real VCS system and gives the URL stored in the checked out directory.
246The first parameter is the schema of the VCS systems (svn, cvs, svn+ssh, ...)
247The second parameter is the directory in which it is locally exposed (result of a checkout).
248
249=cut
250
251sub pb_vcs_get_uri {
252
253my $scheme = shift;
254my $dir = shift;
255
256my $res = "";
257my $void = "";
258my $vcscmd = pb_vcs_cmd($scheme);
259
260if ($scheme =~ /^svn/) {
261 open(PIPE,"LANGUAGE=C $vcscmd info $dir 2> /dev/null |") || return("");
262 while (<PIPE>) {
263 ($void,$res) = split(/^URL:/) if (/^URL:/);
264 }
265 $res =~ s/^\s*//;
266 close(PIPE);
267 chomp($res);
268} elsif ($scheme =~ /^svk/) {
269 open(PIPE,"LANGUAGE=C $vcscmd info $dir 2> /dev/null |") || return("");
270 my $void2 = "";
271 while (<PIPE>) {
272 ($void,$void2,$res) = split(/ /) if (/^Depot/);
273 }
274 $res =~ s/^\s*//;
275 close(PIPE);
276 chomp($res);
277} elsif ($scheme =~ /^hg/) {
278 open(HGRC,".hg/hgrc/") || return("");
279 while (<HGRC>) {
280 ($void,$res) = split(/^default.*=/) if (/^default.*=/);
281 }
282 close(HGRC);
283 chomp($res);
284} elsif ($scheme =~ /^git/) {
285 if ($scheme =~ /svn/) {
286 my $cwd = abs_path();
287 chdir($dir) || return("");;
288 open(PIPE,"LANGUAGE=C $vcscmd info . 2> /dev/null |") || return("");
289 chdir($cwd) || return("");
290 while (<PIPE>) {
291 ($void,$res) = split(/^URL:/) if (/^URL:/);
292 }
293 $res =~ s/^\s*//;
294 close(PIPE);
295 chomp($res);
296 # We've got an SVN ref so add git in front of it for coherency
297 $res = "git+".$res;
298 } else {
299 # Pure git
300 # First we may deal with a separate git repo under $dir
301 if ( -d "$dir/.git" ) {
302 open(GIT,"LANGUAGE=C $vcscmd --git-dir=$dir/.git remote -v 2> /dev/null |") || return("");
303 } else {
304 # If not, the pbconf dir may be in the pbprojdir so sharing the .git dir
305 my $cwd = abs_path();
306 chdir($dir) || return("");;
307 open(GIT,"LANGUAGE=C $vcscmd remote -v 2> /dev/null |") || return("");
308 chdir($cwd) || return("");
309 }
310 while (<GIT>) {
311 next unless (/^origin\s+(\S+) \(push\)$/);
312 return $1;
313 }
314 close(GIT);
315 warn "Unable to find remote origin for $dir";
316 return "";
317 }
318} elsif ($scheme =~ /^cvs/) {
319 # This path is always the root path of CVS, but we may be below
320 open(FILE,"$dir/CVS/Root") || confess "$dir isn't CVS controlled";
321 $res = <FILE>;
322 chomp($res);
323 close(FILE);
324 # Find where we are in the tree
325 my $rdir = $dir;
326 while ((! -d "$rdir/CVSROOT") && ($rdir ne "/")) {
327 $rdir = dirname($rdir);
328 }
329 confess "Unable to find a CVSROOT dir in the parents of $dir" if (! -d "$rdir/CVSROOT");
330 #compute our place under that root dir - should be a relative path
331 $dir =~ s|^$rdir||;
332 my $suffix = "";
333 $suffix = "$dir" if ($dir ne "");
334
335 my $prefix = "";
336 if ($scheme =~ /ssh/) {
337 $prefix = "cvs+ssh://";
338 } else {
339 $prefix = "cvs://";
340 }
341 $res = $prefix.$res.$suffix;
342} else {
343 confess "cms $scheme unknown";
344}
345pb_log(1,"pb_vcs_get_uri returns $res\n");
346return($res);
347}
348
349=item B<pb_vcs_copy>
350
351This function copies a VCS content to another.
352The first parameter is the schema of the VCS systems (svn, cvs, svn+ssh, ...)
353The second parameter is the URL of the original VCS content.
354The third parameter is the URL of the destination VCS content.
355
356Only coded for SVN now as used for pbconf itself not the project
357
358=cut
359
360sub pb_vcs_copy {
361my $scheme = shift;
362my $oldurl = shift;
363my $newurl = shift;
364my $vcscmd = pb_vcs_cmd($scheme);
365$oldurl = pb_vcs_mod_socks($oldurl);
366$newurl = pb_vcs_mod_socks($newurl);
367
368if ($scheme =~ /^svn/) {
369 $oldurl = pb_vcs_mod_htftp($oldurl,"svn");
370 $newurl = pb_vcs_mod_htftp($newurl,"svn");
371 pb_system("$vcscmd copy -m \"Creation of $newurl from $oldurl\" $oldurl $newurl","Copying $oldurl to $newurl ");
372} elsif ($scheme =~ /^(flat)|(ftp)|(http)|(file)\b/o) {
373 # Nothing to do.
374} else {
375 confess "cms $scheme unknown for project management";
376}
377}
378
379=item B<pb_vcs_checkout>
380
381This function checks a VCS content out to a directory.
382The first parameter is the schema of the VCS systems (svn, cvs, svn+ssh, ...)
383The second parameter is the URL of the VCS content.
384The third parameter is the directory where we want to deliver it (result of export).
385
386=cut
387
388sub pb_vcs_checkout {
389my $scheme = shift;
390my $url = shift;
391my $destination = shift;
392my $vcscmd = pb_vcs_cmd($scheme);
393$url = pb_vcs_mod_socks($url);
394
395if ($scheme =~ /^svn/) {
396 $url = pb_vcs_mod_htftp($url,"svn");
397 pb_system("$vcscmd co $url $destination","Checking out $url to $destination ");
398} elsif ($scheme =~ /^svk/) {
399 $url = pb_vcs_mod_htftp($url,"svk");
400 pb_system("$vcscmd co $url $destination","Checking out $url to $destination ");
401} elsif ($scheme =~ /^hg/) {
402 $url = pb_vcs_mod_htftp($url,"hg");
403 pb_system("$vcscmd clone $url $destination","Checking out $url to $destination ");
404} elsif ($scheme =~ /^git/) {
405 $url = pb_vcs_mod_htftp($url,"git");
406 pb_system("$vcscmd clone $url $destination","Checking out $url to $destination ");
407} elsif (($scheme eq "ftp") || ($scheme eq "http")) {
408 return;
409} elsif ($scheme =~ /^cvs/) {
410 my ($scheme, $account, $host, $port, $path) = pb_get_uri($url);
411
412 # If we're working on the CVS itself
413 my $cvstag = basename($ENV{'PBROOTDIR'});
414 my $cvsopt = "";
415 if ($cvstag eq "cvs") {
416 my @date = pb_get_date();
417 my $pbdate = strftime("%Y-%m-%d %H:%M:%S", @date);
418 $cvsopt = "-D \"$pbdate\"";
419 } else {
420 # we're working on a tag which should be the last part of PBROOTDIR
421 $cvsopt = "-r $cvstag";
422 }
423 pb_mkdir_p("$destination");
424 pb_system("cd $destination ; $vcscmd -d $account\@$host:$path co $cvsopt .","Checking out $url to $destination ");
425} elsif ($scheme =~ /^file/) {
426 pb_vcs_export($url,undef,$destination);
427} else {
428 confess "cms $scheme unknown";
429}
430}
431
432=item B<pb_vcs_up>
433
434This function updates a local directory with the VCS content.
435The first parameter is the schema of the VCS systems (svn, cvs, svn+ssh, ...)
436The second parameter is the list of directory to update.
437
438=cut
439
440sub pb_vcs_up {
441my $scheme = shift;
442my @dir = @_;
443my $vcscmd = pb_vcs_cmd($scheme);
444
445if ($scheme =~ /^((svn)|(cvs)|(svk))/o) {
446 pb_system("$vcscmd up ".join(' ',@dir),"Updating ".join(' ',@dir));
447} elsif ($scheme =~ /^((hg)|(git))/o) {
448 foreach my $d (@dir) {
449 pb_system("(cd $d && $vcscmd fetch)", "Updating $d ");
450 }
451} elsif ($scheme =~ /^(flat)|(ftp)|(http)|(file)\b/o) {
452 # Nothing to do.
453} else {
454 confess "cms $scheme unknown";
455}
456}
457
458=item B<pb_vcs_checkin>
459
460This function updates a VCS content from a local directory.
461The first parameter is the schema of the VCS systems (svn, cvs, svn+ssh, ...)
462The second parameter is the directory to update from.
463The third parameter is the comment to pass during the commit
464
465=cut
466
467sub pb_vcs_checkin {
468my $scheme = shift;
469my $dir = shift;
470my $msg = shift;
471my $vcscmd = pb_vcs_cmd($scheme);
472
473if ($scheme =~ /^((svn)|(cvs)|(svk))/o) {
474 pb_system("cd $dir && $vcscmd ci -m \"$msg\" .","Checking in $dir ");
475} elsif ($scheme =~ /^git/) {
476 pb_system("cd $dir && $vcscmd commit -a -m \"$msg\"", "Checking in $dir ");
477} elsif ($scheme =~ /^(flat)|(ftp)|(http)|(file)\b/o) {
478 # Nothing to do.
479} else {
480 confess "cms $scheme unknown";
481}
482pb_vcs_up($scheme,$dir);
483}
484
485=item B<pb_vcs_add_if_not_in>
486
487This function adds to a VCS content from a local directory if the content wasn't already managed under th VCS.
488The first parameter is the schema of the VCS systems (svn, cvs, svn+ssh, ...)
489The second parameter is a list of directory/file to add.
490
491=cut
492
493sub pb_vcs_add_if_not_in {
494my $scheme = shift;
495my @f = @_;
496my $vcscmd = pb_vcs_cmd($scheme);
497
498if ($scheme =~ /^((hg)|(git)|(svn)|(svk)|(cvs))/o) {
499 for my $f (@f) {
500 my $uri = pb_vcs_get_uri($scheme,$f);
501 pb_vcs_add($scheme,$f) if ($uri !~ /^$scheme/);
502 }
503} elsif ($scheme =~ /^(flat)|(ftp)|(http)|(file)\b/o) {
504 # Nothing to do.
505} else {
506 confess "cms $scheme unknown";
507}
508}
509
510=item B<pb_vcs_add>
511
512This function adds to a VCS content from a local directory.
513The first parameter is the schema of the VCS systems (svn, cvs, svn+ssh, ...)
514The second parameter is a list of directory/file to add.
515
516=cut
517
518sub pb_vcs_add {
519my $scheme = shift;
520my @f = @_;
521my $vcscmd = pb_vcs_cmd($scheme);
522
523if ($scheme =~ /^((hg)|(git)|(svn)|(svk)|(cvs))/o) {
524 pb_system("$vcscmd add ".join(' ',@f),"Adding ".join(' ',@f)." to VCS ");
525} elsif ($scheme =~ /^(flat)|(ftp)|(http)|(file)\b/o) {
526 # Nothing to do.
527} else {
528 confess "cms $scheme unknown";
529}
530pb_vcs_up($scheme,@f);
531}
532
533=item B<pb_vcs_isdiff>
534
535This function returns a integer indicating the number of differences between the VCS content and the local directory where it's checked out.
536The first parameter is the schema of the VCS systems (svn, cvs, svn+ssh, ...)
537The second parameter is the directory to consider.
538
539=cut
540
541sub pb_vcs_isdiff {
542my $scheme = shift;
543my $dir =shift;
544my $vcscmd = pb_vcs_cmd($scheme);
545my $l = undef;
546
547if ($scheme =~ /^((svn)|(cvs)|(svk)|(git))/o) {
548 open(PIPE,"$vcscmd diff $dir |") || confess "Unable to get $vcscmd diff from $dir";
549 $l = 0;
550 while (<PIPE>) {
551 # Skipping normal messages in case of CVS
552 next if (/^cvs diff:/);
553 $l++;
554 }
555} elsif ($scheme =~ /^(flat)|(ftp)|(http)|(file)\b/o) {
556 $l = 0;
557} else {
558 confess "cms $scheme unknown";
559}
560pb_log(1,"pb_vcs_isdiff returns $l\n");
561return($l);
562}
563
564sub pb_vcs_mod_htftp {
565
566my $url = shift;
567my $proto = shift;
568
569$url =~ s/^$proto\+((ht|f)tp[s]*):/$1:/;
570pb_log(1,"pb_vcs_mod_htftp returns $url\n");
571return($url);
572}
573
574sub pb_vcs_mod_socks {
575
576my $url = shift;
577
578$url =~ s/^([A-z0-9]+)\+(socks):/$1:/;
579pb_log(1,"pb_vcs_mod_socks returns $url\n");
580return($url);
581}
582
583
584sub pb_vcs_cmd {
585
586my $scheme = shift;
587my $cmd = "";
588my $cmdopt = "";
589
590# If there is a socks proxy to use
591if ($scheme =~ /socks/) {
592 # Get the socks proxy command from the conf file
593 my ($pbsockscmd) = pb_conf_get("pbsockscmd");
594 $cmd = "$pbsockscmd->{$ENV{'PBPROJ'}} ";
595}
596
597if (defined $ENV{'PBVCSOPT'}) {
598 $cmdopt .= " $ENV{'PBVCSOPT'}";
599}
600
601if ($scheme =~ /hg/) {
602 $cmd .= "hg".$cmdopt;
603} elsif ($scheme =~ /git/) {
604 if ($scheme =~ /svn/) {
605 $cmd .= "git svn".$cmdopt;
606 } else {
607 $cmd .= "git".$cmdopt;
608 }
609} elsif ($scheme =~ /svn/) {
610 $cmd .= "svn".$cmdopt;
611} elsif ($scheme =~ /svk/) {
612 $cmd .= "svk".$cmdopt;
613} elsif ($scheme =~ /cvs/) {
614 $cmd .= "cvs".$cmdopt;
615} elsif (($scheme =~ /http/) || ($scheme =~ /ftp/)) {
616 my $command = pb_check_req("wget",1);
617 if (-x $command) {
618 $cmd .= "$command -nv -O ";
619 } else {
620 $command = pb_check_req("curl",1);
621 if (-x $command) {
622 $cmd .= "$command -o ";
623 } else {
624 confess "Unable to handle $scheme.\nNo wget/curl available, please install one of those";
625 }
626 }
627} else {
628 $cmd = "";
629}
630pb_log(3,"pb_vcs_cmd returns $cmd\n");
631return($cmd);
632}
633
634=item B<pb_vcs_compliant>
635
636This function checks the compliance of the project and the pbconf directory.
637The first parameter is the key name of the value that needs to be read in the configuration file.
638The second parameter is the environment variable this key will populate.
639The third parameter is the location of the pbconf dir.
640The fourth parameter is the URI of the CMS content related to the pbconf dir.
641The fifth parameter indicates whether we should inititate the context or not.
642
643=cut
644
645sub pb_vcs_compliant {
646
647my $param = shift;
648my $envar = shift;
649my $defdir = shift;
650my $uri = shift;
651my $pbinit = shift;
652my %pdir;
653
654pb_log(1,"pb_vcs_compliant: envar: $envar - defdir: $defdir - uri: $uri\n");
655my ($pdir) = pb_conf_get_if($param) if (defined $param);
656if (defined $pdir) {
657 %pdir = %$pdir;
658}
659
660if ((defined $pdir) && (%pdir) && (defined $pdir{$ENV{'PBPROJ'}})) {
661 # That's always the environment variable that will be used
662 $ENV{$envar} = $pdir{$ENV{'PBPROJ'}};
663} else {
664 if (defined $param) {
665 pb_log(1,"WARNING: no $param defined, using $defdir\n");
666 pb_log(1," Please create a $param reference for project $ENV{'PBPROJ'} in $ENV{'PBETC'}\n");
667 pb_log(1," if you want to use another directory\n");
668 }
669 $ENV{$envar} = "$defdir";
670}
671
672# Expand potential env variable in it
673eval { $ENV{$envar} =~ s/(\$ENV.+\})/$1/eeg };
674pb_log(2,"$envar: $ENV{$envar}\n");
675
676my ($scheme, $account, $host, $port, $path) = pb_get_uri($uri);
677
678if (($scheme !~ /^cvs/) && ($scheme !~ /^svn/) && ($scheme !~ /^svk/) && ($scheme !~ /^hg/) && ($scheme !~ /^git/)) {
679 # Do not compare if it's not a real cms
680 pb_log(1,"pb_vcs_compliant useless\n");
681 return;
682} elsif (defined $pbinit) {
683 pb_mkdir_p("$ENV{$envar}");
684} elsif (! -d "$ENV{$envar}") {
685 # Either we have a version in the uri, and it should be the same
686 # as the one in the envar. Or we should add the version to the uri
687 # But not if it's git as it manages version branches internally
688 if ((basename($uri) ne basename($ENV{$envar})) && ($scheme !~ /^git/)) {
689 $uri .= "/".basename($ENV{$envar})
690 }
691 pb_log(1,"Checking out $uri\n");
692 # Create structure and remove end dir before exporting
693 pb_mkdir_p("$ENV{$envar}");
694 pb_rm_rf($ENV{$envar});
695 pb_vcs_checkout($scheme,$uri,$ENV{$envar});
696} else {
697 pb_log(1,"$uri found locally, checking content\n");
698 my $cmsurl = pb_vcs_get_uri($scheme,$ENV{$envar});
699 my ($scheme2, $account2, $host2, $port2, $path2) = pb_get_uri($cmsurl);
700 # For svk, scheme doesn't appear in svk info so remove it here in uri coming from conf file
701 # which needs it to trigger correct behaviour
702 $uri =~ s/^svk://;
703 if ($scheme2 =~ /^git/) {
704 # remove schema from `git+file:` and `git+dir:` urls
705 # TODO: handle query-parameters
706 $uri =~ s/^git\+(file|dir|ssh):[\/]*//;
707 # Expand potential env variable in it -- this is required due to the consistency check
708 $uri =~ s/(\$ENV.+\})/$1/eeg;
709 } elsif ($scheme2 =~ /^hg/) {
710 # This VCS manages branches internally not with different tree structures
711 # Assuming it's correct for now.
712 return;
713 }
714 # Remove git+ part if only in scheme
715 $uri =~ s/^git\+// if (($scheme =~ /^git\+/) && ($scheme2 !~ /^git\+/));
716
717 if ($cmsurl ne $uri) {
718 # The local content doesn't correpond to the repository
719 pb_log(0,"ERROR: Inconsistency detected:\n");
720 pb_log(0," * $ENV{$envar} ($envar) refers to $cmsurl but\n");
721 pb_log(0," * $ENV{'PBETC'} refers to $uri\n");
722 die "Project $ENV{'PBPROJ'} is not Project-Builder compliant.";
723 } else {
724 pb_log(1,"Content correct - doing nothing - you may want to update your repository however\n");
725 # they match - do nothing - there may be local changes
726 }
727}
728pb_log(1,"pb_vcs_compliant end\n");
729}
730
731
732=back
733
734=head1 WEB SITES
735
736The 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/>.
737
738=head1 USER MAILING LIST
739
740None exists for the moment.
741
742=head1 AUTHORS
743
744The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
745
746=head1 COPYRIGHT
747
748Project-Builder.org is distributed under the GPL v2.0 license
749described in the file C<COPYING> included with the distribution.
750
751=cut
752
7531;
Note: See TracBrowser for help on using the repository browser.