diff mbox series

[v2] pager: die when paging to non-existing command

Message ID 0df06a80-723f-4ad7-9f2e-74c8fb5b8283@gmail.com (mailing list archive)
State Superseded
Headers show
Series [v2] pager: die when paging to non-existing command | expand

Commit Message

Rubén Justo June 21, 2024, 9:29 p.m. UTC
When trying to execute a non-existent program from GIT_PAGER, we display
an error.  However, we also send the complete text to the terminal
and return a successful exit code.  This can be confusing for the user
and the displayed error could easily become obscured by a lengthy
text.

For example, here the error message would be very far above after
sending 50 MB of text:

    $ GIT_PAGER=non-existent t/test-terminal.perl git log | wc -c
    error: cannot run non-existent: No such file or directory
    50314363

Let's make the error clear by aborting the process and return an error
so that the user can easily correct their mistake.

This will be the result of the change:

    $ GIT_PAGER=non-existent t/test-terminal.perl git log | wc -c
    error: cannot run non-existent: No such file or directory
    fatal: unable to start the pager: 'non-existent'
    0

The behavior change we're introducing in this commit affects two tests
in t7006, which is a good sign regarding test coverage and requires us
to address it.

The first test is 'git skips paging non-existing command'.  This test
comes from f7991f01f2 (t7006: clean up SIGPIPE handling in trace2 tests,
2021-11-21,) where a modification was made to a test that was originally
introduced in c24b7f6736 (pager: test for exit code with and without
SIGPIPE, 2021-02-02).  That original test was, IMHO, in the same
direction we're going in this commit.

At any rate, this test obviously needs to be adjusted to check the new
behavior we are introducing.  Do it.

The second test being affected is: 'non-existent pager doesnt cause
crash', introduced in f917f57f40 (pager: fix crash when pager program
doesn't exist, 2021-11-24).  As its name states, it has the intention of
checking that we don't introduce a regression that produces a crash when
GIT_PAGER points to a nonexistent program.

This test could be considered redundant nowadays, due to us already
having several tests checking implicitly what a non-existent command in
GIT_PAGER produces.  However, let's maintain a good belt-and-suspenders
strategy; adapt it to the new world.

Finally, it's worth noting that we are not changing the behavior if the
command specified in GIT_PAGER is a shell command.  In such cases, it
is:

    $ GIT_PAGER=:\;non-existent t/test-terminal.perl git log
    :;non-existent: 1: non-existent: not found
    died of signal 13 at t/test-terminal.perl line 33.

Signed-off-by: Rubén Justo <rjusto@gmail.com>
---

This iteration, v2, is just to "revert" to the original error message
lost by ea27a18c. 

For those not yet used to it, the range-diff is at the end of the
message. ;)

Thanks!


 pager.c          |  3 ++-
 t/t7006-pager.sh | 17 +++++------------
 2 files changed, 7 insertions(+), 13 deletions(-)


Range-diff against v1:
1:  5c7997810c ! 1:  95a2f36d18 pager: die when paging to non-existing command
    @@ Commit message
         Signed-off-by: Rubén Justo <rjusto@gmail.com>
     
      ## pager.c ##
    +@@
    + #include "git-compat-util.h"
    + #include "config.h"
    + #include "editor.h"
    ++#include "gettext.h"
    + #include "pager.h"
    + #include "run-command.h"
    + #include "sigchain.h"
     @@ pager.c: void setup_pager(void)
      	pager_process.in = -1;
      	strvec_push(&pager_process.env, "GIT_PAGER_IN_USE");
      	if (start_command(&pager_process))
     -		return;
    -+		die("unable to start the pager: '%s'", pager);
    ++		die(_("unable to execute pager '%s'"), pager);
      
      	/* original process continues, but writes to the pipe */
      	dup2(pager_process.in, 1);
    @@ t/t7006-pager.sh: test_expect_success TTY 'git discards pager non-zero exit with
     -test_expect_success TTY 'git skips paging nonexisting command' '
     -	test_when_finished "rm trace.normal" &&
     +test_expect_success TTY 'git errors when asked to execute nonexisting pager' '
    ++	test_when_finished "rm -f err" &&
      	test_config core.pager "does-not-exist" &&
     -	GIT_TRACE2="$(pwd)/trace.normal" &&
     -	export GIT_TRACE2 &&
    @@ t/t7006-pager.sh: test_expect_success TTY 'git discards pager non-zero exit with
     -	grep child_exit trace.normal >child-exits &&
     -	test_line_count = 1 child-exits &&
     -	grep " code:-1 " child-exits
    -+	test_must_fail test_terminal git log
    ++	test_must_fail test_terminal git log 2>err &&
    ++	test_grep "unable to execute pager" err
      '
      
      test_expect_success TTY 'git returns SIGPIPE on propagated signals from pager' '
diff mbox series

Patch

diff --git a/pager.c b/pager.c
index e9e121db69..f5b6dc9b60 100644
--- a/pager.c
+++ b/pager.c
@@ -1,6 +1,7 @@ 
 #include "git-compat-util.h"
 #include "config.h"
 #include "editor.h"
+#include "gettext.h"
 #include "pager.h"
 #include "run-command.h"
 #include "sigchain.h"
@@ -137,7 +138,7 @@  void setup_pager(void)
 	pager_process.in = -1;
 	strvec_push(&pager_process.env, "GIT_PAGER_IN_USE");
 	if (start_command(&pager_process))
-		return;
+		die(_("unable to execute pager '%s'"), pager);
 
 	/* original process continues, but writes to the pipe */
 	dup2(pager_process.in, 1);
diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh
index e56ca5b0fa..932c26cb45 100755
--- a/t/t7006-pager.sh
+++ b/t/t7006-pager.sh
@@ -725,18 +725,11 @@  test_expect_success TTY 'git discards pager non-zero exit without SIGPIPE' '
 	test_path_is_file pager-used
 '
 
-test_expect_success TTY 'git skips paging nonexisting command' '
-	test_when_finished "rm trace.normal" &&
+test_expect_success TTY 'git errors when asked to execute nonexisting pager' '
+	test_when_finished "rm -f err" &&
 	test_config core.pager "does-not-exist" &&
-	GIT_TRACE2="$(pwd)/trace.normal" &&
-	export GIT_TRACE2 &&
-	test_when_finished "unset GIT_TRACE2" &&
-
-	test_terminal git log &&
-
-	grep child_exit trace.normal >child-exits &&
-	test_line_count = 1 child-exits &&
-	grep " code:-1 " child-exits
+	test_must_fail test_terminal git log 2>err &&
+	test_grep "unable to execute pager" err
 '
 
 test_expect_success TTY 'git returns SIGPIPE on propagated signals from pager' '
@@ -762,7 +755,7 @@  test_expect_success TTY 'git returns SIGPIPE on propagated signals from pager' '
 
 test_expect_success TTY 'non-existent pager doesnt cause crash' '
 	test_config pager.show invalid-pager &&
-	test_terminal git show
+	test_must_fail test_terminal git show
 '
 
 test_done