diff options
Diffstat (limited to 'crates/shirabe-external-packages/src/symfony/console/command/dump_completion_command.rs')
| -rw-r--r-- | crates/shirabe-external-packages/src/symfony/console/command/dump_completion_command.rs | 248 |
1 files changed, 72 insertions, 176 deletions
diff --git a/crates/shirabe-external-packages/src/symfony/console/command/dump_completion_command.rs b/crates/shirabe-external-packages/src/symfony/console/command/dump_completion_command.rs index 9604c0a..c8947b8 100644 --- a/crates/shirabe-external-packages/src/symfony/console/command/dump_completion_command.rs +++ b/crates/shirabe-external-packages/src/symfony/console/command/dump_completion_command.rs @@ -1,6 +1,6 @@ //! ref: composer/vendor/symfony/console/Command/DumpCompletionCommand.php -use crate::symfony::console::command::command::{BaseCommand, Command}; +use crate::symfony::console::command::command::{Command, CommandData}; use crate::symfony::console::completion::completion_input::CompletionInput; use crate::symfony::console::completion::completion_suggestions::{ CompletionSuggestions, StringOrSuggestion, @@ -17,11 +17,11 @@ use std::rc::Rc; /// Dumps the completion script for the current shell. #[derive(Debug)] pub struct DumpCompletionCommand { - inner: BaseCommand, + inner: CommandData, } impl Deref for DumpCompletionCommand { - type Target = BaseCommand; + type Target = CommandData; fn deref(&self) -> &Self::Target { &self.inner @@ -38,6 +38,23 @@ impl DumpCompletionCommand { pub const DEFAULT_NAME: &'static str = "completion"; pub const DEFAULT_DESCRIPTION: &'static str = "Dump the shell completion script"; + pub fn new() -> Self { + let mut command = DumpCompletionCommand { + inner: CommandData::new(None), + }; + // PHP: static $defaultName = 'completion' / $defaultDescription, applied by the parent + // constructor before configure(). + command + .inner + .apply_default_name(Self::DEFAULT_NAME) + .expect("DumpCompletionCommand default name is valid"); + command.inner.set_description(Self::DEFAULT_DESCRIPTION); + command + .configure() + .expect("DumpCompletionCommand::configure uses static, valid metadata"); + command + } + pub fn complete_impl(&self, input: &CompletionInput, suggestions: &mut CompletionSuggestions) { if input.must_suggest_argument_values_for("shell") { suggestions.suggest_values( @@ -49,6 +66,45 @@ impl DumpCompletionCommand { } } + fn guess_shell() -> String { + shirabe_php_shim::basename(&shirabe_php_shim::server_shell().unwrap_or_default()) + } + + fn tail_debug_log(&self, command_name: &str, _output: &dyn OutputInterface) { + let debug_file = format!( + "{}/sf_{}.log", + shirabe_php_shim::sys_get_temp_dir(), + command_name + ); + if !shirabe_php_shim::file_exists(&debug_file) { + shirabe_php_shim::touch(&debug_file); + } + // TODO: Process::run() expects a `'static` callback, but the PHP closure captures + // `$output` by reference and writes each line to it. Bridging the borrowed `output` + // into a `'static` callback requires shared ownership of the output (Phase C). + todo!() + } + + fn get_supported_shells(&self) -> Vec<String> { + let mut shells = vec![]; + + // foreach (new \DirectoryIterator(__DIR__.'/../Resources/') as $file) + for file in shirabe_php_shim::directory_iterator(&format!( + "{}/../Resources/", + shirabe_php_shim::dir() + )) { + if shirabe_php_shim::str_starts_with(&file.get_basename(), "completion.") + && file.is_file() + { + shells.push(file.get_extension()); + } + } + + shells + } +} + +impl Command for DumpCompletionCommand { fn configure(&mut self) -> anyhow::Result<()> { let full_command = shirabe_php_shim::server_php_self(); let command_name = shirabe_php_shim::basename(&full_command); @@ -85,14 +141,14 @@ impl DumpCompletionCommand { Add this to the end of your shell configuration file (e.g. <info>\"~/.bashrc\"</>):\n\ \n\ \x20\x20\x20\x20<info>eval \"$({full_command} completion bash)\"</>", - )) - .add_argument( + )); + self.inner.add_argument( "shell", Some(InputArgument::OPTIONAL), "The shell type (e.g. \"bash\"), the value of the \"$SHELL\" env var will be used if this is not given", PhpMixed::Null, - )? - .add_option( + )?; + self.inner.add_option( "debug", PhpMixed::Null, Some(InputOption::VALUE_NONE), @@ -105,18 +161,18 @@ impl DumpCompletionCommand { fn execute( &mut self, - input: &mut dyn InputInterface, - output: &mut dyn OutputInterface, + input: Rc<RefCell<dyn InputInterface>>, + output: Rc<RefCell<dyn OutputInterface>>, ) -> anyhow::Result<i64> { let command_name = shirabe_php_shim::basename(&shirabe_php_shim::server_argv()[0]); - if input.get_option("debug")?.to_bool() { - self.tail_debug_log(&command_name, output); + if input.borrow().get_option("debug")?.to_bool() { + self.tail_debug_log(&command_name, &*output.borrow()); return Ok(0); } - let shell = match input.get_argument("shell")?.as_string() { + let shell = match input.borrow().get_argument("shell")?.as_string() { Some(s) => s.to_string(), None => Self::guess_shell(), }; @@ -132,7 +188,7 @@ impl DumpCompletionCommand { // : $output`. There is no way to test trait membership through `&dyn OutputInterface` // here; OutputInterface would need a downcast hook (Phase C). Writing to `output`. if !shell.is_empty() { - output.writeln( + output.borrow_mut().writeln( &[format!( "<error>Detected shell \"{}\", which is not supported by Symfony shell completion (supported shells: \"{}\").</>", shell, @@ -141,7 +197,7 @@ impl DumpCompletionCommand { output_interface::OUTPUT_NORMAL, ); } else { - output.writeln( + output.borrow_mut().writeln( &[format!( "<error>Shell not detected, Symfony shell completion only supports \"{}\").</>", supported_shells.join("\", \"") @@ -155,7 +211,7 @@ impl DumpCompletionCommand { let application = self.get_application().unwrap(); let version = application.borrow().get_version(); - output.write( + output.borrow_mut().write( &[shirabe_php_shim::str_replace_arrays( &[ "{{ COMMAND_NAME }}".to_string(), @@ -171,169 +227,9 @@ impl DumpCompletionCommand { Ok(0) } - fn guess_shell() -> String { - shirabe_php_shim::basename(&shirabe_php_shim::server_shell().unwrap_or_default()) - } - - fn tail_debug_log(&self, command_name: &str, _output: &dyn OutputInterface) { - let debug_file = format!( - "{}/sf_{}.log", - shirabe_php_shim::sys_get_temp_dir(), - command_name - ); - if !shirabe_php_shim::file_exists(&debug_file) { - shirabe_php_shim::touch(&debug_file); - } - // TODO: Process::run() expects a `'static` callback, but the PHP closure captures - // `$output` by reference and writes each line to it. Bridging the borrowed `output` - // into a `'static` callback requires shared ownership of the output (Phase C). - todo!() - } - - fn get_supported_shells(&self) -> Vec<String> { - let mut shells = vec![]; - - // foreach (new \DirectoryIterator(__DIR__.'/../Resources/') as $file) - for file in shirabe_php_shim::directory_iterator(&format!( - "{}/../Resources/", - shirabe_php_shim::dir() - )) { - if shirabe_php_shim::str_starts_with(&file.get_basename(), "completion.") - && file.is_file() - { - shells.push(file.get_extension()); - } - } - - shells - } -} - -impl Command for DumpCompletionCommand { - fn configure(&mut self) { - let _ = DumpCompletionCommand::configure(self); - } - - fn run( - &mut self, - input: &mut dyn InputInterface, - output: &mut dyn OutputInterface, - ) -> anyhow::Result<i64> { - self.inner.run(input, output) - } - fn complete(&self, input: &CompletionInput, suggestions: &mut CompletionSuggestions) { self.complete_impl(input, suggestions); } - fn is_enabled(&self) -> bool { - self.inner.is_enabled() - } - - fn set_application( - &mut self, - application: Option<Rc<RefCell<dyn crate::symfony::console::application::Application>>>, - ) { - self.inner.set_application(application); - } - - fn get_application( - &self, - ) -> Option<Rc<RefCell<dyn crate::symfony::console::application::Application>>> { - self.inner.get_application() - } - - fn set_helper_set( - &mut self, - helper_set: Rc<RefCell<crate::symfony::console::helper::helper_set::HelperSet>>, - ) { - self.inner.set_helper_set(helper_set); - } - - fn get_helper_set( - &self, - ) -> Option<Rc<RefCell<crate::symfony::console::helper::helper_set::HelperSet>>> { - self.inner.get_helper_set() - } - - fn merge_application_definition(&mut self, merge_args: bool) { - self.inner.merge_application_definition(merge_args); - } - - fn get_definition(&self) -> &crate::symfony::console::input::input_definition::InputDefinition { - self.inner.get_definition() - } - - fn get_native_definition( - &self, - ) -> &crate::symfony::console::input::input_definition::InputDefinition { - self.inner.get_native_definition() - } - - fn set_name(&mut self, name: &str) -> anyhow::Result<()> { - self.inner.set_name(name)?; - Ok(()) - } - - fn get_name(&self) -> Option<String> { - self.inner.get_name() - } - - fn set_hidden(&mut self, hidden: bool) { - self.inner.set_hidden(hidden); - } - - fn is_hidden(&self) -> bool { - self.inner.is_hidden() - } - - fn set_description(&mut self, description: &str) { - self.inner.set_description(description); - } - - fn get_description(&self) -> String { - self.inner.get_description() - } - - fn set_help(&mut self, help: &str) { - self.inner.set_help(help); - } - - fn get_help(&self) -> String { - self.inner.get_help() - } - - fn get_processed_help(&self) -> String { - self.inner.get_processed_help() - } - - fn set_aliases(&mut self, aliases: Vec<String>) -> anyhow::Result<()> { - self.inner.set_aliases(aliases)?; - Ok(()) - } - - fn get_aliases(&self) -> Vec<String> { - self.inner.get_aliases() - } - - fn get_synopsis(&mut self, short: bool) -> String { - self.inner.get_synopsis(short) - } - - fn get_usages(&self) -> Vec<String> { - self.inner.get_usages() - } - - fn get_helper( - &self, - name: &str, - ) -> anyhow::Result< - Result<PhpMixed, crate::symfony::console::exception::logic_exception::LogicException>, - > { - self.inner.get_helper(name) - } - - fn ignore_validation_errors(&mut self) { - self.inner.ignore_validation_errors(); - } + crate::delegate_command_trait_impls_to_inner!(inner); } |
