From 3ab879836093f2cb028b93e9c436209fd4c11ea5 Mon Sep 17 00:00:00 2001 From: Brian Henry Date: Tue, 2 Jul 2024 18:18:45 -0700 Subject: [PATCH] Add `wp handbook gen-custom` --- bin/command.php | 96 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/bin/command.php b/bin/command.php index c10f9ae1..0e84a256 100644 --- a/bin/command.php +++ b/bin/command.php @@ -16,6 +16,8 @@ /** * @when before_wp_load + * + * @phpstan-type Command_Array array{name:string, description:string, longdesc:string, subcommands?:array, synopsis?:string, hook?:string} */ class Command { @@ -382,7 +384,17 @@ public function api_dump() { echo json_encode( $apis ); } - private static function gen_cmd_pages( $cmd, $parent = [], $verbose = false ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.parentFound + /** + * Generate and save markdown documentation for the provided command and its sub-commands. + * + * @param Command_Array $cmd Command details as array. + * @param string[] $parent The breadcrumb of parent commands. + * @param bool $verbose Whether to output the command page as it is generated. + * @param ?string $output_dir The directory to output the generated command pages, null for default `../commands`. + * @return void + */ + private static function gen_cmd_pages( $cmd, $parent = [], $verbose = false, ?string $output_dir = null ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.parentFound + $parent[] = $cmd['name']; static $params; @@ -516,7 +528,7 @@ private static function gen_cmd_pages( $cmd, $parent = [], $verbose = false ) { $binding['docs'] = $docs; } - $path = dirname( __DIR__ ) . '/commands/' . $binding['path']; + $path = ( $output_dir ?? dirname( __DIR__ ) . '/commands' ) . '/' . $binding['path']; if ( ! is_dir( dirname( $path ) ) ) { mkdir( dirname( $path ) ); } @@ -530,7 +542,7 @@ private static function gen_cmd_pages( $cmd, $parent = [], $verbose = false ) { } foreach ( $cmd['subcommands'] as $subcmd ) { - self::gen_cmd_pages( $subcmd, $parent, $verbose ); + self::gen_cmd_pages( $subcmd, $parent, $verbose, $output_dir ); } } @@ -674,6 +686,84 @@ private static function empty_dir( $dir ) { } WP_CLI::log( sprintf( "Removed existing contents of '%s'", $dir ) ); } + + /** + * Generate the documentation page for a custom command using the same templates as the official WP-CLI commands. + * + * ## OPTIONS + * + * + * : The custom WP CLI command to generate the documentation for. + * + * [--output_dir=] + * : Directory in which to save the documentation. + * --- + * default: ./docs/wp-cli + * --- + * + * [--verbose] + * : If set will list command pages as they are generated. + * + * @subcommand gen-custom + * + * @when after_wp_load + * + * @param string[] $args + * @param array $assoc_args + * @return void + */ + public function gen_custom_cmd_pages( $args, $assoc_args ) { + + $command_name = $args[0]; + + $output_dir = Utils\is_path_absolute( $assoc_args['output_dir'] ) + ? $assoc_args['output_dir'] + : getcwd() . '/' . $assoc_args['output_dir']; + + if ( ! is_dir( $output_dir ) ) { + mkdir( $output_dir, 0777, true ); + } + + $verbose = Utils\get_flag_value( $assoc_args, 'verbose', false ); + + /** + * Get all registered WP-CLI commands. + * + * @see \CLI_Command::cmd_dump() + * + * @var array{name:string,description:string,longdesc:string,subcommands:array} $all_commands + */ + $all_commands = WP_CLI::runcommand( + 'cli cmd-dump', + [ + 'launch' => false, + 'return' => 'stdout', + 'parse' => 'json', + ] + ); + + /** + * Filter the list of WP-CLI commands to find one matching the name passed as an argument to this command. + * + * @var array $my_commands + */ + $my_commands = array_values( + array_filter( + $all_commands['subcommands'], + function ( array $command ) use ( $command_name ): bool { + return $command['name'] === $command_name; + } + ) + ); + + if ( empty( $my_commands ) ) { + WP_CLI::error( "Failed to find command '{$command_name}'." ); + } + + self::gen_cmd_pages( $my_commands[0], [], $verbose, $output_dir ); + + WP_CLI::success( "Generated command pages for '{$command_name}'." ); + } } WP_CLI::add_command( 'handbook', '\WP_CLI\Handbook\Command' );