Skip to content
Merged
Show file tree
Hide file tree
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
60 changes: 60 additions & 0 deletions features/cli-bash-completion.feature
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,66 @@ Feature: `wp cli completions` tasks
When I run `wp cli completions --line="wp core download --no-color --no-color" --point=100`
Then STDOUT should be empty

Scenario: Bash Completion for global --url parameter in subdirectory installation
Given a WP multisite subdirectory installation
And I run `wp site create --slug=foo`
And I run `wp site create --slug=foot`
And I run `wp site create --slug=football`
And I run `wp site create --slug=bar`
And I run `wp site create --slug=baz`
And I run `wp site create --slug=waldo`

# show all matches
When I run `wp cli completions --line="wp plugin list --url=fo" --point=100`
Then STDOUT should contain:
"""
foo
"""
And STDOUT should contain:
"""
foot
"""
And STDOUT should contain:
"""
football
"""

When I run `wp cli completions --line="wp plugin list --url=https://example.com/bar" --point=100`
Then STDOUT should contain:
"""
https://example.com/bar/
"""

Scenario: Bash Completion for global --url parameter in subdomain installation
Given a WP multisite subdomain installation
And I run `wp site create --slug=foo`
And I run `wp site create --slug=foot`
And I run `wp site create --slug=football`
And I run `wp site create --slug=bar`
And I run `wp site create --slug=baz`
And I run `wp site create --slug=waldo`

# show all matches
When I run `wp cli completions --line="wp plugin list --url=fo" --point=100`
Then STDOUT should contain:
"""
foo.example.com
"""
And STDOUT should contain:
"""
foot.example.com
"""
And STDOUT should contain:
"""
football.example.com
"""

When I run `wp cli completions --line="wp plugin list --url=http://bar" --point=100`
Then STDOUT should contain:
"""
http://bar.example.com
"""

Scenario: Bash Completion for flag values with enum options
Given an empty directory

Expand Down
88 changes: 88 additions & 0 deletions php/WP_CLI/Completions.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,32 @@ public function __construct( $line ) {
array_pop( $this->words );
}

// Last word is an incomplete `--url` parameter.
if ( 0 === strpos( $this->cur_word, '--url=' ) ) {
$parameter = explode( '=', $this->cur_word, 2 );
$this->cur_word = isset( $parameter[1] ) ? $parameter[1] : '';
$urls = $this->get_network_urls();

// So we can remove the network URL from the subdirectory.
$home_url = $this->get_network_home_url();
$home_url_no_scheme = (string) preg_replace( '#^https?://#', '', $home_url );

foreach ( $urls as $url ) {
$this->add( $url );
$url_no_scheme = (string) preg_replace( '#^https?://#', '', $url );
if ( $url_no_scheme !== $url ) {
$this->add( rtrim( $url_no_scheme, '/\\' ) );
}

$url_no_home = str_replace( Utils\trailingslashit( $home_url_no_scheme ), '', $url_no_scheme );
if ( $url_no_home !== $url ) {
$this->add( rtrim( $url_no_home, '/\\' ) );
}
}

return;
}

$is_alias = false;
$is_help = false;
if ( ! empty( $this->words[0] ) && preg_match( '/^@/', $this->words[0] ) ) {
Expand Down Expand Up @@ -186,6 +212,68 @@ private function get_global_parameters() {
return $params;
}

/**
* Get the current network's home URL.
*
* @return string Home URL.
*/
private function get_network_home_url() {
$cache = WP_CLI::get_cache();

// Use the WP root to key the cache, so we don't mix results from different projects.
$wp_root = WP_CLI::get_runner()->find_wp_root();
$cache_key = sprintf( 'network-home:%s', md5( $wp_root ) );

$result = $cache->read( $cache_key, 300 ); // 5 minutes TTL

if ( false === $result ) {
$result = WP_CLI::runcommand(
'option get home',
[
'return' => 'stdout',
]
);

$cache->write( $cache_key, $result );
}

return $result;
}

/**
* Get URLs in the Multisite network matching the input.
*
* @return string[] All of the URLs.
*/
private function get_network_urls() {
$cache = WP_CLI::get_cache();

// Use the WP root to key the cache, so we don't mix results from different projects.
$wp_root = WP_CLI::get_runner()->find_wp_root();
$cache_key = sprintf( 'network-urls:%s', md5( $wp_root ) );

$result = $cache->read( $cache_key, 300 ); // 5 minutes TTL

if ( false === $result ) {
$result = WP_CLI::runcommand(
'site list',
[
'return' => 'stdout',
'command_args' => [ '--field=url', '--number=-1', '--format=json' ],
]
);

$cache->write( $cache_key, $result );
}

/**
* @var string[]|null $urls
*/
$urls = json_decode( (string) $result, true );

return is_array( $urls ) ? $urls : [];
}

/**
* Add parameter values to completions if the parameter has defined options.
*
Expand Down
2 changes: 2 additions & 0 deletions php/class-wp-cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,8 @@ public static function launch( $command, $exit_on_error = true, $return_detailed
* @param bool $return_detailed Whether to return an exit status (default) or detailed execution results.
* @param array $runtime_args Override one or more global args (path,url,user,allow-root)
* @return int|ProcessRun The command exit status, or a ProcessRun instance
*
* @phpstan-return ($return_detailed is false ? int : ProcessRun)
*/
public static function launch_self( $command, $args = [], $assoc_args = [], $exit_on_error = true, $return_detailed = false, $runtime_args = [] ) {
$reused_runtime_args = [
Expand Down
Loading