X-Git-Url: https://git.madduck.net/code/myrepos.git/blobdiff_plain/fab3cd8dccfedbc3e70531f916551b12a48cfec1..8ddd51f2c761cb3fc33bd9c8aa509992e1561490:/mr?ds=inline diff --git a/mr b/mr index 4f33567..ab71f36 100755 --- a/mr +++ b/mr @@ -82,9 +82,10 @@ Be verbose. =head1 FILES -B is configured by .mrconfig files. It searches for .mrconfig files in -your home directory, and in the root directory of each repository specified -in a .mrconfig file. So you could have a ~/.mrconfig that registers a +B is configured by .mrconfig files. It starts by reading the .mrconfig +file in your home directory. Each repository specified in a .mrconfig file +can also have its own .mrconfig file in its root directory that can +optionally be used as well. So you could have a ~/.mrconfig that registers a repository ~/src, that itself contains a ~/src/.mrconfig file, that in turn registers several additional repositories. @@ -100,8 +101,14 @@ environment, where any additional parameters you pass are available in a command, except for the "checkout" command, which is run in the parent of the repository directory, since the repository isn't checked out yet. -There are two special parameters. If the "skip" parameter is set and +There are three special parameters. If the "skip" parameter is set and its command returns nonzero, then B will skip acting on that repository. +If the "chain" parameter is set and its command returns nonzero, then B +will try to load a .mrconfig file from the root of the repository. (You +should avoid chaining from repositories with untrusted committers.) The +"lib" parameter can specify some shell code that will be run before each +command, this can be a useful way to define shell functions other commands +can use. The "default" section allows setting up default handlers for each action, and is overridden by the contents of other sections. mr contains default @@ -112,12 +119,22 @@ For example: [src] checkout = svn co svn://svn.example.com/src/trunk src + chain = true [src/linux-2.6] - # only check this out on kodama - skip = test $(hostname) != kodama + skip = small checkout = git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git + [default] + lib = \ + small() { + case "$(hostname)" in; \ + slug|snail); \ + return 0; ;; ; \ + esac; \ + return 1; \ + } + =head1 AUTHOR Copyright 2007 Joey Hess @@ -184,15 +201,6 @@ foreach my $topdir (sort keys %config) { print "\n" unless $first; $first=0; - if (exists $config{$topdir}{$subdir}{skip}) { - my $ret=system($config{$topdir}{$subdir}{skip}); - if ($ret >> 8 == 0) { - print "mr $action: $dir skipped per config file\n" if $verbose; - push @skipped, $dir; - next; - } - } - action($action, $dir, $topdir, $subdir); } @@ -203,29 +211,42 @@ sub action { if ($action eq 'checkout') { if (-d $dir) { - print "mr $action: $dir already exists, skipping checkout\n"; + print "mr $action: $dir already exists, skipping checkout\n" if $verbose; push @skipped, $dir; - next; + return; } $dir=~s/^(.*)\/[^\/]+\/?$/$1/; } - if ($action eq 'update') { + elsif ($action eq 'update') { if (! -d $dir) { return action("checkout", $dir, $topdir, $subdir); } } - + if (! chdir($dir)) { print STDERR "mr $action: failed to chdir to $dir: $!\n"; push @skipped, $dir; } - elsif (! exists $config{$topdir}{$subdir}{$action}) { + + if (exists $config{$topdir}{$subdir}{skip}) { + my $ret=system($config{$topdir}{$subdir}{skip}); + if ($ret >> 8 == 0) { + print "mr $action: $dir skipped per config file\n" if $verbose; + push @skipped, $dir; + next; + } + } + + if (! exists $config{$topdir}{$subdir}{$action}) { print STDERR "mr $action: no defined $action command for $topdir$subdir, skipping\n"; push @skipped, $dir; } else { print "mr $action: in $dir\n"; - my $command="set -e; my_action(){ $config{$topdir}{$subdir}{$action} ; }; my_action ". + my $command="set -e; ". + (exists $config{$topdir}{$subdir}{lib} ? + $config{$topdir}{$subdir}{lib} : ""). + "my_action(){ $config{$topdir}{$subdir}{$action} ; }; my_action ". join(" ", map { s/\//\/\//g; s/"/\"/g; '"'.$_.'"' } @ARGV); my $ret=system($command); if ($ret != 0) { @@ -258,7 +279,13 @@ print "\nmr $action: finished (".join("; ", showstat($#failed+1, "failed", "failed"), showstat($#skipped+1, "skipped", "skipped"), ).")\n"; -exit @failed ? 1 : 0; +if (@failed) { + exit 1; +} +elsif (! @successful && @skipped) { + exit 1; +} +exit 0; my %loaded; sub loadconfig { @@ -305,10 +332,6 @@ sub loadconfig { next if /^\s*\#/ || /^\s*$/; if (/^\s*\[([^\]]*)\]\s*$/) { $section=$1; - if (length $dir && $section ne "default" && - -e $dir.$section."/.mrconfig") { - push @toload, $dir.$section."/.mrconfig"; - } } elsif (/^\s*(\w+)\s*=\s*(.*)/) { my $parameter=$1; @@ -328,8 +351,20 @@ sub loadconfig { # copy in defaults $config{$dir}{$section}={ %{$config{$dir}{default}} }; } - $config{$dir}{$section}{$parameter}=$value; - $knownactions{$parameter}=1; + if ($parameter ne 'lib') { + $config{$dir}{$section}{$parameter}=$value; + $knownactions{$parameter}=1; + } + else { + $config{$dir}{$section}{$parameter}.=$value." ; "; + } + + if ($parameter eq 'chain' && + length $dir && $section ne "default" && + -e $dir.$section."/.mrconfig" && + system($value) >> 8 == 0) { + push @toload, $dir.$section."/.mrconfig"; + } } else { die "$f line $.: parse error\n"; @@ -342,18 +377,22 @@ sub loadconfig { } } -__DATA__ -# Some useful actions that mr knows about by default. +# Finally, some useful actions that mr knows about by default. # These can be overridden in ~/.mrconfig. +__DATA__ [default] +lib = \ + error() { \ + echo "mr: $@" >&2; \ + exit 1; \ + } update = \ if [ -d .svn ]; then \ svn update; \ elif [ -d .git ]; then \ git pull origin master; \ else \ - echo "mr update: unknown repo type"; \ - exit 1; \ + error "unknown repo type"; \ fi status = \ if [ -d .svn ]; then \ @@ -361,15 +400,13 @@ status = \ elif [ -d .git ]; then \ git status || true; \ else \ - echo "mr status: unknown repo type"; \ - exit 1; \ + error "unknown repo type"; \ fi commit = \ if [ -d .svn ]; then \ svn commit "$@"; \ elif [ -d .git ]; then \ - git commit -a "$@" && git push --all \ + git commit -a "$@" && git push --all; \ else \ - echo "mr commit: unknown repo type"; \ - exit 1; \ + error "unknown repo type"; \ fi