Control: retitle -1 mr: Add a minimal output mode that shows output when 
appropriate.

On Fri, 2012-11-23 at 12:46 +0800, Paul Wise wrote:

> For mr summary (#693021), I would like to have an option to make mr not
> print anything unless the command produces some output. Preferably any
> colour normally printed by the command to the terminal should be
> preserved. Without this I get a wall of less-than-useful text like this:

I rewrote the patches (attached) as follows:

Introduce a new mode instead of changing the quiet mode.

The fake terminal is optional, the dependency is optional and the commit
log explains why this is needed.

-- 
bye,
pabs

http://wiki.debian.org/PaulWise
From c559a08b46ed63c056187c28a9e53e03ea2f8300 Mon Sep 17 00:00:00 2001
From: Paul Wise <[email protected]>
Date: Wed, 20 Feb 2013 11:25:55 +0800
Subject: [PATCH 1/5] Always print a new line after failed commands.

---
 mr | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mr b/mr
index 4d77368..a99f7d8 100755
--- a/mr
+++ b/mr
@@ -978,7 +978,7 @@ sub record {
 			system((getpwuid($<))[8], "-i");
 		}
 		push @failed, $dir;
-		print "\n" unless $quiet;
+		print "\n";
 	}
 	elsif ($ret == SKIPPED) {
 		push @skipped, $dir;
-- 
1.8.3

From 1c0578ee545c4010df4942ed4b421aaa1bf91f7a Mon Sep 17 00:00:00 2001
From: Paul Wise <[email protected]>
Date: Wed, 20 Feb 2013 12:03:38 +0800
Subject: [PATCH 2/5] Pass a fake terminal to subcommands when mr is run in a
 terminal.

This is needed so that programs that print color to terminals
but not to pipes continue to do so when mr redirects output
to a variable before printing it or not printing it.
---
 debian/control |  2 +-
 mr             | 47 ++++++++++++++++++++++++++++++++---------------
 2 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/debian/control b/debian/control
index 7189dc4..2700380 100644
--- a/debian/control
+++ b/debian/control
@@ -12,7 +12,7 @@ Architecture: all
 Section: vcs
 Depends: ${misc:Depends}
 Suggests: subversion, git-core | git (>= 1:1.7), cvs, bzr, mercurial, darcs, fossil, vcsh, liburi-perl, curl
-Recommends: libwww-perl, libhtml-parser-perl, perl
+Recommends: libwww-perl, libio-pty-easy-perl, libhtml-parser-perl, perl
 Description: Multiple Repository management tool
  The mr(1) command can checkout, update, or perform other actions on
  a set of repositories as if they were one combined respository. It
diff --git a/mr b/mr
index a99f7d8..52e67f7 100755
--- a/mr
+++ b/mr
@@ -549,6 +549,7 @@ my $no_chdir=0;
 my $jobs=1;
 my $trust_all=0;
 my $directory=getcwd();
+my $terminal=-t STDOUT && eval{require IO::Pty::Easy;IO::Pty::Easy->import();1;} eq 1;
 
 my $HOME_MR_CONFIG = "$ENV{HOME}/.mrconfig";
 $ENV{MR_CONFIG}=find_mrconfig();
@@ -692,6 +693,33 @@ sub fulldir {
 	return $subdir =~ /^\// ? $subdir : $topdir.$subdir;
 }
 
+sub terminal_friendly_spawn {
+	my $actionmsg = shift;
+	my $sh = shift;
+	my $quiet = shift;
+	my $output = "";
+	if ($terminal) {
+		my $pty = IO::Pty::Easy->new;
+		$pty->spawn($sh);
+		while ($pty->is_active) {
+			my $data = $pty->read();
+			$output .= $data if defined $data;
+		}
+		$pty->close;
+	} else {
+		$output = qx/$sh 2>&1/;
+	}
+	my $ret = $?;
+	if ($quiet && $ret != 0) {
+		print "$actionmsg\n" if $actionmsg;
+		print STDERR $output;
+	} elsif (!$quiet) {
+		print "$actionmsg\n" if $actionmsg;
+		print $output;
+	}
+	return $ret;
+}
+
 sub action {
 	my ($action, $dir, $topdir, $subdir, $force_checkout) = @_;
 	my $fulldir=fulldir($topdir, $subdir);
@@ -793,14 +821,8 @@ sub action {
 		my $ret=runsh $action, $topdir, $subdir,
 			$command, \@ARGV, sub {
 				my $sh=shift;
-				if ($quiet) {
-					my $output = qx/$sh 2>&1/;
-					my $ret = $?;
-					if ($ret != 0) {
-						print "$actionmsg\n";
-						print STDERR $output;
-					}
-					return $ret;
+				if (!$jobs || $jobs > 1 || $quiet) {
+					return terminal_friendly_spawn($actionmsg, $sh, $quiet);
 				}
 				else {
 					system($sh);
@@ -864,13 +886,8 @@ sub hook {
 	return OK unless defined $command;
 	my $ret=runsh $hook, $topdir, $subdir, $command, [], sub {
 			my $sh=shift;
-			if ($quiet) {
-				my $output = qx/$sh 2>&1/;
-				my $ret = $?;
-				if ($ret != 0) {
-					print STDERR $output;
-				}
-				return $ret;
+			if (!$jobs || $jobs > 1 || $quiet) {
+				return terminal_friendly_spawn(undef, $sh, $quiet);
 			}
 			else {
 				system($sh);
-- 
1.8.3

From 442547ca219eddfe33432f808f1d49496844ef92 Mon Sep 17 00:00:00 2001
From: Paul Wise <[email protected]>
Date: Sun, 9 Jun 2013 15:36:37 +0800
Subject: [PATCH 3/5] Add a minimal output mode that shows output when
 appropriate. Closes: #694031

---
 mr | 47 +++++++++++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/mr b/mr
index 52e67f7..bb6ec41 100755
--- a/mr
+++ b/mr
@@ -236,6 +236,13 @@ configuration.
 
 Be verbose.
 
+=item -m
+
+=item --minimal
+
+Minimise output. If a command fails or there is any output then the usual
+output will be shown.
+
 =item -q
 
 =item --quiet
@@ -539,6 +546,7 @@ use constant {
 # configurables
 my $config_overridden=0;
 my $verbose=0;
+my $minimal=0;
 my $quiet=0;
 my $stats=0;
 my $force=0;
@@ -697,6 +705,7 @@ sub terminal_friendly_spawn {
 	my $actionmsg = shift;
 	my $sh = shift;
 	my $quiet = shift;
+	my $minimal = shift;
 	my $output = "";
 	if ($terminal) {
 		my $pty = IO::Pty::Easy->new;
@@ -713,11 +722,11 @@ sub terminal_friendly_spawn {
 	if ($quiet && $ret != 0) {
 		print "$actionmsg\n" if $actionmsg;
 		print STDERR $output;
-	} elsif (!$quiet) {
+	} elsif (!$quiet && (!$minimal || $output)) {
 		print "$actionmsg\n" if $actionmsg;
 		print $output;
 	}
-	return $ret;
+	return ($ret, $output ? 1 : 0);
 }
 
 sub action {
@@ -799,7 +808,7 @@ sub action {
 			return FAILED;
 		}
 		else {
-			print STDERR "mr $action: no defined action for $vcs repository $fulldir, skipping\n";
+			print STDERR "mr $action: no defined action for $vcs repository $fulldir, skipping\n" unless $minimal;
 			return SKIPPED;
 		}
 	}
@@ -813,16 +822,16 @@ sub action {
 			$s=~s/^\Q$fulldir\E\/?//;
 			$actionmsg="mr $action: $fulldir (in subdir $s)";
 		}
-		print "$actionmsg\n" unless $quiet;
+		print "$actionmsg\n" unless $quiet || $minimal;
 
 		my $hookret=hook("pre_$action", $topdir, $subdir);
 		return $hookret if $hookret != OK;
 
-		my $ret=runsh $action, $topdir, $subdir,
+		my ($ret, $out)=runsh $action, $topdir, $subdir,
 			$command, \@ARGV, sub {
 				my $sh=shift;
-				if (!$jobs || $jobs > 1 || $quiet) {
-					return terminal_friendly_spawn($actionmsg, $sh, $quiet);
+				if (!$jobs || $jobs > 1 || $quiet || $minimal) {
+					return terminal_friendly_spawn($actionmsg, $sh, $quiet, $minimal);
 				}
 				else {
 					system($sh);
@@ -860,7 +869,7 @@ sub action {
 				return FAILED;
 			}
 
-			my $ret=hook("post_$action", $topdir, $subdir);
+			my ($ret, $hook_out)=hook("post_$action", $topdir, $subdir);
 			return $ret if $ret != OK;
 			
 			if ($is_checkout || $is_update) {
@@ -874,7 +883,7 @@ sub action {
 				return $ret if $ret != OK;
 			}
 			
-			return OK;
+			return (OK, $out || $hook_out);
 		}
 	}
 }
@@ -884,10 +893,10 @@ sub hook {
 
 	my $command=$config{$topdir}{$subdir}{$hook};
 	return OK unless defined $command;
-	my $ret=runsh $hook, $topdir, $subdir, $command, [], sub {
+	my ($ret,$out)=runsh $hook, $topdir, $subdir, $command, [], sub {
 			my $sh=shift;
-			if (!$jobs || $jobs > 1 || $quiet) {
-				return terminal_friendly_spawn(undef, $sh, $quiet);
+			if (!$jobs || $jobs > 1 || $quiet || $minimal) {
+				return terminal_friendly_spawn(undef, $sh, $quiet, $minimal);
 			}
 			else {
 				system($sh);
@@ -907,7 +916,7 @@ sub hook {
 		}
 	}
 
-	return OK;
+	return (OK, $out);
 }
 
 # run actions on multiple repos, in parallel
@@ -935,7 +944,7 @@ sub mrs {
 				close CHILD_STDERR;
 				close $outfh;
 				close $errfh;
-				exit action($action, @$repo);
+				exit +(action($action, @$repo))[0];
 			}
 			close CHILD_STDOUT;
 			close CHILD_STDERR;
@@ -966,7 +975,7 @@ sub mrs {
 						    	waitpid($active[$i][0], 0);
 							print STDOUT $out[$i][0];
 							print STDERR $out[$i][1];
-							record($active[$i][1], $? >> 8);
+							record($active[$i][1], $? >> 8, $out[$i][0] || $out[$i][1]);
 						    	splice(@fhs, $i, 1);
 						    	splice(@active, $i, 1);
 						    	splice(@out, $i, 1);
@@ -983,10 +992,11 @@ sub mrs {
 sub record {
 	my $dir=shift()->[0];
 	my $ret=shift;
+	my $out=shift;
 
 	if ($ret == OK) {
 		push @ok, $dir;
-		print "\n" unless $quiet;
+		print "\n" unless $quiet || ($minimal && !$out);
 	}
 	elsif ($ret == FAILED) {
 		if ($interactive) {
@@ -1017,10 +1027,10 @@ sub showstats {
 		showstat($#ok+1, "ok", "ok"),
 		showstat($#failed+1, "failed", "failed"),
 		showstat($#skipped+1, "skipped", "skipped"),
-	).")\n" unless $quiet;
+	).")\n" unless $quiet || $minimal;
 	if ($stats) {
 		if (@skipped) {
-			print "mr $action: (skipped: ".join(" ", @skipped).")\n" unless $quiet;
+			print "mr $action: (skipped: ".join(" ", @skipped).")\n" unless $quiet || $minimal;
 		}
 		if (@failed) {
 			print STDERR "mr $action: (failed: ".join(" ", @failed).")\n";
@@ -1778,6 +1788,7 @@ sub getopts {
 		"p|path" => sub { }, # now default, ignore
 		"f|force" => \$force,
 		"v|verbose" => \$verbose,
+		"m|minimal" => \$minimal,
 		"q|quiet" => \$quiet,
 		"s|stats" => \$stats,
 		"k|insecure" => \$insecure,
-- 
1.8.3

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to