Check whether less pager exists before trying to pipe content through it#6020
Check whether less pager exists before trying to pipe content through it#6020swissspidy merged 14 commits intowp-cli:mainfrom
less pager exists before trying to pipe content through it#6020Conversation
|
Noting that, due to Thanksgiving, I will respond to comments on this PR in December. |
|
Thank you for the pull request. I don't think it works to change the default pager since it would be a downgrade and create new issues for the majority of users:
So replacing The standard I think if you wanted to attempt to detect |
less exists on non-Windows systemsless pager exists before trying to pipe content through it
|
@mrsdizzie I've updated this to use the same Unfortunately, I don't have a Windows machine handy to test this change. |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
Fixes a crash in wp help when PAGER is unset and less is not installed by selecting an available pager at runtime instead of assuming less exists.
Changes:
- Adds pager discovery logic (
less -Rif available, otherwisemore) and reuses it whenPAGERis unset. - Introduces a helper to detect whether a given binary exists using a platform-specific command.
- Adds a docblock to
Help_Command::pass_through_pager().
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| public static function locate_pager() { | ||
| static $pager = null; | ||
|
|
||
| if ( empty( $pager ) ) { | ||
| if ( self::binary_exists( 'less' ) ) { | ||
| // less is not available in all systems | ||
| $pager = 'less -R'; | ||
| } else { | ||
| // more is part of the POSIX definition, and is also available on Windows. | ||
| $pager = 'more'; | ||
| } |
There was a problem hiding this comment.
This change fixes a crash when PAGER is unset and less is missing, but the existing features/help.feature scenarios don’t exercise that environment (they’ll typically run on hosts where less exists). Consider adding a regression test that runs wp help with PAGER unset and a PATH that makes less unavailable, to prevent this from reappearing.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This comment was marked as resolved.
This comment was marked as resolved.
There was a problem hiding this comment.
Code Review
This pull request addresses a crash that occurs when the less command is unavailable by implementing a check for its existence and providing a fallback to more. The changes are well-structured, introducing binary_exists() and locate_pager() helper methods to encapsulate the logic. The approach is sound and effectively resolves the reported issue. I have one minor suggestion to improve code conciseness.
| if ( 0 !== $result->return_code ) { | ||
| // We could not reliably determine that the binary exists | ||
| return false; | ||
| } else { | ||
| // POSIX binaries: command -v will return the path and exit 0 | ||
| // aliases: command -v may return the alias command and exit 0 | ||
| return true; | ||
| } |
Problem
in the corner case where:
wp-cliis running on a non-Windows systemPAGERenvironment variable is not setlessis not installedwp helpcommand:wp-clicommandwp-cli crashes, as documented in #5333
An example of an environment without
lessis many "minimalist" Docker server containers.Changes
lessexists in non-Windows environments when the environment variable$PAGERis not set. Instead, in all environments, invocations ofwp helpwill first check to see iflessexists, and use that, before falling back tomore. The previous behavior was to pipe output throughless -Ron non-Windows systems without first checking iflessexists.Help_Command::pass_through_pager()Alternatives considered
Replacing
less -RwithcatThis would replace a pager with a non-pager, which seems like a feature regression
Replacing
less -Rwithmorein all casesRuled out by @mrsdizzie at #6020 (comment), and removed in b88c438
Accurately checking whether
lessexistsI started a branch with this intent, at benlk@832bb1e , but this approach proved nonviable.
To accurately test whether
lessexists:cmd.exeor Powershell, ascmd.execan usewhereto determine whether a command exists, but Powershell needs to use a different commandcommand -vaccurately determines whether a command exists, we would also need to check for the existence of analias, which is a separate can of wormsproc_close()isn't guaranteed to return the command's exit codeThis seemed like way too much scope creep, introducing too much code, requiring too much testing, for a fallback scenario around displaying a help message.
Testing
The existing tests in https://github.com/wp-cli/wp-cli/blob/main/features/help.feature do not care about whether
moreorlessis used.If additional tests are needed for this change, I'm open to suggestions on what should be tested.
For local testing, on all OS:
echo $PAGERto check what your local shell'sPAGERvariable is. If it is set to any value, including an emptystring, rununset PAGERto unset it.lessto determine whetherlessexists on your system. If it does, runcommand -v less(POSIX) orwhere less(Windows) to determine whether it exists as a binary or as an alias.wpwithout any other commands or optionswp helpis displayed. Iflessexists on your system, it should be paged inless. Iflessdoes not exist, butmoredoes exist in your system, the output should be paged inmore.