From b40a1edd0c50e6913ad5a59d1991583016fd1a2f Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Sun, 19 Jul 2020 21:01:46 -0300 Subject: [PATCH 1/3] Adding base for the BuddyPress scaffold command --- .behat-progress.log | 1 + features/scaffold.feature | 29 +++ phpcs.xml.dist | 10 +- src/scaffold.php | 146 +++++++++++++ src/templates/bootstrap-buddypress.php | 24 +++ src/templates/install-bp-tests.sh | 27 +++ wp-cli-bp.php | 284 +++++++++++++------------ 7 files changed, 383 insertions(+), 138 deletions(-) create mode 100644 .behat-progress.log create mode 100644 features/scaffold.feature create mode 100644 src/scaffold.php create mode 100644 src/templates/bootstrap-buddypress.php create mode 100644 src/templates/install-bp-tests.sh diff --git a/.behat-progress.log b/.behat-progress.log new file mode 100644 index 0000000..fbbed44 --- /dev/null +++ b/.behat-progress.log @@ -0,0 +1 @@ +/Users/espellcaste/Sites/bp/wp-content/plugins/bp-cli/features/scaffold.feature:10 diff --git a/features/scaffold.feature b/features/scaffold.feature new file mode 100644 index 0000000..5daf47b --- /dev/null +++ b/features/scaffold.feature @@ -0,0 +1,29 @@ +Feature: Scaffold BuddyPress tests + + Background: + Given a WP install + And these installed and active plugins: + """ + https://github.com/buddypress/BuddyPress/archive/master.zip + """ + + Scenario: Scaffold plugin tests + When I run `wp bp scaffold plugin-tests hello-world` + Then STDOUT should not be empty + And the {PLUGIN_DIR}/hello-world/tests directory should contain: + """ + bootstrap.php + """ + And the {PLUGIN_DIR}/hello-world/tests/bootstrap.php file should contain: + """ + require_once getenv( 'BP_TESTS_DIR' ) . '/includes/loader.php'; + """ + And the {PLUGIN_DIR}/hello-world/bin directory should contain: + """ + install-bp-tests.sh + """ + When I run `wp eval "if ( is_executable( '{PLUGIN_DIR}/hello-world/bin/install-bp-tests.sh' ) ) { echo 'executable'; } else { exit( 1 ); }"` + Then STDOUT should be: + """ + executable + """ diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 62b856c..3ecbc28 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -18,9 +18,17 @@ + https://github.com/PHPCompatibility/PHPCompatibility#sniffing-your-code-for-compatibility-with-specific-php-versions --> + + */src/templates/bootstrap-buddypress.php + + + + */src/templates/bootstrap-buddypress.php + + 0 diff --git a/src/scaffold.php b/src/scaffold.php new file mode 100644 index 0000000..7cc2fbe --- /dev/null +++ b/src/scaffold.php @@ -0,0 +1,146 @@ + + * : The slug of the BuddyPress plugin. + * + * ## EXAMPLE + * + * $ wp bp scaffold plugin sample-test + * Success: Created test files. + * + * @subcommand plugin-tests + */ + public function plugin( $args, $assoc_args ) { + $wp_filesystem = $this->init_wp_filesystem(); + + $slug = $args[0]; + $target_dir = WP_PLUGIN_DIR . "/{$slug}"; + + if ( ! is_dir( $target_dir ) ) { + WP_CLI::error( "Invalid plugin slug specified. No such target directory '{$target_dir}'." ); + } + + $error_msg = $this->check_target_directory( $target_dir ); + if ( ! empty( $error_msg ) ) { + WP_CLI::error( "Invalid plugin slug specified. {$error_msg}" ); + } + + $to_copy = array( + 'install-bp-tests.sh' => "{$target_dir}/bin", + 'bootstrap-buddypress.php' => "{$target_dir}/tests", + ); + + foreach ( $to_copy as $file => $dir ) { + $file_name = "$dir/$file"; + $force = WP_CLI\Utils\get_flag_value( $assoc_args, 'force' ); + $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_name, $force ); + + if ( ! $should_write_file ) { + continue; + } + + $files_written[] = $file_name; + + $wp_filesystem->copy( self::get_template_path( $file ), $file_name, true ); + + if ( 'install-bp-tests.sh' === $file ) { + if ( ! $wp_filesystem->chmod( "$dir/$file", 0755 ) ) { + WP_CLI::warning( "Couldn't mark 'install-bp-tests.sh' as executable." ); + } + } + } + + $this->log_whether_files_written( + $files_written, + 'All BuddyPress test files were skipped.', + 'Created BuddyPress test files.' + ); + } + + /** + * Checks that the `$target_dir` is a child directory of the WP themes or plugins directory, depending on `$type`. + * + * @param string $type "theme" or "plugin" + * @param string $target_dir The theme/plugin directory to check. + * + * @return null|string Returns null on success, error message on error. + */ + public function check_target_directory( $target_dir ) { + $parent_dir = dirname( self::canonicalize_path( str_replace( '\\', '/', $target_dir ) ) ); + + if ( str_replace( '\\', '/', WP_PLUGIN_DIR ) !== $parent_dir ) { + return sprintf( 'The target directory \'%1$s\' is not in \'%2$s\'.', $target_dir, WP_PLUGIN_DIR ); + } + + // Success. + return null; + } + + public static function canonicalize_path( $path ) { + if ( '' === $path || '/' === $path ) { + return $path; + } + + if ( '.' === substr( $path, -1 ) ) { + $path .= '/'; + } + + $output = array(); + + foreach ( explode( '/', $path ) as $segment ) { + if ( '..' === $segment ) { + array_pop( $output ); + } elseif ( '.' !== $segment ) { + $output[] = $segment; + } + } + + return implode( '/', $output ); + } + + /** + * Gets the template path based on installation type. + */ + public static function get_template_path( $template ) { + $command_root = WP_CLI\Utils\phar_safe_path( dirname( __DIR__ ) ); + $template_path = "{$command_root}/templates/{$template}"; + + if ( ! file_exists( $template_path ) ) { + WP_CLI::error( "Couldn't find {$template}" ); + } + + return $template_path; + } +} diff --git a/src/templates/bootstrap-buddypress.php b/src/templates/bootstrap-buddypress.php new file mode 100644 index 0000000..33cb87a --- /dev/null +++ b/src/templates/bootstrap-buddypress.php @@ -0,0 +1,24 @@ +> tests/bootstrap.php diff --git a/wp-cli-bp.php b/wp-cli-bp.php index a324055..aa67669 100644 --- a/wp-cli-bp.php +++ b/wp-cli-bp.php @@ -9,140 +9,150 @@ use WP_CLI; -WP_CLI::add_hook( 'before_wp_load', function() { - require_once( __DIR__ . '/src/command.php' ); - require_once( __DIR__ . '/src/buddypress.php' ); - require_once( __DIR__ . '/src/signup.php' ); - require_once( __DIR__ . '/src/activity.php' ); - require_once( __DIR__ . '/src/activity-favorite.php' ); - require_once( __DIR__ . '/src/components.php' ); - require_once( __DIR__ . '/src/tool.php' ); - require_once( __DIR__ . '/src/notification.php' ); - require_once( __DIR__ . '/src/email.php' ); - require_once( __DIR__ . '/src/member.php' ); - require_once( __DIR__ . '/src/friends.php' ); - require_once( __DIR__ . '/src/messages.php' ); - require_once( __DIR__ . '/src/xprofile.php' ); - require_once( __DIR__ . '/src/xprofile-group.php' ); - require_once( __DIR__ . '/src/xprofile-field.php' ); - require_once( __DIR__ . '/src/xprofile-data.php' ); - require_once( __DIR__ . '/src/group-fetcher.php' ); - require_once( __DIR__ . '/src/group.php' ); - require_once( __DIR__ . '/src/group-member.php' ); - require_once( __DIR__ . '/src/group-invite.php' ); - require_once( __DIR__ . '/src/group-meta.php' ); - - WP_CLI::add_command( - 'bp', - __NAMESPACE__ . '\\Command\\BuddyPress', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\BuddyPress::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp signup', - __NAMESPACE__ . '\\Command\\Signup', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Signup::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp tool', - __NAMESPACE__ . '\\Command\\Tool', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Tool::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp notification', - __NAMESPACE__ . '\\Command\\Notification', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Notification::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp email', - __NAMESPACE__ . '\\Command\\Email', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Email::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp member', - __NAMESPACE__ . '\\Command\\Member', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Member::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp message', - __NAMESPACE__ . '\\Command\\Messages', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Messages::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp component', - __NAMESPACE__ . '\\Command\\Components', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Components::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp friend', - __NAMESPACE__ . '\\Command\\Friends', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Friends::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp activity', - __NAMESPACE__ . '\\Command\\Activity', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Activity::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp activity favorite', - __NAMESPACE__ . '\\Command\\Activity_Favorite', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Activity::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp group', - __NAMESPACE__ . '\\Command\\Group', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp group member', - __NAMESPACE__ . '\\Command\\Group_Member', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp group meta', - __NAMESPACE__ . '\\Command\\Group_Meta', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp group invite', - __NAMESPACE__ . '\\Command\\Group_Invite', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp xprofile', - __NAMESPACE__ . '\\Command\\XProfile', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp xprofile group', - __NAMESPACE__ . '\\Command\\XProfile_Group', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp xprofile field', - __NAMESPACE__ . '\\Command\\XProfile_Field', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ) - ); - - WP_CLI::add_command( - 'bp xprofile data', - __NAMESPACE__ . '\\Command\\XProfile_Data', - array( 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ) - ); -}); +WP_CLI::add_hook( + 'before_wp_load', + function() { + require_once( __DIR__ . '/src/command.php' ); + require_once( __DIR__ . '/src/buddypress.php' ); + require_once( __DIR__ . '/src/signup.php' ); + require_once( __DIR__ . '/src/activity.php' ); + require_once( __DIR__ . '/src/activity-favorite.php' ); + require_once( __DIR__ . '/src/components.php' ); + require_once( __DIR__ . '/src/tool.php' ); + require_once( __DIR__ . '/src/notification.php' ); + require_once( __DIR__ . '/src/email.php' ); + require_once( __DIR__ . '/src/member.php' ); + require_once( __DIR__ . '/src/friends.php' ); + require_once( __DIR__ . '/src/messages.php' ); + require_once( __DIR__ . '/src/xprofile.php' ); + require_once( __DIR__ . '/src/xprofile-group.php' ); + require_once( __DIR__ . '/src/xprofile-field.php' ); + require_once( __DIR__ . '/src/xprofile-data.php' ); + require_once( __DIR__ . '/src/group-fetcher.php' ); + require_once( __DIR__ . '/src/group.php' ); + require_once( __DIR__ . '/src/group-member.php' ); + require_once( __DIR__ . '/src/group-invite.php' ); + require_once( __DIR__ . '/src/group-meta.php' ); + require_once( __DIR__ . '/src/scaffold.php' ); + + WP_CLI::add_command( + 'bp', + __NAMESPACE__ . '\\Command\\BuddyPress', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\BuddyPress::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp signup', + __NAMESPACE__ . '\\Command\\Signup', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Signup::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp tool', + __NAMESPACE__ . '\\Command\\Tool', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Tool::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp notification', + __NAMESPACE__ . '\\Command\\Notification', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Notification::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp email', + __NAMESPACE__ . '\\Command\\Email', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Email::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp member', + __NAMESPACE__ . '\\Command\\Member', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Member::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp message', + __NAMESPACE__ . '\\Command\\Messages', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Messages::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp component', + __NAMESPACE__ . '\\Command\\Components', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Components::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp friend', + __NAMESPACE__ . '\\Command\\Friends', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Friends::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp activity', + __NAMESPACE__ . '\\Command\\Activity', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Activity::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp activity favorite', + __NAMESPACE__ . '\\Command\\Activity_Favorite', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Activity::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp group', + __NAMESPACE__ . '\\Command\\Group', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp group member', + __NAMESPACE__ . '\\Command\\Group_Member', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp group meta', + __NAMESPACE__ . '\\Command\\Group_Meta', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp group invite', + __NAMESPACE__ . '\\Command\\Group_Invite', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Group::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp xprofile', + __NAMESPACE__ . '\\Command\\XProfile', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp xprofile group', + __NAMESPACE__ . '\\Command\\XProfile_Group', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp xprofile field', + __NAMESPACE__ . '\\Command\\XProfile_Field', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp xprofile data', + __NAMESPACE__ . '\\Command\\XProfile_Data', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\XProfile::check_dependencies' ) + ); + + WP_CLI::add_command( + 'bp scaffold', + __NAMESPACE__ . '\\Command\\Scaffold', + array( 'before_invoke' => __NAMESPACE__ . '\\Command\\Scaffold::check_dependencies' ) + ); + } +); From e447a3594971844574e790a839eddc0811ea819c Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Mon, 7 Sep 2020 14:59:17 -0300 Subject: [PATCH 2/3] Updating composer.lock --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index e736bd2..77531f2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "04bdd738d315388bd1708a3872f823bb", + "content-hash": "cb47effaacff63cc3c19ecbf40a44ca7", "packages": [ { "name": "mustache/mustache", From e5675cf17be05c82261c8a2b1fc9d00cfcc0cf71 Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Mon, 7 Sep 2020 15:10:43 -0300 Subject: [PATCH 3/3] Fixing a bug and other doc improvements --- features/scaffold.feature | 3 +++ src/member.php | 11 ----------- src/tool.php | 7 ++++--- src/xprofile-field.php | 4 ++-- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/features/scaffold.feature b/features/scaffold.feature index e41191a..ed79abe 100644 --- a/features/scaffold.feature +++ b/features/scaffold.feature @@ -21,6 +21,9 @@ Feature: Scaffold BuddyPress tests And the {PLUGIN_DIR}/hello-world/tests directory should contain: """ bootstrap.php + """ + And the {PLUGIN_DIR}/hello-world/tests directory should contain: + """ bootstrap-buddypress.php """ And the {PLUGIN_DIR}/hello-world/tests/bootstrap-buddypress.php file should contain: diff --git a/src/member.php b/src/member.php index d5e7406..e42ef43 100644 --- a/src/member.php +++ b/src/member.php @@ -2,8 +2,6 @@ namespace Buddypress\CLI\Command; -use WP_CLI; - /** * Manage BuddyPress Members * @@ -16,15 +14,6 @@ */ class Member extends BuddyPressCommand { - /** - * Default dependency check for a BuddyPress CLI command. - */ - public static function check_dependencies() { - if ( ! class_exists( 'Buddypress' ) ) { - WP_CLI::error( 'The BuddyPress plugin is not active.' ); - } - } - /** * Generate BuddyPress members. See documentation for `wp_user_generate`. * diff --git a/src/tool.php b/src/tool.php index 5f76db4..c6dc118 100644 --- a/src/tool.php +++ b/src/tool.php @@ -12,6 +12,9 @@ * $ wp bp tool repair friend-count * Success: Counting the number of friends for each user. Complete! * + * $ wp bp tool version + * BuddyPress: 6.0.0 + * * @since 1.5.0 */ class Tool extends BuddyPressCommand { @@ -41,7 +44,7 @@ public static function check_dependencies() { * - last-activity * --- * - * ## EXAMPLES + * ## EXAMPLE * * $ wp bp tool repair friend-count * Success: Counting the number of friends for each user. Complete! @@ -94,8 +97,6 @@ public function version() { * * $ wp bp tool signup 0 * Success: Signup tool updated. - * - * @since 2.0.0 */ public function signup( $args ) { bp_update_option( 'users_can_register', $args[0] ); diff --git a/src/xprofile-field.php b/src/xprofile-field.php index 6574a37..5dc6e50 100644 --- a/src/xprofile-field.php +++ b/src/xprofile-field.php @@ -68,7 +68,7 @@ public function list_( $args, $assoc_args ) { // phpcs:ignore PSR2.Methods.Metho * * ## OPTIONS * - * --type= + * [--type=] * : Field type. * --- * default: textbox @@ -88,7 +88,7 @@ public function list_( $args, $assoc_args ) { // phpcs:ignore PSR2.Methods.Metho * $ wp bp xprofile field create --type=checkbox --field-group-id=508 --name="Field Name" * Success: Created XProfile field "Field Name" (ID 24564). * - * $ wp bp xprofile field add --type=checkbox --field-group-id=165 --name="Another Field" + * $ wp bp xprofile field add --field-group-id=165 --name="Another Field" * Success: Created XProfile field "Another Field" (ID 5465). * * @alias add