X-Git-Url: https://git.madduck.net/code/myrepos.git/blobdiff_plain/9a9cbb453427926f2f658734285f6305c7502afb..c428c39904c8cffa8389687cee683cfa32836920:/mr diff --git a/mr b/mr index bb98ba6..7eaaddd 100755 --- a/mr +++ b/mr @@ -7,7 +7,7 @@ mr - a Multiple Repository management tool =head1 SYNOPSIS - +/ B [options] checkout B [options] update @@ -28,6 +28,10 @@ B [options] config section ["parameter=[value]" ...] B [options] action [params ...] +B [options] [online|offline] + +B [options] remember action [params ...] + =head1 DESCRIPTION B is a Multiple Repository management tool. It can checkout, update, or @@ -126,6 +130,24 @@ To see the built-in library of shell functions contained in mr: The ~/.mrconfig file is used by default. To use a different config file, use the -c option. +=item offline + +Advises mr that it is in offline mode. Any commands that fail in +offline mode will be remembered, and retried when mr is told it's online. + +=item online + +Advices mr that it is in online mode again. Commands that failed while in +offline mode will be re-run. + +=item remember + +Remember a command, to be run later when mr re-enters online mode. This +implicitly puts mr into offline mode. The command can be any regular mr +command. This is useful when you know that a command will fail due to being +offline, and so don't want to run it right now at all, but just remember +to run it when you go back online. + =item help Displays this help. @@ -196,6 +218,11 @@ a good speedup in updates without loading the machine too much. =head1 FILES +The ~/.mrlog file contains commands that mr has remembered to run later, +due to being offline. You can delete or edit this file to remove commands, +or even to add other commands for 'mr online' to run. If the file is +present, mr assumes it is in offline mode. + B is configured by .mrconfig files. It starts by reading the .mrconfig file in your home directory, and this can in turn chain load .mrconfig files from repositories. @@ -425,6 +452,8 @@ sub action { #{{{ $config{$topdir}{$subdir}{lib}."\n" : ""; my $is_checkout=($action eq 'checkout'); + $ENV{MR_REPO}=$dir; + if ($is_checkout) { if (-d $dir) { print "mr $action: $dir already exists, skipping checkout\n" if $verbose; @@ -439,8 +468,6 @@ sub action { #{{{ } } - $ENV{MR_REPO}=$dir; - my $skiptest=findcommand("skip", $dir, $topdir, $subdir, $is_checkout); my $command=findcommand($action, $dir, $topdir, $subdir, $is_checkout); @@ -511,6 +538,12 @@ sub action { #{{{ print STDERR "mr $action: failed ($ret)\n" if $verbose; if ($ret >> 8 != 0) { print STDERR "mr $action: command failed\n"; + if (-e "$ENV{HOME}/.mrlog" && $action ne 'remember') { + # recreate original command line to + # remember, and avoid recursing + @ARGV=('-n', $action, @ARGV); + action("remember", $dir, $topdir, $subdir); + } } elsif ($ret != 0) { print STDERR "mr $action: command died ($ret)\n"; @@ -973,6 +1006,13 @@ sub dispatch { #{{{ elsif ($action eq 'register') { register(@ARGV); } + elsif ($action eq 'remember' || + $action eq 'offline' || + $action eq 'online') { + my @repos=selectrepos; + action($action, @{$repos[0]}) if @repos; + exit 0; + } if (!$jobs || $jobs > 1) { mrs($action, selectrepos()); @@ -987,7 +1027,7 @@ sub dispatch { #{{{ sub help { #{{{ exec($config{''}{DEFAULT}{help}) || die "exec: $!"; } #}}} - + sub config { #{{{ if (@_ < 2) { die "mr config: not enough parameters\n"; @@ -1027,7 +1067,12 @@ sub config { #{{{ } #}}} sub register { #{{{ - if (! $config_overridden) { + if ($config_overridden) { + # Find the directory that the specified config file is + # located in. + ($directory)=abs_path($ENV{MR_CONFIG})=~/^(.*\/)[^\/]+$/; + } + else { # Find the closest known mrconfig file to the current # directory. $directory.="/" unless $directory=~/\/$/; @@ -1091,6 +1136,7 @@ sub expandaction { #{{{ } #}}} sub getopts { #{{{ + my @saved=@ARGV; Getopt::Long::Configure("bundling", "no_permute"); my $result=GetOptions( "d|directory=s" => sub { $directory=abs_path($_[1]) }, @@ -1106,6 +1152,12 @@ sub getopts { #{{{ die("Usage: mr [-d directory] action [params ...]\n". "(Use mr help for man page.)\n"); } + + $ENV{MR_SWITCHES}=""; + foreach my $option (@saved) { + last if $option eq $ARGV[0]; + $ENV{MR_SWITCHES}.="$option "; + } } #}}} sub init { #{{{ @@ -1135,10 +1187,11 @@ sub init { #{{{ sub main { #{{{ getopts(); init(); + loadconfig(\*DATA); loadconfig($ENV{MR_CONFIG}); #use Data::Dumper; print Dumper(\%config); - + my $action=expandaction(shift @ARGV); dispatch($action); showstats($action); @@ -1306,6 +1359,30 @@ help = list = true config = +online = + if [ -s ~/.mrlog ]; then + info "running offline commands" + mv -f ~/.mrlog ~/.mrlog.old + if ! sh -e ~/.mrlog.old; then + error "offline command failed; left in ~/.mrlog.old" + fi + rm -f ~/.mrlog.old + else + info "no offline commands to run" + fi +offline = + touch ~/.mrlog + info "offline mode enabled" +remember = + info "remembering command: 'mr $@'" + command="mr -d '$(pwd)' $MR_SWITCHES" + for w in "$@"; do + command="$command '$w'" + done + if [ ! -e ~/.mrlog ] || ! grep -q -F "$command" ~/.mrlog; then + echo "$command" >> ~/.mrlog + fi + ed = echo "A horse is a horse, of course, of course.." T = echo "I pity the fool." right = echo "Not found."