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<mr> will skip acting on that repository.
If the "chain" parameter is set and its command returns nonzero, then B<mr>
will try to load a .mrconfig file from the root of the repository. (You
-should avoid chaining from repositories with untrusted committers.)
+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
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 <joey@kitenet.net>
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);
}
sub action {
my ($action, $dir, $topdir, $subdir) = @_;
+
+ my $lib= exists $config{$topdir}{$subdir}{lib} ?
+ $config{$topdir}{$subdir}{lib} : "";
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;
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($lib.$config{$topdir}{$subdir}{skip});
+ if ($ret >> 8 == 0) {
+ print "mr $action: $dir skipped per config file\n" if $verbose;
+ push @skipped, $dir;
+ return;
+ }
+ }
+
+ 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; ".$lib.
+ "my_action(){ $config{$topdir}{$subdir}{$action} ; }; my_action ".
join(" ", map { s/\//\/\//g; s/"/\"/g; '"'.$_.'"' } @ARGV);
my $ret=system($command);
if ($ret != 0) {
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 {
# 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" &&
}
}
-__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 \
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 \
- echo git commit -a "$@" && echo git push --all \
- 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