If the .mrconfig file includes a repository named ".", that
is checked out into the top of the specified directory.
+To bootstrap from a SSL url with an untrusted certificate, you may
+need to specify the -k option.
+
=item list (or ls)
List the repositories that mr will act on.
Be quiet.
+=item -k
+
+=item --insecure
+
+Accept untrusted SSL certificates when bootstrapping.
+
=item -s
=item --stats
or even to add other commands for 'mr online' to run. If the file is
present, mr assumes it is in offline mode.
-=head "UNTRUSTED MRCONFIG FILES"
+=head1 "UNTRUSTED MRCONFIG FILES"
Since mrconfig files can contain arbitrary shell commands, they can do
anything. This flexability is good, but it also allows a malicious mrconfig
my $verbose=0;
my $quiet=0;
my $stats=0;
+my $insecure=0;
my $interactive=0;
my $max_depth;
my $no_chdir=0;
if ($ret == OK) {
push @ok, $dir;
- print "\n";
+ print "\n" unless $quiet;
}
elsif ($ret == FAILED) {
if ($interactive) {
system((getpwuid($<))[8], "-i");
}
push @failed, $dir;
- print "\n";
+ print "\n" unless $quiet;
}
elsif ($ret == SKIPPED) {
push @skipped, $dir;
open($in, "<", $f) || die "mr: open $f: $!\n";
}
my @lines=<$in>;
- close $in;
+ close $in unless ref $f eq 'GLOB';
my $section;
my $line=0;
}
}
+sub startingconfig {
+ %alias=%config=%configfiles=%knownactions=%loaded=();
+ my $datapos=tell(DATA);
+ loadconfig(\*DATA);
+ seek(DATA,$datapos,0); # rewind
+}
+
sub modifyconfig {
my $f=shift;
# the section to modify or add
eval q{use File::Temp};
die $@ if $@;
my $tmpconfig=File::Temp->new();
- if (system("curl", "-A", "mr", "-s", $url, "-o", $tmpconfig) != 0) {
- die "mr: download of $url failed\n";
- }
+ my @curlargs = ("curl", "-A", "mr", "-s", $url, "-o", $tmpconfig);
+ push(@curlargs, "-k") if $insecure;
+ my $curlstatus = system(@curlargs);
+ die "mr bootstrap: invalid SSL certificate for $url (consider -k)\n" if $curlstatus >> 8 == 60;
+ die "mr bootstrap: download of $url failed\n" if $curlstatus != 0;
if (! -e $dir) {
system("mkdir", "-p", $dir);
if exists $config{$topdir}{"."}{"checkout"};
if (-e ".mrconfig") {
- print STDERR "mr: .mrconfig file already exists, not overwriting with $url\n";
+ print STDERR "mr bootstrap: .mrconfig file already exists, not overwriting with $url\n";
}
else {
eval q{use File::Copy};
+ die $@ if $@;
move($tmpconfig, ".mrconfig") || die "rename: $!";
}
- exec("mr $ENV{MR_SWITCHES} -c .mrconfig checkout");
- die "failed to run mr checkout";
+ # Reload the config file (in case we got a different version)
+ # and checkout everything else.
+ startingconfig();
+ loadconfig(".mrconfig");
+ dispatch("checkout");
+ @skipped=grep { abs_path($_) ne abs_path($topdir) } @skipped;
+ showstats("bootstrap");
+ exitstats();
}
# alias expansion and command stemming
"v|verbose" => \$verbose,
"q|quiet" => \$quiet,
"s|stats" => \$stats,
+ "k|insecure" => \$insecure,
"i|interactive" => \$interactive,
"n|no-recurse:i" => \$max_depth,
"j|jobs:i" => \$jobs,
$ENV{MR_PATH}=$Bin."/".$Script;
};
}
+
+sub exitstats {
+ if (@failed) {
+ exit 1;
+ }
+ elsif (! @ok && @skipped) {
+ exit 1;
+ }
+ else {
+ exit 0;
+ }
+}
sub main {
getopts();
init();
- loadconfig(\*DATA);
+ startingconfig();
loadconfig($ENV{MR_CONFIG});
#use Data::Dumper; print Dumper(\%config);
my $action=expandaction(shift @ARGV);
dispatch($action);
- showstats($action);
- if (@failed) {
- exit 1;
- }
- elsif (! @ok && @skipped) {
- exit 1;
- }
- else {
- exit 0;
- }
+ showstats($action);
+ exitstats();
}
# Finally, some useful actions that mr knows about by default.