From 3f5c60e6349094ab77636ea12e0d7cc4c5dd0f9a Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Mon, 17 Feb 2020 11:12:01 +0100 Subject: [PATCH] Silence some errors for `fish --no-execute` It used to error out when a command wasn't known, even when it was a function that would only be discovered via autoloading. Now we just accept that a command doesn't exist when no-execute is given - we're not gonna execute it anyway. Also, in the same breath stop counting empty commands after expansion and empty wildcard expansions as errors - these depend on runtime values, so we can't verify them without executing. Fixes #977. (note that it still executes "time", but that's another commit) --- src/parse_execution.cpp | 10 ++++++++-- tests/checks/no-execute.fish | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tests/checks/no-execute.fish diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index fe7c6a33a..e524af8c6 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -718,7 +718,8 @@ end_execution_reason_t parse_execution_context_t::expand_command( assert(expand_err == expand_result_t::ok); // Complain if the resulting expansion was empty, or expanded to an empty string. - if (out_cmd->empty()) { + // For no-exec it's okay, as we can't really perform the expansion. + if (out_cmd->empty() && !no_exec()) { return this->report_error(STATUS_ILLEGAL_CMD, statement, _(L"The expanded command was empty.")); } @@ -741,6 +742,8 @@ end_execution_reason_t parse_execution_context_t::populate_plain_process( if (ret != end_execution_reason_t::ok) { return ret; } + // For no-exec, having an empty command is okay. We can't do anything more with it tho. + if (no_exec()) return end_execution_reason_t::ok; assert(!cmd.empty() && "expand_command should not produce an empty command"); // Determine the process type. @@ -795,7 +798,8 @@ end_execution_reason_t parse_execution_context_t::populate_plain_process( } if (!has_command && !use_implicit_cd) { - // No command. + // No command. If we're --no-execute return okay - it might be a function. + if (no_exec()) return end_execution_reason_t::ok; return this->handle_command_not_found(cmd, statement, no_cmd_err_code); } } @@ -875,6 +879,8 @@ end_execution_reason_t parse_execution_context_t::expand_arguments_from_nodes( } case expand_result_t::wildcard_no_match: { if (glob_behavior == failglob) { + // For no_exec, ignore the error - this might work at runtime. + if (no_exec()) return end_execution_reason_t::ok; // Report the unmatched wildcard error and stop processing. return report_error(STATUS_UNMATCHED_WILDCARD, arg_node, WILDCARD_ERR_MSG, get_source(arg_node).c_str()); diff --git a/tests/checks/no-execute.fish b/tests/checks/no-execute.fish new file mode 100644 index 000000000..1ea4f8aba --- /dev/null +++ b/tests/checks/no-execute.fish @@ -0,0 +1,22 @@ +#RUN: %fish -C 'set -l fish %fish' %s + +# Test that fish -n doesn't check for command existence - function autoloading throws a wrench in that. +echo "type foo" | $fish -n +echo $status +#CHECK: 0 + +# Test that it doesn't check globs. +echo "echo /asfjidhfiusnlkxcnvklxcvlkmcxlv*" | $fish -n +echo $status +#CHECK: 0 + +# Test that it does print syntax errors. +echo "begin; echo oops" | $fish -n +#CHECKERR: fish: Missing end to balance this begin +#CHECKERR: begin; echo oops +#CHECKERR: ^ +echo $status +#CHECK: 127 + +# Littlecheck assumes a status of 127 means the shebang was invalid. +exit 0