Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 69 additions & 1 deletion php/commands/src/Help_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use cli\Shell;
use WP_CLI\Dispatcher;
use WP_CLI\Utils;
use WP_CLI\Process;

class Help_Command extends WP_CLI_Command {

Expand Down Expand Up @@ -115,6 +116,68 @@ private static function indent( $whitespace, $text ) {
return implode( "\n", $lines );
}

/**
* Locate an executable binary or command by name using a platform-appropriate detector.
*
* On Windows, this uses `where`, and on POSIX systems it uses `command -v`.
* This may not work accurately in PowerShell.
*
* @param string $binary Name of the binary or command to be found.
* @return bool True if this command has determined that the binary or other command exists, false otherwise.
*/
public static function binary_exists( $binary ) {
if ( Utils\is_windows() ) {
// This may not work in PowerShell; see https://stackoverflow.com/a/304447
// If this needs to be adjusted to use 'where.exe' for PowerShell,
// then we will need to add a way of detecting whether wp-cli is running in PowerShell.
$detector = 'where';
} else {
// POSIX method to detect whether a command exists
// This sometimes detects aliases.
$detector = 'command -v';
}

$result = Process::create( $detector . ' ' . escapeshellarg( $binary ), null, null )->run();

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;
}
Comment on lines +142 to +149
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This if/else block can be simplified to a single return statement. This will make the code more concise and easier to read.

        return 0 === $result->return_code;

}

/**
* Determine whether to use `less` or `more` as a pager
*
* This caches the determined pager.
*
* @return string The command to use for the pager. Defaults to `more`.
*/
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';
}
Comment on lines +159 to +169
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
}

return $pager;
}

/**
* Pass a given set of output through the system's terminal pager.
*
* @param string $out The output to be run through the pager.
* @return mixed Termination status of the pager as reported by https://www.php.net/manual/en/function.proc-close.php
*/
private static function pass_through_pager( $out ) {

if ( ! Utils\check_proc_available( null /*context*/, true /*return*/ ) ) {
Expand All @@ -124,8 +187,13 @@ private static function pass_through_pager( $out ) {
}

$pager = getenv( 'PAGER' );
// if '' we should assume that the user has explicitly disabled the pager by setting `PAGER=`
if ( '' === $pager ) {
WP_CLI::line( $out );
return 0;
}
if ( false === $pager ) {
$pager = Utils\is_windows() ? 'more' : 'less -R';
$pager = self::locate_pager();
}

// For Windows 7 need to set code page to something other than Unicode (65001) to get around "Not enough memory." error with `more.com` on PHP 7.1+.
Expand Down
Loading