File: //usr/local/wp/features/bootstrap.feature
Feature: Bootstrap WP-CLI
Background:
When I run `wp package path`
And save STDOUT as {PACKAGE_PATH}
And I run `rm -rf {PACKAGE_PATH}/vendor`
And I run `rm -rf {PACKAGE_PATH}/composer.json`
And I run `rm -rf {PACKAGE_PATH}/composer.lock`
@less-than-php-7.4 @require-opcache-save-comments
Scenario: Basic Composer stack
Given an empty directory
And a composer.json file:
"""
{
"name": "wp-cli/composer-test",
"type": "project",
"require": {
"wp-cli/wp-cli": "1.1.0"
}
}
"""
# Note: Composer outputs messages to stderr.
And I run `composer install --no-interaction 2>&1`
When I run `vendor/bin/wp cli version`
Then STDOUT should contain:
"""
WP-CLI 1.1.0
"""
Scenario: Composer stack with override requirement before WP-CLI
Given a WP installation
And a composer.json file:
"""
{
"name": "wp-cli/composer-test",
"type": "project",
"minimum-stability": "dev",
"prefer-stable": true,
"repositories": [
{
"type": "path",
"url": "./override",
"options": {
"symlink": false
}
}
],
"require": {
"wp-cli/override": "*",
"wp-cli/wp-cli": "dev-main"
}
}
"""
And a override/override.php file:
"""
<?php
if ( ! class_exists( 'WP_CLI' ) ) {
return;
}
// Override bundled command.
WP_CLI::add_command( 'eval', 'Custom_Eval_Command', array( 'when' => 'before_wp_load' ) );
"""
And a override/src/Custom_Eval_Command.php file:
"""
<?php
class Custom_Eval_Command extends WP_CLI_Command {
public function __invoke() {
WP_CLI::success( "WP-Override-Eval" );
}
}
"""
And a override/composer.json file:
"""
{
"name": "wp-cli/override",
"description": "A command that overrides the 'eval' command.",
"autoload": {
"psr-4": { "": "src/" },
"files": [ "override.php" ]
},
"extra": {
"commands": [
"eval"
]
}
}
"""
And I run `composer install --no-interaction 2>&1`
When I run `vendor/bin/wp eval '\WP_CLI::Success( "WP-Standard-Eval" );'`
Then STDOUT should contain:
"""
Success: WP-Override-Eval
"""
Scenario: Override command bundled with current source
Given a WP installation
And a override/override.php file:
"""
<?php
if ( ! class_exists( 'WP_CLI' ) ) {
return;
}
$autoload = dirname( __FILE__ ) . '/vendor/autoload.php';
if ( file_exists( $autoload ) && ! class_exists( 'Custom_CLI_Command' ) ) {
require_once $autoload;
}
// Override framework command.
WP_CLI::add_command( 'cli', 'Custom_CLI_Command', array( 'when' => 'before_wp_load' ) );
// Override bundled command.
WP_CLI::add_hook(
'after_add_command:eval',
static function () {
static $added = false;
if ( ! $added ) {
$added = true;
WP_CLI::add_command( 'eval', 'Custom_Eval_Command', array( 'when' => 'before_wp_load' ) );
}
}
);
"""
And a override/src/Custom_CLI_Command.php file:
"""
<?php
class Custom_CLI_Command extends WP_CLI_Command {
public function version() {
WP_CLI::success( "WP-Override-CLI" );
}
}
"""
And a override/src/Custom_Eval_Command.php file:
"""
<?php
class Custom_Eval_Command extends WP_CLI_Command {
public function __invoke() {
WP_CLI::success( "WP-Override-Eval" );
}
}
"""
And a override/composer.json file:
"""
{
"name": "wp-cli/override",
"description": "A command that overrides the bundled 'cli' and 'eval' commands.",
"autoload": {
"psr-4": { "": "src/" },
"files": [ "override.php" ]
},
"extra": {
"commands": [
"cli",
"eval"
]
}
}
"""
And I run `composer install --working-dir={RUN_DIR}/override --no-interaction 2>&1`
When I run `wp cli version`
Then STDOUT should contain:
"""
WP-CLI
"""
When I run `wp eval '\WP_CLI::Success( "WP-Standard-Eval" );'`
Then STDOUT should contain:
"""
Success: WP-Standard-Eval
"""
When I run `wp --require=override/override.php cli version`
Then STDOUT should contain:
"""
WP-Override-CLI
"""
When I run `wp --require=override/override.php eval '\WP_CLI::Success( "WP-Standard-Eval" );'`
Then STDOUT should contain:
"""
Success: WP-Override-Eval
"""
Scenario: Override command through package manager
Given a WP installation
And a override/override.php file:
"""
<?php
if ( ! class_exists( 'WP_CLI' ) ) {
return;
}
$autoload = dirname( __FILE__ ) . '/vendor/autoload.php';
if ( file_exists( $autoload ) && ! class_exists( 'Custom_CLI_Command' ) ) {
require_once $autoload;
}
// Override framework command.
WP_CLI::add_command( 'cli', 'Custom_CLI_Command', array( 'when' => 'before_wp_load' ) );
// Override bundled command.
WP_CLI::add_hook(
'after_add_command:eval',
static function () {
static $added = false;
if ( ! $added ) {
$added = true;
WP_CLI::add_command( 'eval', 'Custom_Eval_Command', array( 'when' => 'before_wp_load' ) );
}
}
);
"""
And a override/src/Custom_CLI_Command.php file:
"""
<?php
class Custom_CLI_Command extends WP_CLI_Command {
public function version() {
WP_CLI::success( "WP-Override-CLI" );
}
}
"""
And a override/src/Custom_Eval_Command.php file:
"""
<?php
class Custom_Eval_Command extends WP_CLI_Command {
public function __invoke() {
WP_CLI::success( "WP-Override-Eval" );
}
}
"""
And a override/composer.json file:
"""
{
"name": "wp-cli/override",
"description": "A command that overrides the bundled 'cli' and 'eval' commands.",
"autoload": {
"psr-4": { "": "src/" },
"files": [ "override.php" ]
},
"extra": {
"commands": [
"cli",
"eval"
]
}
}
"""
And I run `wp package install {RUN_DIR}/override`
When I run `wp cli version --skip-packages`
Then STDOUT should contain:
"""
WP-CLI
"""
When I run `wp eval '\WP_CLI::Success( "WP-Standard-Eval" );' --skip-packages`
Then STDOUT should contain:
"""
Success: WP-Standard-Eval
"""
When I run `wp cli version`
Then STDOUT should contain:
"""
WP-Override-CLI
"""
When I run `wp eval '\WP_CLI::Success( "WP-Standard-Eval" );'`
Then STDOUT should contain:
"""
Success: WP-Override-Eval
"""
Scenario: Extend existing bundled command through package manager
Given a WP installation
And a override/override.php file:
"""
<?php
if ( ! class_exists( 'WP_CLI' ) ) {
return;
}
WP_CLI::add_hook( 'before_wp_load', static function () {
WP_CLI::add_command( 'plugin', 'My_Extended_Plugin_Command' );
} );
"""
And a override/src/My_Extended_Plugin_Command.php file:
"""
<?php
class My_Extended_Plugin_Command extends Plugin_Command {
public function install( $args, $assoc_args ) {
WP_CLI::error( 'Plugin installation has been disabled.' );
}
}
"""
And a override/composer.json file:
"""
{
"name": "wp-cli/override",
"description": "A command that extends the bundled 'plugin' command.",
"autoload": {
"psr-4": { "": "src/" },
"files": [ "override.php" ]
},
"extra": {
"commands": [
"plugin"
]
}
}
"""
And I run `wp package install {RUN_DIR}/override`
When I try `wp plugin install duplicate-post`
Then STDERR should contain:
"""
Error: Plugin installation has been disabled.
"""
When I run `wp plugin list`
Then STDOUT should contain:
"""
hello
"""
Scenario: Define constant before running a command
Given a WP installation
# Expect a warning from WP core for PHP 8+.
When I try `wp --exec="define( 'WP_ADMIN', true );" eval "echo WP_ADMIN;"`
Then STDOUT should contain:
"""
1
"""
@require-php-7.0
Scenario: Composer stack with both WordPress and wp-cli as dependencies (command line)
Given a WP installation with Composer
And a dependency on current wp-cli
# Redirect STDERR to STDOUT as Composer produces non-error output on STDERR
And I run `composer require wp-cli/entity-command --with-all-dependencies --no-interaction 2>&1`
When I run `vendor/bin/wp option get blogname`
Then STDOUT should contain:
"""
WP CLI Site with both WordPress and wp-cli as Composer dependencies
"""
@broken @require-php-7.0
Scenario: Composer stack with both WordPress and wp-cli as dependencies (web)
Given a WP installation with Composer
And a dependency on current wp-cli
And a PHP built-in web server to serve 'WordPress'
Then the HTTP status code should be 200
@require-php-7.0
Scenario: Composer stack with both WordPress and wp-cli as dependencies and a custom vendor directory
Given a WP installation with Composer and a custom vendor directory 'vendor-custom'
And a dependency on current wp-cli
# Redirect STDERR to STDOUT as Composer produces non-error output on STDERR
And I run `composer require wp-cli/entity-command --with-all-dependencies --no-interaction 2>&1`
When I run `vendor-custom/bin/wp option get blogname`
Then STDOUT should contain:
"""
WP CLI Site with both WordPress and wp-cli as Composer dependencies
"""
Scenario: Setting an environment variable passes the value through
Given an empty directory
And WP files
And a database
And a env-var.php file:
"""
<?php
putenv( 'WP_CLI_TEST_ENV_VAR=foo' );
"""
And a wp-cli.yml file:
"""
config create:
extra-php: |
require_once __DIR__ . '/env-var.php';
define( 'WP_CLI_TEST_CONSTANT', getenv( 'WP_CLI_TEST_ENV_VAR' ) );
"""
When I run `wp config create --skip-check {CORE_CONFIG_SETTINGS}`
Then STDOUT should contain:
"""
Success:
"""
# Use try to cater for wp-db errors in old WPs.
When I try `wp core install --url=example.com --title=example --admin_user=example --admin_email=example@example.org`
Then STDOUT should contain:
"""
Success:
"""
And the return code should be 0
When I run `wp eval 'echo constant( "WP_CLI_TEST_CONSTANT" );'`
Then STDOUT should be:
"""
foo
"""
@require-wp-3.9
Scenario: Run cache flush on ms_site_not_found
Given a WP multisite installation
And a wp-cli.yml file:
"""
url: invalid.com
"""
And I run `wp package install wp-cli/cache-command`
When I try `wp cache add foo bar`
Then STDERR should contain:
"""
Error: Site 'invalid.com' not found.
"""
And the return code should be 1
When I try `wp cache flush --url=invalid.com`
Then STDOUT should contain:
"""
Success: The cache was flushed.
"""
And the return code should be 0
# `wp search-replace` does not yet support SQLite
# See https://github.com/wp-cli/search-replace-command/issues/190
@require-wp-4.0 @require-mysql
Scenario: Run search-replace on ms_site_not_found
Given a WP multisite installation
And a wp-cli.yml file:
"""
url: invalid.com
"""
And I run `wp package install wp-cli/search-replace-command`
When I try `wp search-replace foo bar`
Then STDERR should contain:
"""
Error: Site 'invalid.com' not found.
"""
And the return code should be 1
When I run `wp option update test_key '["foo"]' --format=json --url=example.com`
Then STDOUT should contain:
"""
Success:
"""
# --network should permit search-replace
When I run `wp search-replace foo bar --network`
Then STDOUT should contain:
"""
Success:
"""
And the return code should be 0
When I run `wp option update test_key '["foo"]' --format=json --url=example.com`
Then STDOUT should contain:
"""
Success:
"""
# --all-tables should permit search-replace
When I run `wp search-replace foo bar --all-tables`
Then STDOUT should contain:
"""
Success:
"""
And the return code should be 0
When I run `wp option update test_key '["foo"]' --format=json --url=example.com`
Then STDOUT should contain:
"""
Success:
"""
# --all-tables-with-prefix should permit search-replace
When I run `wp search-replace foo bar --all-tables-with-prefix`
Then STDOUT should contain:
"""
Success:
"""
And the return code should be 0
When I run `wp option update test_key '["foo"]' --format=json --url=example.com`
Then STDOUT should contain:
"""
Success:
"""
# Specific tables should permit search-replace
When I run `wp search-replace foo bar wp_options`
Then STDOUT should contain:
"""
Success:
"""
And the return code should be 0
Scenario: Allow disabling ini_set()
Given an empty directory
When I try `{INVOKE_WP_CLI_WITH_PHP_ARGS--ddisable_functions=ini_set} cli info`
Then the return code should be 0
Scenario: Test early root detection
Given an empty directory
And a include.php file:
"""
<?php
namespace WP_CLI\Bootstrap;
// To override posix_geteuid in our namespace
function posix_geteuid() {
return 0;
}
?>
"""
And I try `WP_CLI_EARLY_REQUIRE=include.php wp cli version --debug`
Then STDERR should contain:
"""
WP_CLI\Bootstrap\CheckRoot
"""
And STDERR should not contain:
"""
WP_CLI\Bootstrap\IncludeRequestsAutoloader
"""
And STDERR should contain:
"""
YIKES!
"""