X-Git-Url: https://git.madduck.net/code/myrepos.git/blobdiff_plain/791dd2c6b4bff3e46b8dd45bf1b6d0aa8d15b5bc..bda9d51f221aba0d3aba2be58c9dde82193611d7:/mr?ds=sidebyside diff --git a/mr b/mr index 2b1a36c..89f3281 100755 --- a/mr +++ b/mr @@ -160,10 +160,8 @@ recurse into deeper repositories. =item -j number Run the specified number of jobs in parallel. This can greatly speed up -operations such as updates. - -Note that in -j mode, all output of the jobs goes to standard output, even -output that would normally go to standard error. +operations such as updates. It is not recommended for interactive +operations. =back @@ -231,7 +229,7 @@ mr is run by joey. The second uses the hours_since function been at least 12 hours since the last update. skip = test $(whoami) != joey - skip = [ "$1" = update ] && [ $(hours_since "$1") -lt 12 ] + skip = [ "$1" = update ] && ! hours_since "$1" 12 =item chain @@ -443,6 +441,7 @@ if ($jobs > 1) { else { foreach my $repo (@repos) { record($repo, action($action, @$repo)); + print "\n"; } } if (! @ok && ! @failed && ! @skipped) { @@ -489,7 +488,7 @@ sub action { #{{{ system("mkdir", "-p", $dir); } } - elsif ($action eq 'update') { + elsif ($action =~ /update/) { if (! -d $dir) { return action("checkout", $dir, $topdir, $subdir); } @@ -538,7 +537,6 @@ sub action { #{{{ join(" ", map { s/\//\/\//g; s/"/\"/g; '"'.$_.'"' } @ARGV); print STDERR "mr $action: running >>$command<<\n" if $verbose; my $ret=system($command); - print "\n"; if ($ret != 0) { if (($? & 127) == 2) { print STDERR "mr $action: interrupted\n"; @@ -569,63 +567,73 @@ sub action { #{{{ } #}}} # run actions on multiple repos, in parallel -my %jobs; sub mrs { #{{{ $| = 1; + my @active; my @fhs; my @out; my $running=0; while (@fhs or @repos) { while ($running < $jobs && @repos) { - $SIG{CHLD}='DEFAULT'; $running++; my $repo = shift @repos; - my $pid = open(my $fh, "-|"); - if (! $pid) { - open(STDERR, ">&STDOUT"); + pipe(my $outfh, CHILD_STDOUT); + pipe(my $errfh, CHILD_STDERR); + my $pid; + unless ($pid = fork) { + die "mr $action: cannot fork: $!" unless defined $pid; + open(STDOUT, ">&CHILD_STDOUT") || die "mr $action cannot reopen stdout: $!"; + open(STDERR, ">&CHILD_STDERR") || die "mr $action cannot reopen stderr: $!"; + close CHILD_STDOUT; + close CHILD_STDERR; + close $outfh; + close $errfh; exit action($action, @$repo); } - $jobs{$pid}=$repo; - push @fhs, $fh; - push @out, ""; - reaper(); - $SIG{CHLD}=\&reaper; + close CHILD_STDOUT; + close CHILD_STDERR; + push @active, [$pid, $repo]; + push @fhs, [$outfh, $errfh]; + push @out, ['', '']; } - my ($rin, $rout) = ('','', ''); + my ($rin, $rout) = ('',''); my $nfound; - foreach my $x (@fhs) { - next unless defined $x; - vec($rin, fileno($x), 1) = 1; + foreach my $fh (@fhs) { + next unless defined $fh; + vec($rin, fileno($fh->[0]), 1) = 1 if defined $fh->[0]; + vec($rin, fileno($fh->[1]), 1) = 1 if defined $fh->[1]; } $nfound = select($rout=$rin, undef, undef, 1); - foreach my $i (0..$#fhs) { - my $fh = $fhs[$i]; - next unless defined $fh; - if (vec($rout, fileno($fh), 1) == 1) { - my $r = ''; - if (sysread($fh, $r, 1024) == 0) { - close($fh); - $fhs[$i] = undef; - $running--; - print $out[$i]; - $out[$i]=''; + foreach my $channel (0, 1) { + foreach my $i (0..$#fhs) { + next unless defined $fhs[$i]; + my $fh = $fhs[$i][$channel]; + next unless defined $fh; + if (vec($rout, fileno($fh), 1) == 1) { + my $r = ''; + if (sysread($fh, $r, 1024) == 0) { + close($fh); + $fhs[$i][$channel] = undef; + if (! defined $fhs[$i][0] && + ! defined $fhs[$i][1]) { + waitpid($active[$i][0], 0); + print STDOUT $out[$i][0]; + print STDERR $out[$i][1]; + print "\n"; + record($active[$i][1], $? >> 8); + splice(@fhs, $i, 1); + splice(@active, $i, 1); + splice(@out, $i, 1); + $running--; + } + } + $out[$i][$channel] .= $r; } - $out[$i] .= $r; } } - while (@fhs and !defined $fhs[0]) { - shift @fhs; - shift @out; - } } } #}}} -sub reaper { #{{{ - while ((my $pid = waitpid(-1, &WNOHANG)) > 0) { - record($jobs{$pid}, $? >> 8) if exists $jobs{$pid}; - } -} #}}} - sub record { #{{{ my $dir=shift()->[0]; my $ret=shift; @@ -891,6 +899,9 @@ lib = exit 1 } hours_since() { + if [ -z "$1" ] || [ -z "$2" ]; then + error "mr: usage: hours_since action num" + fi for dir in .git .svn .bzr CVS .hg; do if [ -e "$MR_REPO/$dir" ]; then flagfile="$MR_REPO/$dir/.mr_last$1" @@ -900,8 +911,13 @@ lib = if [ -z "$flagfile" ]; then error "cannot determine flag filename" fi - perl -wle 'print -f shift() ? int((-M _) * 24) : 9999' "$flagfile" - touch "$flagfile" + delta=$(perl -wle 'print -f shift() ? int((-M _) * 24) : 9999' "$flagfile") + if [ "$delta" -lt "$2" ]; then + exit 0 + else + touch "$flagfile" + exit 1 + fi } update =