madduck's git repository
Every one of the projects in this repository is available at the canonical
URL git://git.madduck.net/madduck/pub/<projectpath> — see
each project's metadata for the exact URL.
All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
SSH access, as well as push access can be individually
arranged.
If you use my repositories frequently, consider adding the following
snippet to ~/.gitconfig and using the third clone URL listed for each
project:
[url "git://git.madduck.net/madduck/"]
insteadOf = madduck:
+B<mr> [options] run command [param ...]
+
B<mr> [options] bootstrap url [directory]
B<mr> [options] register [repository]
B<mr> [options] bootstrap url [directory]
B<mr> [options] register [repository]
B<mr> is configured by .mrconfig files, which list the repositories. It
starts by reading the .mrconfig file in your home directory, and this can
B<mr> is configured by .mrconfig files, which list the repositories. It
starts by reading the .mrconfig file in your home directory, and this can
-in turn chain load .mrconfig files from repositories.
+in turn chain load .mrconfig files from repositories. It also automatically
+looks for a .mrconfig file in the current directory, or in one of its
+parent directories.
These predefined commands should be fairly familiar to users of any revision
control system:
These predefined commands should be fairly familiar to users of any revision
control system:
+=item run command [param ...]
+
+Runs the specified command in each repository.
+
=back
These commands are also available:
=back
These commands are also available:
directory to register.
The mrconfig file that is modified is chosen by either the -c option, or by
directory to register.
The mrconfig file that is modified is chosen by either the -c option, or by
-looking for the closest known one at or below the current directory.
+looking for the closest known one at or in a parent of the current directory.
-The ~/.mrconfig file is used by default. To use a different config file,
-use the -c option.
+The mrconfig file that is used is chosen by either the -c option, or by
+looking for the closest known one at or in a parent of the current directory.
-Use the specified mrconfig file. The default is B<~/.mrconfig>
-
-=item -p
-
-=item --path
-
-Search in the current directory, and its parent directories and use
-the first B<.mrconfig> found, instead of the default B<~/.mrconfig>.
+Use the specified mrconfig file. The default is to use both B<~/.mrconfig>
+as well as look for a .mrconfig file in the current directory, or in one
+of its parent directories.
+Be quiet. This supresses mr's usual output, as well as any output from
+commands that are run (including stderr output). If a command fails,
+the output will be shown.
Trust all mrconfig files even if they are not listed in ~/.mrtrust.
Use with caution.
Trust all mrconfig files even if they are not listed in ~/.mrtrust.
Use with caution.
+=item -p
+
+=item --path
+
+This obsolete flag is ignored.
+
=back
=head1 MRCONFIG FILES
=back
=head1 MRCONFIG FILES
my $jobs=1;
my $trust_all=0;
my $directory=getcwd();
my $jobs=1;
my $trust_all=0;
my $directory=getcwd();
-$ENV{MR_CONFIG}="$ENV{HOME}/.mrconfig";
+
+$ENV{MR_CONFIG}=find_mrconfig();
# globals :-(
my %config;
# globals :-(
my %config;
- print "mr $action: $fulldir\n" unless $quiet;
+ $actionmsg="mr $action: $fulldir";
}
else {
my $s=$directory;
$s=~s/^\Q$fulldir\E\/?//;
}
else {
my $s=$directory;
$s=~s/^\Q$fulldir\E\/?//;
- print "mr $action: $fulldir (in subdir $s)\n" unless $quiet;
+ $actionmsg="mr $action: $fulldir (in subdir $s)";
+ print "$actionmsg\n" unless $quiet;
my $hookret=hook("pre_$action", $topdir, $subdir);
return $hookret if $hookret != OK;
$command="set -e; ".$lib.
"my_action(){ $command\n }; my_action ".
my $hookret=hook("pre_$action", $topdir, $subdir);
return $hookret if $hookret != OK;
$command="set -e; ".$lib.
"my_action(){ $command\n }; my_action ".
- join(" ", map { s/\//\/\//g; s/"/\"/g; '"'.$_.'"' } @ARGV);
+ join(" ", map { s/\\/\\\\/g; s/"/\"/g; '"'.$_.'"' } @ARGV);
print "mr $action: running >>$command<<\n" if $verbose;
print "mr $action: running >>$command<<\n" if $verbose;
- my $ret=system($command);
+ my $ret;
+ if ($quiet) {
+ my $output = qx/$command 2>&1/;
+ $ret = $?;
+ if ($ret != 0) {
+ print "$actionmsg\n";
+ print STDERR $output;
+ }
+ }
+ else {
+ $ret=system($command);
+ }
if ($ret != 0) {
if (($? & 127) == 2) {
print STDERR "mr $action: interrupted\n";
if ($ret != 0) {
if (($? & 127) == 2) {
print STDERR "mr $action: interrupted\n";
my $shell="set -e;".$lib.
"my_hook(){ $command\n }; my_hook";
print "mr $hook: running >>$shell<<\n" if $verbose;
my $shell="set -e;".$lib.
"my_hook(){ $command\n }; my_hook";
print "mr $hook: running >>$shell<<\n" if $verbose;
- my $ret=system($shell);
+ my $ret;
+ if ($quiet) {
+ my $output = qx/$shell 2>&1/;
+ $ret = $?;
+ if ($ret != 0) {
+ print STDERR $output;
+ }
+ }
+ else {
+ $ret=system($shell);
+ }
if ($ret != 0) {
if (($? & 127) == 2) {
print STDERR "mr $hook: interrupted\n";
if ($ret != 0) {
if (($? & 127) == 2) {
print STDERR "mr $hook: interrupted\n";
$ENV{MR_REPO}=~s/.*\/(.*)/$1/;
$command="set -e; ".$config{$directory}{DEFAULT}{lib}."\n".
"my_action(){ $command\n }; my_action ".
$ENV{MR_REPO}=~s/.*\/(.*)/$1/;
$command="set -e; ".$config{$directory}{DEFAULT}{lib}."\n".
"my_action(){ $command\n }; my_action ".
- join(" ", map { s/\//\/\//g; s/"/\"/g; '"'.$_.'"' } @ARGV);
+ join(" ", map { s/\\/\\\\/g; s/"/\"/g; '"'.$_.'"' } @ARGV);
print "mr register: running >>$command<<\n" if $verbose;
exec($command) || die "exec: $!";
}
print "mr register: running >>$command<<\n" if $verbose;
exec($command) || die "exec: $!";
}
-sub find_nearest_mrconfig {
my $dir=getcwd();
while (length $dir) {
if (-e "$dir/.mrconfig") {
my $dir=getcwd();
while (length $dir) {
if (-e "$dir/.mrconfig") {
- die "no .mrconfig found in path\n";
+ return "$ENV{HOME}/.mrconfig";
my $result=GetOptions(
"d|directory=s" => sub { $directory=abs_path($_[1]) },
"c|config=s" => sub { $ENV{MR_CONFIG}=$_[1]; $config_overridden=1 },
my $result=GetOptions(
"d|directory=s" => sub { $directory=abs_path($_[1]) },
"c|config=s" => sub { $ENV{MR_CONFIG}=$_[1]; $config_overridden=1 },
- "p|path" => sub { $ENV{MR_CONFIG}=find_nearest_mrconfig(); $config_overridden=1 },
+ "p|path" => sub { }, # now default, ignore
"v|verbose" => \$verbose,
"q|quiet" => \$quiet,
"s|stats" => \$stats,
"v|verbose" => \$verbose,
"q|quiet" => \$quiet,
"s|stats" => \$stats,
init();
startingconfig();
init();
startingconfig();
+ loadconfig("$ENV{HOME}/.mrconfig");
loadconfig($ENV{MR_CONFIG});
#use Data::Dumper; print Dumper(\%config);
loadconfig($ENV{MR_CONFIG});
#use Data::Dumper; print Dumper(\%config);
git_bare_log = git log "$@"
fossil_log = fossil timeline "$@"
git_bare_log = git log "$@"
fossil_log = fossil timeline "$@"
svn_register =
url=`LC_ALL=C svn info . | grep -i '^URL:' | cut -d ' ' -f 2`
if [ -z "$url" ]; then
svn_register =
url=`LC_ALL=C svn info . | grep -i '^URL:' | cut -d ' ' -f 2`
if [ -z "$url" ]; then