From 0800c90a7ec0bc7a3d4c13063dfe6d2298a557bc Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 19 Aug 2026 23:45:37 +0900 Subject: fix(input): thread a typed InputValue through the input layer Options and arguments were stored and passed as PhpMixed even though Symfony only ever puts a string, a bool, a list of strings or null in one. get_option already narrowed to InputOptionValue at the boundary; this widens that enum into InputValue and pushes it through InputInterface, InputOption/InputArgument defaults, the Input storage, ArgvInput/ArrayInput/StringInput/CompletionInput, Command::add_option and add_argument, and the Composer-side wrappers. Two neighbouring string|int unions get types of their own: InputDefinition::{get_argument,has_argument} take an ArgumentName, and ArrayInput keys its parameters by ParameterName. has_parameter_option and get_parameter_option take the values they look for as &[&str], which is what PHP's `(array) $values` cast produced anyway. Two behaviours change along the way. Input::set_option on a negated option now negates with PHP's loose bool cast rather than treating a non-bool as false, matching `!$value`. ArrayInput::parse now resolves an integer key to an argument position instead of looking up an argument literally named "0". Co-Authored-By: Claude Opus 5 (1M context) --- .../shirabe-symfony-console/src/command/command.rs | 13 +- .../src/command/complete_command.rs | 17 +- .../src/command/dump_completion_command.rs | 7 +- .../src/command/help_command.rs | 15 +- .../src/command/list_command.rs | 19 +- .../src/completion/completion_input.rs | 34 ++- .../src/descriptor/json_descriptor.rs | 23 +- .../src/descriptor/markdown_descriptor.rs | 4 +- .../src/descriptor/text_descriptor.rs | 20 +- .../src/descriptor/xml_descriptor.rs | 18 +- crates/shirabe-symfony-console/src/input.rs | 2 + .../src/input/argv_input.rs | 153 ++++++----- .../src/input/array_input.rs | 167 ++++++------ crates/shirabe-symfony-console/src/input/input.rs | 47 ++-- .../src/input/input_argument.rs | 18 +- .../src/input/input_definition.rs | 53 ++-- .../src/input/input_interface.rs | 23 +- .../src/input/input_option.rs | 138 ++-------- .../src/input/input_value.rs | 146 +++++++++++ .../src/input/string_input.rs | 24 +- crates/shirabe/src/command/archive_command.rs | 2 +- crates/shirabe/src/command/audit_command.rs | 7 +- crates/shirabe/src/command/base_command.rs | 40 ++- crates/shirabe/src/command/bump_command.rs | 12 +- .../src/command/check_platform_reqs_command.rs | 5 +- crates/shirabe/src/command/config_command.rs | 22 +- .../shirabe/src/command/create_project_command.rs | 14 +- crates/shirabe/src/command/depends_command.rs | 4 +- .../shirabe/src/command/dump_autoload_command.rs | 6 +- crates/shirabe/src/command/exec_command.rs | 18 +- crates/shirabe/src/command/fund_command.rs | 5 +- crates/shirabe/src/command/global_command.rs | 2 +- crates/shirabe/src/command/home_command.rs | 12 +- crates/shirabe/src/command/init_command.rs | 70 +++--- crates/shirabe/src/command/install_command.rs | 20 +- crates/shirabe/src/command/licenses_command.rs | 5 +- crates/shirabe/src/command/outdated_command.rs | 73 +++--- crates/shirabe/src/command/prohibits_command.rs | 4 +- crates/shirabe/src/command/reinstall_command.rs | 14 +- crates/shirabe/src/command/remove_command.rs | 25 +- crates/shirabe/src/command/repository_command.rs | 11 +- crates/shirabe/src/command/require_command.rs | 37 ++- crates/shirabe/src/command/run_script_command.rs | 15 +- crates/shirabe/src/command/script_alias_command.rs | 8 +- crates/shirabe/src/command/search_command.rs | 19 +- crates/shirabe/src/command/self_update_command.rs | 4 +- crates/shirabe/src/command/show_command.rs | 17 +- crates/shirabe/src/command/status_command.rs | 2 +- crates/shirabe/src/command/suggests_command.rs | 14 +- crates/shirabe/src/command/update_command.rs | 35 ++- crates/shirabe/src/command/validate_command.rs | 2 +- crates/shirabe/src/console/application.rs | 195 +++++--------- crates/shirabe/src/console/input/input_argument.rs | 8 +- crates/shirabe/src/console/input/input_option.rs | 16 +- crates/shirabe/src/plugin/php_plugin_proxy.rs | 14 +- crates/shirabe/tests/application_test.rs | 21 +- crates/shirabe/tests/command/about_command_test.rs | 5 +- .../shirabe/tests/command/archive_command_test.rs | 4 +- crates/shirabe/tests/command/audit_command_test.rs | 17 +- .../tests/command/base_dependency_command_test.rs | 116 +++++---- crates/shirabe/tests/command/bump_command_test.rs | 28 +-- .../command/check_platform_reqs_command_test.rs | 27 +- .../tests/command/clear_cache_command_test.rs | 22 +- .../shirabe/tests/command/config_command_test.rs | 32 +-- .../shirabe/tests/command/diagnose_command_test.rs | 7 +- .../tests/command/dump_autoload_command_test.rs | 91 +++++-- crates/shirabe/tests/command/exec_command_test.rs | 11 +- crates/shirabe/tests/command/fund_command_test.rs | 12 +- .../shirabe/tests/command/global_command_test.rs | 62 +++-- crates/shirabe/tests/command/home_command_test.rs | 25 +- crates/shirabe/tests/command/init_command_test.rs | 29 ++- .../shirabe/tests/command/install_command_test.rs | 33 +-- .../shirabe/tests/command/licenses_command_test.rs | 35 +-- .../tests/command/reinstall_command_test.rs | 27 +- .../shirabe/tests/command/remove_command_test.rs | 139 +++++----- .../tests/command/repository_command_test.rs | 189 +++++++------- .../shirabe/tests/command/require_command_test.rs | 69 ++--- .../tests/command/run_script_command_test.rs | 46 ++-- .../shirabe/tests/command/search_command_test.rs | 67 ++--- .../tests/command/self_update_command_test.rs | 9 +- crates/shirabe/tests/command/show_command_test.rs | 280 +++++++++++---------- .../shirabe/tests/command/status_command_test.rs | 17 +- .../shirabe/tests/command/suggests_command_test.rs | 19 +- .../shirabe/tests/command/update_command_test.rs | 110 ++++---- .../shirabe/tests/command/validate_command_test.rs | 14 +- crates/shirabe/tests/common/test_case.rs | 6 +- crates/shirabe/tests/installer_test.rs | 37 ++- .../question/strict_confirmation_question_test.rs | 6 +- 88 files changed, 1705 insertions(+), 1605 deletions(-) create mode 100644 crates/shirabe-symfony-console/src/input/input_value.rs diff --git a/crates/shirabe-symfony-console/src/command/command.rs b/crates/shirabe-symfony-console/src/command/command.rs index 27966ec1..3fd39bc4 100644 --- a/crates/shirabe-symfony-console/src/command/command.rs +++ b/crates/shirabe-symfony-console/src/command/command.rs @@ -9,6 +9,7 @@ use crate::input::InputArgument; use crate::input::InputDefinition; use crate::input::InputInterface; use crate::input::InputOption; +use crate::input::InputValue; use crate::output::OutputInterface; use indexmap::IndexMap; use shirabe_php_shim::{PhpMixed, php_regex, preg_is_match}; @@ -148,7 +149,7 @@ impl CommandData { name: &str, mode: Option, description: &str, - default: PhpMixed, + default: InputValue, ) -> anyhow::Result<&Self> { self.definition .borrow_mut() @@ -178,10 +179,10 @@ impl CommandData { pub fn add_option( &self, name: &str, - shortcut: PhpMixed, + shortcut: Option<&str>, mode: Option, description: &str, - default: PhpMixed, + default: InputValue, ) -> anyhow::Result<&Self> { self.definition .borrow_mut() @@ -189,7 +190,7 @@ impl CommandData { .unwrap() .add_option(InputOption::new( name, - shortcut.clone(), + shortcut, mode, description.to_string(), default.clone(), @@ -403,12 +404,12 @@ pub trait Command: std::fmt::Debug + shirabe_php_shim::AsAny + shirabe_php_shim: // It would fail the validation if we didn't make sure the command argument is present, // since it's required by the application. if input.borrow().has_argument("command") - && matches!(input.borrow().get_argument("command")?, PhpMixed::Null) + && input.borrow().get_argument("command")?.is_null() { let name = self.get_name(); input .borrow_mut() - .set_argument("command", PhpMixed::from(name))?; + .set_argument("command", InputValue::from(name))?; } input.borrow_mut().validate()?; diff --git a/crates/shirabe-symfony-console/src/command/complete_command.rs b/crates/shirabe-symfony-console/src/command/complete_command.rs index 432888b6..2f540f42 100644 --- a/crates/shirabe-symfony-console/src/command/complete_command.rs +++ b/crates/shirabe-symfony-console/src/command/complete_command.rs @@ -7,6 +7,7 @@ use crate::completion::CompletionOutputInterface; use crate::completion::{CompletionSuggestions, StringOrSuggestion}; use crate::input::InputInterface; use crate::input::InputOption; +use crate::input::InputValue; use crate::output::OutputInterface; use indexmap::IndexMap; use shirabe_php_shim::{PhpMixed, impl_php_class}; @@ -191,31 +192,31 @@ impl Command for CompleteCommand { self.inner .add_option( "shell", - PhpMixed::from("s".to_string()), + Some("s"), Some(InputOption::VALUE_REQUIRED), &format!("The shell type (\"{}\")", shells), - PhpMixed::Null, + InputValue::Null, )? .add_option( "input", - PhpMixed::from("i".to_string()), + Some("i"), Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "An array of input tokens (e.g. COMP_WORDS or argv)", - PhpMixed::Null, + InputValue::Null, )? .add_option( "current", - PhpMixed::from("c".to_string()), + Some("c"), Some(InputOption::VALUE_REQUIRED), "The index of the \"input\" array that the cursor is in (e.g. COMP_CWORD)", - PhpMixed::Null, + InputValue::Null, )? .add_option( "symfony", - PhpMixed::from("S".to_string()), + Some("S"), Some(InputOption::VALUE_REQUIRED), "The version of the completion script", - PhpMixed::Null, + InputValue::Null, )?; Ok(()) diff --git a/crates/shirabe-symfony-console/src/command/dump_completion_command.rs b/crates/shirabe-symfony-console/src/command/dump_completion_command.rs index 4db6c233..49a66f6d 100644 --- a/crates/shirabe-symfony-console/src/command/dump_completion_command.rs +++ b/crates/shirabe-symfony-console/src/command/dump_completion_command.rs @@ -6,6 +6,7 @@ use crate::completion::{CompletionSuggestions, StringOrSuggestion}; use crate::input::InputArgument; use crate::input::InputInterface; use crate::input::InputOption; +use crate::input::InputValue; use crate::output::OutputInterface; use crate::output::output_interface; use shirabe_php_shim::{PhpMixed, impl_php_class}; @@ -189,14 +190,14 @@ impl Command for DumpCompletionCommand { "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, + InputValue::Null, )?; self.inner.add_option( "debug", - PhpMixed::Null, + None, Some(InputOption::VALUE_NONE), "Tail the completion debug log", - PhpMixed::Null, + InputValue::Null, )?; Ok(()) diff --git a/crates/shirabe-symfony-console/src/command/help_command.rs b/crates/shirabe-symfony-console/src/command/help_command.rs index 2081e0e1..4d8f7dbd 100644 --- a/crates/shirabe-symfony-console/src/command/help_command.rs +++ b/crates/shirabe-symfony-console/src/command/help_command.rs @@ -10,8 +10,9 @@ use crate::input::DefinitionItem; use crate::input::InputArgument; use crate::input::InputInterface; use crate::input::InputOption; +use crate::input::InputValue; use crate::output::OutputInterface; -use shirabe_php_shim::{PhpMixed, impl_php_class}; +use shirabe_php_shim::impl_php_class; use std::ops::{Deref, DerefMut}; /// HelpCommand displays the help for a given command. @@ -101,21 +102,21 @@ impl Command for HelpCommand { "command_name".to_string(), Some(InputArgument::OPTIONAL), "The command name".to_string(), - PhpMixed::from("help".to_string()), + InputValue::from("help".to_string()), )?), DefinitionItem::InputOption(InputOption::new( "format", - PhpMixed::Null, + None, Some(InputOption::VALUE_REQUIRED), "The output format (txt, xml, json, or md)".to_string(), - PhpMixed::from("txt".to_string()), + InputValue::from("txt".to_string()), )?), DefinitionItem::InputOption(InputOption::new( "raw", - PhpMixed::Null, + None, Some(InputOption::VALUE_NONE), "To output raw command help".to_string(), - PhpMixed::Null, + InputValue::Null, )?), ])); self.inner.set_description("Display help for a command"); @@ -141,7 +142,7 @@ impl Command for HelpCommand { ) -> anyhow::Result { if self.command.borrow().is_none() { let application = self.get_application().unwrap(); - let command_name = input.borrow().get_argument("command_name")?.to_string(); + let command_name = input.borrow().get_argument("command_name")?.to_php_string(); let found = application.borrow_mut().find(&command_name)?; *self.command.borrow_mut() = Some(found); } diff --git a/crates/shirabe-symfony-console/src/command/list_command.rs b/crates/shirabe-symfony-console/src/command/list_command.rs index 6074b49a..08faea71 100644 --- a/crates/shirabe-symfony-console/src/command/list_command.rs +++ b/crates/shirabe-symfony-console/src/command/list_command.rs @@ -10,8 +10,9 @@ use crate::input::DefinitionItem; use crate::input::InputArgument; use crate::input::InputInterface; use crate::input::InputOption; +use crate::input::InputValue; use crate::output::OutputInterface; -use shirabe_php_shim::{PhpMixed, impl_php_class}; +use shirabe_php_shim::impl_php_class; use std::ops::{Deref, DerefMut}; /// ListCommand displays the list of all available commands for the application. @@ -93,28 +94,28 @@ impl Command for ListCommand { "namespace".to_string(), Some(InputArgument::OPTIONAL), "The namespace name".to_string(), - PhpMixed::Null, + InputValue::Null, )?), DefinitionItem::InputOption(InputOption::new( "raw", - PhpMixed::Null, + None, Some(InputOption::VALUE_NONE), "To output raw command list".to_string(), - PhpMixed::Null, + InputValue::Null, )?), DefinitionItem::InputOption(InputOption::new( "format", - PhpMixed::Null, + None, Some(InputOption::VALUE_REQUIRED), "The output format (txt, xml, json, or md)".to_string(), - PhpMixed::from("txt".to_string()), + InputValue::from("txt".to_string()), )?), DefinitionItem::InputOption(InputOption::new( "short", - PhpMixed::Null, + None, Some(InputOption::VALUE_NONE), "To skip describing commands' arguments".to_string(), - PhpMixed::Null, + InputValue::Null, )?), ])); self.inner.set_description("List commands"); @@ -157,7 +158,7 @@ impl Command for ListCommand { ); options.insert( "namespace".to_string(), - input.borrow().get_argument("namespace")?, + input.borrow().get_argument("namespace")?.into(), ); options.insert( "short".to_string(), diff --git a/crates/shirabe-symfony-console/src/completion/completion_input.rs b/crates/shirabe-symfony-console/src/completion/completion_input.rs index c667ef60..419e6e80 100644 --- a/crates/shirabe-symfony-console/src/completion/completion_input.rs +++ b/crates/shirabe-symfony-console/src/completion/completion_input.rs @@ -3,7 +3,8 @@ use crate::input::ArgvInput; use crate::input::InputDefinition; use crate::input::InputOption; -use shirabe_php_shim::{PhpMixed, php_regex, preg_match_all}; +use crate::input::InputValue; +use shirabe_php_shim::{php_regex, preg_match_all}; /// An input specialized for shell completion. /// @@ -148,13 +149,10 @@ impl CompletionInput { let argument_value = self.inner.inner.arguments[¤t_argument_name].clone(); self.completion_name = Some(current_argument_name.clone()); - if let PhpMixed::List(argument_value) = &argument_value { - self.completion_value = argument_value - .last() - .map(|v| v.to_string()) - .unwrap_or_default(); + if let InputValue::Array(argument_value) = &argument_value { + self.completion_value = argument_value.last().cloned().unwrap_or_default(); } else { - self.completion_value = argument_value.to_string(); + self.completion_value = argument_value.to_php_string(); } } @@ -165,7 +163,7 @@ impl CompletionInput { .inner .inner .definition - .get_argument(&PhpMixed::String(argument_name.clone())) + .get_argument(&crate::input::ArgumentName::of(&argument_name)) .unwrap() .is_array() { @@ -304,16 +302,16 @@ impl crate::input::InputInterface for CompletionInput { self.to_string() } - fn has_parameter_option(&self, values: PhpMixed, only_params: bool) -> bool { + fn has_parameter_option(&self, values: &[&str], only_params: bool) -> bool { crate::input::InputInterface::has_parameter_option(&self.inner, values, only_params) } fn get_parameter_option( &self, - values: PhpMixed, - default: PhpMixed, + values: &[&str], + default: InputValue, only_params: bool, - ) -> PhpMixed { + ) -> InputValue { crate::input::InputInterface::get_parameter_option( &self.inner, values, @@ -330,15 +328,15 @@ impl crate::input::InputInterface for CompletionInput { crate::input::InputInterface::validate(&mut self.inner) } - fn get_arguments(&self) -> indexmap::IndexMap { + fn get_arguments(&self) -> indexmap::IndexMap { crate::input::InputInterface::get_arguments(&self.inner) } - fn get_argument(&self, name: &str) -> anyhow::Result { + fn get_argument(&self, name: &str) -> anyhow::Result { crate::input::InputInterface::get_argument(&self.inner, name) } - fn set_argument(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { + fn set_argument(&mut self, name: &str, value: InputValue) -> anyhow::Result<()> { crate::input::InputInterface::set_argument(&mut self.inner, name, value) } @@ -346,15 +344,15 @@ impl crate::input::InputInterface for CompletionInput { crate::input::InputInterface::has_argument(&self.inner, name) } - fn get_options(&self) -> indexmap::IndexMap { + fn get_options(&self) -> indexmap::IndexMap { crate::input::InputInterface::get_options(&self.inner) } - fn get_option(&self, name: &str) -> anyhow::Result { + fn get_option(&self, name: &str) -> anyhow::Result { crate::input::InputInterface::get_option(&self.inner, name) } - fn set_option(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { + fn set_option(&mut self, name: &str, value: InputValue) -> anyhow::Result<()> { crate::input::InputInterface::set_option(&mut self.inner, name, value) } diff --git a/crates/shirabe-symfony-console/src/descriptor/json_descriptor.rs b/crates/shirabe-symfony-console/src/descriptor/json_descriptor.rs index 53941663..97c1c4f1 100644 --- a/crates/shirabe-symfony-console/src/descriptor/json_descriptor.rs +++ b/crates/shirabe-symfony-console/src/descriptor/json_descriptor.rs @@ -165,14 +165,9 @@ impl JsonDescriptor { argument.get_description(), )), ); - data.insert( - "default".to_string(), - if matches!(argument.get_default(), PhpMixed::Float(f) if f.is_infinite() && *f > 0.0) { - PhpMixed::String("INF".to_string()) - } else { - argument.get_default().clone() - }, - ); + // TODO(type-model): PHP compares the default against `INF` and serializes it as the + // string "INF"; `InputValue` has no float variant to hold one. + data.insert("default".to_string(), argument.get_default().clone().into()); Ok(data) } @@ -226,15 +221,9 @@ impl JsonDescriptor { option.get_description(), )), ); - data.insert( - "default".to_string(), - if matches!(option.get_default(), PhpMixed::Float(f) if f.is_infinite() && *f > 0.0) - { - PhpMixed::String("INF".to_string()) - } else { - option.get_default().clone() - }, - ); + // TODO(type-model): PHP compares the default against `INF` and serializes it as the + // string "INF"; `InputValue` has no float variant to hold one. + data.insert("default".to_string(), option.get_default().clone().into()); } Ok(data) } diff --git a/crates/shirabe-symfony-console/src/descriptor/markdown_descriptor.rs b/crates/shirabe-symfony-console/src/descriptor/markdown_descriptor.rs index d6285468..f7b3cd71 100644 --- a/crates/shirabe-symfony-console/src/descriptor/markdown_descriptor.rs +++ b/crates/shirabe-symfony-console/src/descriptor/markdown_descriptor.rs @@ -64,7 +64,7 @@ impl MarkdownDescriptor { shirabe_php_shim::str_replace( "\n", "", - &shirabe_php_shim::var_export(argument.get_default(), true), + &shirabe_php_shim::var_export(&argument.get_default().to_php_mixed(), true), ), ), true, @@ -104,7 +104,7 @@ impl MarkdownDescriptor { shirabe_php_shim::str_replace( "\n", "", - &shirabe_php_shim::var_export(option.get_default(), true), + &shirabe_php_shim::var_export(&option.get_default().to_php_mixed(), true), ), ), true, diff --git a/crates/shirabe-symfony-console/src/descriptor/text_descriptor.rs b/crates/shirabe-symfony-console/src/descriptor/text_descriptor.rs index 8783ef5e..c15cdebb 100644 --- a/crates/shirabe-symfony-console/src/descriptor/text_descriptor.rs +++ b/crates/shirabe-symfony-console/src/descriptor/text_descriptor.rs @@ -36,15 +36,14 @@ impl TextDescriptor { argument: &InputArgument, options: IndexMap, ) -> anyhow::Result<()> { - let default = if !argument.get_default().is_null() - && (!matches!( - argument.get_default(), - PhpMixed::List(_) | PhpMixed::Array(_) - ) || shirabe_php_shim::count(argument.get_default()) != 0) + let default_value = argument.get_default().to_php_mixed(); + let default = if !default_value.is_null() + && (!matches!(default_value, PhpMixed::List(_) | PhpMixed::Array(_)) + || shirabe_php_shim::count(&default_value) != 0) { format!( " [default: {}]", - self.format_default_value(argument.get_default())? + self.format_default_value(&default_value)? ) } else { String::new() @@ -82,14 +81,15 @@ impl TextDescriptor { option: &InputOption, options: IndexMap, ) -> anyhow::Result<()> { + let default_value = option.get_default().to_php_mixed(); let default = if option.accept_value() - && !option.get_default().is_null() - && (!matches!(option.get_default(), PhpMixed::List(_) | PhpMixed::Array(_)) - || shirabe_php_shim::count(option.get_default()) != 0) + && !default_value.is_null() + && (!matches!(default_value, PhpMixed::List(_) | PhpMixed::Array(_)) + || shirabe_php_shim::count(&default_value) != 0) { format!( " [default: {}]", - self.format_default_value(option.get_default())? + self.format_default_value(&default_value)? ) } else { String::new() diff --git a/crates/shirabe-symfony-console/src/descriptor/xml_descriptor.rs b/crates/shirabe-symfony-console/src/descriptor/xml_descriptor.rs index 1a001b22..0b74fe3a 100644 --- a/crates/shirabe-symfony-console/src/descriptor/xml_descriptor.rs +++ b/crates/shirabe-symfony-console/src/descriptor/xml_descriptor.rs @@ -233,13 +233,14 @@ impl XmlDescriptor { description_xml.append_child(dom.create_text_node(argument.get_description())); let defaults_xml = object_xml.append_child(dom.create_element("defaults")); - let defaults: Vec = match argument.get_default() { + let default_value = argument.get_default().to_php_mixed(); + let defaults: Vec = match &default_value { PhpMixed::List(_) | PhpMixed::Array(_) => { - self.default_values_as_strings(argument.get_default()) + self.default_values_as_strings(&default_value) } - PhpMixed::Bool(_) => vec![shirabe_php_shim::var_export(argument.get_default(), true)], + PhpMixed::Bool(_) => vec![shirabe_php_shim::var_export(&default_value, true)], d if shirabe_php_shim::php_truthy(d) => { - vec![shirabe_php_shim::php_to_string(argument.get_default())] + vec![shirabe_php_shim::php_to_string(&default_value)] } _ => vec![], }; @@ -294,13 +295,14 @@ impl XmlDescriptor { description_xml.append_child(dom.create_text_node(option.get_description())); if option.accept_value() { - let defaults: Vec = match option.get_default() { + let default_value = option.get_default().to_php_mixed(); + let defaults: Vec = match &default_value { PhpMixed::List(_) | PhpMixed::Array(_) => { - self.default_values_as_strings(option.get_default()) + self.default_values_as_strings(&default_value) } - PhpMixed::Bool(_) => vec![shirabe_php_shim::var_export(option.get_default(), true)], + PhpMixed::Bool(_) => vec![shirabe_php_shim::var_export(&default_value, true)], d if shirabe_php_shim::php_truthy(d) => { - vec![shirabe_php_shim::php_to_string(option.get_default())] + vec![shirabe_php_shim::php_to_string(&default_value)] } _ => vec![], }; diff --git a/crates/shirabe-symfony-console/src/input.rs b/crates/shirabe-symfony-console/src/input.rs index f05188fe..c09e590f 100644 --- a/crates/shirabe-symfony-console/src/input.rs +++ b/crates/shirabe-symfony-console/src/input.rs @@ -6,6 +6,7 @@ mod input_aware_interface; mod input_definition; mod input_interface; mod input_option; +mod input_value; mod streamable_input_interface; mod string_input; @@ -17,5 +18,6 @@ pub use input_aware_interface::*; pub use input_definition::*; pub use input_interface::*; pub use input_option::*; +pub use input_value::*; pub use streamable_input_interface::*; pub use string_input::*; diff --git a/crates/shirabe-symfony-console/src/input/argv_input.rs b/crates/shirabe-symfony-console/src/input/argv_input.rs index 6138c195..a0f1d4d3 100644 --- a/crates/shirabe-symfony-console/src/input/argv_input.rs +++ b/crates/shirabe-symfony-console/src/input/argv_input.rs @@ -1,13 +1,14 @@ //! ref: composer/vendor/symfony/console/Input/ArgvInput.php use crate::exception::RuntimeException; +use crate::input::ArgumentName; use crate::input::Input; use crate::input::InputDefinition; use crate::input::InputInterface; -use crate::input::InputOptionValue; +use crate::input::InputValue; use crate::input::StreamableInputInterface; use indexmap::IndexMap; -use shirabe_php_shim::{PhpMixed, php_regex, preg_match}; +use shirabe_php_shim::{php_regex, preg_match}; /// ArgvInput represents an input coming from the CLI arguments. /// @@ -144,13 +145,13 @@ impl ArgvInput { // an option with a value (with no space) self.add_short_option( &first, - PhpMixed::String(shirabe_php_shim::substr(&name, 1, None)), + InputValue::String(shirabe_php_shim::substr(&name, 1, None)), )?; } else { self.parse_short_option_set(&name)?; } } else { - self.add_short_option(&name, PhpMixed::Null)?; + self.add_short_option(&name, InputValue::Null)?; } Ok(()) @@ -180,15 +181,15 @@ impl ArgvInput { let option = self.inner.definition.get_option_for_shortcut(&name_i)?; if option.accept_value() { let value = if i == len - 1 { - PhpMixed::Null + InputValue::Null } else { - PhpMixed::String(shirabe_php_shim::substr(name, i + 1, None)) + InputValue::String(shirabe_php_shim::substr(name, i + 1, None)) }; self.add_long_option(option.get_name(), value)?; break; } else { - self.add_long_option(option.get_name(), PhpMixed::Null)?; + self.add_long_option(option.get_name(), InputValue::Null)?; } i += 1; } @@ -209,11 +210,11 @@ impl ArgvInput { } self.add_long_option( &shirabe_php_shim::substr(&name, 0, Some(pos)), - PhpMixed::String(value), + InputValue::String(value), )?; } None => { - self.add_long_option(&name, PhpMixed::Null)?; + self.add_long_option(&name, InputValue::Null)?; } } @@ -225,34 +226,47 @@ impl ArgvInput { let c = self.inner.arguments.len() as i64; // if input is expecting another argument, add it - if self.inner.definition.has_argument(&PhpMixed::Int(c)) { - let arg = self.inner.definition.get_argument(&PhpMixed::Int(c))?; + if self + .inner + .definition + .has_argument(&ArgumentName::Position(c)) + { + let arg = self + .inner + .definition + .get_argument(&ArgumentName::Position(c))?; let value = if arg.is_array() { - PhpMixed::List(vec![PhpMixed::String(token.to_string())]) + InputValue::Array(vec![token.to_string()]) } else { - PhpMixed::String(token.to_string()) + InputValue::String(token.to_string()) }; self.inner .arguments .insert(arg.get_name().to_string(), value); // if last argument isArray(), append token to last argument - } else if self.inner.definition.has_argument(&PhpMixed::Int(c - 1)) + } else if self + .inner + .definition + .has_argument(&ArgumentName::Position(c - 1)) && self .inner .definition - .get_argument(&PhpMixed::Int(c - 1))? + .get_argument(&ArgumentName::Position(c - 1))? .is_array() { - let arg = self.inner.definition.get_argument(&PhpMixed::Int(c - 1))?; - if let Some(PhpMixed::List(list)) = self.inner.arguments.get_mut(arg.get_name()) { - list.push(PhpMixed::String(token.to_string())); + let arg = self + .inner + .definition + .get_argument(&ArgumentName::Position(c - 1))?; + if let Some(InputValue::Array(list)) = self.inner.arguments.get_mut(arg.get_name()) { + list.push(token.to_string()); } // unexpected argument } else { let mut all = self.inner.definition.get_arguments().clone(); - let mut symfony_command_name: Option = None; + let mut symfony_command_name: Option = None; let first_key = all.keys().next().cloned(); if let Some(key) = &first_key { let input_argument = &all[key]; @@ -265,12 +279,10 @@ impl ArgvInput { let message = if !all.is_empty() { let names: Vec = all.keys().cloned().collect(); match &symfony_command_name { - Some(symfony_command_name) - if !matches!(symfony_command_name, PhpMixed::Null) => - { + Some(symfony_command_name) if !symfony_command_name.is_null() => { format!( "Too many arguments to \"{}\" command, expected arguments \"{}\".", - symfony_command_name.clone(), + symfony_command_name.to_php_string(), shirabe_php_shim::implode("\" \"", &names), ) } @@ -281,12 +293,12 @@ impl ArgvInput { } } else if symfony_command_name .as_ref() - .map(|n| !matches!(n, PhpMixed::Null)) + .map(|n| !n.is_null()) .unwrap_or(false) { format!( "No arguments expected for \"{}\" command, got \"{}\".", - symfony_command_name.unwrap(), + symfony_command_name.unwrap().to_php_string(), token, ) } else { @@ -300,7 +312,7 @@ impl ArgvInput { } /// Adds a short option value. - fn add_short_option(&mut self, shortcut: &str, value: PhpMixed) -> anyhow::Result<()> { + fn add_short_option(&mut self, shortcut: &str, value: InputValue) -> anyhow::Result<()> { if !self.inner.definition.has_shortcut(shortcut) { return Err(RuntimeException::new(format!( "The \"-{}\" option does not exist.", @@ -319,7 +331,7 @@ impl ArgvInput { } /// Adds a long option value. - fn add_long_option(&mut self, name: &str, mut value: PhpMixed) -> anyhow::Result<()> { + fn add_long_option(&mut self, name: &str, mut value: InputValue) -> anyhow::Result<()> { if !self.inner.definition.has_option(name) { if !self.inner.definition.has_negation(name) { return Err(RuntimeException::new(format!( @@ -330,7 +342,7 @@ impl ArgvInput { } let option_name = self.inner.definition.negation_to_name(name)?; - if !matches!(value, PhpMixed::Null) { + if !value.is_null() { return Err(RuntimeException::new(format!( "The \"--{}\" option does not accept a value.", name @@ -339,14 +351,14 @@ impl ArgvInput { } self.inner .options - .insert(option_name, PhpMixed::Bool(false)); + .insert(option_name, InputValue::Bool(false)); return Ok(()); } let option = self.inner.definition.get_option(name)?; - if !matches!(value, PhpMixed::Null) && !option.accept_value() { + if !value.is_null() && !option.accept_value() { return Err(RuntimeException::new(format!( "The \"--{}\" option does not accept a value.", name @@ -355,8 +367,8 @@ impl ArgvInput { } // in_array($value, ['', null], true) - let value_is_empty_or_null = matches!(&value, PhpMixed::String(s) if s.is_empty()) - || matches!(value, PhpMixed::Null); + let value_is_empty_or_null = + matches!(&value, InputValue::String(s) if s.is_empty()) || value.is_null(); if value_is_empty_or_null && option.accept_value() && !self.parsed.is_empty() { // if option accepts an optional or mandatory argument // let's see if there is one provided @@ -364,13 +376,13 @@ impl ArgvInput { // (isset($next[0]) && '-' !== $next[0]) || in_array($next, ['', null], true) let next_first = next.as_bytes().first().copied(); if (next_first.is_some() && next_first != Some(b'-')) || next.is_empty() { - value = PhpMixed::String(next); + value = InputValue::String(next); } else { self.parsed.insert(0, next); } } - if matches!(value, PhpMixed::Null) { + if value.is_null() { if option.is_value_required() { return Err(RuntimeException::new(format!( "The \"--{}\" option requires a value.", @@ -380,19 +392,25 @@ impl ArgvInput { } if !option.is_array() && !option.is_value_optional() { - value = PhpMixed::Bool(true); + value = InputValue::Bool(true); } } if option.is_array() { + // TODO(type-model): PHP appends the value as it stands, so a + // VALUE_OPTIONAL|VALUE_IS_ARRAY option given no value collects a null; + // `InputValue::Array` only holds strings. + let InputValue::String(value) = value else { + panic!("an array option cannot hold {:?}", value) + }; match self.inner.options.get_mut(name) { - Some(PhpMixed::List(list)) => { + Some(InputValue::Array(list)) => { list.push(value); } _ => { self.inner .options - .insert(name.to_string(), PhpMixed::List(vec![value])); + .insert(name.to_string(), InputValue::Array(vec![value])); } } } else { @@ -448,21 +466,19 @@ impl ArgvInput { None } - pub fn has_parameter_option(&self, values: PhpMixed, only_params: bool) -> bool { - let values = to_array(values); - + pub fn has_parameter_option(&self, values: &[&str], only_params: bool) -> bool { for token in &self.tokens { if only_params && token == "--" { return false; } - for value in &values { + for value in values { // Options with values: // For long options, test for '--option=' at beginning // For short options, test for '-o' at beginning let leading = if value.starts_with("--") { format!("{}=", value) } else { - value.clone() + value.to_string() }; if token == value || (!leading.is_empty() && token.starts_with(&leading)) { return true; @@ -475,11 +491,10 @@ impl ArgvInput { pub fn get_parameter_option( &self, - values: PhpMixed, - default: PhpMixed, + values: &[&str], + default: InputValue, only_params: bool, - ) -> PhpMixed { - let values = to_array(values); + ) -> InputValue { let mut tokens = self.tokens.clone(); while !tokens.is_empty() { @@ -488,11 +503,11 @@ impl ArgvInput { return default; } - for value in &values { + for value in values { if &token == value { return match tokens.first() { - Some(_) => PhpMixed::String(tokens.remove(0)), - None => PhpMixed::Null, + Some(_) => InputValue::String(tokens.remove(0)), + None => InputValue::Null, }; } // Options with values: @@ -501,10 +516,10 @@ impl ArgvInput { let leading = if value.starts_with("--") { format!("{}=", value) } else { - value.clone() + value.to_string() }; if !leading.is_empty() && token.starts_with(&leading) { - return PhpMixed::String(shirabe_php_shim::substr( + return InputValue::String(shirabe_php_shim::substr( &token, shirabe_php_shim::strlen(&leading), None, @@ -553,16 +568,16 @@ impl InputInterface for ArgvInput { ArgvInput::get_first_argument(self) } - fn has_parameter_option(&self, values: PhpMixed, only_params: bool) -> bool { + fn has_parameter_option(&self, values: &[&str], only_params: bool) -> bool { ArgvInput::has_parameter_option(self, values, only_params) } fn get_parameter_option( &self, - values: PhpMixed, - default: PhpMixed, + values: &[&str], + default: InputValue, only_params: bool, - ) -> PhpMixed { + ) -> InputValue { ArgvInput::get_parameter_option(self, values, default, only_params) } @@ -574,15 +589,15 @@ impl InputInterface for ArgvInput { self.inner.validate() } - fn get_arguments(&self) -> IndexMap { + fn get_arguments(&self) -> IndexMap { self.inner.get_arguments() } - fn get_argument(&self, name: &str) -> anyhow::Result { + fn get_argument(&self, name: &str) -> anyhow::Result { self.inner.get_argument(name) } - fn set_argument(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { + fn set_argument(&mut self, name: &str, value: InputValue) -> anyhow::Result<()> { self.inner.set_argument(name, value) } @@ -590,15 +605,15 @@ impl InputInterface for ArgvInput { self.inner.has_argument(name) } - fn get_options(&self) -> IndexMap { + fn get_options(&self) -> IndexMap { self.inner.get_options() } - fn get_option(&self, name: &str) -> anyhow::Result { + fn get_option(&self, name: &str) -> anyhow::Result { self.inner.get_option(name) } - fn set_option(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { + fn set_option(&mut self, name: &str, value: InputValue) -> anyhow::Result<()> { self.inner.set_option(name, value) } @@ -636,19 +651,3 @@ impl StreamableInputInterface for ArgvInput { self.inner.get_stream() } } - -/// PHP `(array) $values` cast: a string becomes a single-element array. -fn to_array(values: PhpMixed) -> Vec { - match values { - PhpMixed::List(list) => list - .into_iter() - .map(|v| shirabe_php_shim::php_to_string(&v)) - .collect(), - PhpMixed::Array(array) => array - .into_iter() - .map(|(_, v)| shirabe_php_shim::php_to_string(&v)) - .collect(), - PhpMixed::Null => vec![], - other => vec![shirabe_php_shim::php_to_string(&other)], - } -} diff --git a/crates/shirabe-symfony-console/src/input/array_input.rs b/crates/shirabe-symfony-console/src/input/array_input.rs index c9bc9dce..437bdde2 100644 --- a/crates/shirabe-symfony-console/src/input/array_input.rs +++ b/crates/shirabe-symfony-console/src/input/array_input.rs @@ -2,13 +2,13 @@ use crate::exception::InvalidArgumentException; use crate::exception::InvalidOptionException; +use crate::input::ArgumentName; use crate::input::Input; use crate::input::InputDefinition; use crate::input::InputInterface; -use crate::input::InputOptionValue; +use crate::input::InputValue; use crate::input::StreamableInputInterface; use indexmap::IndexMap; -use shirabe_php_shim::PhpMixed; /// ArrayInput represents an input provided as an array. /// @@ -19,16 +19,16 @@ use shirabe_php_shim::PhpMixed; /// ``` /// /// PHP arrays can mix integer and string keys; `parameters` preserves both the -/// key type (`PhpMixed::Int` / `PhpMixed::String`) and the insertion order. +/// key type and the insertion order. #[derive(Debug, Clone)] pub struct ArrayInput { inner: Input, - parameters: Vec<(PhpMixed, PhpMixed)>, + parameters: Vec<(ParameterName, InputValue)>, } impl ArrayInput { pub fn new( - parameters: Vec<(PhpMixed, PhpMixed)>, + parameters: Vec<(ParameterName, InputValue)>, definition: Option, ) -> anyhow::Result { let mut array_input = ArrayInput { @@ -58,10 +58,10 @@ impl ArrayInput { Ok(()) } - pub fn get_first_argument(&self) -> Option { + pub fn get_first_argument(&self) -> Option { for (param, value) in &self.parameters { // $param && \is_string($param) && '-' === $param[0] - if let PhpMixed::String(param) = param + if let ParameterName::Name(param) = param && !param.is_empty() && param.as_bytes()[0] == b'-' { @@ -74,21 +74,19 @@ impl ArrayInput { None } - pub fn has_parameter_option(&self, values: PhpMixed, only_params: bool) -> bool { - let values = to_array(values); - + pub fn has_parameter_option(&self, values: &[&str], only_params: bool) -> bool { for (k, v) in &self.parameters { // if (!\is_int($k)) { $v = $k; } - let v: PhpMixed = match k { - PhpMixed::Int(_) => v.clone(), - _ => k.clone(), + let v = match k { + ParameterName::Index(_) => v.as_string(), + ParameterName::Name(k) => Some(k.as_str()), }; - if only_params && matches!(&v, PhpMixed::String(s) if s == "--") { + if only_params && v == Some("--") { return false; } - if values.iter().any(|x| x == &v) { + if v.is_some_and(|v| values.contains(&v)) { return true; } } @@ -98,31 +96,29 @@ impl ArrayInput { pub fn get_parameter_option( &self, - values: PhpMixed, - default: PhpMixed, + values: &[&str], + default: InputValue, only_params: bool, - ) -> PhpMixed { - let values = to_array(values); - + ) -> InputValue { for (k, v) in &self.parameters { // $onlyParams && ('--' === $k || (\is_int($k) && '--' === $v)) if only_params { - let k_is_double_dash = matches!(k, PhpMixed::String(s) if s == "--"); + let k_is_double_dash = matches!(k, ParameterName::Name(k) if k == "--"); let int_v_double_dash = - matches!(k, PhpMixed::Int(_)) && matches!(v, PhpMixed::String(s) if s == "--"); + matches!(k, ParameterName::Index(_)) && v.as_string() == Some("--"); if k_is_double_dash || int_v_double_dash { return default; } } match k { - PhpMixed::Int(_) => { - if values.iter().any(|x| x == v) { - return PhpMixed::Bool(true); + ParameterName::Index(_) => { + if v.as_string().is_some_and(|v| values.contains(&v)) { + return InputValue::Bool(true); } } - _ => { - if values.iter().any(|x| x == k) { + ParameterName::Name(k) => { + if values.contains(&k.as_str()) { return v.clone(); } } @@ -136,16 +132,17 @@ impl ArrayInput { // Clone to avoid borrowing self while mutating; PHP iterates over a copy semantically. let parameters = self.parameters.clone(); for (key, value) in parameters { - let key = shirabe_php_shim::php_to_string(&key); - if key == "--" { + // PHP compares the key as a string even when it is an int. + let key_string = key.to_string(); + if key_string == "--" { return Ok(()); } - if key.starts_with("--") { - self.add_long_option(&shirabe_php_shim::substr(&key, 2, None), value)?; - } else if key.starts_with("-") { - self.add_short_option(&shirabe_php_shim::substr(&key, 1, None), value)?; + if key_string.starts_with("--") { + self.add_long_option(&shirabe_php_shim::substr(&key_string, 2, None), value)?; + } else if key_string.starts_with("-") { + self.add_short_option(&shirabe_php_shim::substr(&key_string, 1, None), value)?; } else { - self.add_argument(&PhpMixed::String(key), value)?; + self.add_argument(&key.to_argument_name(), value)?; } } @@ -153,7 +150,7 @@ impl ArrayInput { } /// Adds a short option value. - fn add_short_option(&mut self, shortcut: &str, value: PhpMixed) -> anyhow::Result<()> { + fn add_short_option(&mut self, shortcut: &str, value: InputValue) -> anyhow::Result<()> { if !self.inner.definition.has_shortcut(shortcut) { return Err(InvalidOptionException::new(format!( "The \"-{}\" option does not exist.", @@ -172,7 +169,7 @@ impl ArrayInput { } /// Adds a long option value. - fn add_long_option(&mut self, name: &str, mut value: PhpMixed) -> anyhow::Result<()> { + fn add_long_option(&mut self, name: &str, mut value: InputValue) -> anyhow::Result<()> { if !self.inner.definition.has_option(name) { if !self.inner.definition.has_negation(name) { return Err(InvalidOptionException::new(format!( @@ -185,14 +182,14 @@ impl ArrayInput { let option_name = self.inner.definition.negation_to_name(name)?; self.inner .options - .insert(option_name, PhpMixed::Bool(false)); + .insert(option_name, InputValue::Bool(false)); return Ok(()); } let option = self.inner.definition.get_option(name)?; - if matches!(value, PhpMixed::Null) { + if value.is_null() { if option.is_value_required() { return Err(InvalidOptionException::new(format!( "The \"--{}\" option requires a value.", @@ -202,7 +199,7 @@ impl ArrayInput { } if !option.is_value_optional() { - value = PhpMixed::Bool(true); + value = InputValue::Bool(true); } } @@ -212,18 +209,16 @@ impl ArrayInput { } /// Adds an argument value. - fn add_argument(&mut self, name: &PhpMixed, value: PhpMixed) -> anyhow::Result<()> { + fn add_argument(&mut self, name: &ArgumentName, value: InputValue) -> anyhow::Result<()> { if !self.inner.definition.has_argument(name) { return Err(InvalidArgumentException::new(format!( "The \"{}\" argument does not exist.", - name.clone() + name )) .into()); } - self.inner - .arguments - .insert(shirabe_php_shim::php_to_string(name), value); + self.inner.arguments.insert(name.to_string(), value); Ok(()) } @@ -235,30 +230,29 @@ impl std::fmt::Display for ArrayInput { let mut params: Vec = vec![]; for (param, val) in &self.parameters { // $param && \is_string($param) && '-' === $param[0] - let is_option_key = - matches!(param, PhpMixed::String(s) if !s.is_empty() && s.as_bytes()[0] == b'-'); - if is_option_key { - let param = param.as_string().unwrap(); + if let ParameterName::Name(param) = param + && !param.is_empty() + && param.as_bytes()[0] == b'-' + { let glue = if param.as_bytes().get(1) == Some(&b'-') { "=" } else { " " }; - if let PhpMixed::List(list) = val { + if let InputValue::Array(list) = val { for v in list { - let v = shirabe_php_shim::php_to_string(v); params.push(format!( "{}{}", param, if !v.is_empty() { - format!("{}{}", glue, self.inner.escape_token(&v)) + format!("{}{}", glue, self.inner.escape_token(v)) } else { String::new() } )); } } else { - let val = shirabe_php_shim::php_to_string(val); + let val = val.to_php_string(); params.push(format!( "{}{}", param, @@ -269,17 +263,12 @@ impl std::fmt::Display for ArrayInput { } )); } - } else if let PhpMixed::List(list) = val { - let escaped: Vec = list - .iter() - .map(|v| self.inner.escape_token(&shirabe_php_shim::php_to_string(v))) - .collect(); + } else if let InputValue::Array(list) = val { + let escaped: Vec = + list.iter().map(|v| self.inner.escape_token(v)).collect(); params.push(shirabe_php_shim::implode(" ", &escaped)); } else { - params.push( - self.inner - .escape_token(&shirabe_php_shim::php_to_string(val)), - ); + params.push(self.inner.escape_token(&val.to_php_string())); } } @@ -293,19 +282,19 @@ impl InputInterface for ArrayInput { } fn get_first_argument(&self) -> Option { - ArrayInput::get_first_argument(self).map(|v| shirabe_php_shim::php_to_string(&v)) + ArrayInput::get_first_argument(self).map(|v| v.to_php_string()) } - fn has_parameter_option(&self, values: PhpMixed, only_params: bool) -> bool { + fn has_parameter_option(&self, values: &[&str], only_params: bool) -> bool { ArrayInput::has_parameter_option(self, values, only_params) } fn get_parameter_option( &self, - values: PhpMixed, - default: PhpMixed, + values: &[&str], + default: InputValue, only_params: bool, - ) -> PhpMixed { + ) -> InputValue { ArrayInput::get_parameter_option(self, values, default, only_params) } @@ -317,15 +306,15 @@ impl InputInterface for ArrayInput { self.inner.validate() } - fn get_arguments(&self) -> IndexMap { + fn get_arguments(&self) -> IndexMap { self.inner.get_arguments() } - fn get_argument(&self, name: &str) -> anyhow::Result { + fn get_argument(&self, name: &str) -> anyhow::Result { self.inner.get_argument(name) } - fn set_argument(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { + fn set_argument(&mut self, name: &str, value: InputValue) -> anyhow::Result<()> { self.inner.set_argument(name, value) } @@ -333,15 +322,15 @@ impl InputInterface for ArrayInput { self.inner.has_argument(name) } - fn get_options(&self) -> IndexMap { + fn get_options(&self) -> IndexMap { self.inner.get_options() } - fn get_option(&self, name: &str) -> anyhow::Result { + fn get_option(&self, name: &str) -> anyhow::Result { self.inner.get_option(name) } - fn set_option(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { + fn set_option(&mut self, name: &str, value: InputValue) -> anyhow::Result<()> { self.inner.set_option(name, value) } @@ -376,12 +365,32 @@ impl StreamableInputInterface for ArrayInput { } } -/// PHP `(array) $values` cast: a string becomes a single-element array. -fn to_array(values: PhpMixed) -> Vec { - match values { - PhpMixed::List(list) => list.into_iter().collect(), - PhpMixed::Array(array) => array.into_iter().map(|(_, v)| v).collect(), - PhpMixed::Null => vec![], - other => vec![other], +/// The `string|int` key of an [`ArrayInput`] parameter: a named argument, a named option +/// (`--foo` / `-f`), or the position of a bare token. +#[derive(Debug, Clone, PartialEq)] +pub enum ParameterName { + Name(String), + Index(i64), +} + +impl ParameterName { + pub fn of(name: &str) -> Self { + Self::Name(name.to_string()) + } + + fn to_argument_name(&self) -> ArgumentName { + match self { + Self::Name(name) => ArgumentName::Name(name.clone()), + Self::Index(index) => ArgumentName::Position(*index), + } + } +} + +impl std::fmt::Display for ParameterName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Name(name) => write!(f, "{}", name), + Self::Index(index) => write!(f, "{}", index), + } } } diff --git a/crates/shirabe-symfony-console/src/input/input.rs b/crates/shirabe-symfony-console/src/input/input.rs index 795e9c81..44519698 100644 --- a/crates/shirabe-symfony-console/src/input/input.rs +++ b/crates/shirabe-symfony-console/src/input/input.rs @@ -2,10 +2,11 @@ use crate::exception::InvalidArgumentException; use crate::exception::RuntimeException; +use crate::input::ArgumentName; use crate::input::InputDefinition; -use crate::input::InputOptionValue; +use crate::input::InputValue; use indexmap::IndexMap; -use shirabe_php_shim::{PhpMixed, PhpResource, php_regex, preg_is_match}; +use shirabe_php_shim::{PhpResource, php_regex, preg_is_match}; /// Input is the base class for all concrete Input classes. /// @@ -18,8 +19,8 @@ use shirabe_php_shim::{PhpMixed, PhpResource, php_regex, preg_is_match}; pub struct Input { pub(crate) definition: InputDefinition, stream: Option, - pub(crate) options: IndexMap, - pub(crate) arguments: IndexMap, + pub(crate) options: IndexMap, + pub(crate) arguments: IndexMap, interactive: bool, } @@ -74,7 +75,7 @@ impl Input { |argument: &String| { !given_arguments.contains_key(argument) && definition - .get_argument(&PhpMixed::String(argument.clone())) + .get_argument(&ArgumentName::of(argument)) .map(|a| a.is_required()) .unwrap_or(false) }, @@ -99,18 +100,15 @@ impl Input { self.interactive = interactive; } - pub fn get_arguments(&self) -> IndexMap { + pub fn get_arguments(&self) -> IndexMap { shirabe_php_shim::array_merge_map( self.definition.get_argument_defaults(), self.arguments.clone(), ) } - pub fn get_argument(&self, name: &str) -> anyhow::Result { - if !self - .definition - .has_argument(&PhpMixed::String(name.to_string())) - { + pub fn get_argument(&self, name: &str) -> anyhow::Result { + if !self.definition.has_argument(&ArgumentName::of(name)) { return Err(InvalidArgumentException::new(format!( "The \"{}\" argument does not exist.", name @@ -122,17 +120,14 @@ impl Input { Some(value) => value.clone(), None => self .definition - .get_argument(&PhpMixed::String(name.to_string()))? + .get_argument(&ArgumentName::of(name))? .get_default() .clone(), }) } - pub fn set_argument(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { - if !self - .definition - .has_argument(&PhpMixed::String(name.to_string())) - { + pub fn set_argument(&mut self, name: &str, value: InputValue) -> anyhow::Result<()> { + if !self.definition.has_argument(&ArgumentName::of(name)) { return Err(InvalidArgumentException::new(format!( "The \"{}\" argument does not exist.", name @@ -146,25 +141,24 @@ impl Input { } pub fn has_argument(&self, name: &str) -> bool { - self.definition - .has_argument(&PhpMixed::String(name.to_string())) + self.definition.has_argument(&ArgumentName::of(name)) } - pub fn get_options(&self) -> IndexMap { + pub fn get_options(&self) -> IndexMap { shirabe_php_shim::array_merge_map( self.definition.get_option_defaults(), self.options.clone(), ) } - pub fn get_option(&self, name: &str) -> anyhow::Result { + pub fn get_option(&self, name: &str) -> anyhow::Result { if self.definition.has_negation(name) { let value = self.get_option(&self.definition.negation_to_name(name)?)?; if value.is_null() { return Ok(value); } - return Ok(InputOptionValue::Bool(!value.to_bool())); + return Ok(InputValue::Bool(!value.to_bool())); } if !self.definition.has_option(name) { @@ -176,18 +170,17 @@ impl Input { } Ok(if let Some(value) = self.options.get(name) { - InputOptionValue::from_php_mixed(value) + value.clone() } else { - let option = self.definition.get_option(name)?; - InputOptionValue::from_php_mixed(option.get_default()) + self.definition.get_option(name)?.get_default().clone() }) } - pub fn set_option(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { + pub fn set_option(&mut self, name: &str, value: InputValue) -> anyhow::Result<()> { if self.definition.has_negation(name) { let negated = self.definition.negation_to_name(name)?; self.options - .insert(negated, PhpMixed::Bool(!value.as_bool().unwrap_or(false))); + .insert(negated, InputValue::Bool(!value.to_bool())); return Ok(()); } else if !self.definition.has_option(name) { diff --git a/crates/shirabe-symfony-console/src/input/input_argument.rs b/crates/shirabe-symfony-console/src/input/input_argument.rs index 5ca91a6b..ef07af0e 100644 --- a/crates/shirabe-symfony-console/src/input/input_argument.rs +++ b/crates/shirabe-symfony-console/src/input/input_argument.rs @@ -2,13 +2,13 @@ use crate::exception::InvalidArgumentException; use crate::exception::LogicException; -use shirabe_php_shim::PhpMixed; +use crate::input::InputValue; #[derive(Debug, Clone)] pub struct InputArgument { name: String, mode: i64, - default: PhpMixed, + default: InputValue, description: String, } @@ -21,7 +21,7 @@ impl InputArgument { name: String, mode: Option, description: String, - default: PhpMixed, + default: InputValue, ) -> anyhow::Result { let mode = match mode { None => Self::OPTIONAL, @@ -39,7 +39,7 @@ impl InputArgument { name, mode, description, - default: PhpMixed::Null, + default: InputValue::Null, }; argument.set_default(default)?; @@ -59,8 +59,8 @@ impl InputArgument { Self::IS_ARRAY == (Self::IS_ARRAY & self.mode) } - pub fn set_default(&mut self, default: PhpMixed) -> anyhow::Result<()> { - if self.is_required() && !matches!(default, PhpMixed::Null) { + pub fn set_default(&mut self, default: InputValue) -> anyhow::Result<()> { + if self.is_required() && !default.is_null() { return Err(LogicException::new( "Cannot set a default value except for InputArgument::OPTIONAL mode.".to_string(), ) @@ -69,8 +69,8 @@ impl InputArgument { let default = if self.is_array() { match default { - PhpMixed::Null => PhpMixed::List(vec![]), - PhpMixed::List(_) => default, + InputValue::Null => InputValue::Array(vec![]), + InputValue::Array(_) => default, _ => { return Err(LogicException::new( "A default value for an array argument must be an array.".to_string(), @@ -86,7 +86,7 @@ impl InputArgument { Ok(()) } - pub fn get_default(&self) -> &PhpMixed { + pub fn get_default(&self) -> &InputValue { &self.default } diff --git a/crates/shirabe-symfony-console/src/input/input_definition.rs b/crates/shirabe-symfony-console/src/input/input_definition.rs index 8d116bc1..35fa4e52 100644 --- a/crates/shirabe-symfony-console/src/input/input_definition.rs +++ b/crates/shirabe-symfony-console/src/input/input_definition.rs @@ -4,8 +4,8 @@ use crate::exception::InvalidArgumentException; use crate::exception::LogicException; use crate::input::InputArgument; use crate::input::InputOption; +use crate::input::InputValue; use indexmap::IndexMap; -use shirabe_php_shim::PhpMixed; /// A InputDefinition represents a set of valid command line arguments and options. /// @@ -154,40 +154,32 @@ impl InputDefinition { } /// Returns an InputArgument by name or by position. - pub fn get_argument(&self, name: &PhpMixed) -> anyhow::Result> { + pub fn get_argument(&self, name: &ArgumentName) -> anyhow::Result> { if !self.has_argument(name) { return Err(InvalidArgumentException::new(format!( "The \"{}\" argument does not exist.", - name.clone() + name )) .into()); } match name { - PhpMixed::Int(index) => { + ArgumentName::Position(index) => { let arguments: Vec> = self.arguments.values().cloned().collect(); Ok(std::rc::Rc::clone(&arguments[*index as usize])) } - _ => { - let key = shirabe_php_shim::php_to_string(name); - Ok(std::rc::Rc::clone(&self.arguments[&key])) - } + ArgumentName::Name(name) => Ok(std::rc::Rc::clone(&self.arguments[name])), } } /// Returns true if an InputArgument object exists by name or position. - pub fn has_argument(&self, name: &PhpMixed) -> bool { + pub fn has_argument(&self, name: &ArgumentName) -> bool { match name { - PhpMixed::Int(index) => { - let arguments: Vec> = - self.arguments.values().cloned().collect(); - *index >= 0 && (*index as usize) < arguments.len() - } - _ => { - let key = shirabe_php_shim::php_to_string(name); - self.arguments.contains_key(&key) + ArgumentName::Position(index) => { + *index >= 0 && (*index as usize) < self.arguments.len() } + ArgumentName::Name(name) => self.arguments.contains_key(name), } } @@ -210,7 +202,7 @@ impl InputDefinition { self.required_count } - pub fn get_argument_defaults(&self) -> IndexMap { + pub fn get_argument_defaults(&self) -> IndexMap { let mut values = IndexMap::new(); for argument in self.arguments.values() { values.insert( @@ -346,7 +338,7 @@ impl InputDefinition { self.get_option(&self.shortcut_to_name(shortcut)?) } - pub fn get_option_defaults(&self) -> IndexMap { + pub fn get_option_defaults(&self) -> IndexMap { let mut values = IndexMap::new(); for option in self.options.values() { values.insert(option.get_name().to_string(), option.get_default().clone()); @@ -448,3 +440,26 @@ impl InputDefinition { format!("{}{}", shirabe_php_shim::implode(" ", &elements), tail) } } + +/// The `string|int` selector [`InputDefinition::get_argument`] and +/// [`InputDefinition::has_argument`] accept. +#[derive(Debug, Clone)] +pub enum ArgumentName { + Name(String), + Position(i64), +} + +impl ArgumentName { + pub fn of(name: &str) -> Self { + Self::Name(name.to_string()) + } +} + +impl std::fmt::Display for ArgumentName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Name(name) => write!(f, "{}", name), + Self::Position(index) => write!(f, "{}", index), + } + } +} diff --git a/crates/shirabe-symfony-console/src/input/input_interface.rs b/crates/shirabe-symfony-console/src/input/input_interface.rs index 3c3ec2d5..85cd5e7f 100644 --- a/crates/shirabe-symfony-console/src/input/input_interface.rs +++ b/crates/shirabe-symfony-console/src/input/input_interface.rs @@ -1,9 +1,8 @@ //! ref: composer/vendor/symfony/console/Input/InputInterface.php use crate::input::InputDefinition; -use crate::input::InputOptionValue; +use crate::input::InputValue; use crate::input::StreamableInputInterface; -use shirabe_php_shim::PhpMixed; pub trait InputInterface: std::fmt::Debug + shirabe_php_shim::AsAny { /// Models PHP's `clone` operatior. @@ -11,32 +10,32 @@ pub trait InputInterface: std::fmt::Debug + shirabe_php_shim::AsAny { fn get_first_argument(&self) -> Option; - fn has_parameter_option(&self, values: PhpMixed, only_params: bool) -> bool; + fn has_parameter_option(&self, values: &[&str], only_params: bool) -> bool; fn get_parameter_option( &self, - values: PhpMixed, - default: PhpMixed, + values: &[&str], + default: InputValue, only_params: bool, - ) -> PhpMixed; + ) -> InputValue; fn bind(&mut self, definition: &InputDefinition) -> anyhow::Result<()>; fn validate(&mut self) -> anyhow::Result<()>; - fn get_arguments(&self) -> indexmap::IndexMap; + fn get_arguments(&self) -> indexmap::IndexMap; - fn get_argument(&self, name: &str) -> anyhow::Result; + fn get_argument(&self, name: &str) -> anyhow::Result; - fn set_argument(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()>; + fn set_argument(&mut self, name: &str, value: InputValue) -> anyhow::Result<()>; fn has_argument(&self, name: &str) -> bool; - fn get_options(&self) -> indexmap::IndexMap; + fn get_options(&self) -> indexmap::IndexMap; - fn get_option(&self, name: &str) -> anyhow::Result; + fn get_option(&self, name: &str) -> anyhow::Result; - fn set_option(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()>; + fn set_option(&mut self, name: &str, value: InputValue) -> anyhow::Result<()>; fn has_option(&self, name: &str) -> bool; diff --git a/crates/shirabe-symfony-console/src/input/input_option.rs b/crates/shirabe-symfony-console/src/input/input_option.rs index d37e18ae..6484d832 100644 --- a/crates/shirabe-symfony-console/src/input/input_option.rs +++ b/crates/shirabe-symfony-console/src/input/input_option.rs @@ -2,14 +2,15 @@ use crate::exception::InvalidArgumentException; use crate::exception::LogicException; -use shirabe_php_shim::{PhpMixed, php_regex, preg_split}; +use crate::input::InputValue; +use shirabe_php_shim::{php_regex, preg_split}; #[derive(Debug, Clone)] pub struct InputOption { name: String, shortcut: Option, mode: i64, - default: PhpMixed, + default: InputValue, description: String, } @@ -22,10 +23,10 @@ impl InputOption { pub fn new( name: &str, - shortcut: PhpMixed, + shortcut: Option<&str>, mode: Option, description: String, - default: PhpMixed, + default: InputValue, ) -> anyhow::Result { let name = if let Some(stripped) = name.strip_prefix("--") { stripped.to_string() @@ -41,26 +42,8 @@ impl InputOption { } let shortcut = match shortcut { - PhpMixed::String(ref s) if s.is_empty() => None, - PhpMixed::List(ref v) if v.is_empty() => None, - PhpMixed::Bool(false) => None, - PhpMixed::Null => None, - PhpMixed::List(ref arr) => { - let parts: Vec = arr - .iter() - .filter_map(|v| { - if let PhpMixed::String(s) = v { - Some(s.clone()) - } else { - None - } - }) - .collect(); - let joined = shirabe_php_shim::implode("|", &parts); - Self::normalize_shortcut(joined)? - } - PhpMixed::String(s) => Self::normalize_shortcut(s)?, - _ => None, + None | Some("") => None, + Some(shortcut) => Self::normalize_shortcut(shortcut)?, }; let mode = match mode { @@ -80,7 +63,7 @@ impl InputOption { shortcut, mode, description, - default: PhpMixed::Null, + default: InputValue::Null, }; if option.is_array() && !option.accept_value() { @@ -97,8 +80,8 @@ impl InputOption { Ok(option) } - fn normalize_shortcut(s: String) -> anyhow::Result> { - let stripped = shirabe_php_shim::ltrim(&s, Some("-")); + fn normalize_shortcut(s: &str) -> anyhow::Result> { + let stripped = shirabe_php_shim::ltrim(s, Some("-")); let parts = preg_split(php_regex!(r"{(\|)-?}"), &stripped); let filtered: Vec = shirabe_php_shim::array_filter(&parts, |s: &String| !s.is_empty()); @@ -140,9 +123,8 @@ impl InputOption { Self::VALUE_NEGATABLE == (Self::VALUE_NEGATABLE & self.mode) } - pub fn set_default(&mut self, default: PhpMixed) -> anyhow::Result<()> { - if Self::VALUE_NONE == (Self::VALUE_NONE & self.mode) && !matches!(default, PhpMixed::Null) - { + pub fn set_default(&mut self, default: InputValue) -> anyhow::Result<()> { + if Self::VALUE_NONE == (Self::VALUE_NONE & self.mode) && !default.is_null() { return Err(LogicException::new( "Cannot set a default value when using InputOption::VALUE_NONE mode.".to_string(), ) @@ -151,9 +133,8 @@ impl InputOption { let default = if self.is_array() { match default { - PhpMixed::Null => PhpMixed::List(vec![]), - // PHP `is_array()` accepts both list-style and associative arrays. - PhpMixed::List(_) | PhpMixed::Array(_) => default, + InputValue::Null => InputValue::Array(vec![]), + InputValue::Array(_) => default, _ => { return Err(LogicException::new( "A default value for an array option must be an array.".to_string(), @@ -168,12 +149,12 @@ impl InputOption { self.default = if self.accept_value() || self.is_negatable() { default } else { - PhpMixed::Bool(false) + InputValue::Bool(false) }; Ok(()) } - pub fn get_default(&self) -> &PhpMixed { + pub fn get_default(&self) -> &InputValue { &self.default } @@ -191,90 +172,3 @@ impl InputOption { && option.is_value_optional() == self.is_value_optional() } } - -/// The `bool|string|string[]|null` domain of a parsed option value, as returned by -/// [`InputInterface::get_option`](crate::input::InputInterface::get_option). -#[derive(Debug, Clone, PartialEq)] -pub enum InputOptionValue { - Null, - Bool(bool), - String(String), - Array(Vec), -} - -impl InputOptionValue { - /// Narrows a raw option value to this domain. - /// - /// TODO(type-model): `Input` keeps parsed options and `InputOption` defaults as `PhpMixed`, so - /// a value outside this domain — an int, a float, or an array holding one — can only be - /// rejected here. - pub(crate) fn from_php_mixed(value: &PhpMixed) -> Self { - match value { - PhpMixed::Null => Self::Null, - PhpMixed::Bool(b) => Self::Bool(*b), - PhpMixed::String(s) => Self::String(s.clone()), - PhpMixed::List(_) | PhpMixed::Array(_) => Self::Array( - value - .values() - .into_iter() - .map(|item| match item { - PhpMixed::String(s) => s.clone(), - other => panic!("an option array holds {:?}, not a string", other), - }) - .collect(), - ), - other => panic!( - "an option holds {:?}, not a bool, string, array or null", - other - ), - } - } - - pub fn is_null(&self) -> bool { - matches!(self, Self::Null) - } - - pub fn as_bool(&self) -> Option { - match self { - Self::Bool(b) => Some(*b), - _ => None, - } - } - - pub fn as_string(&self) -> Option<&str> { - match self { - Self::String(s) => Some(s.as_str()), - _ => None, - } - } - - pub fn as_array(&self) -> Option<&[String]> { - match self { - Self::Array(items) => Some(items), - _ => None, - } - } - - /// PHP loose boolean cast `(bool) $value`. - pub fn to_bool(&self) -> bool { - match self { - Self::Null => false, - Self::Bool(b) => *b, - Self::String(s) => !s.is_empty() && s != "0", - Self::Array(items) => !items.is_empty(), - } - } -} - -impl From for PhpMixed { - fn from(value: InputOptionValue) -> Self { - match value { - InputOptionValue::Null => PhpMixed::Null, - InputOptionValue::Bool(b) => PhpMixed::Bool(b), - InputOptionValue::String(s) => PhpMixed::String(s), - InputOptionValue::Array(items) => { - PhpMixed::List(items.into_iter().map(PhpMixed::String).collect()) - } - } - } -} diff --git a/crates/shirabe-symfony-console/src/input/input_value.rs b/crates/shirabe-symfony-console/src/input/input_value.rs new file mode 100644 index 00000000..288c55d6 --- /dev/null +++ b/crates/shirabe-symfony-console/src/input/input_value.rs @@ -0,0 +1,146 @@ +//! ref: composer/vendor/symfony/console/Input/InputInterface.php + +/// The value an option or an argument can hold. +/// +/// Symfony declares the domain as `string|bool|int|float|array|null` and only ever narrows it in +/// PHPDoc; the arrays it stores are lists of strings. +#[derive(Debug, Clone, PartialEq)] +pub enum InputValue { + Null, + Bool(bool), + String(String), + Array(Vec), +} + +impl InputValue { + /// Narrows a PHP value to this domain. + /// + /// TODO(type-model): the question helpers and the plugin bridge still hand back a + /// `PhpMixed`, so a value outside this domain can only be rejected here. + pub fn from_php_mixed(value: &shirabe_php_shim::PhpMixed) -> Self { + use shirabe_php_shim::PhpMixed; + match value { + PhpMixed::Null => Self::Null, + PhpMixed::Bool(b) => Self::Bool(*b), + PhpMixed::String(s) => Self::String(s.clone()), + PhpMixed::List(_) | PhpMixed::Array(_) => Self::Array( + value + .values() + .into_iter() + .map(|item| match item { + PhpMixed::String(s) => s.clone(), + other => panic!("an input array holds {:?}, not a string", other), + }) + .collect(), + ), + other => panic!( + "an input value holds {:?}, not a bool, string, array or null", + other + ), + } + } + + pub fn is_null(&self) -> bool { + matches!(self, Self::Null) + } + + pub fn is_array(&self) -> bool { + matches!(self, Self::Array(_)) + } + + pub fn as_bool(&self) -> Option { + match self { + Self::Bool(b) => Some(*b), + _ => None, + } + } + + pub fn as_string(&self) -> Option<&str> { + match self { + Self::String(s) => Some(s.as_str()), + _ => None, + } + } + + pub fn as_array(&self) -> Option<&[String]> { + match self { + Self::Array(items) => Some(items), + _ => None, + } + } + + /// PHP's `(bool) $value`. + pub fn to_bool(&self) -> bool { + match self { + Self::Null => false, + Self::Bool(b) => *b, + Self::String(s) => !s.is_empty() && s != "0", + Self::Array(items) => !items.is_empty(), + } + } + + /// The value as a PHP `mixed`, for the shim functions that take one. + pub fn to_php_mixed(&self) -> shirabe_php_shim::PhpMixed { + self.clone().into() + } + + /// PHP's `(string) $value`, which is a fatal error for an array. + pub fn to_php_string(&self) -> String { + match self { + Self::Null => String::new(), + Self::Bool(b) => { + if *b { + "1".to_string() + } else { + String::new() + } + } + Self::String(s) => s.clone(), + Self::Array(_) => panic!("array to string conversion"), + } + } +} + +impl From for shirabe_php_shim::PhpMixed { + fn from(value: InputValue) -> Self { + match value { + InputValue::Null => Self::Null, + InputValue::Bool(b) => Self::Bool(b), + InputValue::String(s) => Self::String(s), + InputValue::Array(items) => Self::List(items.into_iter().map(Self::String).collect()), + } + } +} + +impl From<&str> for InputValue { + fn from(value: &str) -> Self { + Self::String(value.to_string()) + } +} + +impl From for InputValue { + fn from(value: String) -> Self { + Self::String(value) + } +} + +impl From for InputValue { + fn from(value: bool) -> Self { + Self::Bool(value) + } +} + +impl From> for InputValue { + fn from(value: Option) -> Self { + match value { + Some(value) => Self::String(value), + None => Self::Null, + } + } +} + +impl From> for InputValue { + fn from(value: Vec) -> Self { + Self::Array(value) + } +} diff --git a/crates/shirabe-symfony-console/src/input/string_input.rs b/crates/shirabe-symfony-console/src/input/string_input.rs index 9fcb3fc8..09cee120 100644 --- a/crates/shirabe-symfony-console/src/input/string_input.rs +++ b/crates/shirabe-symfony-console/src/input/string_input.rs @@ -4,10 +4,10 @@ use crate::exception::InvalidArgumentException; use crate::input::ArgvInput; use crate::input::InputDefinition; use crate::input::InputInterface; -use crate::input::InputOptionValue; +use crate::input::InputValue; use crate::input::StreamableInputInterface; use indexmap::IndexMap; -use shirabe_php_shim::{PhpMixed, php_regex, preg_match}; +use shirabe_php_shim::{php_regex, preg_match}; /// StringInput represents an input provided as a string. /// @@ -137,16 +137,16 @@ impl InputInterface for StringInput { self.inner.get_first_argument() } - fn has_parameter_option(&self, values: PhpMixed, only_params: bool) -> bool { + fn has_parameter_option(&self, values: &[&str], only_params: bool) -> bool { InputInterface::has_parameter_option(&self.inner, values, only_params) } fn get_parameter_option( &self, - values: PhpMixed, - default: PhpMixed, + values: &[&str], + default: InputValue, only_params: bool, - ) -> PhpMixed { + ) -> InputValue { InputInterface::get_parameter_option(&self.inner, values, default, only_params) } @@ -158,15 +158,15 @@ impl InputInterface for StringInput { self.inner.validate() } - fn get_arguments(&self) -> IndexMap { + fn get_arguments(&self) -> IndexMap { InputInterface::get_arguments(&self.inner) } - fn get_argument(&self, name: &str) -> anyhow::Result { + fn get_argument(&self, name: &str) -> anyhow::Result { self.inner.get_argument(name) } - fn set_argument(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { + fn set_argument(&mut self, name: &str, value: InputValue) -> anyhow::Result<()> { self.inner.set_argument(name, value) } @@ -174,15 +174,15 @@ impl InputInterface for StringInput { self.inner.has_argument(name) } - fn get_options(&self) -> IndexMap { + fn get_options(&self) -> IndexMap { InputInterface::get_options(&self.inner) } - fn get_option(&self, name: &str) -> anyhow::Result { + fn get_option(&self, name: &str) -> anyhow::Result { self.inner.get_option(name) } - fn set_option(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()> { + fn set_option(&mut self, name: &str, value: InputValue) -> anyhow::Result<()> { self.inner.set_option(name, value) } diff --git a/crates/shirabe/src/command/archive_command.rs b/crates/shirabe/src/command/archive_command.rs index e10601ac..a50b9602 100644 --- a/crates/shirabe/src/command/archive_command.rs +++ b/crates/shirabe/src/command/archive_command.rs @@ -310,7 +310,7 @@ impl Command for ArchiveCommand { self.set_definition(&[ InputArgument::new5("package", Some(InputArgument::OPTIONAL), "The package to archive instead of the current project", None, self.suggest_available_package(99)).unwrap().into(), InputArgument::new("version", Some(InputArgument::OPTIONAL), "A version constraint to find the package to archive", None).unwrap().into(), - InputOption::new6("format", Some(shirabe_php_shim::PhpMixed::String("f".to_string())), Some(InputOption::VALUE_REQUIRED), "Format of the resulting archive: tar, tar.gz, tar.bz2 or zip (default tar)", None, SuggestedValues::List(Self::FORMATS.iter().map(|s| s.to_string()).collect())).unwrap().into(), + InputOption::new6("format", Some("f"), Some(InputOption::VALUE_REQUIRED), "Format of the resulting archive: tar, tar.gz, tar.bz2 or zip (default tar)", None, SuggestedValues::List(Self::FORMATS.iter().map(|s| s.to_string()).collect())).unwrap().into(), InputOption::new("dir", None, Some(InputOption::VALUE_REQUIRED), "Write the archive to this directory", None).unwrap().into(), InputOption::new("file", None, Some(InputOption::VALUE_REQUIRED), "Write the archive with the given file name. Note that the format will be appended.", None).unwrap().into(), InputOption::new("ignore-filters", None, Some(InputOption::VALUE_NONE), "Ignore filters when saving package", None).unwrap().into(), diff --git a/crates/shirabe/src/command/audit_command.rs b/crates/shirabe/src/command/audit_command.rs index d067e074..238451e0 100644 --- a/crates/shirabe/src/command/audit_command.rs +++ b/crates/shirabe/src/command/audit_command.rs @@ -19,6 +19,7 @@ use shirabe_php_shim::{ }; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -113,10 +114,10 @@ impl Command for AuditCommand { .into(), InputOption::new6( "format", - Some(PhpMixed::String("f".to_string())), + Some("f"), Some(InputOption::VALUE_REQUIRED), "Output format. Must be \"table\", \"plain\", \"json\", or \"summary\".", - Some(PhpMixed::String(Auditor::FORMAT_TABLE.to_string())), + Some(InputValue::String(Auditor::FORMAT_TABLE.to_string())), SuggestedValues::List(Auditor::FORMATS.iter().map(|s| s.to_string()).collect()), ) .unwrap() @@ -145,7 +146,7 @@ impl Command for AuditCommand { None, Some(InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED), "Ignore advisories of a certain severity level.", - Some(PhpMixed::Array(indexmap::IndexMap::new())), + Some(InputValue::Array(vec![])), SuggestedValues::List(vec![ "low".to_string(), "medium".to_string(), diff --git a/crates/shirabe/src/command/base_command.rs b/crates/shirabe/src/command/base_command.rs index 8ec9f350..d1d9ecf2 100644 --- a/crates/shirabe/src/command/base_command.rs +++ b/crates/shirabe/src/command/base_command.rs @@ -26,7 +26,9 @@ use shirabe_symfony_console::Terminal; use shirabe_symfony_console::command::{Command, CommandData, SetDefinitionArg}; use shirabe_symfony_console::helper::Table; use shirabe_symfony_console::helper::TableSeparator; +use shirabe_symfony_console::input::ArgumentName; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; pub const SUCCESS: i64 = 0; @@ -122,7 +124,7 @@ pub trait BaseCommand: Command { name: &str, mode: Option, description: &str, - default: PhpMixed, + default: InputValue, ) -> &Self where Self: Sized, @@ -139,14 +141,11 @@ pub trait BaseCommand: Command { shortcut: Option<&str>, mode: Option, description: &str, - default: PhpMixed, + default: InputValue, ) -> &Self where Self: Sized, { - let shortcut = shortcut - .map(|s| PhpMixed::from(s.to_string())) - .unwrap_or(PhpMixed::Null); self.command_data() .add_option(name, shortcut, mode, description, default) .expect("command option definitions in configure() are statically valid"); @@ -400,11 +399,11 @@ impl BaseCommand for BaseCommandData { let disable_plugins = disable_plugins || input .borrow() - .has_parameter_option(PhpMixed::from(vec!["--no-plugins"]), false); + .has_parameter_option(&["--no-plugins"], false); let disable_scripts = disable_scripts.unwrap_or(false) || input .borrow() - .has_parameter_option(PhpMixed::from(vec!["--no-scripts"]), false); + .has_parameter_option(&["--no-scripts"], false); let (disable_plugins, disable_scripts) = apply_application_defaults(self.get_application(), disable_plugins, disable_scripts); @@ -478,12 +477,12 @@ impl BaseCommand for BaseCommandData { "dist" => { input .borrow_mut() - .set_option("prefer-dist", PhpMixed::Bool(true))?; + .set_option("prefer-dist", InputValue::Bool(true))?; } "source" => { input .borrow_mut() - .set_option("prefer-source", PhpMixed::Bool(true))?; + .set_option("prefer-source", InputValue::Bool(true))?; } "auto" => { prefer_dist = false; @@ -771,7 +770,7 @@ pub fn base_command_complete( } else if CompletionInput::TYPE_ARGUMENT_VALUE == input.get_completion_type() && cmd .get_definition() - .has_argument(&PhpMixed::String(name.clone())) + .has_argument(&ArgumentName::Name(name.clone())) { let argument = cmd .base_command_data() @@ -799,10 +798,10 @@ pub fn base_command_initialize( // initialize a plugin-enabled Composer instance, either local or global let disable_plugins = input .borrow() - .has_parameter_option(PhpMixed::from(vec!["--no-plugins"]), false); + .has_parameter_option(&["--no-plugins"], false); let disable_scripts = input .borrow() - .has_parameter_option(PhpMixed::from(vec!["--no-scripts"]), false); + .has_parameter_option(&["--no-scripts"], false); let (mut disable_plugins, mut disable_scripts) = apply_application_defaults(cmd.get_application(), disable_plugins, disable_scripts); @@ -839,14 +838,12 @@ pub fn base_command_initialize( )?; } - if input - .borrow() - .has_parameter_option(PhpMixed::from(vec!["--no-ansi"]), false) + if input.borrow().has_parameter_option(&["--no-ansi"], false) && input.borrow().has_option("no-progress") { input .borrow_mut() - .set_option("no-progress", PhpMixed::Bool(true)); + .set_option("no-progress", InputValue::Bool(true)); } let env_options: IndexMap<&str, Vec<&str>> = [ @@ -879,7 +876,7 @@ pub fn base_command_initialize( { input .borrow_mut() - .set_option(option_name, PhpMixed::Bool(true)); + .set_option(option_name, InputValue::Bool(true)); } } } @@ -895,7 +892,7 @@ pub fn base_command_initialize( { input .borrow_mut() - .set_option("ignore-platform-reqs", PhpMixed::Bool(true)); + .set_option("ignore-platform-reqs", InputValue::Bool(true)); io.write_error("COMPOSER_IGNORE_PLATFORM_REQS is set. You may experience unexpected errors."); } @@ -917,12 +914,7 @@ pub fn base_command_initialize( { input.borrow_mut().set_option( "ignore-platform-req", - PhpMixed::List( - explode(",", &ignore_str) - .into_iter() - .map(PhpMixed::String) - .collect(), - ), + InputValue::Array(explode(",", &ignore_str)), ); io.write_error(&format!( diff --git a/crates/shirabe/src/command/bump_command.rs b/crates/shirabe/src/command/bump_command.rs index 3b680a29..8f95366f 100644 --- a/crates/shirabe/src/command/bump_command.rs +++ b/crates/shirabe/src/command/bump_command.rs @@ -349,7 +349,7 @@ impl Command for BumpCommand { .into(), InputOption::new( "dev-only", - Some(PhpMixed::String("D".to_string())), + Some("D"), Some(InputOption::VALUE_NONE), "Only bump requirements in \"require-dev\".", None, @@ -358,7 +358,7 @@ impl Command for BumpCommand { .into(), InputOption::new( "no-dev-only", - Some(PhpMixed::String("R".to_string())), + Some("R"), Some(InputOption::VALUE_NONE), "Only bump requirements in \"require\".", None, @@ -397,12 +397,8 @@ impl Command for BumpCommand { let packages_filter: Vec = input .borrow() .get_argument("packages")? - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) + .as_array() + .map(<[String]>::to_vec) .unwrap_or_default(); let dev_only = input diff --git a/crates/shirabe/src/command/check_platform_reqs_command.rs b/crates/shirabe/src/command/check_platform_reqs_command.rs index d1cbf33c..21e71fee 100644 --- a/crates/shirabe/src/command/check_platform_reqs_command.rs +++ b/crates/shirabe/src/command/check_platform_reqs_command.rs @@ -17,6 +17,7 @@ use shirabe_semver::constraint::AnyConstraint; use shirabe_semver::constraint::SimpleConstraint; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; struct CheckResult { @@ -165,10 +166,10 @@ impl Command for CheckPlatformReqsCommand { .into(), InputOption::new6( "format", - Some(shirabe_php_shim::PhpMixed::String("f".to_string())), + Some("f"), Some(InputOption::VALUE_REQUIRED), "Format of the output: text or json", - Some(shirabe_php_shim::PhpMixed::String("text".to_string())), + Some(InputValue::String("text".to_string())), SuggestedValues::List(vec!["json".to_string(), "text".to_string()]), ) .unwrap() diff --git a/crates/shirabe/src/command/config_command.rs b/crates/shirabe/src/command/config_command.rs index 0788d694..90f2d7c0 100644 --- a/crates/shirabe/src/command/config_command.rs +++ b/crates/shirabe/src/command/config_command.rs @@ -443,15 +443,15 @@ impl Command for ConfigCommand { self.set_name("config")?; self.set_description("Sets config options"); self.set_definition(&[ - InputOption::new("global", Some(PhpMixed::String("g".to_string())), Some(InputOption::VALUE_NONE), "Apply command to the global config file", None).unwrap().into(), - InputOption::new("editor", Some(PhpMixed::String("e".to_string())), Some(InputOption::VALUE_NONE), "Open editor", None).unwrap().into(), - InputOption::new("auth", Some(PhpMixed::String("a".to_string())), Some(InputOption::VALUE_NONE), "Affect auth config file (only used for --editor)", None).unwrap().into(), + InputOption::new("global", Some("g"), Some(InputOption::VALUE_NONE), "Apply command to the global config file", None).unwrap().into(), + InputOption::new("editor", Some("e"), Some(InputOption::VALUE_NONE), "Open editor", None).unwrap().into(), + InputOption::new("auth", Some("a"), Some(InputOption::VALUE_NONE), "Affect auth config file (only used for --editor)", None).unwrap().into(), InputOption::new("unset", None, Some(InputOption::VALUE_NONE), "Unset the given setting-key", None).unwrap().into(), - InputOption::new("list", Some(PhpMixed::String("l".to_string())), Some(InputOption::VALUE_NONE), "List configuration settings", None).unwrap().into(), - InputOption::new("file", Some(PhpMixed::String("f".to_string())), Some(InputOption::VALUE_REQUIRED), "If you want to choose a different composer.json or config.json", None).unwrap().into(), + InputOption::new("list", Some("l"), Some(InputOption::VALUE_NONE), "List configuration settings", None).unwrap().into(), + InputOption::new("file", Some("f"), Some(InputOption::VALUE_REQUIRED), "If you want to choose a different composer.json or config.json", None).unwrap().into(), InputOption::new("absolute", None, Some(InputOption::VALUE_NONE), "Returns absolute paths when fetching *-dir config values instead of relative", None).unwrap().into(), - InputOption::new("json", Some(PhpMixed::String("j".to_string())), Some(InputOption::VALUE_NONE), "JSON decode the setting value, to be used with extra.* keys", None).unwrap().into(), - InputOption::new("merge", Some(PhpMixed::String("m".to_string())), Some(InputOption::VALUE_NONE), "Merge the setting value with the current value, to be used with extra.* or audit.ignore[-abandoned] keys in combination with --json", None).unwrap().into(), + InputOption::new("json", Some("j"), Some(InputOption::VALUE_NONE), "JSON decode the setting value, to be used with extra.* keys", None).unwrap().into(), + InputOption::new("merge", Some("m"), Some(InputOption::VALUE_NONE), "Merge the setting value with the current value, to be used with extra.* or audit.ignore[-abandoned] keys in combination with --json", None).unwrap().into(), InputOption::new("append", None, Some(InputOption::VALUE_NONE), "When adding a repository, append it (lowest priority) to the existing ones instead of prepending it (highest priority)", None).unwrap().into(), InputOption::new("source", None, Some(InputOption::VALUE_NONE), "Display where the config value is loaded from", None).unwrap().into(), InputArgument::new5("setting-key", None, "Setting key", None, self.suggest_setting_keys()).unwrap().into(), @@ -664,12 +664,8 @@ impl Command for ConfigCommand { // If the user enters in a config variable, parse it and save to file let setting_values_raw = input.borrow().get_argument("setting-value")?; let setting_values: Vec = setting_values_raw - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) + .as_array() + .map(<[String]>::to_vec) .unwrap_or_default(); if !setting_values.is_empty() && input.borrow().get_option("unset")?.as_bool() == Some(true) { diff --git a/crates/shirabe/src/command/create_project_command.rs b/crates/shirabe/src/command/create_project_command.rs index eb23ffff..e2161aa3 100644 --- a/crates/shirabe/src/command/create_project_command.rs +++ b/crates/shirabe/src/command/create_project_command.rs @@ -45,6 +45,7 @@ use shirabe_php_shim::{ }; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; use shirabe_symfony_finder::Finder; use std::path::PathBuf; @@ -834,7 +835,7 @@ impl Command for CreateProjectCommand { InputArgument::new5("package", Some(InputArgument::OPTIONAL), "Package name to be installed", None, self.suggest_available_package(99)).unwrap().into(), InputArgument::new("directory", Some(InputArgument::OPTIONAL), "Directory where the files should be created", None).unwrap().into(), InputArgument::new("version", Some(InputArgument::OPTIONAL), "Version, will default to latest", None).unwrap().into(), - InputOption::new("stability", Some(PhpMixed::String("s".to_string())), Some(InputOption::VALUE_REQUIRED), "Minimum-stability allowed (unless a version is specified).", None).unwrap().into(), + InputOption::new("stability", Some("s"), Some(InputOption::VALUE_REQUIRED), "Minimum-stability allowed (unless a version is specified).", None).unwrap().into(), InputOption::new("prefer-source", None, Some(InputOption::VALUE_NONE), "Forces installation from package sources when possible, including VCS information.", None).unwrap().into(), InputOption::new("prefer-dist", None, Some(InputOption::VALUE_NONE), "Forces installation from package dist (default behavior).", None).unwrap().into(), InputOption::new6("prefer-install", None, Some(InputOption::VALUE_REQUIRED), "Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).", None, self.suggest_prefer_install()).unwrap().into(), @@ -851,7 +852,7 @@ impl Command for CreateProjectCommand { InputOption::new("remove-vcs", None, Some(InputOption::VALUE_NONE), "Whether to force deletion of the vcs folder without prompting.", None).unwrap().into(), InputOption::new("no-install", None, Some(InputOption::VALUE_NONE), "Whether to skip installation of the package dependencies.", None).unwrap().into(), InputOption::new("no-audit", None, Some(InputOption::VALUE_NONE), "Whether to skip auditing of the installed package dependencies (can also be set via the COMPOSER_NO_AUDIT=1 env var).", None).unwrap().into(), - InputOption::new6("audit-format", None, Some(InputOption::VALUE_REQUIRED), "Audit output format. Must be \"table\", \"plain\", \"json\" or \"summary\".", Some(PhpMixed::String(Auditor::FORMAT_SUMMARY.to_string())), SuggestedValues::List(Auditor::FORMATS.iter().map(|s| s.to_string()).collect())).unwrap().into(), + InputOption::new6("audit-format", None, Some(InputOption::VALUE_REQUIRED), "Audit output format. Must be \"table\", \"plain\", \"json\" or \"summary\".", Some(InputValue::String(Auditor::FORMAT_SUMMARY.to_string())), SuggestedValues::List(Auditor::FORMATS.iter().map(|s| s.to_string()).collect())).unwrap().into(), InputOption::new("no-security-blocking", None, Some(InputOption::VALUE_NONE), "Allows installing packages with security advisories or that are abandoned (can also be set via the COMPOSER_NO_SECURITY_BLOCKING=1 env var).", None).unwrap().into(), InputOption::new("ignore-platform-req", None, Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "Ignore a specific platform requirement (php & ext- packages).", None).unwrap().into(), InputOption::new("ignore-platform-reqs", None, Some(InputOption::VALUE_NONE), "Ignore all platform requirements (php & ext- packages).", None).unwrap().into(), @@ -900,7 +901,7 @@ impl Command for CreateProjectCommand { io.write_error("You are using the deprecated option \"no-custom-installers\". Use \"no-plugins\" instead."); input .borrow_mut() - .set_option("no-plugins", PhpMixed::Bool(true)); + .set_option("no-plugins", InputValue::Bool(true)); } if input.borrow().is_interactive() @@ -919,9 +920,10 @@ impl Command for CreateProjectCommand { "New project directory [{}]: ", array_pop(&mut parts).unwrap_or_default() ); - input - .borrow_mut() - .set_argument("directory", io.ask(prompt, PhpMixed::Null)?); + input.borrow_mut().set_argument( + "directory", + InputValue::from_php_mixed(&io.ask(prompt, PhpMixed::Null)?), + ); } let repository_opt = input.borrow().get_option("repository")?; diff --git a/crates/shirabe/src/command/depends_command.rs b/crates/shirabe/src/command/depends_command.rs index f22682e8..25f7bfd9 100644 --- a/crates/shirabe/src/command/depends_command.rs +++ b/crates/shirabe/src/command/depends_command.rs @@ -67,7 +67,7 @@ impl Command for DependsCommand { .into(), InputOption::new( crate::command::OPTION_RECURSIVE, - Some(shirabe_php_shim::PhpMixed::String("r".to_string())), + Some("r"), Some(InputOption::VALUE_NONE), "Recursively resolves up to the root package", None, @@ -76,7 +76,7 @@ impl Command for DependsCommand { .into(), InputOption::new( crate::command::OPTION_TREE, - Some(shirabe_php_shim::PhpMixed::String("t".to_string())), + Some("t"), Some(InputOption::VALUE_NONE), "Prints the results as a nested tree", None, diff --git a/crates/shirabe/src/command/dump_autoload_command.rs b/crates/shirabe/src/command/dump_autoload_command.rs index d9ac44ba..87acd74f 100644 --- a/crates/shirabe/src/command/dump_autoload_command.rs +++ b/crates/shirabe/src/command/dump_autoload_command.rs @@ -7,7 +7,7 @@ use crate::console::input::InputOption; use crate::io::IOInterfaceImmutable; use crate::plugin::CommandEvent; use crate::plugin::PluginEvents; -use shirabe_php_shim::{InvalidArgumentException, PhpMixed, file_exists, impl_php_class}; +use shirabe_php_shim::{InvalidArgumentException, file_exists, impl_php_class}; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::InputInterface; use shirabe_symfony_console::output::OutputInterface; @@ -43,8 +43,8 @@ impl Command for DumpAutoloadCommand { self.set_aliases(vec!["dumpautoload".to_string()])?; self.set_description("Dumps the autoloader"); self.set_definition(&[ - InputOption::new("optimize", Some(PhpMixed::String("o".to_string())), Some(InputOption::VALUE_NONE), "Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.", None).unwrap().into(), - InputOption::new("classmap-authoritative", Some(PhpMixed::String("a".to_string())), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize`.", None).unwrap().into(), + InputOption::new("optimize", Some("o"), Some(InputOption::VALUE_NONE), "Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.", None).unwrap().into(), + InputOption::new("classmap-authoritative", Some("a"), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize`.", None).unwrap().into(), InputOption::new("apcu", None, Some(InputOption::VALUE_NONE), "Use APCu to cache found/not-found classes.", None).unwrap().into(), InputOption::new("apcu-prefix", None, Some(InputOption::VALUE_REQUIRED), "Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu", None).unwrap().into(), InputOption::new("dry-run", None, Some(InputOption::VALUE_NONE), "Outputs the operations but will not execute anything.", None).unwrap().into(), diff --git a/crates/shirabe/src/command/exec_command.rs b/crates/shirabe/src/command/exec_command.rs index 92e46c8b..7afab2ab 100644 --- a/crates/shirabe/src/command/exec_command.rs +++ b/crates/shirabe/src/command/exec_command.rs @@ -10,6 +10,7 @@ use crate::io::IOInterfaceImmutable; use shirabe_php_shim::{PhpMixed, RuntimeException, basename, chdir, getcwd, glob, impl_php_class}; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -78,7 +79,7 @@ impl Command for ExecCommand { self.set_name("exec")?; self.set_description("Executes a vendored binary/script"); self.set_definition(&[ - InputOption::new("list", Some(PhpMixed::String("l".to_string())), Some(InputOption::VALUE_NONE), "", None).unwrap().into(), + InputOption::new("list", Some("l"), Some(InputOption::VALUE_NONE), "", None).unwrap().into(), // PHP passes an inline closure here (it takes no arguments; PHP tolerates the // extra ones the caller passes). InputArgument::new5("binary", @@ -141,10 +142,9 @@ impl Command for ExecCommand { )?; if let Some(idx) = binary.as_int() { - input.borrow_mut().set_argument( - "binary", - shirabe_php_shim::PhpMixed::String(binaries[idx as usize].clone()), - ); + input + .borrow_mut() + .set_argument("binary", InputValue::String(binaries[idx as usize].clone())); } Ok(()) @@ -230,12 +230,8 @@ impl Command for ExecCommand { let args = input .borrow() .get_argument("args")? - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect::>() - }) + .as_array() + .map(<[String]>::to_vec) .unwrap_or_default(); dispatcher.borrow_mut().dispatch_script( diff --git a/crates/shirabe/src/command/fund_command.rs b/crates/shirabe/src/command/fund_command.rs index 089f69e8..9511cc31 100644 --- a/crates/shirabe/src/command/fund_command.rs +++ b/crates/shirabe/src/command/fund_command.rs @@ -16,6 +16,7 @@ use shirabe_semver::constraint::MatchAllConstraint; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::formatter::OutputFormatter; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -85,10 +86,10 @@ impl Command for FundCommand { self.set_description("Discover how to help fund the maintenance of your dependencies"); self.set_definition(&[InputOption::new6( "format", - Some(PhpMixed::String("f".to_string())), + Some("f"), Some(InputOption::VALUE_REQUIRED), "Format of the output: text or json", - Some(PhpMixed::String("text".to_string())), + Some(InputValue::String("text".to_string())), SuggestedValues::List(vec!["text".to_string(), "json".to_string()]), ) .unwrap() diff --git a/crates/shirabe/src/command/global_command.rs b/crates/shirabe/src/command/global_command.rs index f31d29c4..0e3606a4 100644 --- a/crates/shirabe/src/command/global_command.rs +++ b/crates/shirabe/src/command/global_command.rs @@ -185,7 +185,7 @@ impl Command for GlobalCommand { return Ok(()); } - let command_name = input.get_argument("command-name")?.to_string(); + let command_name = input.get_argument("command-name")?.to_php_string(); let has = { let mut app_ref = application.borrow_mut(); let app = app_ref diff --git a/crates/shirabe/src/command/home_command.rs b/crates/shirabe/src/command/home_command.rs index c147bb68..015b6cf2 100644 --- a/crates/shirabe/src/command/home_command.rs +++ b/crates/shirabe/src/command/home_command.rs @@ -144,7 +144,7 @@ impl Command for HomeCommand { .into(), InputOption::new( "homepage", - Some(shirabe_php_shim::PhpMixed::String("H".to_string())), + Some("H"), Some(InputOption::VALUE_NONE), "Open the homepage instead of the repository URL.", None, @@ -153,7 +153,7 @@ impl Command for HomeCommand { .into(), InputOption::new( "show", - Some(shirabe_php_shim::PhpMixed::String("s".to_string())), + Some("s"), Some(InputOption::VALUE_NONE), "Only show the homepage or repository URL.", None, @@ -183,12 +183,8 @@ impl Command for HomeCommand { let packages: Vec = input .borrow() .get_argument("packages")? - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) + .as_array() + .map(<[String]>::to_vec) .unwrap_or_default(); let packages = if packages.is_empty() { diff --git a/crates/shirabe/src/command/init_command.rs b/crates/shirabe/src/command/init_command.rs index d1b5dbe5..9399c2a7 100644 --- a/crates/shirabe/src/command/init_command.rs +++ b/crates/shirabe/src/command/init_command.rs @@ -32,6 +32,7 @@ use shirabe_symfony_console::command::Command; use shirabe_symfony_console::helper::FormatBlockMessages; use shirabe_symfony_console::input::ArrayInput; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -444,10 +445,10 @@ impl Command for InitCommand { InputOption::new("homepage", None, Some(InputOption::VALUE_REQUIRED), "Homepage of package", None).unwrap().into(), InputOption::new6("require", None, Some(InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED), "Package to require with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or \"foo/bar 1.0.0\"", None, self.suggest_available_package_incl_platform()).unwrap().into(), InputOption::new6("require-dev", None, Some(InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED), "Package to require for development with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or \"foo/bar 1.0.0\"", None, self.suggest_available_package_incl_platform()).unwrap().into(), - InputOption::new("stability", Some(PhpMixed::String("s".to_string())), Some(InputOption::VALUE_REQUIRED), &format!("Minimum stability (empty or one of: {})", implode(", ", &base_package::STABILITIES.keys().map(|k| k.to_string()).collect::>())), None).unwrap().into(), - InputOption::new("license", Some(PhpMixed::String("l".to_string())), Some(InputOption::VALUE_REQUIRED), "License of package", None).unwrap().into(), + InputOption::new("stability", Some("s"), Some(InputOption::VALUE_REQUIRED), &format!("Minimum stability (empty or one of: {})", implode(", ", &base_package::STABILITIES.keys().map(|k| k.to_string()).collect::>())), None).unwrap().into(), + InputOption::new("license", Some("l"), Some(InputOption::VALUE_REQUIRED), "License of package", None).unwrap().into(), InputOption::new("repository", None, Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "Add custom repositories, either by URL or using JSON arrays", None).unwrap().into(), - InputOption::new("autoload", Some(PhpMixed::String("a".to_string())), Some(InputOption::VALUE_REQUIRED), "Add PSR-4 autoload mapping. Maps your package's namespace to the provided directory. (Expects a relative path, e.g. src/)", None).unwrap().into(), + InputOption::new("autoload", Some("a"), Some(InputOption::VALUE_REQUIRED), "Add PSR-4 autoload mapping. Maps your package's namespace to the provided directory. (Expects a relative path, e.g. src/)", None).unwrap().into(), ]); self.set_help( "The init command creates a basic composer.json file\n\ @@ -480,12 +481,16 @@ impl Command for InitCommand { "license".to_string(), "autoload".to_string(), ]; - let filtered_input: IndexMap = array_intersect_key( - &input.borrow().get_options(), - &array_flip_strings(&allowlist), - ) - .into_iter() - .collect(); + let options: IndexMap = input + .borrow() + .get_options() + .into_iter() + .map(|(key, value)| (key, value.to_php_mixed())) + .collect(); + let filtered_input: IndexMap = + array_intersect_key(&options, &array_flip_strings(&allowlist)) + .into_iter() + .collect(); let mut options = shirabe_php_shim::array_filter_map(&filtered_input, |val: &PhpMixed| { !matches!(val, PhpMixed::Null) && !matches!(val, PhpMixed::List(l) if l.is_empty()) }); @@ -752,7 +757,7 @@ impl Command for InitCommand { let name = self.get_default_package_name()?; input .borrow_mut() - .set_option("name", PhpMixed::from(name)) + .set_option("name", InputValue::from(name)) .expect("name option is defined"); } @@ -760,7 +765,7 @@ impl Command for InitCommand { let author = self.get_default_author()?; input .borrow_mut() - .set_option("author", PhpMixed::from(author)) + .set_option("author", InputValue::from(author)) .expect("author option is defined"); } } @@ -919,7 +924,7 @@ impl Command for InitCommand { .to_string(); input .borrow_mut() - .set_option("name", PhpMixed::String(name)); + .set_option("name", InputValue::String(name)); let description = input .borrow() @@ -936,7 +941,9 @@ impl Command for InitCommand { .map(PhpMixed::String) .unwrap_or(PhpMixed::Null), )?; - input.borrow_mut().set_option("description", description); + input + .borrow_mut() + .set_option("description", InputValue::from_php_mixed(&description)); let author_option = input .borrow() @@ -984,7 +991,9 @@ impl Command for InitCommand { None, PhpMixed::String(author_default), )?; - input.borrow_mut().set_option("author", author_value); + input + .borrow_mut() + .set_option("author", InputValue::from_php_mixed(&author_value)); let minimum_stability = input .borrow() @@ -1029,9 +1038,10 @@ impl Command for InitCommand { .map(PhpMixed::String) .unwrap_or(PhpMixed::Null), )?; - input - .borrow_mut() - .set_option("stability", minimum_stability_value); + input.borrow_mut().set_option( + "stability", + InputValue::from_php_mixed(&minimum_stability_value), + ); let type_val = input.borrow().get_option("type")?; let type_str = type_val.as_string().unwrap_or("").to_string(); @@ -1045,7 +1055,9 @@ impl Command for InitCommand { if type_value.as_string() == Some("") || matches!(type_value, PhpMixed::Bool(false)) { type_value = PhpMixed::Null; } - input.borrow_mut().set_option("type", type_value); + input + .borrow_mut() + .set_option("type", InputValue::from_php_mixed(&type_value)); let mut license = input .borrow() @@ -1086,7 +1098,9 @@ impl Command for InitCommand { )) .into()); } - input.borrow_mut().set_option("license", license); + input + .borrow_mut() + .set_option("license", InputValue::from_php_mixed(&license)); io.write_error3("\nDefine your dependencies.\n", true, io_interface::NORMAL); @@ -1135,10 +1149,9 @@ impl Command for InitCommand { } else { vec![] }; - input.borrow_mut().set_option( - "require", - PhpMixed::List(requirements.into_iter().map(PhpMixed::String).collect()), - ); + input + .borrow_mut() + .set_option("require", InputValue::Array(requirements)); let question = "Would you like to define your dev dependencies (require-dev) interactively [yes]? ".to_string(); let require_dev: Vec = input @@ -1161,10 +1174,9 @@ impl Command for InitCommand { } else { vec![] }; - input.borrow_mut().set_option( - "require-dev", - PhpMixed::List(dev_requirements.into_iter().map(PhpMixed::String).collect()), - ); + input + .borrow_mut() + .set_option("require-dev", InputValue::Array(dev_requirements)); // --autoload - input and validation let autoload = input @@ -1220,7 +1232,9 @@ impl Command for InitCommand { None, PhpMixed::String(autoload_default), )?; - input.borrow_mut().set_option("autoload", autoload_value); + input + .borrow_mut() + .set_option("autoload", InputValue::from_php_mixed(&autoload_value)); Ok(()) })(); diff --git a/crates/shirabe/src/command/install_command.rs b/crates/shirabe/src/command/install_command.rs index f1a6df35..1431fb57 100644 --- a/crates/shirabe/src/command/install_command.rs +++ b/crates/shirabe/src/command/install_command.rs @@ -13,9 +13,10 @@ use crate::io::IOInterfaceImmutable; use crate::plugin::CommandEvent; use crate::plugin::PluginEvents; use crate::util::HttpDownloader; -use shirabe_php_shim::{PhpMixed, impl_php_class}; +use shirabe_php_shim::impl_php_class; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -62,10 +63,10 @@ impl Command for InstallCommand { InputOption::new("no-progress", None, Some(InputOption::VALUE_NONE), "Do not output download progress.", None).unwrap().into(), InputOption::new("no-install", None, Some(InputOption::VALUE_NONE), "Do not use, only defined here to catch misuse of the install command.", None).unwrap().into(), InputOption::new("audit", None, Some(InputOption::VALUE_NONE), "Run an audit after installation is complete.", None).unwrap().into(), - InputOption::new6("audit-format", None, Some(InputOption::VALUE_REQUIRED), "Audit output format. Must be \"table\", \"plain\", \"json\", or \"summary\".", Some(PhpMixed::String(Auditor::FORMAT_SUMMARY.to_string())), SuggestedValues::List(Auditor::FORMATS.iter().map(|s| s.to_string()).collect())).unwrap().into(), - InputOption::new("verbose", Some(PhpMixed::String("v|vv|vvv".to_string())), Some(InputOption::VALUE_NONE), "Shows more details including new commits pulled in when updating packages.", None).unwrap().into(), - InputOption::new("optimize-autoloader", Some(PhpMixed::String("o".to_string())), Some(InputOption::VALUE_NONE), "Optimize autoloader during autoloader dump", None).unwrap().into(), - InputOption::new("classmap-authoritative", Some(PhpMixed::String("a".to_string())), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.", None).unwrap().into(), + InputOption::new6("audit-format", None, Some(InputOption::VALUE_REQUIRED), "Audit output format. Must be \"table\", \"plain\", \"json\", or \"summary\".", Some(InputValue::String(Auditor::FORMAT_SUMMARY.to_string())), SuggestedValues::List(Auditor::FORMATS.iter().map(|s| s.to_string()).collect())).unwrap().into(), + InputOption::new("verbose", Some("v|vv|vvv"), Some(InputOption::VALUE_NONE), "Shows more details including new commits pulled in when updating packages.", None).unwrap().into(), + InputOption::new("optimize-autoloader", Some("o"), Some(InputOption::VALUE_NONE), "Optimize autoloader during autoloader dump", None).unwrap().into(), + InputOption::new("classmap-authoritative", Some("a"), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.", None).unwrap().into(), InputOption::new("apcu-autoloader", None, Some(InputOption::VALUE_NONE), "Use APCu to cache found/not-found classes.", None).unwrap().into(), InputOption::new("apcu-autoloader-prefix", None, Some(InputOption::VALUE_REQUIRED), "Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader", None).unwrap().into(), InputOption::new("ignore-platform-req", None, Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "Ignore a specific platform requirement (php & ext- packages).", None).unwrap().into(), @@ -103,14 +104,7 @@ impl Command for InstallCommand { } let args = input.borrow().get_argument("packages")?; - let args_vec: Vec = args - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) - .unwrap_or_default(); + let args_vec: Vec = args.as_array().map(<[String]>::to_vec).unwrap_or_default(); if !args_vec.is_empty() { io.write_error(&format!( "Invalid argument {}. Use \"composer require {}\" instead to add packages to your composer.json.", diff --git a/crates/shirabe/src/command/licenses_command.rs b/crates/shirabe/src/command/licenses_command.rs index 4087e6e3..4270c03d 100644 --- a/crates/shirabe/src/command/licenses_command.rs +++ b/crates/shirabe/src/command/licenses_command.rs @@ -19,6 +19,7 @@ use shirabe_symfony_console::formatter::OutputFormatter; use shirabe_symfony_console::helper::Row; use shirabe_symfony_console::helper::Table; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; use shirabe_symfony_console::style::StyleInterface; use shirabe_symfony_console::style::SymfonyStyle; @@ -55,10 +56,10 @@ impl Command for LicensesCommand { self.set_definition(&[ InputOption::new6( "format", - Some(PhpMixed::String("f".to_string())), + Some("f"), Some(InputOption::VALUE_REQUIRED), "Format of the output: text, json or summary", - Some(PhpMixed::String("text".to_string())), + Some(InputValue::String("text".to_string())), SuggestedValues::List(vec![ "text".to_string(), "json".to_string(), diff --git a/crates/shirabe/src/command/outdated_command.rs b/crates/shirabe/src/command/outdated_command.rs index a89a1cd8..b32fccdf 100644 --- a/crates/shirabe/src/command/outdated_command.rs +++ b/crates/shirabe/src/command/outdated_command.rs @@ -8,10 +8,12 @@ use crate::console::input::InputArgument; use crate::console::input::InputOption; use crate::console::input::SuggestedValues; use indexmap::IndexMap; -use shirabe_php_shim::{PhpMixed, impl_php_class}; +use shirabe_php_shim::impl_php_class; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::ArrayInput; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -45,16 +47,16 @@ impl Command for OutdatedCommand { self.set_description("Shows a list of installed packages that have updates available, including their latest version"); self.set_definition(&[ InputArgument::new5("package", Some(InputArgument::OPTIONAL), "Package to inspect. Or a name including a wildcard (*) to filter lists of packages instead.", None, self.suggest_installed_package(false, false)).unwrap().into(), - InputOption::new("outdated", Some(PhpMixed::String("o".to_string())), Some(InputOption::VALUE_NONE), "Show only packages that are outdated (this is the default, but present here for compat with `show`", None).unwrap().into(), - InputOption::new("all", Some(PhpMixed::String("a".to_string())), Some(InputOption::VALUE_NONE), "Show all installed packages with their latest versions", None).unwrap().into(), + InputOption::new("outdated", Some("o"), Some(InputOption::VALUE_NONE), "Show only packages that are outdated (this is the default, but present here for compat with `show`", None).unwrap().into(), + InputOption::new("all", Some("a"), Some(InputOption::VALUE_NONE), "Show all installed packages with their latest versions", None).unwrap().into(), InputOption::new("locked", None, Some(InputOption::VALUE_NONE), "Shows updates for packages from the lock file, regardless of what is currently in vendor dir", None).unwrap().into(), - InputOption::new("direct", Some(PhpMixed::String("D".to_string())), Some(InputOption::VALUE_NONE), "Shows only packages that are directly required by the root package", None).unwrap().into(), + InputOption::new("direct", Some("D"), Some(InputOption::VALUE_NONE), "Shows only packages that are directly required by the root package", None).unwrap().into(), InputOption::new("strict", None, Some(InputOption::VALUE_NONE), "Return a non-zero exit code when there are outdated packages", None).unwrap().into(), - InputOption::new("major-only", Some(PhpMixed::String("M".to_string())), Some(InputOption::VALUE_NONE), "Show only packages that have major SemVer-compatible updates.", None).unwrap().into(), - InputOption::new("minor-only", Some(PhpMixed::String("m".to_string())), Some(InputOption::VALUE_NONE), "Show only packages that have minor SemVer-compatible updates.", None).unwrap().into(), - InputOption::new("patch-only", Some(PhpMixed::String("p".to_string())), Some(InputOption::VALUE_NONE), "Show only packages that have patch SemVer-compatible updates.", None).unwrap().into(), - InputOption::new("sort-by-age", Some(PhpMixed::String("A".to_string())), Some(InputOption::VALUE_NONE), "Displays the installed version's age, and sorts packages oldest first.", None).unwrap().into(), - InputOption::new6("format", Some(PhpMixed::String("f".to_string())), Some(InputOption::VALUE_REQUIRED), "Format of the output: text or json", Some(PhpMixed::String("text".to_string())), SuggestedValues::List(vec!["json".to_string(), "text".to_string()])).unwrap().into(), + InputOption::new("major-only", Some("M"), Some(InputOption::VALUE_NONE), "Show only packages that have major SemVer-compatible updates.", None).unwrap().into(), + InputOption::new("minor-only", Some("m"), Some(InputOption::VALUE_NONE), "Show only packages that have minor SemVer-compatible updates.", None).unwrap().into(), + InputOption::new("patch-only", Some("p"), Some(InputOption::VALUE_NONE), "Show only packages that have patch SemVer-compatible updates.", None).unwrap().into(), + InputOption::new("sort-by-age", Some("A"), Some(InputOption::VALUE_NONE), "Displays the installed version's age, and sorts packages oldest first.", None).unwrap().into(), + InputOption::new6("format", Some("f"), Some(InputOption::VALUE_REQUIRED), "Format of the output: text or json", Some(InputValue::String("text".to_string())), SuggestedValues::List(vec!["json".to_string(), "text".to_string()])).unwrap().into(), InputOption::new6("ignore", None, Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "Ignore specified package(s). Can contain wildcards (*). Use it if you don't want to be informed about new versions of some packages.", None, self.suggest_installed_package(false, false)).unwrap().into(), InputOption::new("no-dev", None, Some(InputOption::VALUE_NONE), "Disables search in require-dev packages.", None).unwrap().into(), InputOption::new("ignore-platform-req", None, Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "Ignore a specific platform requirement (php & ext- packages). Use with the --outdated option", None).unwrap().into(), @@ -78,9 +80,12 @@ impl Command for OutdatedCommand { input: std::rc::Rc>, output: std::rc::Rc>, ) -> anyhow::Result { - let mut args: IndexMap = IndexMap::new(); - args.insert("command".to_string(), PhpMixed::String("show".to_string())); - args.insert("--latest".to_string(), PhpMixed::Bool(true)); + let mut args: IndexMap = IndexMap::new(); + args.insert( + "command".to_string(), + InputValue::String("show".to_string()), + ); + args.insert("--latest".to_string(), InputValue::Bool(true)); if input .borrow() @@ -88,7 +93,7 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--no-interaction".to_string(), PhpMixed::Bool(true)); + args.insert("--no-interaction".to_string(), InputValue::Bool(true)); } if input .borrow() @@ -96,7 +101,7 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--no-plugins".to_string(), PhpMixed::Bool(true)); + args.insert("--no-plugins".to_string(), InputValue::Bool(true)); } if input .borrow() @@ -104,7 +109,7 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--no-scripts".to_string(), PhpMixed::Bool(true)); + args.insert("--no-scripts".to_string(), InputValue::Bool(true)); } if input .borrow() @@ -112,10 +117,10 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--no-cache".to_string(), PhpMixed::Bool(true)); + args.insert("--no-cache".to_string(), InputValue::Bool(true)); } if !input.borrow().get_option("all")?.as_bool().unwrap_or(false) { - args.insert("--outdated".to_string(), PhpMixed::Bool(true)); + args.insert("--outdated".to_string(), InputValue::Bool(true)); } if input .borrow() @@ -123,10 +128,10 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--direct".to_string(), PhpMixed::Bool(true)); + args.insert("--direct".to_string(), InputValue::Bool(true)); } let package_arg = input.borrow().get_argument("package")?; - if !matches!(package_arg, PhpMixed::Null) { + if !package_arg.is_null() { args.insert("package".to_string(), package_arg); } if input @@ -135,7 +140,7 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--strict".to_string(), PhpMixed::Bool(true)); + args.insert("--strict".to_string(), InputValue::Bool(true)); } if input .borrow() @@ -143,7 +148,7 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--major-only".to_string(), PhpMixed::Bool(true)); + args.insert("--major-only".to_string(), InputValue::Bool(true)); } if input .borrow() @@ -151,7 +156,7 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--minor-only".to_string(), PhpMixed::Bool(true)); + args.insert("--minor-only".to_string(), InputValue::Bool(true)); } if input .borrow() @@ -159,7 +164,7 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--patch-only".to_string(), PhpMixed::Bool(true)); + args.insert("--patch-only".to_string(), InputValue::Bool(true)); } if input .borrow() @@ -167,7 +172,7 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--locked".to_string(), PhpMixed::Bool(true)); + args.insert("--locked".to_string(), InputValue::Bool(true)); } if input .borrow() @@ -175,7 +180,7 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--no-dev".to_string(), PhpMixed::Bool(true)); + args.insert("--no-dev".to_string(), InputValue::Bool(true)); } if input .borrow() @@ -183,11 +188,11 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--sort-by-age".to_string(), PhpMixed::Bool(true)); + args.insert("--sort-by-age".to_string(), InputValue::Bool(true)); } args.insert( "--ignore-platform-req".to_string(), - input.borrow().get_option("ignore-platform-req")?.into(), + input.borrow().get_option("ignore-platform-req")?, ); if input .borrow() @@ -195,20 +200,14 @@ impl Command for OutdatedCommand { .as_bool() .unwrap_or(false) { - args.insert("--ignore-platform-reqs".to_string(), PhpMixed::Bool(true)); + args.insert("--ignore-platform-reqs".to_string(), InputValue::Bool(true)); } - args.insert( - "--format".to_string(), - input.borrow().get_option("format")?.into(), - ); - args.insert( - "--ignore".to_string(), - input.borrow().get_option("ignore")?.into(), - ); + args.insert("--format".to_string(), input.borrow().get_option("format")?); + args.insert("--ignore".to_string(), input.borrow().get_option("ignore")?); let input = ArrayInput::new( args.into_iter() - .map(|(k, v)| (PhpMixed::String(k), v)) + .map(|(k, v)| (ParameterName::Name(k), v)) .collect(), None, )?; diff --git a/crates/shirabe/src/command/prohibits_command.rs b/crates/shirabe/src/command/prohibits_command.rs index ae38f9d2..c7579efb 100644 --- a/crates/shirabe/src/command/prohibits_command.rs +++ b/crates/shirabe/src/command/prohibits_command.rs @@ -74,7 +74,7 @@ impl Command for ProhibitsCommand { .into(), InputOption::new( ::OPTION_RECURSIVE, - Some(shirabe_php_shim::PhpMixed::String("r".to_string())), + Some("r"), Some(InputOption::VALUE_NONE), "Recursively resolves up to the root package", None, @@ -83,7 +83,7 @@ impl Command for ProhibitsCommand { .into(), InputOption::new( ::OPTION_TREE, - Some(shirabe_php_shim::PhpMixed::String("t".to_string())), + Some("t"), Some(InputOption::VALUE_NONE), "Prints the results as a nested tree", None, diff --git a/crates/shirabe/src/command/reinstall_command.rs b/crates/shirabe/src/command/reinstall_command.rs index 43978191..aa98e89f 100644 --- a/crates/shirabe/src/command/reinstall_command.rs +++ b/crates/shirabe/src/command/reinstall_command.rs @@ -55,8 +55,8 @@ impl Command for ReinstallCommand { InputOption::new6("prefer-install", None, Some(InputOption::VALUE_REQUIRED), "Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).", None, self.suggest_prefer_install()).unwrap().into(), InputOption::new("no-autoloader", None, Some(InputOption::VALUE_NONE), "Skips autoloader generation", None).unwrap().into(), InputOption::new("no-progress", None, Some(InputOption::VALUE_NONE), "Do not output download progress.", None).unwrap().into(), - InputOption::new("optimize-autoloader", Some(shirabe_php_shim::PhpMixed::String("o".to_string())), Some(InputOption::VALUE_NONE), "Optimize autoloader during autoloader dump", None).unwrap().into(), - InputOption::new("classmap-authoritative", Some(shirabe_php_shim::PhpMixed::String("a".to_string())), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.", None).unwrap().into(), + InputOption::new("optimize-autoloader", Some("o"), Some(InputOption::VALUE_NONE), "Optimize autoloader during autoloader dump", None).unwrap().into(), + InputOption::new("classmap-authoritative", Some("a"), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.", None).unwrap().into(), InputOption::new("apcu-autoloader", None, Some(InputOption::VALUE_NONE), "Use APCu to cache found/not-found classes.", None).unwrap().into(), InputOption::new("apcu-autoloader-prefix", None, Some(InputOption::VALUE_REQUIRED), "Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader", None).unwrap().into(), InputOption::new("ignore-platform-req", None, Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "Ignore a specific platform requirement (php & ext- packages).", None).unwrap().into(), @@ -93,7 +93,7 @@ impl Command for ReinstallCommand { let type_option = input.borrow().get_option("type")?; let type_count = type_option.as_array().map_or(0, <[String]>::len); let packages_arg = input.borrow().get_argument("packages")?; - let packages_count = packages_arg.as_list().map_or(0, |l| l.len()); + let packages_count = packages_arg.as_array().map_or(0, <[String]>::len); if type_count > 0 { if packages_count > 0 { @@ -121,12 +121,8 @@ impl Command for ReinstallCommand { .into()); } let patterns: Vec = packages_arg - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) + .as_array() + .map(<[String]>::to_vec) .unwrap_or_default(); for pattern in &patterns { let pattern_regexp = base_package::package_name_to_regexp(pattern); diff --git a/crates/shirabe/src/command/remove_command.rs b/crates/shirabe/src/command/remove_command.rs index 7eb88f2b..9004a9fd 100644 --- a/crates/shirabe/src/command/remove_command.rs +++ b/crates/shirabe/src/command/remove_command.rs @@ -21,6 +21,7 @@ use shirabe_php_shim::{PhpMixed, UnexpectedValueException, impl_php_class, preg_ use shirabe_symfony_console::command::Command; use shirabe_symfony_console::exception::InvalidArgumentException; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -93,7 +94,7 @@ impl Command for RemoveCommand { None, Some(InputOption::VALUE_REQUIRED), "Audit output format. Must be \"table\", \"plain\", \"json\", or \"summary\".", - Some(PhpMixed::String(Auditor::FORMAT_SUMMARY.to_string())), + Some(InputValue::String(Auditor::FORMAT_SUMMARY.to_string())), SuggestedValues::List(Auditor::FORMATS.iter().map(|s| s.to_string()).collect())).unwrap().into(), InputOption::new("no-security-blocking", None, @@ -106,12 +107,12 @@ impl Command for RemoveCommand { "Run the dependency update with the --no-dev option.", None).unwrap().into(), InputOption::new("update-with-dependencies", - Some(PhpMixed::String("w".to_string())), + Some("w"), Some(InputOption::VALUE_NONE), "Allows inherited dependencies to be updated with explicit dependencies (can also be set via the COMPOSER_WITH_DEPENDENCIES=1 env var). (Deprecated, is now default behavior)", None).unwrap().into(), InputOption::new("update-with-all-dependencies", - Some(PhpMixed::String("W".to_string())), + Some("W"), Some(InputOption::VALUE_NONE), "Allows all inherited dependencies to be updated, including those that are root requirements (can also be set via the COMPOSER_WITH_ALL_DEPENDENCIES=1 env var).", None).unwrap().into(), @@ -126,7 +127,7 @@ impl Command for RemoveCommand { "Does not allow inherited dependencies to be updated with explicit dependencies.", None).unwrap().into(), InputOption::new("minimal-changes", - Some(PhpMixed::String("m".to_string())), + Some("m"), Some(InputOption::VALUE_NONE), "During an update with -w/-W, only perform absolutely necessary changes to transitive dependencies (can also be set via the COMPOSER_MINIMAL_CHANGES=1 env var).", None).unwrap().into(), @@ -146,12 +147,12 @@ impl Command for RemoveCommand { "Ignore all platform requirements (php & ext- packages).", None).unwrap().into(), InputOption::new("optimize-autoloader", - Some(PhpMixed::String("o".to_string())), + Some("o"), Some(InputOption::VALUE_NONE), "Optimize autoloader during autoloader dump", None).unwrap().into(), InputOption::new("classmap-authoritative", - Some(PhpMixed::String("a".to_string())), + Some("a"), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.", None).unwrap().into(), @@ -183,8 +184,8 @@ impl Command for RemoveCommand { if input .borrow() .get_argument("packages")? - .as_list() - .map(|l| l.is_empty()) + .as_array() + .map(<[String]>::is_empty) .unwrap_or(true) && !input .borrow() @@ -201,12 +202,8 @@ impl Command for RemoveCommand { let mut packages: Vec = input .borrow() .get_argument("packages")? - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(strtolower)) - .collect() - }) + .as_array() + .map(|l| l.iter().map(|v| strtolower(v)).collect()) .unwrap_or_default(); if input diff --git a/crates/shirabe/src/command/repository_command.rs b/crates/shirabe/src/command/repository_command.rs index 8f68b16b..4cf0c981 100644 --- a/crates/shirabe/src/command/repository_command.rs +++ b/crates/shirabe/src/command/repository_command.rs @@ -16,6 +16,7 @@ use shirabe_php_shim::{ }; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -128,7 +129,7 @@ impl RepositoryCommand { /// PHP: private function suggestTypeForAdd(): \Closure (a static closure — `this` unused) fn suggest_type_for_add(&self) -> crate::console::input::SuggestedValues { crate::console::input::SuggestedValues::Closure(Box::new(|_this, input, _suggestions| { - if input.get_argument("action")?.to_string() == "add" { + if input.get_argument("action")?.to_php_string() == "add" { return Ok(vec![ "composer".to_string(), "vcs".to_string(), @@ -143,7 +144,7 @@ impl RepositoryCommand { fn suggest_repo_names(&self) -> crate::console::input::SuggestedValues { crate::console::input::SuggestedValues::Closure(Box::new(|this, input, _suggestions| { - let action = input.get_argument("action")?.to_string(); + let action = input.get_argument("action")?.to_php_string(); if ["enable", "disable"].contains(&action.as_str()) { return Ok(vec!["packagist.org".to_string()]); } @@ -202,7 +203,7 @@ impl Command for RepositoryCommand { self.set_definition(&[ InputOption::new( "global", - Some(PhpMixed::String("g".to_string())), + Some("g"), Some(InputOption::VALUE_NONE), "Apply command to the global config file", None, @@ -211,7 +212,7 @@ impl Command for RepositoryCommand { .into(), InputOption::new( "file", - Some(PhpMixed::String("f".to_string())), + Some("f"), Some(InputOption::VALUE_REQUIRED), "If you want to choose a different composer.json or config.json", None, @@ -251,7 +252,7 @@ impl Command for RepositoryCommand { "action", Some(InputArgument::OPTIONAL), "Action to perform: list, add, remove, set-url, get-url, enable, disable", - Some(PhpMixed::String("list".to_string())), + Some(InputValue::String("list".to_string())), crate::console::input::SuggestedValues::List(vec![ "list".to_string(), "add".to_string(), diff --git a/crates/shirabe/src/command/require_command.rs b/crates/shirabe/src/command/require_command.rs index f06c4d84..15eae91b 100644 --- a/crates/shirabe/src/command/require_command.rs +++ b/crates/shirabe/src/command/require_command.rs @@ -40,6 +40,7 @@ use shirabe_php_shim::{ }; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -440,12 +441,8 @@ impl RequireCommand { input .borrow() .get_argument("packages")? - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) + .as_array() + .map(<[String]>::to_vec) .unwrap_or_default(), )? { if !req.contains_key("version") { @@ -753,21 +750,21 @@ impl Command for RequireCommand { InputOption::new("no-update", None, Some(InputOption::VALUE_NONE), "Disables the automatic update of the dependencies (implies --no-install).", None).unwrap().into(), InputOption::new("no-install", None, Some(InputOption::VALUE_NONE), "Skip the install step after updating the composer.lock file.", None).unwrap().into(), InputOption::new("no-audit", None, Some(InputOption::VALUE_NONE), "Skip the audit step after updating the composer.lock file (can also be set via the COMPOSER_NO_AUDIT=1 env var).", None).unwrap().into(), - InputOption::new6("audit-format", None, Some(InputOption::VALUE_REQUIRED), "Audit output format. Must be \"table\", \"plain\", \"json\", or \"summary\".", Some(PhpMixed::String(Auditor::FORMAT_SUMMARY.to_string())), SuggestedValues::List(Auditor::FORMATS.iter().map(|s| s.to_string()).collect())).unwrap().into(), + InputOption::new6("audit-format", None, Some(InputOption::VALUE_REQUIRED), "Audit output format. Must be \"table\", \"plain\", \"json\", or \"summary\".", Some(InputValue::String(Auditor::FORMAT_SUMMARY.to_string())), SuggestedValues::List(Auditor::FORMATS.iter().map(|s| s.to_string()).collect())).unwrap().into(), InputOption::new("no-security-blocking", None, Some(InputOption::VALUE_NONE), "Allows installing packages with security advisories or that are abandoned (can also be set via the COMPOSER_NO_SECURITY_BLOCKING=1 env var).", None).unwrap().into(), InputOption::new("update-no-dev", None, Some(InputOption::VALUE_NONE), "Run the dependency update with the --no-dev option.", None).unwrap().into(), - InputOption::new("update-with-dependencies", Some(PhpMixed::String("w".to_string())), Some(InputOption::VALUE_NONE), "Allows inherited dependencies to be updated, except those that are root requirements (can also be set via the COMPOSER_WITH_DEPENDENCIES=1 env var).", None).unwrap().into(), - InputOption::new("update-with-all-dependencies", Some(PhpMixed::String("W".to_string())), Some(InputOption::VALUE_NONE), "Allows all inherited dependencies to be updated, including those that are root requirements (can also be set via the COMPOSER_WITH_ALL_DEPENDENCIES=1 env var).", None).unwrap().into(), + InputOption::new("update-with-dependencies", Some("w"), Some(InputOption::VALUE_NONE), "Allows inherited dependencies to be updated, except those that are root requirements (can also be set via the COMPOSER_WITH_DEPENDENCIES=1 env var).", None).unwrap().into(), + InputOption::new("update-with-all-dependencies", Some("W"), Some(InputOption::VALUE_NONE), "Allows all inherited dependencies to be updated, including those that are root requirements (can also be set via the COMPOSER_WITH_ALL_DEPENDENCIES=1 env var).", None).unwrap().into(), InputOption::new("with-dependencies", None, Some(InputOption::VALUE_NONE), "Alias for --update-with-dependencies", None).unwrap().into(), InputOption::new("with-all-dependencies", None, Some(InputOption::VALUE_NONE), "Alias for --update-with-all-dependencies", None).unwrap().into(), InputOption::new("ignore-platform-req", None, Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "Ignore a specific platform requirement (php & ext- packages).", None).unwrap().into(), InputOption::new("ignore-platform-reqs", None, Some(InputOption::VALUE_NONE), "Ignore all platform requirements (php & ext- packages).", None).unwrap().into(), InputOption::new("prefer-stable", None, Some(InputOption::VALUE_NONE), "Prefer stable versions of dependencies (can also be set via the COMPOSER_PREFER_STABLE=1 env var).", None).unwrap().into(), InputOption::new("prefer-lowest", None, Some(InputOption::VALUE_NONE), "Prefer lowest versions of dependencies (can also be set via the COMPOSER_PREFER_LOWEST=1 env var).", None).unwrap().into(), - InputOption::new("minimal-changes", Some(PhpMixed::String("m".to_string())), Some(InputOption::VALUE_NONE), "During an update with -w/-W, only perform absolutely necessary changes to transitive dependencies (can also be set via the COMPOSER_MINIMAL_CHANGES=1 env var).", None).unwrap().into(), + InputOption::new("minimal-changes", Some("m"), Some(InputOption::VALUE_NONE), "During an update with -w/-W, only perform absolutely necessary changes to transitive dependencies (can also be set via the COMPOSER_MINIMAL_CHANGES=1 env var).", None).unwrap().into(), InputOption::new("sort-packages", None, Some(InputOption::VALUE_NONE), "Sorts packages when adding/updating a new dependency", None).unwrap().into(), - InputOption::new("optimize-autoloader", Some(PhpMixed::String("o".to_string())), Some(InputOption::VALUE_NONE), "Optimize autoloader during autoloader dump", None).unwrap().into(), - InputOption::new("classmap-authoritative", Some(PhpMixed::String("a".to_string())), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.", None).unwrap().into(), + InputOption::new("optimize-autoloader", Some("o"), Some(InputOption::VALUE_NONE), "Optimize autoloader during autoloader dump", None).unwrap().into(), + InputOption::new("classmap-authoritative", Some("a"), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.", None).unwrap().into(), InputOption::new("apcu-autoloader", None, Some(InputOption::VALUE_NONE), "Use APCu to cache found/not-found classes.", None).unwrap().into(), InputOption::new("apcu-autoloader-prefix", None, Some(InputOption::VALUE_REQUIRED), "Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader", None).unwrap().into(), ]); @@ -934,12 +931,8 @@ impl Command for RequireCommand { let packages: Vec = input .borrow() .get_argument("packages")? - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) + .as_array() + .map(<[String]>::to_vec) .unwrap_or_default(); // if there is no update, we need to use the best possible version constraint directly as we cannot rely on the solver to guess the best constraint let no_update = input @@ -1057,7 +1050,9 @@ impl Command for RequireCommand { .to_string(), true, ) { - input.borrow_mut().set_option("dev", PhpMixed::Bool(true))?; + input + .borrow_mut() + .set_option("dev", InputValue::Bool(true))?; } } @@ -1142,7 +1137,9 @@ impl Command for RequireCommand { return Ok(0); } - input.borrow_mut().set_option("dev", PhpMixed::Bool(true))?; + input + .borrow_mut() + .set_option("dev", InputValue::Bool(true))?; std::mem::swap(&mut require_key, &mut remove_key); } } diff --git a/crates/shirabe/src/command/run_script_command.rs b/crates/shirabe/src/command/run_script_command.rs index a3a7d5be..5dc323cc 100644 --- a/crates/shirabe/src/command/run_script_command.rs +++ b/crates/shirabe/src/command/run_script_command.rs @@ -18,6 +18,7 @@ use shirabe_symfony_console::command::Command; use shirabe_symfony_console::exception::CommandNotFoundException; use shirabe_symfony_console::exception::NamespaceNotFoundException; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -182,7 +183,7 @@ impl Command for RunScriptCommand { .into(), InputOption::new( "list", - Some(PhpMixed::String("l".to_string())), + Some("l"), Some(InputOption::VALUE_NONE), "List scripts.", None, @@ -234,7 +235,9 @@ impl Command for RunScriptCommand { false, )?; - input.borrow_mut().set_argument("script", script)?; + input + .borrow_mut() + .set_argument("script", InputValue::from_php_mixed(&script))?; Ok(()) })(); @@ -309,12 +312,8 @@ impl Command for RunScriptCommand { let args: Vec = input .borrow() .get_argument("args")? - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) + .as_array() + .map(<[String]>::to_vec) .unwrap_or_default(); if let Some(timeout_val) = input.borrow().get_option("timeout")?.as_string() { diff --git a/crates/shirabe/src/command/script_alias_command.rs b/crates/shirabe/src/command/script_alias_command.rs index 713947f4..32d32634 100644 --- a/crates/shirabe/src/command/script_alias_command.rs +++ b/crates/shirabe/src/command/script_alias_command.rs @@ -144,12 +144,8 @@ impl Command for ScriptAliasCommand { let args_value: Vec = args .get("args") - .and_then(|v| v.as_list()) - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) + .and_then(|v| v.as_array()) + .map(<[String]>::to_vec) .unwrap_or_default(); dispatcher diff --git a/crates/shirabe/src/command/search_command.rs b/crates/shirabe/src/command/search_command.rs index e66c574b..0c7e8631 100644 --- a/crates/shirabe/src/command/search_command.rs +++ b/crates/shirabe/src/command/search_command.rs @@ -20,6 +20,7 @@ use shirabe_php_shim::{ use shirabe_symfony_console::command::Command; use shirabe_symfony_console::formatter::OutputFormatter; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -54,7 +55,7 @@ impl Command for SearchCommand { self.set_definition(&[ InputOption::new( "only-name", - Some(PhpMixed::String("N".to_string())), + Some("N"), Some(InputOption::VALUE_NONE), "Search only in package names", None, @@ -63,7 +64,7 @@ impl Command for SearchCommand { .into(), InputOption::new( "only-vendor", - Some(PhpMixed::String("O".to_string())), + Some("O"), Some(InputOption::VALUE_NONE), "Search only for vendor / organization names, returns only \"vendor\" as result", None, @@ -72,7 +73,7 @@ impl Command for SearchCommand { .into(), InputOption::new( "type", - Some(PhpMixed::String("t".to_string())), + Some("t"), Some(InputOption::VALUE_REQUIRED), "Search for a specific package type", None, @@ -81,10 +82,10 @@ impl Command for SearchCommand { .into(), InputOption::new6( "format", - Some(PhpMixed::String("f".to_string())), + Some("f"), Some(InputOption::VALUE_REQUIRED), "Format of the output: text or json", - Some(PhpMixed::String("text".to_string())), + Some(InputValue::String("text".to_string())), SuggestedValues::List(vec!["json".to_string(), "text".to_string()]), ) .unwrap() @@ -204,12 +205,8 @@ impl Command for SearchCommand { let tokens_arg = input.borrow().get_argument("tokens")?; let token_strings: Vec = tokens_arg - .as_list() - .map(|list| { - list.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) + .as_array() + .map(<[String]>::to_vec) .unwrap_or_default(); let mut query = implode(" ", &token_strings); if mode != repository_interface::SEARCH_FULLTEXT { diff --git a/crates/shirabe/src/command/self_update_command.rs b/crates/shirabe/src/command/self_update_command.rs index dabe8bc8..f78c53af 100644 --- a/crates/shirabe/src/command/self_update_command.rs +++ b/crates/shirabe/src/command/self_update_command.rs @@ -7,7 +7,7 @@ use crate::console::input::InputArgument; use crate::console::input::InputOption; use crate::io::IOInterfaceImmutable; use crate::io::io_interface; -use shirabe_php_shim::{PhpMixed, impl_php_class}; +use shirabe_php_shim::impl_php_class; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::InputInterface; use shirabe_symfony_console::output::OutputInterface; @@ -43,7 +43,7 @@ impl Command for SelfUpdateCommand { self.set_aliases(vec!["selfupdate".to_string()])?; self.set_description("Updates composer.phar to the latest version"); self.set_definition(&[ - InputOption::new("rollback", Some(PhpMixed::String("r".to_string())), Some(InputOption::VALUE_NONE), "Revert to an older installation of composer", None).unwrap().into(), + InputOption::new("rollback", Some("r"), Some(InputOption::VALUE_NONE), "Revert to an older installation of composer", None).unwrap().into(), InputOption::new("clean-backups", None, Some(InputOption::VALUE_NONE), "Delete old backups during an update. This makes the current version of composer the only backup available after the update", None).unwrap().into(), InputArgument::new("version", Some(InputArgument::OPTIONAL), "The version to update to", None).unwrap().into(), InputOption::new("no-progress", None, Some(InputOption::VALUE_NONE), "Do not output download progress.", None).unwrap().into(), diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs index 3cc80b4c..f605e2b5 100644 --- a/crates/shirabe/src/command/show_command.rs +++ b/crates/shirabe/src/command/show_command.rs @@ -49,6 +49,7 @@ use shirabe_symfony_console::command::Command; use shirabe_symfony_console::formatter::OutputFormatter; use shirabe_symfony_console::formatter::OutputFormatterStyle; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -1345,7 +1346,7 @@ impl Command for ShowCommand { let opt_none = |name: &str, shortcut: Option<&str>, description: &str| { InputOption::new( name, - shortcut.map(|s| PhpMixed::String(s.to_string())), + shortcut, Some(InputOption::VALUE_NONE), description, None, @@ -1432,10 +1433,10 @@ impl Command for ShowCommand { ), InputOption::new6( "format", - Some(PhpMixed::String("f".to_string())), + Some("f"), Some(InputOption::VALUE_REQUIRED), "Format of the output: text or json", - Some(PhpMixed::String("text".to_string())), + Some(InputValue::String("text".to_string())), SuggestedValues::List(vec!["json".to_string(), "text".to_string()]), ) .unwrap() @@ -1485,7 +1486,7 @@ impl Command for ShowCommand { if input.borrow().get_option("outdated")?.as_bool() == Some(true) { input .borrow_mut() - .set_option("latest", PhpMixed::Bool(true)); + .set_option("latest", InputValue::Bool(true)); } else if input .borrow() .get_option("ignore")? @@ -1857,7 +1858,7 @@ impl Command for ShowCommand { ); input .borrow_mut() - .set_option("latest", PhpMixed::Bool(false)); + .set_option("latest", InputValue::Bool(false)); } let package_filter: Option = input @@ -1876,7 +1877,7 @@ impl Command for ShowCommand { &installed_repo, &repos, pf, - input.borrow().get_argument("version")?, + input.borrow().get_argument("version")?.to_php_mixed(), )?; if let Some(ref pkg) = matched_package @@ -2084,7 +2085,9 @@ impl Command for ShowCommand { self.get_io().write_error( "No composer.json found in the current directory, disabling \"path\" option", ); - input.borrow_mut().set_option("path", PhpMixed::Bool(false)); + input + .borrow_mut() + .set_option("path", InputValue::Bool(false)); } for repo in RepositoryUtils::flatten_repositories(repos, true) { diff --git a/crates/shirabe/src/command/status_command.rs b/crates/shirabe/src/command/status_command.rs index bcb83a3a..2c7cb361 100644 --- a/crates/shirabe/src/command/status_command.rs +++ b/crates/shirabe/src/command/status_command.rs @@ -321,7 +321,7 @@ impl Command for StatusCommand { self.set_description("Shows a list of locally modified packages"); self.set_definition(&[InputOption::new( "verbose", - Some(shirabe_php_shim::PhpMixed::String("v|vv|vvv".to_string())), + Some("v|vv|vvv"), Some(InputOption::VALUE_NONE), "Show modified files for each directory that contains changes.", None, diff --git a/crates/shirabe/src/command/suggests_command.rs b/crates/shirabe/src/command/suggests_command.rs index 44f903da..e34a1faa 100644 --- a/crates/shirabe/src/command/suggests_command.rs +++ b/crates/shirabe/src/command/suggests_command.rs @@ -12,7 +12,7 @@ use crate::repository::RepositoryInterface; use crate::repository::RepositoryInterfaceHandle; use crate::repository::RootPackageRepository; use indexmap::IndexMap; -use shirabe_php_shim::{PhpMixed, empty, impl_php_class, in_array_loose}; +use shirabe_php_shim::{PhpMixed, impl_php_class, in_array_loose}; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::InputInterface; use shirabe_symfony_console::output::OutputInterface; @@ -67,7 +67,7 @@ impl Command for SuggestsCommand { .into(), InputOption::new( "all", - Some(PhpMixed::String("a".to_string())), + Some("a"), Some(InputOption::VALUE_NONE), "Show suggestions from all dependencies, including transitive ones", None, @@ -168,12 +168,18 @@ impl Command for SuggestsCommand { let mut reporter = SuggestedPackagesReporter::new(self.get_io().clone()); let filter = input.borrow().get_argument("packages")?; + let filter_values: Vec = filter + .as_array() + .unwrap_or_default() + .iter() + .map(|value| PhpMixed::String(value.clone())) + .collect(); let mut packages = RepositoryInterface::get_packages(&mut installed_repo)?; let root_pkg_as_base: crate::package::BasePackageHandle = composer.get_package().clone().into(); packages.push(root_pkg_as_base); for package in &packages { - if !empty(&filter) && !in_array_loose(package.get_name(), filter.values()) { + if filter.to_bool() && !in_array_loose(package.get_name(), &filter_values) { continue; } reporter.add_suggestions_from_package(package.clone()); @@ -207,7 +213,7 @@ impl Command for SuggestsCommand { } let only_dependents_of: Option = - if empty(&filter) && !input.borrow().get_option("all")?.as_bool().unwrap_or(false) { + if !filter.to_bool() && !input.borrow().get_option("all")?.as_bool().unwrap_or(false) { Some(composer.get_package().clone().into()) } else { None diff --git a/crates/shirabe/src/command/update_command.rs b/crates/shirabe/src/command/update_command.rs index d2e380ac..0548fc02 100644 --- a/crates/shirabe/src/command/update_command.rs +++ b/crates/shirabe/src/command/update_command.rs @@ -37,6 +37,7 @@ use shirabe_semver::constraint::MultiConstraint; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::helper::Table; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; #[derive(Debug)] @@ -271,27 +272,27 @@ impl Command for UpdateCommand { InputOption::new("lock", None, Some(InputOption::VALUE_NONE), "Overwrites the lock file hash to suppress warning about the lock file being out of date without updating package versions. Package metadata like mirrors and URLs are updated if they changed.", None).unwrap().into(), InputOption::new("no-install", None, Some(InputOption::VALUE_NONE), "Skip the install step after updating the composer.lock file.", None).unwrap().into(), InputOption::new("no-audit", None, Some(InputOption::VALUE_NONE), "Skip the audit step after updating the composer.lock file (can also be set via the COMPOSER_NO_AUDIT=1 env var).", None).unwrap().into(), - InputOption::new6("audit-format", None, Some(InputOption::VALUE_REQUIRED), "Audit output format. Must be \"table\", \"plain\", \"json\", or \"summary\".", Some(PhpMixed::String(Auditor::FORMAT_SUMMARY.to_string())), SuggestedValues::List(Auditor::FORMATS.iter().map(|s| s.to_string()).collect())).unwrap().into(), + InputOption::new6("audit-format", None, Some(InputOption::VALUE_REQUIRED), "Audit output format. Must be \"table\", \"plain\", \"json\", or \"summary\".", Some(InputValue::String(Auditor::FORMAT_SUMMARY.to_string())), SuggestedValues::List(Auditor::FORMATS.iter().map(|s| s.to_string()).collect())).unwrap().into(), InputOption::new("no-security-blocking", None, Some(InputOption::VALUE_NONE), "Allows installing packages with security advisories or that are abandoned (can also be set via the COMPOSER_NO_SECURITY_BLOCKING=1 env var).", None).unwrap().into(), InputOption::new("no-autoloader", None, Some(InputOption::VALUE_NONE), "Skips autoloader generation", None).unwrap().into(), InputOption::new("no-suggest", None, Some(InputOption::VALUE_NONE), "DEPRECATED: This flag does not exist anymore.", None).unwrap().into(), InputOption::new("no-progress", None, Some(InputOption::VALUE_NONE), "Do not output download progress.", None).unwrap().into(), - InputOption::new("with-dependencies", Some(PhpMixed::String("w".to_string())), Some(InputOption::VALUE_NONE), "Update also dependencies of packages in the argument list, except those which are root requirements (can also be set via the COMPOSER_WITH_DEPENDENCIES=1 env var).", None).unwrap().into(), - InputOption::new("with-all-dependencies", Some(PhpMixed::String("W".to_string())), Some(InputOption::VALUE_NONE), "Update also dependencies of packages in the argument list, including those which are root requirements (can also be set via the COMPOSER_WITH_ALL_DEPENDENCIES=1 env var).", None).unwrap().into(), - InputOption::new("verbose", Some(PhpMixed::String("v|vv|vvv".to_string())), Some(InputOption::VALUE_NONE), "Shows more details including new commits pulled in when updating packages.", None).unwrap().into(), - InputOption::new("optimize-autoloader", Some(PhpMixed::String("o".to_string())), Some(InputOption::VALUE_NONE), "Optimize autoloader during autoloader dump.", None).unwrap().into(), - InputOption::new("classmap-authoritative", Some(PhpMixed::String("a".to_string())), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.", None).unwrap().into(), + InputOption::new("with-dependencies", Some("w"), Some(InputOption::VALUE_NONE), "Update also dependencies of packages in the argument list, except those which are root requirements (can also be set via the COMPOSER_WITH_DEPENDENCIES=1 env var).", None).unwrap().into(), + InputOption::new("with-all-dependencies", Some("W"), Some(InputOption::VALUE_NONE), "Update also dependencies of packages in the argument list, including those which are root requirements (can also be set via the COMPOSER_WITH_ALL_DEPENDENCIES=1 env var).", None).unwrap().into(), + InputOption::new("verbose", Some("v|vv|vvv"), Some(InputOption::VALUE_NONE), "Shows more details including new commits pulled in when updating packages.", None).unwrap().into(), + InputOption::new("optimize-autoloader", Some("o"), Some(InputOption::VALUE_NONE), "Optimize autoloader during autoloader dump.", None).unwrap().into(), + InputOption::new("classmap-authoritative", Some("a"), Some(InputOption::VALUE_NONE), "Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.", None).unwrap().into(), InputOption::new("apcu-autoloader", None, Some(InputOption::VALUE_NONE), "Use APCu to cache found/not-found classes.", None).unwrap().into(), InputOption::new("apcu-autoloader-prefix", None, Some(InputOption::VALUE_REQUIRED), "Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader", None).unwrap().into(), InputOption::new("ignore-platform-req", None, Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "Ignore a specific platform requirement (php & ext- packages).", None).unwrap().into(), InputOption::new("ignore-platform-reqs", None, Some(InputOption::VALUE_NONE), "Ignore all platform requirements (php & ext- packages).", None).unwrap().into(), InputOption::new("prefer-stable", None, Some(InputOption::VALUE_NONE), "Prefer stable versions of dependencies (can also be set via the COMPOSER_PREFER_STABLE=1 env var).", None).unwrap().into(), InputOption::new("prefer-lowest", None, Some(InputOption::VALUE_NONE), "Prefer lowest versions of dependencies (can also be set via the COMPOSER_PREFER_LOWEST=1 env var).", None).unwrap().into(), - InputOption::new("minimal-changes", Some(PhpMixed::String("m".to_string())), Some(InputOption::VALUE_NONE), "Only perform absolutely necessary changes to dependencies. If packages cannot be kept at their currently locked version they are updated. For partial updates the allow-listed packages are always updated fully. (can also be set via the COMPOSER_MINIMAL_CHANGES=1 env var).", None).unwrap().into(), + InputOption::new("minimal-changes", Some("m"), Some(InputOption::VALUE_NONE), "Only perform absolutely necessary changes to dependencies. If packages cannot be kept at their currently locked version they are updated. For partial updates the allow-listed packages are always updated fully. (can also be set via the COMPOSER_MINIMAL_CHANGES=1 env var).", None).unwrap().into(), InputOption::new("patch-only", None, Some(InputOption::VALUE_NONE), "Only allow patch version updates for currently installed dependencies.", None).unwrap().into(), - InputOption::new("interactive", Some(PhpMixed::String("i".to_string())), Some(InputOption::VALUE_NONE), "Interactive interface with autocompletion to select the packages to update.", None).unwrap().into(), + InputOption::new("interactive", Some("i"), Some(InputOption::VALUE_NONE), "Interactive interface with autocompletion to select the packages to update.", None).unwrap().into(), InputOption::new("root-reqs", None, Some(InputOption::VALUE_NONE), "Restricts the update to your first degree dependencies.", None).unwrap().into(), - InputOption::new6("bump-after-update", None, Some(InputOption::VALUE_OPTIONAL), "Runs bump after performing the update.", Some(PhpMixed::Bool(false)), crate::console::input::SuggestedValues::List(vec!["dev".to_string(), "no-dev".to_string(), "all".to_string()])).unwrap().into(), + InputOption::new6("bump-after-update", None, Some(InputOption::VALUE_OPTIONAL), "Runs bump after performing the update.", Some(InputValue::Bool(false)), crate::console::input::SuggestedValues::List(vec!["dev".to_string(), "no-dev".to_string(), "all".to_string()])).unwrap().into(), ]); self.set_help( "The update command reads the composer.json file from the\n\ @@ -354,12 +355,8 @@ impl Command for UpdateCommand { let mut packages: Vec = input .borrow() .get_argument("packages")? - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) + .as_array() + .map(<[String]>::to_vec) .unwrap_or_default(); let mut reqs: IndexMap = self.format_requirements( input @@ -731,12 +728,8 @@ impl Command for UpdateCommand { input .borrow() .get_argument("packages")? - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect() - }) + .as_array() + .map(<[String]>::to_vec) .unwrap_or_default(), "--bump-after-update=dev".to_string(), )?; diff --git a/crates/shirabe/src/command/validate_command.rs b/crates/shirabe/src/command/validate_command.rs index d2e8f2a7..d460ea6c 100644 --- a/crates/shirabe/src/command/validate_command.rs +++ b/crates/shirabe/src/command/validate_command.rs @@ -189,7 +189,7 @@ impl Command for ValidateCommand { .into(), InputOption::new( "with-dependencies", - Some(shirabe_php_shim::PhpMixed::String("A".to_string())), + Some("A"), Some(InputOption::VALUE_NONE), "Also validate the composer.json of all installed dependencies", None, diff --git a/crates/shirabe/src/console/application.rs b/crates/shirabe/src/console/application.rs index d73a1c6b..c9b06412 100644 --- a/crates/shirabe/src/console/application.rs +++ b/crates/shirabe/src/console/application.rs @@ -83,12 +83,15 @@ use shirabe_symfony_console::helper::Helper; use shirabe_symfony_console::helper::HelperSet; use shirabe_symfony_console::helper::QuestionHelper; use shirabe_symfony_console::helper::{FormatBlockMessages, FormatterHelper}; +use shirabe_symfony_console::input::ArgumentName; use shirabe_symfony_console::input::ArgvInput; use shirabe_symfony_console::input::ArrayInput; use shirabe_symfony_console::input::InputArgument; use shirabe_symfony_console::input::InputDefinition; use shirabe_symfony_console::input::InputInterface; use shirabe_symfony_console::input::InputOption; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; use shirabe_symfony_console::output::ConsoleOutput; use shirabe_symfony_console::output::ConsoleOutputInterface; use shirabe_symfony_console::output::{OutputInterface, output_interface}; @@ -207,11 +210,7 @@ impl Application { ) -> anyhow::Result> { let working_dir = input .borrow() - .get_parameter_option( - PhpMixed::from(vec!["--working-dir", "-d"]), - PhpMixed::Null, - true, - ) + .get_parameter_option(&["--working-dir", "-d"], InputValue::Null, true) .as_string() .map(|s| s.to_string()); if let Some(ref wd) = working_dir @@ -527,38 +526,38 @@ impl Application { let mut definition = self.base_get_default_input_definition(); definition.add_option(InputOption::new( "--profile", - PhpMixed::Null, + None, Some(InputOption::VALUE_NONE), "Display timing and memory usage information".to_string(), - PhpMixed::Null, + InputValue::Null, )?)?; definition.add_option(InputOption::new( "--no-plugins", - PhpMixed::Null, + None, Some(InputOption::VALUE_NONE), "Whether to disable plugins.".to_string(), - PhpMixed::Null, + InputValue::Null, )?)?; definition.add_option(InputOption::new( "--no-scripts", - PhpMixed::Null, + None, Some(InputOption::VALUE_NONE), "Skips the execution of all scripts defined in composer.json file.".to_string(), - PhpMixed::Null, + InputValue::Null, )?)?; definition.add_option(InputOption::new( "--working-dir", - PhpMixed::from("-d"), + Some("-d"), Some(InputOption::VALUE_REQUIRED), "If specified, use the given directory as working directory.".to_string(), - PhpMixed::Null, + InputValue::Null, )?)?; definition.add_option(InputOption::new( "--no-cache", - PhpMixed::Null, + None, Some(InputOption::VALUE_NONE), "Prevent use of the cache".to_string(), - PhpMixed::Null, + InputValue::Null, )?)?; Ok(definition) @@ -1414,25 +1413,16 @@ impl Application { input: &std::rc::Rc>, output: &std::rc::Rc>, ) -> anyhow::Result<()> { - if input.borrow().has_parameter_option( - PhpMixed::from(vec![PhpMixed::from("--ansi".to_string())]), - true, - ) { + if input.borrow().has_parameter_option(&["--ansi"], true) { output.borrow().set_decorated(true); - } else if input.borrow().has_parameter_option( - PhpMixed::from(vec![PhpMixed::from("--no-ansi".to_string())]), - true, - ) { + } else if input.borrow().has_parameter_option(&["--no-ansi"], true) { output.borrow().set_decorated(false); } - if input.borrow().has_parameter_option( - PhpMixed::from(vec![ - PhpMixed::from("--no-interaction".to_string()), - PhpMixed::from("-n".to_string()), - ]), - true, - ) { + if input + .borrow() + .has_parameter_option(&["--no-interaction", "-n"], true) + { input.borrow_mut().set_interactive(false); } @@ -1468,63 +1458,39 @@ impl Application { } } - if input.borrow().has_parameter_option( - PhpMixed::from(vec![ - PhpMixed::from("--quiet".to_string()), - PhpMixed::from("-q".to_string()), - ]), - true, - ) { + if input + .borrow() + .has_parameter_option(&["--quiet", "-q"], true) + { output .borrow() .set_verbosity(output_interface::VERBOSITY_QUIET); shell_verbosity = -1; - } else if input - .borrow() - .has_parameter_option(PhpMixed::from("-vvv".to_string()), true) - || input - .borrow() - .has_parameter_option(PhpMixed::from("--verbose=3".to_string()), true) - || input.borrow().get_parameter_option( - PhpMixed::from("--verbose".to_string()), - PhpMixed::Bool(false), - true, - ) == PhpMixed::from(3i64) + } else if input.borrow().has_parameter_option(&["-vvv"], true) + || input.borrow().has_parameter_option(&["--verbose=3"], true) + // TODO(type-model): PHP also matches when `--verbose` carries the int 3; + // `InputValue` has no int variant, so only the flag spellings above are checked. { output .borrow() .set_verbosity(output_interface::VERBOSITY_DEBUG); shell_verbosity = 3; - } else if input - .borrow() - .has_parameter_option(PhpMixed::from("-vv".to_string()), true) - || input - .borrow() - .has_parameter_option(PhpMixed::from("--verbose=2".to_string()), true) - || input.borrow().get_parameter_option( - PhpMixed::from("--verbose".to_string()), - PhpMixed::Bool(false), - true, - ) == PhpMixed::from(2i64) + } else if input.borrow().has_parameter_option(&["-vv"], true) + || input.borrow().has_parameter_option(&["--verbose=2"], true) + // TODO(type-model): PHP also matches when `--verbose` carries the int 2; + // `InputValue` has no int variant, so only the flag spellings above are checked. { output .borrow() .set_verbosity(output_interface::VERBOSITY_VERY_VERBOSE); shell_verbosity = 2; - } else if input - .borrow() - .has_parameter_option(PhpMixed::from("-v".to_string()), true) + } else if input.borrow().has_parameter_option(&["-v"], true) + || input.borrow().has_parameter_option(&["--verbose=1"], true) + || input.borrow().has_parameter_option(&["--verbose"], true) || input .borrow() - .has_parameter_option(PhpMixed::from("--verbose=1".to_string()), true) - || input - .borrow() - .has_parameter_option(PhpMixed::from("--verbose".to_string()), true) - || shirabe_php_shim::php_truthy(&input.borrow().get_parameter_option( - PhpMixed::from("--verbose".to_string()), - PhpMixed::Bool(false), - true, - )) + .get_parameter_option(&["--verbose"], InputValue::Bool(false), true) + .to_bool() { output .borrow() @@ -1569,70 +1535,70 @@ impl Application { "command".to_string(), Some(InputArgument::REQUIRED), "The command to execute".to_string(), - PhpMixed::Null, + InputValue::Null, ) .unwrap(), ), DefinitionItem::InputOption( InputOption::new( "--help", - PhpMixed::from("-h".to_string()), + Some("-h"), Some(InputOption::VALUE_NONE), format!( "Display help for the given command. When no command is given display help for the {} command", self.default_command ), - PhpMixed::Null, + InputValue::Null, ) .unwrap(), ), DefinitionItem::InputOption( InputOption::new( "--quiet", - PhpMixed::from("-q".to_string()), + Some("-q"), Some(InputOption::VALUE_NONE), "Do not output any message".to_string(), - PhpMixed::Null, + InputValue::Null, ) .unwrap(), ), DefinitionItem::InputOption( InputOption::new( "--verbose", - PhpMixed::from("-v|vv|vvv".to_string()), + Some("-v|vv|vvv"), Some(InputOption::VALUE_NONE), "Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug".to_string(), - PhpMixed::Null, + InputValue::Null, ) .unwrap(), ), DefinitionItem::InputOption( InputOption::new( "--version", - PhpMixed::from("-V".to_string()), + Some("-V"), Some(InputOption::VALUE_NONE), "Display this application version".to_string(), - PhpMixed::Null, + InputValue::Null, ) .unwrap(), ), DefinitionItem::InputOption( InputOption::new( "--ansi", - PhpMixed::from("".to_string()), + Some(""), Some(InputOption::VALUE_NEGATABLE), "Force (or disable --no-ansi) ANSI output".to_string(), - PhpMixed::Null, + InputValue::Null, ) .unwrap(), ), DefinitionItem::InputOption( InputOption::new( "--no-interaction", - PhpMixed::from("-n".to_string()), + Some("-n"), Some(InputOption::VALUE_NONE), "Do not ask any interactive question".to_string(), - PhpMixed::Null, + InputValue::Null, ) .unwrap(), ), @@ -1955,10 +1921,10 @@ impl ApplicationHandle { let application = &self.0; application.borrow_mut().disable_plugins_by_default = input .borrow() - .has_parameter_option(PhpMixed::from(vec!["--no-plugins"]), false); + .has_parameter_option(&["--no-plugins"], false); application.borrow_mut().disable_scripts_by_default = input .borrow() - .has_parameter_option(PhpMixed::from(vec!["--no-scripts"]), false); + .has_parameter_option(&["--no-scripts"], false); let stdin = shirabe_php_shim::STDIN; if Platform::get_env("COMPOSER_TESTS_ARE_RUNNING").as_deref() != Some("1") @@ -1980,10 +1946,7 @@ impl ApplicationHandle { // Register error handler again to pass it the IO instance ErrorHandler::register(Some(io.clone())); - if input - .borrow() - .has_parameter_option(PhpMixed::from(vec!["--no-cache"]), false) - { + if input.borrow().has_parameter_option(&["--no-cache"], false) { io.write_error3("Disabling cache usage", true, io_interface::DEBUG); Platform::put_env( "COMPOSER_CACHE_DIR", @@ -2053,18 +2016,10 @@ impl ApplicationHandle { && !file_exists(Factory::get_composer_file().unwrap_or_default()) && use_parent_dir_if_no_json_available.as_bool() != Some(false) && (command_name.as_deref() != Some("config") - || (!input - .borrow() - .has_parameter_option(PhpMixed::from(vec!["--file"]), true) - && !input - .borrow() - .has_parameter_option(PhpMixed::from(vec!["-f"]), true))) - && !input - .borrow() - .has_parameter_option(PhpMixed::from(vec!["--help"]), true) - && !input - .borrow() - .has_parameter_option(PhpMixed::from(vec!["-h"]), true) + || (!input.borrow().has_parameter_option(&["--file"], true) + && !input.borrow().has_parameter_option(&["-f"], true))) + && !input.borrow().has_parameter_option(&["--help"], true) + && !input.borrow().has_parameter_option(&["-h"], true) { let mut dir = dirname(&Platform::get_cwd(true).unwrap_or_default()); let home_value = Platform::get_env("HOME") @@ -2141,7 +2096,7 @@ impl ApplicationHandle { // if showing the version, we never need plugin commands let may_need_plugin_command = !input .borrow() - .has_parameter_option(PhpMixed::from(vec!["--version", "-V"]), false) + .has_parameter_option(&["--version", "-V"], false) && (command_name.is_none() || matches!(command_name.as_deref().unwrap_or(""), "" | "list" | "help") || (command_name.as_deref() == Some("_complete") && !is_non_allowed_root)); @@ -2547,10 +2502,7 @@ impl ApplicationHandle { let mut start_time: Option = None; let result_outcome: anyhow::Result = (|| -> anyhow::Result { - if input - .borrow() - .has_parameter_option(PhpMixed::from(vec!["--profile"]), false) - { + if input.borrow().has_parameter_option(&["--profile"], false) { start_time = Some(microtime()); io.borrow_mut().enable_debugging(start_time.unwrap()); } @@ -2559,7 +2511,7 @@ impl ApplicationHandle { if input .borrow() - .has_parameter_option(PhpMixed::from(vec!["--version", "-V"]), true) + .has_parameter_option(&["--version", "-V"], true) { io.write_error(&format!( "PHP version {} ({})", @@ -2764,13 +2716,10 @@ impl ApplicationHandle { output: std::rc::Rc>, ) -> anyhow::Result { let application = &self.0; - if input.borrow().has_parameter_option( - PhpMixed::from(vec![ - PhpMixed::from("--version".to_string()), - PhpMixed::from("-V".to_string()), - ]), - true, - ) { + if input + .borrow() + .has_parameter_option(&["--version", "-V"], true) + { let long_version = application.borrow().get_long_version(); output .borrow() @@ -2793,20 +2742,14 @@ impl ApplicationHandle { let mut input = input; let mut name = application.borrow().get_command_name(&*input.borrow()); - if input.borrow().has_parameter_option( - PhpMixed::from(vec![ - PhpMixed::from("--help".to_string()), - PhpMixed::from("-h".to_string()), - ]), - true, - ) { + if input.borrow().has_parameter_option(&["--help", "-h"], true) { if name.is_none() { name = Some("help".to_string()); let default_command = application.borrow().default_command.clone(); input = std::rc::Rc::new(std::cell::RefCell::new(ArrayInput::new( vec![( - PhpMixed::from("command_name".to_string()), - PhpMixed::from(default_command), + ParameterName::of("command_name"), + InputValue::from(default_command), )], None, )?)); @@ -2822,14 +2765,14 @@ impl ApplicationHandle { let definition = application.borrow_mut().get_definition(); let command_description = definition .borrow() - .get_argument(&PhpMixed::from("command".to_string()))? + .get_argument(&ArgumentName::Name("command".to_string()))? .get_description() .to_string(); let new_command_argument = InputArgument::new( "command".to_string(), Some(InputArgument::OPTIONAL), command_description, - PhpMixed::from(name.clone()), + InputValue::from(name.clone()), )?; // $definition->setArguments(array_merge($definition->getArguments(), // ['command' => new InputArgument('command', InputArgument::OPTIONAL, ...)])) diff --git a/crates/shirabe/src/console/input/input_argument.rs b/crates/shirabe/src/console/input/input_argument.rs index 1e550926..8f7d526c 100644 --- a/crates/shirabe/src/console/input/input_argument.rs +++ b/crates/shirabe/src/console/input/input_argument.rs @@ -1,10 +1,10 @@ //! ref: composer/src/Composer/Console/Input/InputArgument.php use crate::console::input::SuggestedValues; -use shirabe_php_shim::PhpMixed; use shirabe_symfony_console::completion::CompletionInput; use shirabe_symfony_console::completion::CompletionSuggestions; use shirabe_symfony_console::input::InputArgument as BaseInputArgument; +use shirabe_symfony_console::input::InputValue; #[derive(Debug)] pub struct InputArgument { @@ -21,7 +21,7 @@ impl InputArgument { name: &str, mode: Option, description: &str, - default: Option, + default: Option, ) -> anyhow::Result { Self::new5( name, @@ -37,14 +37,14 @@ impl InputArgument { name: &str, mode: Option, description: &str, - default: Option, + default: Option, suggested_values: SuggestedValues, ) -> anyhow::Result { let inner = BaseInputArgument::new( name.to_string(), mode, description.to_string(), - default.unwrap_or(PhpMixed::Null), + default.unwrap_or(InputValue::Null), )?; Ok(Self { inner, diff --git a/crates/shirabe/src/console/input/input_option.rs b/crates/shirabe/src/console/input/input_option.rs index 976f006f..6e84967e 100644 --- a/crates/shirabe/src/console/input/input_option.rs +++ b/crates/shirabe/src/console/input/input_option.rs @@ -1,10 +1,10 @@ //! ref: composer/src/Composer/Console/Input/InputOption.php use crate::console::input::SuggestedValues; -use shirabe_php_shim::PhpMixed; use shirabe_symfony_console::completion::CompletionInput; use shirabe_symfony_console::completion::CompletionSuggestions; use shirabe_symfony_console::input::InputOption as BaseInputOption; +use shirabe_symfony_console::input::InputValue; #[derive(Debug)] pub struct InputOption { @@ -21,10 +21,10 @@ impl InputOption { pub fn new( name: &str, - shortcut: Option, + shortcut: Option<&str>, mode: Option, description: &str, - default: Option, + default: Option, ) -> anyhow::Result { Self::new6( name, @@ -39,16 +39,14 @@ impl InputOption { /// PHP's constructor with the sixth parameter, `$suggestedValues`. pub fn new6( name: &str, - shortcut: Option, + shortcut: Option<&str>, mode: Option, description: &str, - default: Option, + default: Option, suggested_values: SuggestedValues, ) -> anyhow::Result { - let shortcut = shortcut.unwrap_or(PhpMixed::Null); - let default_mixed = default.unwrap_or(PhpMixed::Null); - let inner = - BaseInputOption::new(name, shortcut, mode, description.to_string(), default_mixed)?; + let default = default.unwrap_or(InputValue::Null); + let inner = BaseInputOption::new(name, shortcut, mode, description.to_string(), default)?; // PHP throws LogicException here; suggested values on a valueless option cannot happen // at runtime unless a configure() is wrong, so this is a programming error. assert!( diff --git a/crates/shirabe/src/plugin/php_plugin_proxy.rs b/crates/shirabe/src/plugin/php_plugin_proxy.rs index 643658e3..4b99f528 100644 --- a/crates/shirabe/src/plugin/php_plugin_proxy.rs +++ b/crates/shirabe/src/plugin/php_plugin_proxy.rs @@ -35,6 +35,7 @@ use shirabe_php_rpc::{ use shirabe_php_shim::PhpMixed; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; use shirabe_symfony_console::output::OutputInterface; /// A Rust-side entity a PHP proxy stub points back to. @@ -3295,7 +3296,7 @@ impl PhpCommandProxy { if is_array { mode |= InputArgument::IS_ARRAY; } - let default = field(&mut row, "default").to_php_mixed()?; + let default = InputValue::from_php_mixed(&field(&mut row, "default").to_php_mixed()?); items.push(DefinitionItem::InputArgument(InputArgument::new( name, Some(mode), @@ -3334,17 +3335,20 @@ impl PhpCommandProxy { if matches!(field(&mut row, "isNegatable"), PluginValue::Bool(true)) { mode |= InputOption::VALUE_NEGATABLE; } - let shortcut = field(&mut row, "shortcut").to_php_mixed()?; + let shortcut = match field(&mut row, "shortcut").to_php_mixed()? { + PhpMixed::String(shortcut) => Some(shortcut), + _ => None, + }; // `getDefault()` exposes the stored representation (`false` for VALUE_NONE), while // the constructor only accepts null there; mirror the constructor's normalization. let default = if accept_value { - field(&mut row, "default").to_php_mixed()? + InputValue::from_php_mixed(&field(&mut row, "default").to_php_mixed()?) } else { - PhpMixed::Null + InputValue::Null }; items.push(DefinitionItem::InputOption(InputOption::new( &name, - shortcut, + shortcut.as_deref(), Some(mode), description, default, diff --git a/crates/shirabe/tests/application_test.rs b/crates/shirabe/tests/application_test.rs index 23bc909a..1d5f60eb 100644 --- a/crates/shirabe/tests/application_test.rs +++ b/crates/shirabe/tests/application_test.rs @@ -6,13 +6,15 @@ mod bootstrap; mod test_case; use serial_test::serial; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; use test_case::init_temp_composer; use shirabe::command::about_command::AboutCommand; use shirabe::command::self_update_command::SelfUpdateCommand; use shirabe::console::application::ApplicationHandle; use shirabe::util::platform::Platform; -use shirabe_php_shim::{PHP_EOL, PHP_SERVER, PhpMixed, time}; +use shirabe_php_shim::{PHP_EOL, PHP_SERVER, time}; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::ArrayInput; use shirabe_symfony_console::input::InputInterface; @@ -50,7 +52,7 @@ fn test_dev_warning() { let input: std::rc::Rc> = std::rc::Rc::new(std::cell::RefCell::new( ArrayInput::new( - vec![(PhpMixed::from("command"), PhpMixed::from("about"))], + vec![(ParameterName::of("command"), InputValue::from("about"))], None, ) .unwrap(), @@ -93,7 +95,10 @@ fn test_dev_warning_suppressed_for_self_update() { let input: std::rc::Rc> = std::rc::Rc::new(std::cell::RefCell::new( ArrayInput::new( - vec![(PhpMixed::from("command"), PhpMixed::from("self-update"))], + vec![( + ParameterName::of("command"), + InputValue::from("self-update"), + )], None, ) .unwrap(), @@ -121,7 +126,7 @@ fn test_process_isolation_works_multiple_times() { let input1: std::rc::Rc> = std::rc::Rc::new(std::cell::RefCell::new( ArrayInput::new( - vec![(PhpMixed::from("command"), PhpMixed::from("about"))], + vec![(ParameterName::of("command"), InputValue::from("about"))], None, ) .unwrap(), @@ -134,7 +139,7 @@ fn test_process_isolation_works_multiple_times() { let input2: std::rc::Rc> = std::rc::Rc::new(std::cell::RefCell::new( ArrayInput::new( - vec![(PhpMixed::from("command"), PhpMixed::from("about"))], + vec![(ParameterName::of("command"), InputValue::from("about"))], None, ) .unwrap(), @@ -175,8 +180,8 @@ fn test_no_plugins_disables_plugins_when_script_commands_exist() { std::rc::Rc::new(std::cell::RefCell::new( ArrayInput::new( vec![ - (PhpMixed::from("command"), PhpMixed::from("list")), - (PhpMixed::from("--no-plugins"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("list")), + (ParameterName::of("--no-plugins"), InputValue::from(true)), ], None, ) @@ -240,7 +245,7 @@ fn test_script_command_takes_priority_over_abbreviated_builtin_command() { let input: std::rc::Rc> = std::rc::Rc::new(std::cell::RefCell::new( ArrayInput::new( - vec![(PhpMixed::from("command"), PhpMixed::from("check"))], + vec![(ParameterName::of("command"), InputValue::from("check"))], None, ) .unwrap(), diff --git a/crates/shirabe/tests/command/about_command_test.rs b/crates/shirabe/tests/command/about_command_test.rs index 52e42a1d..86f6f35b 100644 --- a/crates/shirabe/tests/command/about_command_test.rs +++ b/crates/shirabe/tests/command/about_command_test.rs @@ -3,7 +3,8 @@ use crate::test_case::{RunOptions, get_application_tester}; use serial_test::serial; use shirabe::composer; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; #[test] #[serial] @@ -13,7 +14,7 @@ fn test_about() { let mut app_tester = get_application_tester(); let status_code = app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("about"))], + vec![(ParameterName::of("command"), InputValue::from("about"))], RunOptions::default(), ) .unwrap(); diff --git a/crates/shirabe/tests/command/archive_command_test.rs b/crates/shirabe/tests/command/archive_command_test.rs index 90e13e5d..e5beb9ce 100644 --- a/crates/shirabe/tests/command/archive_command_test.rs +++ b/crates/shirabe/tests/command/archive_command_test.rs @@ -20,6 +20,8 @@ use shirabe_semver::VersionParser; use shirabe_symfony_console::command::Command; use shirabe_symfony_console::input::ArrayInput; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; use shirabe_symfony_console::output::BufferedOutput; use shirabe_symfony_console::output::OutputInterface; @@ -202,7 +204,7 @@ fn test_uses_config_from_composer_object_with_package_name() { let input: std::rc::Rc> = std::rc::Rc::new(std::cell::RefCell::new( ArrayInput::new( - vec![(PhpMixed::from("package"), PhpMixed::from("foo/bar"))], + vec![(ParameterName::of("package"), InputValue::from("foo/bar"))], None, ) .unwrap(), diff --git a/crates/shirabe/tests/command/audit_command_test.rs b/crates/shirabe/tests/command/audit_command_test.rs index 617479f3..9d7a64ef 100644 --- a/crates/shirabe/tests/command/audit_command_test.rs +++ b/crates/shirabe/tests/command/audit_command_test.rs @@ -6,7 +6,8 @@ use crate::test_case::{ }; use serial_test::serial; use shirabe::package::handle::PackageInterfaceHandle; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; #[test] #[serial] @@ -16,7 +17,7 @@ fn test_successful_response_code_when_no_packages_are_required() { let mut app_tester = get_application_tester(); app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("audit"))], + vec![(ParameterName::of("command"), InputValue::from("audit"))], RunOptions::default(), ) .unwrap(); @@ -41,8 +42,8 @@ fn test_error_auditing_lock_file_when_it_is_missing() { let err = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("audit")), - (PhpMixed::from("--locked"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("audit")), + (ParameterName::of("--locked"), InputValue::from(true)), ], RunOptions::default(), ) @@ -69,8 +70,8 @@ fn test_audit_package_with_no_security_vulnerabilities() { app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("audit")), - (PhpMixed::from("--locked"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("audit")), + (ParameterName::of("--locked"), InputValue::from(true)), ], RunOptions::default(), ) @@ -100,8 +101,8 @@ fn test_audit_package_with_no_dev_option_passed() { app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("audit")), - (PhpMixed::from("--no-dev"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("audit")), + (ParameterName::of("--no-dev"), InputValue::from(true)), ], RunOptions::default(), ) diff --git a/crates/shirabe/tests/command/base_dependency_command_test.rs b/crates/shirabe/tests/command/base_dependency_command_test.rs index ace43ae7..41aeec56 100644 --- a/crates/shirabe/tests/command/base_dependency_command_test.rs +++ b/crates/shirabe/tests/command/base_dependency_command_test.rs @@ -7,8 +7,9 @@ use crate::test_case::{ use serial_test::serial; use shirabe::package::Link; use shirabe::package::handle::PackageInterfaceHandle; -use shirabe_php_shim::PhpMixed; use shirabe_semver::constraint::{AnyConstraint, MatchAllConstraint, MultiConstraint}; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// ref: TestCase::trimLines — strip trailing spaces from each line, then trim the whole string. fn trim_lines(s: &str) -> String { @@ -29,7 +30,7 @@ fn match_all() -> AnyConstraint { #[serial] fn test_exception_when_no_required_parameters() { // noParametersCaseProvider - let cases: Vec<(&str, Vec<(&str, PhpMixed)>, &str)> = vec![ + let cases: Vec<(&str, Vec<(&str, InputValue)>, &str)> = vec![ ( "why", vec![], @@ -42,21 +43,21 @@ fn test_exception_when_no_required_parameters() { ), ( "why-not", - vec![("version", PhpMixed::from("*"))], + vec![("version", InputValue::from("*"))], "Not enough arguments (missing: \"package\").", ), ( "why-not", - vec![("package", PhpMixed::from("vendor1/package1"))], + vec![("package", InputValue::from("vendor1/package1"))], "Not enough arguments (missing: \"version\").", ), ]; for (command, parameters, expected_message) in cases { - let mut input: Vec<(PhpMixed, PhpMixed)> = - vec![(PhpMixed::from("command"), PhpMixed::from(command))]; + let mut input: Vec<(ParameterName, InputValue)> = + vec![(ParameterName::of("command"), InputValue::from(command))]; for (k, v) in parameters { - input.push((PhpMixed::from(k), v)); + input.push((ParameterName::of(k), v)); } let mut app_tester = get_application_tester(); @@ -77,13 +78,16 @@ fn test_exception_when_no_required_parameters() { #[serial] fn test_exception_when_running_locked_without_lock_file() { // caseProvider - let cases: Vec<(&str, Vec<(&str, PhpMixed)>)> = vec![ - ("why", vec![("package", PhpMixed::from("vendor1/package1"))]), + let cases: Vec<(&str, Vec<(&str, InputValue)>)> = vec![ + ( + "why", + vec![("package", InputValue::from("vendor1/package1"))], + ), ( "why-not", vec![ - ("package", PhpMixed::from("vendor1/package1")), - ("version", PhpMixed::from("1.*")), + ("package", InputValue::from("vendor1/package1")), + ("version", InputValue::from("1.*")), ], ), ]; @@ -91,12 +95,12 @@ fn test_exception_when_running_locked_without_lock_file() { for (command, parameters) in cases { let tear_down = init_temp_composer(None, None, None, true); - let mut input: Vec<(PhpMixed, PhpMixed)> = - vec![(PhpMixed::from("command"), PhpMixed::from(command))]; + let mut input: Vec<(ParameterName, InputValue)> = + vec![(ParameterName::of("command"), InputValue::from(command))]; for (k, v) in parameters { - input.push((PhpMixed::from(k), v)); + input.push((ParameterName::of(k), v)); } - input.push((PhpMixed::from("--locked"), PhpMixed::from(true))); + input.push((ParameterName::of("--locked"), InputValue::from(true))); let mut app_tester = get_application_tester(); let err = app_tester @@ -119,13 +123,16 @@ fn test_exception_when_running_locked_without_lock_file() { #[serial] fn test_exception_when_it_could_not_found_the_package() { // caseProvider - let cases: Vec<(&str, Vec<(&str, PhpMixed)>)> = vec![ - ("why", vec![("package", PhpMixed::from("vendor1/package1"))]), + let cases: Vec<(&str, Vec<(&str, InputValue)>)> = vec![ + ( + "why", + vec![("package", InputValue::from("vendor1/package1"))], + ), ( "why-not", vec![ - ("package", PhpMixed::from("vendor1/package1")), - ("version", PhpMixed::from("1.*")), + ("package", InputValue::from("vendor1/package1")), + ("version", InputValue::from("1.*")), ], ), ]; @@ -135,10 +142,10 @@ fn test_exception_when_it_could_not_found_the_package() { let tear_down = init_temp_composer(None, None, None, true); - let mut input: Vec<(PhpMixed, PhpMixed)> = - vec![(PhpMixed::from("command"), PhpMixed::from(command))]; + let mut input: Vec<(ParameterName, InputValue)> = + vec![(ParameterName::of("command"), InputValue::from(command))]; for (k, v) in parameters { - input.push((PhpMixed::from(k), v)); + input.push((ParameterName::of(k), v)); } let mut app_tester = get_application_tester(); @@ -165,13 +172,16 @@ fn test_exception_when_it_could_not_found_the_package() { #[serial] fn test_exception_when_package_was_not_found_in_project() { // caseProvider - let cases: Vec<(&str, Vec<(&str, PhpMixed)>)> = vec![ - ("why", vec![("package", PhpMixed::from("vendor1/package1"))]), + let cases: Vec<(&str, Vec<(&str, InputValue)>)> = vec![ + ( + "why", + vec![("package", InputValue::from("vendor1/package1"))], + ), ( "why-not", vec![ - ("package", PhpMixed::from("vendor1/package1")), - ("version", PhpMixed::from("1.*")), + ("package", InputValue::from("vendor1/package1")), + ("version", InputValue::from("1.*")), ], ), ]; @@ -201,10 +211,10 @@ fn test_exception_when_package_was_not_found_in_project() { create_installed_json(&packages, &[], false); create_composer_lock(&packages, &[]); - let mut input: Vec<(PhpMixed, PhpMixed)> = - vec![(PhpMixed::from("command"), PhpMixed::from(command))]; + let mut input: Vec<(ParameterName, InputValue)> = + vec![(ParameterName::of("command"), InputValue::from(command))]; for (k, v) in parameters { - input.push((PhpMixed::from(k), v)); + input.push((ParameterName::of(k), v)); } let mut app_tester = get_application_tester(); @@ -233,13 +243,16 @@ fn test_warning_when_dependencies_are_not_installed() { let expected_warning_message = "No dependencies installed. Try running composer install or update, or use --locked."; // caseProvider - let cases: Vec<(&str, Vec<(&str, PhpMixed)>)> = vec![ - ("why", vec![("package", PhpMixed::from("vendor1/package1"))]), + let cases: Vec<(&str, Vec<(&str, InputValue)>)> = vec![ + ( + "why", + vec![("package", InputValue::from("vendor1/package1"))], + ), ( "why-not", vec![ - ("package", PhpMixed::from("vendor1/package1")), - ("version", PhpMixed::from("1.*")), + ("package", InputValue::from("vendor1/package1")), + ("version", InputValue::from("1.*")), ], ), ]; @@ -267,10 +280,10 @@ fn test_warning_when_dependencies_are_not_installed() { std::slice::from_ref(&some_dev_required_package), ); - let mut input: Vec<(PhpMixed, PhpMixed)> = - vec![(PhpMixed::from("command"), PhpMixed::from(command))]; + let mut input: Vec<(ParameterName, InputValue)> = + vec![(ParameterName::of("command"), InputValue::from(command))]; for (k, v) in parameters { - input.push((PhpMixed::from(k), v)); + input.push((ParameterName::of(k), v)); } let mut app_tester = get_application_tester(); @@ -415,18 +428,21 @@ fn test_why_command_outputs() { true, ); - let input: Vec<(PhpMixed, PhpMixed)> = vec![ - (PhpMixed::from("command"), PhpMixed::from("why")), + let input: Vec<(ParameterName, InputValue)> = vec![ + (ParameterName::of("command"), InputValue::from("why")), + ( + ParameterName::of("package"), + InputValue::from(package_to_be_inspected), + ), ( - PhpMixed::from("package"), - PhpMixed::from(package_to_be_inspected), + ParameterName::of("--tree"), + InputValue::from(render_as_tree), ), - (PhpMixed::from("--tree"), PhpMixed::from(render_as_tree)), ( - PhpMixed::from("--recursive"), - PhpMixed::from(render_recursively), + ParameterName::of("--recursive"), + InputValue::from(render_recursively), ), - (PhpMixed::from("--locked"), PhpMixed::from(true)), + (ParameterName::of("--locked"), InputValue::from(true)), ]; let mut app_tester = get_application_tester(); @@ -586,15 +602,15 @@ fn test_why_not_command_outputs() { true, ); - let input: Vec<(PhpMixed, PhpMixed)> = vec![ - (PhpMixed::from("command"), PhpMixed::from("why-not")), + let input: Vec<(ParameterName, InputValue)> = vec![ + (ParameterName::of("command"), InputValue::from("why-not")), ( - PhpMixed::from("package"), - PhpMixed::from(package_to_be_inspected), + ParameterName::of("package"), + InputValue::from(package_to_be_inspected), ), ( - PhpMixed::from("version"), - PhpMixed::from(package_version_to_be_inspected), + ParameterName::of("version"), + InputValue::from(package_version_to_be_inspected), ), ]; diff --git a/crates/shirabe/tests/command/bump_command_test.rs b/crates/shirabe/tests/command/bump_command_test.rs index a7cdfd76..11665e65 100644 --- a/crates/shirabe/tests/command/bump_command_test.rs +++ b/crates/shirabe/tests/command/bump_command_test.rs @@ -7,12 +7,13 @@ use crate::test_case::{ use serial_test::serial; use shirabe::json::JsonFile; use shirabe::package::handle::PackageInterfaceHandle; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// ref: BumpCommandTest::testBump (data provider rolled into one body). fn run_bump_case( composer_json: serde_json::Value, - command: &[(&str, PhpMixed)], + command: &[(&str, InputValue)], expected: serde_json::Value, lock: bool, exit_code: i32, @@ -31,10 +32,10 @@ fn run_bump_case( create_composer_lock(&packages, &dev_packages); } - let mut input: Vec<(PhpMixed, PhpMixed)> = - vec![(PhpMixed::from("command"), PhpMixed::from("bump"))]; + let mut input: Vec<(ParameterName, InputValue)> = + vec![(ParameterName::of("command"), InputValue::from("bump"))]; for (k, v) in command { - input.push((PhpMixed::from(*k), v.clone())); + input.push((ParameterName::of(k), v.clone())); } let mut app_tester = get_application_tester(); @@ -74,7 +75,7 @@ fn test_bump() { "require": { "first/pkg": "^2.0", "second/pkg": "3.*" }, "require-dev": { "dev/pkg": "~2.0" }, }), - &[("--dev-only", PhpMixed::from(true))], + &[("--dev-only", InputValue::from(true))], serde_json::json!({ "require": { "first/pkg": "^2.0", "second/pkg": "3.*" }, "require-dev": { "dev/pkg": "^2.3.4.5" }, @@ -89,7 +90,7 @@ fn test_bump() { "require": { "first/pkg": "^2.0", "second/pkg": "3.*" }, "require-dev": { "dev/pkg": "~2.0" }, }), - &[("--no-dev-only", PhpMixed::from(true))], + &[("--no-dev-only", InputValue::from(true))], serde_json::json!({ "require": { "first/pkg": "^2.3.4", "second/pkg": "^3.4" }, "require-dev": { "dev/pkg": "~2.0" }, @@ -106,10 +107,7 @@ fn test_bump() { }), &[( "packages", - PhpMixed::List(vec![ - PhpMixed::from("first/pkg:3.0.1"), - PhpMixed::from("dev/*"), - ]), + InputValue::Array(vec!["first/pkg:3.0.1".to_string(), "dev/*".to_string()]), )], serde_json::json!({ "require": { "first/pkg": "^2.3.4", "second/pkg": "3.*" }, @@ -138,7 +136,7 @@ fn test_bump() { "require": { "first/pkg": "^2.0", "second/pkg": "3.*" }, "require-dev": { "dev/pkg": "~2.0" }, }), - &[("--dry-run", PhpMixed::from(true))], + &[("--dry-run", InputValue::from(true))], serde_json::json!({ "require": { "first/pkg": "^2.0", "second/pkg": "3.*" }, "require-dev": { "dev/pkg": "~2.0" }, @@ -153,7 +151,7 @@ fn test_bump() { "require": { "first/pkg": "^2.3.4", "second/pkg": "^3.4" }, "require-dev": { "dev/pkg": "^2.3.4.5" }, }), - &[("--dry-run", PhpMixed::from(true))], + &[("--dry-run", InputValue::from(true))], serde_json::json!({ "require": { "first/pkg": "^2.3.4", "second/pkg": "^3.4" }, "require-dev": { "dev/pkg": "^2.3.4.5" }, @@ -214,7 +212,7 @@ fn test_bump_fails_on_non_existing_composer_file() { let mut app_tester = get_application_tester(); let status_code = app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("bump"))], + vec![(ParameterName::of("command"), InputValue::from("bump"))], RunOptions { capture_stderr_separately: true, ..RunOptions::default() @@ -248,7 +246,7 @@ fn test_bump_fails_on_write_error_to_composer_file() { let mut app_tester = get_application_tester(); let status_code = app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("bump"))], + vec![(ParameterName::of("command"), InputValue::from("bump"))], RunOptions { capture_stderr_separately: true, ..RunOptions::default() diff --git a/crates/shirabe/tests/command/check_platform_reqs_command_test.rs b/crates/shirabe/tests/command/check_platform_reqs_command_test.rs index 18eff41e..a9feb1a0 100644 --- a/crates/shirabe/tests/command/check_platform_reqs_command_test.rs +++ b/crates/shirabe/tests/command/check_platform_reqs_command_test.rs @@ -6,12 +6,13 @@ use crate::test_case::{ }; use serial_test::serial; use shirabe::package::handle::PackageInterfaceHandle; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// ref: CheckPlatformReqsCommandTest::testPlatformReqsAreSatisfied (data provider rolled into one body). fn run_platform_reqs_are_satisfied_case( composer_json: serde_json::Value, - command: &[(&str, PhpMixed)], + command: &[(&str, InputValue)], expected: &str, lock: bool, ) { @@ -28,12 +29,12 @@ fn run_platform_reqs_are_satisfied_case( create_composer_lock(&packages, &dev_packages); } - let mut input: Vec<(PhpMixed, PhpMixed)> = vec![( - PhpMixed::from("command"), - PhpMixed::from("check-platform-reqs"), + let mut input: Vec<(ParameterName, InputValue)> = vec![( + ParameterName::of("command"), + InputValue::from("check-platform-reqs"), )]; for (k, v) in command { - input.push((PhpMixed::from(*k), v.clone())); + input.push((ParameterName::of(k), v.clone())); } let mut app_tester = get_application_tester(); @@ -55,7 +56,7 @@ fn test_platform_reqs_are_satisfied() { "require": { "ext-foobar": "^2.0" }, "require-dev": { "ext-barbaz": "~4.0" }, }), - &[("--no-dev", PhpMixed::from(true))], + &[("--no-dev", InputValue::from(true))], "Checking non-dev platform requirements for packages in the vendor dir ext-foobar 2.3.4 success", true, @@ -67,7 +68,7 @@ ext-foobar 2.3.4 success", "require": { "ext-foobar": "^2.3" }, "require-dev": { "ext-barbaz": "~2.0" }, }), - &[("--lock", PhpMixed::from(true))], + &[("--lock", InputValue::from(true))], "Checking platform requirements using the lock file\next-barbaz 2.3.4.5 success \next-foobar 2.3.4 success", true, ); @@ -82,8 +83,8 @@ fn test_exception_thrown_if_no_lockfile_found() { let err = app_tester .run( vec![( - PhpMixed::from("command"), - PhpMixed::from("check-platform-reqs"), + ParameterName::of("command"), + InputValue::from("check-platform-reqs"), )], RunOptions::default(), ) @@ -125,10 +126,10 @@ fn test_failed_platform_requirement() { .run( vec![ ( - PhpMixed::from("command"), - PhpMixed::from("check-platform-reqs"), + ParameterName::of("command"), + InputValue::from("check-platform-reqs"), ), - (PhpMixed::from("--format"), PhpMixed::from("json")), + (ParameterName::of("--format"), InputValue::from("json")), ], RunOptions::default(), ) diff --git a/crates/shirabe/tests/command/clear_cache_command_test.rs b/crates/shirabe/tests/command/clear_cache_command_test.rs index b1855799..b25200f5 100644 --- a/crates/shirabe/tests/command/clear_cache_command_test.rs +++ b/crates/shirabe/tests/command/clear_cache_command_test.rs @@ -3,7 +3,8 @@ use crate::test_case::{RunOptions, get_application_tester}; use serial_test::serial; use shirabe::util::platform::Platform; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; fn tear_down() { // --no-cache triggers the env to change so make sure the env is cleaned up after these tests run @@ -26,7 +27,10 @@ fn test_clear_cache_command_success() { let mut app_tester = get_application_tester(); app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("clear-cache"))], + vec![( + ParameterName::of("command"), + InputValue::from("clear-cache"), + )], RunOptions::default(), ) .unwrap(); @@ -50,8 +54,11 @@ fn test_clear_cache_command_with_option_garbage_collection() { app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("clear-cache")), - (PhpMixed::from("--gc"), PhpMixed::Bool(true)), + ( + ParameterName::of("command"), + InputValue::from("clear-cache"), + ), + (ParameterName::of("--gc"), InputValue::Bool(true)), ], RunOptions::default(), ) @@ -76,8 +83,11 @@ fn test_clear_cache_command_with_option_no_cache() { app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("clear-cache")), - (PhpMixed::from("--no-cache"), PhpMixed::Bool(true)), + ( + ParameterName::of("command"), + InputValue::from("clear-cache"), + ), + (ParameterName::of("--no-cache"), InputValue::Bool(true)), ], RunOptions::default(), ) diff --git a/crates/shirabe/tests/command/config_command_test.rs b/crates/shirabe/tests/command/config_command_test.rs index 35ecb7a5..fc2d4874 100644 --- a/crates/shirabe/tests/command/config_command_test.rs +++ b/crates/shirabe/tests/command/config_command_test.rs @@ -2,28 +2,32 @@ use crate::test_case::{RunOptions, get_application_tester, init_temp_composer}; use serial_test::serial; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// `['command' => 'config'] + $command`, with the command name prepended. -fn config_input(command: Vec<(PhpMixed, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { - let mut input = vec![(PhpMixed::from("command"), PhpMixed::from("config"))]; +fn config_input(command: Vec<(ParameterName, InputValue)>) -> Vec<(ParameterName, InputValue)> { + let mut input = vec![(ParameterName::of("command"), InputValue::from("config"))]; input.extend(command); input } -fn key(setting_key: &str) -> (PhpMixed, PhpMixed) { - (PhpMixed::from("setting-key"), PhpMixed::from(setting_key)) +fn key(setting_key: &str) -> (ParameterName, InputValue) { + ( + ParameterName::of("setting-key"), + InputValue::from(setting_key), + ) } -fn value(values: &[&str]) -> (PhpMixed, PhpMixed) { +fn value(values: &[&str]) -> (ParameterName, InputValue) { ( - PhpMixed::from("setting-value"), - PhpMixed::List(values.iter().map(|v| PhpMixed::from(*v)).collect()), + ParameterName::of("setting-value"), + InputValue::Array(values.iter().map(|v| v.to_string()).collect()), ) } -fn flag(name: &str) -> (PhpMixed, PhpMixed) { - (PhpMixed::from(name), PhpMixed::Bool(true)) +fn flag(name: &str) -> (ParameterName, InputValue) { + (ParameterName::of(name), InputValue::Bool(true)) } /// Reads CWD's composer.json as a `serde_json::Value` (mirrors PHP's `json_decode(..., true)`). @@ -35,7 +39,7 @@ fn read_composer_json() -> serde_json::Value { struct UpdateCase { name: &'static str, before: serde_json::Value, - command: Vec<(PhpMixed, PhpMixed)>, + command: Vec<(ParameterName, InputValue)>, expected: serde_json::Value, } @@ -325,7 +329,7 @@ fn test_config_updates() { struct ReadCase { name: &'static str, composer_json: serde_json::Value, - command: Vec<(PhpMixed, PhpMixed)>, + command: Vec<(ParameterName, InputValue)>, expected: &'static str, } @@ -428,8 +432,8 @@ fn test_config_throws_for_invalid_arg_combination() { let result = app_tester.run( config_input(vec![ ( - PhpMixed::from("--file"), - PhpMixed::from("alt.composer.json"), + ParameterName::of("--file"), + InputValue::from("alt.composer.json"), ), flag("--global"), ]), diff --git a/crates/shirabe/tests/command/diagnose_command_test.rs b/crates/shirabe/tests/command/diagnose_command_test.rs index 8649b45d..d2878120 100644 --- a/crates/shirabe/tests/command/diagnose_command_test.rs +++ b/crates/shirabe/tests/command/diagnose_command_test.rs @@ -3,7 +3,8 @@ use crate::test_case::{RunOptions, get_application_tester, init_temp_composer}; use serial_test::serial; use shirabe::util::platform::Platform; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; #[test] #[serial] @@ -18,7 +19,7 @@ fn test_cmd_fail() { let mut app_tester = get_application_tester(); app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("diagnose"))], + vec![(ParameterName::of("command"), InputValue::from("diagnose"))], RunOptions::default(), ) .unwrap(); @@ -65,7 +66,7 @@ fn test_cmd_success() { let mut app_tester = get_application_tester(); app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("diagnose"))], + vec![(ParameterName::of("command"), InputValue::from("diagnose"))], RunOptions::default(), ) .unwrap(); diff --git a/crates/shirabe/tests/command/dump_autoload_command_test.rs b/crates/shirabe/tests/command/dump_autoload_command_test.rs index c21b13df..bd7771b5 100644 --- a/crates/shirabe/tests/command/dump_autoload_command_test.rs +++ b/crates/shirabe/tests/command/dump_autoload_command_test.rs @@ -3,7 +3,8 @@ use crate::test_case::{RunOptions, get_application_tester, init_temp_composer}; use regex::Regex; use serial_test::serial; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// ref: DumpAutoloadCommandTest::testDumpAutoload #[test] @@ -14,7 +15,10 @@ fn test_dump_autoload() { let mut app_tester = get_application_tester(); let status_code = app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("dump-autoload"))], + vec![( + ParameterName::of("command"), + InputValue::from("dump-autoload"), + )], RunOptions::default(), ) .unwrap(); @@ -37,8 +41,11 @@ fn test_dump_dev_autoload() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("dump-autoload")), - (PhpMixed::from("--dev"), PhpMixed::from(true)), + ( + ParameterName::of("command"), + InputValue::from("dump-autoload"), + ), + (ParameterName::of("--dev"), InputValue::from(true)), ], RunOptions::default(), ) @@ -62,8 +69,11 @@ fn test_dump_no_dev_autoload() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("dump-autoload")), - (PhpMixed::from("--dev"), PhpMixed::from(true)), + ( + ParameterName::of("command"), + InputValue::from("dump-autoload"), + ), + (ParameterName::of("--dev"), InputValue::from(true)), ], RunOptions::default(), ) @@ -87,9 +97,12 @@ fn test_using_optimize_and_strict_psr() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("dump-autoload")), - (PhpMixed::from("--optimize"), PhpMixed::from(true)), - (PhpMixed::from("--strict-psr"), PhpMixed::from(true)), + ( + ParameterName::of("command"), + InputValue::from("dump-autoload"), + ), + (ParameterName::of("--optimize"), InputValue::from(true)), + (ParameterName::of("--strict-psr"), InputValue::from(true)), ], RunOptions::default(), ) @@ -132,9 +145,12 @@ fn test_fails_using_strict_psr_if_class_map_violations_are_found() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("dump-autoload")), - (PhpMixed::from("--optimize"), PhpMixed::from(true)), - (PhpMixed::from("--strict-psr"), PhpMixed::from(true)), + ( + ParameterName::of("command"), + InputValue::from("dump-autoload"), + ), + (ParameterName::of("--optimize"), InputValue::from(true)), + (ParameterName::of("--strict-psr"), InputValue::from(true)), ], RunOptions::default(), ) @@ -161,10 +177,13 @@ fn test_using_classmap_authoritative() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("dump-autoload")), ( - PhpMixed::from("--classmap-authoritative"), - PhpMixed::from(true), + ParameterName::of("command"), + InputValue::from("dump-autoload"), + ), + ( + ParameterName::of("--classmap-authoritative"), + InputValue::from(true), ), ], RunOptions::default(), @@ -192,12 +211,15 @@ fn test_using_classmap_authoritative_and_strict_psr() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("dump-autoload")), ( - PhpMixed::from("--classmap-authoritative"), - PhpMixed::from(true), + ParameterName::of("command"), + InputValue::from("dump-autoload"), + ), + ( + ParameterName::of("--classmap-authoritative"), + InputValue::from(true), ), - (PhpMixed::from("--strict-psr"), PhpMixed::from(true)), + (ParameterName::of("--strict-psr"), InputValue::from(true)), ], RunOptions::default(), ) @@ -224,8 +246,11 @@ fn test_strict_psr_does_not_work_without_optimized_autoloader() { let err = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("dump-autoload")), - (PhpMixed::from("--strict-psr"), PhpMixed::from(true)), + ( + ParameterName::of("command"), + InputValue::from("dump-autoload"), + ), + (ParameterName::of("--strict-psr"), InputValue::from(true)), ], RunOptions::default(), ) @@ -247,9 +272,12 @@ fn test_dev_and_no_dev_cannot_be_combined() { let err = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("dump-autoload")), - (PhpMixed::from("--dev"), PhpMixed::from(true)), - (PhpMixed::from("--no-dev"), PhpMixed::from(true)), + ( + ParameterName::of("command"), + InputValue::from("dump-autoload"), + ), + (ParameterName::of("--dev"), InputValue::from(true)), + (ParameterName::of("--no-dev"), InputValue::from(true)), ], RunOptions::default(), ) @@ -281,7 +309,10 @@ fn test_with_custom_autoloader_suffix() { let mut app_tester = get_application_tester(); let status_code = app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("dump-autoload"))], + vec![( + ParameterName::of("command"), + InputValue::from("dump-autoload"), + )], RunOptions::default(), ) .unwrap(); @@ -329,7 +360,10 @@ fn test_with_existing_composer_lock_and_autoloader_suffix() { let mut app_tester = get_application_tester(); let status_code = app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("dump-autoload"))], + vec![( + ParameterName::of("command"), + InputValue::from("dump-autoload"), + )], RunOptions::default(), ) .unwrap(); @@ -375,7 +409,10 @@ fn test_with_existing_composer_lock_without_autoloader_suffix() { let mut app_tester = get_application_tester(); let status_code = app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("dump-autoload"))], + vec![( + ParameterName::of("command"), + InputValue::from("dump-autoload"), + )], RunOptions::default(), ) .unwrap(); diff --git a/crates/shirabe/tests/command/exec_command_test.rs b/crates/shirabe/tests/command/exec_command_test.rs index 03a2c7cf..a160664f 100644 --- a/crates/shirabe/tests/command/exec_command_test.rs +++ b/crates/shirabe/tests/command/exec_command_test.rs @@ -2,7 +2,8 @@ use crate::test_case::{RunOptions, get_application_tester, init_temp_composer}; use serial_test::serial; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// ref: ExecCommandTest::testListThrowsIfNoBinariesExist #[test] @@ -17,8 +18,8 @@ fn test_list_throws_if_no_binaries_exist() { let err = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("exec")), - (PhpMixed::from("--list"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("exec")), + (ParameterName::of("--list"), InputValue::from(true)), ], RunOptions::default(), ) @@ -62,8 +63,8 @@ fn test_list() { app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("exec")), - (PhpMixed::from("--list"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("exec")), + (ParameterName::of("--list"), InputValue::from(true)), ], RunOptions::default(), ) diff --git a/crates/shirabe/tests/command/fund_command_test.rs b/crates/shirabe/tests/command/fund_command_test.rs index faeda9dc..e1921f4e 100644 --- a/crates/shirabe/tests/command/fund_command_test.rs +++ b/crates/shirabe/tests/command/fund_command_test.rs @@ -8,6 +8,8 @@ use indexmap::IndexMap; use serial_test::serial; use shirabe::package::handle::{CompletePackageHandle, PackageInterfaceHandle}; use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; fn funding_entry(r#type: &str, url: &str) -> IndexMap { let mut m = IndexMap::new(); @@ -19,7 +21,7 @@ fn funding_entry(r#type: &str, url: &str) -> IndexMap { /// Runs one `useCaseProvider` case. fn run_fund_case( composer_json: serde_json::Value, - command: &[(&str, PhpMixed)], + command: &[(&str, InputValue)], funding: &[(&str, IndexMap)], expected: &str, ) { @@ -48,10 +50,10 @@ fn run_fund_case( create_installed_json(&packages, &dev_packages, true); - let mut input: Vec<(PhpMixed, PhpMixed)> = - vec![(PhpMixed::from("command"), PhpMixed::from("fund"))]; + let mut input: Vec<(ParameterName, InputValue)> = + vec![(ParameterName::of("command"), InputValue::from("fund"))]; for (k, v) in command { - input.push((PhpMixed::from(*k), v.clone())); + input.push((ParameterName::of(k), v.clone())); } let mut app_tester = get_application_tester(); @@ -163,7 +165,7 @@ Thank you!", "require": { "first/pkg": "^2.0" }, "require-dev": { "dev/pkg": "~4.0" }, }), - &[("--format", PhpMixed::from("json"))], + &[("--format", InputValue::from("json"))], &[ ( "first/pkg", diff --git a/crates/shirabe/tests/command/global_command_test.rs b/crates/shirabe/tests/command/global_command_test.rs index 0446a007..cd2b7bc9 100644 --- a/crates/shirabe/tests/command/global_command_test.rs +++ b/crates/shirabe/tests/command/global_command_test.rs @@ -6,7 +6,8 @@ use crate::test_case::{ }; use serial_test::serial; use shirabe::util::platform::Platform; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; use std::path::PathBuf; use tempfile::TempDir; @@ -57,12 +58,15 @@ fn test_global() { let mut app_tester = get_application_tester(); let _ = app_tester.run( vec![ - (PhpMixed::from("command"), PhpMixed::from("global")), + (ParameterName::of("command"), InputValue::from("global")), ( - PhpMixed::from("command-name"), - PhpMixed::from("test-script"), + ParameterName::of("command-name"), + InputValue::from("test-script"), + ), + ( + ParameterName::of("--no-interaction"), + InputValue::from(true), ), - (PhpMixed::from("--no-interaction"), PhpMixed::from(true)), ], RunOptions::default(), ); @@ -96,12 +100,15 @@ fn test_cannot_create_home() { let err = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("global")), + (ParameterName::of("command"), InputValue::from("global")), ( - PhpMixed::from("command-name"), - PhpMixed::from("test-script"), + ParameterName::of("command-name"), + InputValue::from("test-script"), + ), + ( + ParameterName::of("--no-interaction"), + InputValue::from(true), ), - (PhpMixed::from("--no-interaction"), PhpMixed::from(true)), ], RunOptions::default(), ) @@ -154,8 +161,8 @@ fn test_global_show() { app_tester.set_inputs(vec!["".to_string()]); let _ = app_tester.run( vec![ - (PhpMixed::from("command"), PhpMixed::from("global")), - (PhpMixed::from("command-name"), PhpMixed::from("show")), + (ParameterName::of("command"), InputValue::from("global")), + (ParameterName::of("command-name"), InputValue::from("show")), ], RunOptions::default(), ); @@ -186,8 +193,8 @@ fn test_global_show_without_packages() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("global")), - (PhpMixed::from("command-name"), PhpMixed::from("show")), + (ParameterName::of("command"), InputValue::from("global")), + (ParameterName::of("command-name"), InputValue::from("show")), ], RunOptions::default(), ) @@ -234,11 +241,14 @@ fn test_global_require() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("global")), - (PhpMixed::from("command-name"), PhpMixed::from("require")), + (ParameterName::of("command"), InputValue::from("global")), + ( + ParameterName::of("command-name"), + InputValue::from("require"), + ), ( - PhpMixed::from("packages"), - PhpMixed::List(vec![PhpMixed::from("vendor/required-pkg:2.0.0")]), + ParameterName::of("packages"), + InputValue::Array(vec!["vendor/required-pkg:2.0.0".to_string()]), ), ], RunOptions::default(), @@ -295,8 +305,11 @@ fn test_global_update() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("global")), - (PhpMixed::from("command-name"), PhpMixed::from("update")), + (ParameterName::of("command"), InputValue::from("global")), + ( + ParameterName::of("command-name"), + InputValue::from("update"), + ), ], RunOptions::default(), ) @@ -330,9 +343,12 @@ fn test_global_changes_directory() { app_tester.set_inputs(vec!["".to_string()]); let _ = app_tester.run( vec![ - (PhpMixed::from("command"), PhpMixed::from("global")), - (PhpMixed::from("command-name"), PhpMixed::from("config")), - (PhpMixed::from("setting-key"), PhpMixed::from("name")), + (ParameterName::of("command"), InputValue::from("global")), + ( + ParameterName::of("command-name"), + InputValue::from("config"), + ), + (ParameterName::of("setting-key"), InputValue::from("name")), ], RunOptions::default(), ); @@ -364,7 +380,7 @@ fn test_global_missing_command_name() { app_tester.set_inputs(vec!["".to_string()]); let err = app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("global"))], + vec![(ParameterName::of("command"), InputValue::from("global"))], RunOptions::default(), ) .expect_err("expected a RuntimeException for the missing command-name argument"); diff --git a/crates/shirabe/tests/command/home_command_test.rs b/crates/shirabe/tests/command/home_command_test.rs index 4a77bd8a..17bfd191 100644 --- a/crates/shirabe/tests/command/home_command_test.rs +++ b/crates/shirabe/tests/command/home_command_test.rs @@ -6,12 +6,13 @@ use crate::test_case::{ }; use serial_test::serial; use shirabe::package::handle::PackageInterfaceHandle; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// ref: HomeCommandTest::testHomeCommandWithShowFlag fn run_use_case( composer_json: serde_json::Value, - command: Vec<(PhpMixed, PhpMixed)>, + command: Vec<(ParameterName, InputValue)>, expected: &str, urls: &[(&str, &str)], ) { @@ -36,8 +37,8 @@ fn run_use_case( let mut app_tester = get_application_tester(); let mut input = vec![ - (PhpMixed::from("command"), PhpMixed::from("home")), - (PhpMixed::from("--show"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("home")), + (ParameterName::of("--show"), InputValue::from(true)), ]; input.extend(command); app_tester.run(input, RunOptions::default()).unwrap(); @@ -64,8 +65,8 @@ fn test_home_command_with_show_flag_invalid_or_missing_repository_url() { }, }), vec![( - PhpMixed::from("packages"), - PhpMixed::List(vec![PhpMixed::from("vendor/package")]), + ParameterName::of("packages"), + InputValue::Array(vec!["vendor/package".to_string()]), )], "Invalid or missing repository URL for vendor/package", &[], @@ -92,8 +93,8 @@ fn test_home_command_with_show_flag_package_not_found() { run_use_case( serde_json::json!({ "repositories": [] }), vec![( - PhpMixed::from("packages"), - PhpMixed::List(vec![PhpMixed::from("vendor/anotherpackage")]), + ParameterName::of("packages"), + InputValue::Array(vec!["vendor/anotherpackage".to_string()]), )], "Package vendor/anotherpackage not found\n\ Invalid or missing repository URL for vendor/anotherpackage", @@ -108,8 +109,8 @@ fn test_home_command_with_show_flag_a_valid_package_url() { run_use_case( serde_json::json!({ "repositories": [] }), vec![( - PhpMixed::from("packages"), - PhpMixed::List(vec![PhpMixed::from("vendor/package")]), + ParameterName::of("packages"), + InputValue::Array(vec!["vendor/package".to_string()]), )], "https://example.org", &[("vendor/package", "https://example.org")], @@ -123,8 +124,8 @@ fn test_home_command_with_show_flag_a_valid_dev_package_url() { run_use_case( serde_json::json!({ "repositories": [] }), vec![( - PhpMixed::from("packages"), - PhpMixed::List(vec![PhpMixed::from("vendor/devpackage")]), + ParameterName::of("packages"), + InputValue::Array(vec!["vendor/devpackage".to_string()]), )], "https://example.org/dev", &[("vendor/devpackage", "https://example.org/dev")], diff --git a/crates/shirabe/tests/command/init_command_test.rs b/crates/shirabe/tests/command/init_command_test.rs index ffb98fbb..02131356 100644 --- a/crates/shirabe/tests/command/init_command_test.rs +++ b/crates/shirabe/tests/command/init_command_test.rs @@ -6,6 +6,8 @@ use shirabe::command::init_command::InitCommand; use shirabe::json::JsonFile; use shirabe::util::platform::Platform; use shirabe_php_shim::{PHP_SERVER, PhpMixed}; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; use tempfile::TempDir; fn set_up() { @@ -33,23 +35,28 @@ fn read_composer_json(dir: &std::path::Path) -> serde_json::Value { } /// `['command' => 'init', '--no-interaction' => true] + $arguments`. -fn non_interactive_input(arguments: Vec<(PhpMixed, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { +fn non_interactive_input( + arguments: Vec<(ParameterName, InputValue)>, +) -> Vec<(ParameterName, InputValue)> { let mut input = vec![ - (PhpMixed::from("command"), PhpMixed::from("init")), - (PhpMixed::from("--no-interaction"), PhpMixed::Bool(true)), + (ParameterName::of("command"), InputValue::from("init")), + ( + ParameterName::of("--no-interaction"), + InputValue::Bool(true), + ), ]; input.extend(arguments); input } -fn opt(name: &str, value: &str) -> (PhpMixed, PhpMixed) { - (PhpMixed::from(name), PhpMixed::from(value)) +fn opt(name: &str, value: &str) -> (ParameterName, InputValue) { + (ParameterName::of(name), InputValue::from(value)) } -fn opt_list(name: &str, values: &[&str]) -> (PhpMixed, PhpMixed) { +fn opt_list(name: &str, values: &[&str]) -> (ParameterName, InputValue) { ( - PhpMixed::from(name), - PhpMixed::List(values.iter().map(|v| PhpMixed::from(*v)).collect()), + ParameterName::of(name), + InputValue::Array(values.iter().map(|v| v.to_string()).collect()), ) } @@ -158,7 +165,7 @@ fn test_namespace_from_missing_package_name() { assert_eq!(None, namespace); } -fn run_data_provider() -> Vec<(serde_json::Value, Vec<(PhpMixed, PhpMixed)>)> { +fn run_data_provider() -> Vec<(serde_json::Value, Vec<(ParameterName, InputValue)>)> { vec![ // name argument ( @@ -382,7 +389,7 @@ enum InvalidExpectation { StderrMatches(&'static str), } -fn run_invalid_data_provider() -> Vec<(InvalidExpectation, Vec<(PhpMixed, PhpMixed)>)> { +fn run_invalid_data_provider() -> Vec<(InvalidExpectation, Vec<(ParameterName, InputValue)>)> { vec![ // invalid name argument ( @@ -547,7 +554,7 @@ fn test_interactive_run() { app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("init"))], + vec![(ParameterName::of("command"), InputValue::from("init"))], RunOptions::default(), ) .unwrap(); diff --git a/crates/shirabe/tests/command/install_command_test.rs b/crates/shirabe/tests/command/install_command_test.rs index 55ea9964..11afd464 100644 --- a/crates/shirabe/tests/command/install_command_test.rs +++ b/crates/shirabe/tests/command/install_command_test.rs @@ -5,12 +5,13 @@ use crate::test_case::{ init_temp_composer, }; use serial_test::serial; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; -fn input(pairs: Vec<(&str, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { +fn input(pairs: Vec<(&str, InputValue)>) -> Vec<(ParameterName, InputValue)> { pairs .into_iter() - .map(|(k, v)| (PhpMixed::from(k), v)) + .map(|(k, v)| (ParameterName::of(k), v)) .collect() } @@ -18,14 +19,14 @@ fn input(pairs: Vec<(&str, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { fn error_cases() -> Vec<( &'static str, serde_json::Value, - Vec<(&'static str, PhpMixed)>, + Vec<(&'static str, InputValue)>, &'static str, )> { vec![ ( "it writes an error when the dev flag is passed", serde_json::json!({ "repositories": [] }), - vec![("--dev", PhpMixed::from(true))], + vec![("--dev", InputValue::from(true))], r#"You are using the deprecated option "--dev". It has no effect and will break in Composer 3. Installing dependencies from lock file (including require-dev) Verifying lock file contents can be installed on current platform. @@ -35,7 +36,7 @@ Generating autoload files"#, ( "it writes an error when no-suggest flag passed", serde_json::json!({ "repositories": [] }), - vec![("--no-suggest", PhpMixed::from(true))], + vec![("--no-suggest", InputValue::from(true))], r#"You are using the deprecated option "--no-suggest". It has no effect and will break in Composer 3. Installing dependencies from lock file (including require-dev) Verifying lock file contents can be installed on current platform. @@ -47,14 +48,14 @@ Generating autoload files"#, serde_json::json!({ "repositories": [] }), vec![( "packages", - PhpMixed::List(vec![PhpMixed::from("vendor/package")]), + InputValue::Array(vec!["vendor/package".to_string()]), )], r#"Invalid argument vendor/package. Use "composer require vendor/package" instead to add packages to your composer.json."#, ), ( "it writes an error when no-install flag is passed", serde_json::json!({ "repositories": [] }), - vec![("--no-install", PhpMixed::from(true))], + vec![("--no-install", InputValue::from(true))], r#"Invalid option "--no-install". Use "composer update --no-install" instead if you are trying to update the composer.lock file."#, ), ] @@ -73,7 +74,7 @@ fn test_install_command_errors() { create_installed_json(&packages, &dev_packages, true); let mut app_tester = get_application_tester(); - let mut args = vec![("command", PhpMixed::from("install"))]; + let mut args = vec![("command", InputValue::from("install"))]; args.extend(command); let _ = app_tester.run(input(args), RunOptions::default()); @@ -107,8 +108,8 @@ fn test_install_from_empty_vendor() { app_tester .run( input(vec![ - ("command", PhpMixed::from("install")), - ("--no-progress", PhpMixed::from(true)), + ("command", InputValue::from("install")), + ("--no-progress", InputValue::from(true)), ]), RunOptions::default(), ) @@ -147,9 +148,9 @@ fn test_install_from_empty_vendor_no_dev() { app_tester .run( input(vec![ - ("command", PhpMixed::from("install")), - ("--no-progress", PhpMixed::from(true)), - ("--no-dev", PhpMixed::from(true)), + ("command", InputValue::from("install")), + ("--no-progress", InputValue::from(true)), + ("--no-dev", InputValue::from(true)), ]), RunOptions::default(), ) @@ -190,8 +191,8 @@ fn test_install_new_packages_with_existing_partial_vendor() { app_tester .run( input(vec![ - ("command", PhpMixed::from("install")), - ("--no-progress", PhpMixed::from(true)), + ("command", InputValue::from("install")), + ("--no-progress", InputValue::from(true)), ]), RunOptions::default(), ) diff --git a/crates/shirabe/tests/command/licenses_command_test.rs b/crates/shirabe/tests/command/licenses_command_test.rs index 5b25aadd..b226f2f0 100644 --- a/crates/shirabe/tests/command/licenses_command_test.rs +++ b/crates/shirabe/tests/command/licenses_command_test.rs @@ -6,7 +6,8 @@ use crate::test_case::{ }; use serial_test::serial; use shirabe::package::handle::PackageInterfaceHandle; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// ref: LicensesCommandTest::setUp fn set_up() -> TearDown { @@ -85,7 +86,7 @@ fn test_basic_run() { let mut app_tester = get_application_tester(); let status_code = app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("license"))], + vec![(ParameterName::of("command"), InputValue::from("license"))], RunOptions::default(), ) .unwrap(); @@ -115,8 +116,8 @@ fn test_no_dev() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("license")), - (PhpMixed::from("--no-dev"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("license")), + (ParameterName::of("--no-dev"), InputValue::from(true)), ], RunOptions::default(), ) @@ -146,8 +147,8 @@ fn test_format_json() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("license")), - (PhpMixed::from("--format"), PhpMixed::from("json")), + (ParameterName::of("command"), InputValue::from("license")), + (ParameterName::of("--format"), InputValue::from("json")), ], RunOptions { capture_stderr_separately: true, @@ -182,8 +183,8 @@ fn test_format_summary() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("license")), - (PhpMixed::from("--format"), PhpMixed::from("summary")), + (ParameterName::of("command"), InputValue::from("license")), + (ParameterName::of("--format"), InputValue::from("summary")), ], RunOptions::default(), ) @@ -223,8 +224,8 @@ fn test_format_unknown() { let mut app_tester = get_application_tester(); let result = app_tester.run( vec![ - (PhpMixed::from("command"), PhpMixed::from("license")), - (PhpMixed::from("--format"), PhpMixed::from("unknown")), + (ParameterName::of("command"), InputValue::from("license")), + (ParameterName::of("--format"), InputValue::from("unknown")), ], RunOptions::default(), ); @@ -244,8 +245,8 @@ fn test_locked() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("license")), - (PhpMixed::from("--locked"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("license")), + (ParameterName::of("--locked"), InputValue::from(true)), ], RunOptions::default(), ) @@ -276,9 +277,9 @@ fn test_locked_no_dev() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("license")), - (PhpMixed::from("--locked"), PhpMixed::from(true)), - (PhpMixed::from("--no-dev"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("license")), + (ParameterName::of("--locked"), InputValue::from(true)), + (ParameterName::of("--no-dev"), InputValue::from(true)), ], RunOptions::default(), ) @@ -310,8 +311,8 @@ fn test_locked_without_lock_file() { let mut app_tester = get_application_tester(); let result = app_tester.run( vec![ - (PhpMixed::from("command"), PhpMixed::from("license")), - (PhpMixed::from("--locked"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("license")), + (ParameterName::of("--locked"), InputValue::from(true)), ], RunOptions::default(), ); diff --git a/crates/shirabe/tests/command/reinstall_command_test.rs b/crates/shirabe/tests/command/reinstall_command_test.rs index ecd98c37..6847d998 100644 --- a/crates/shirabe/tests/command/reinstall_command_test.rs +++ b/crates/shirabe/tests/command/reinstall_command_test.rs @@ -5,26 +5,24 @@ use crate::test_case::{ init_temp_composer, }; use serial_test::serial; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; -fn input(pairs: Vec<(&str, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { +fn input(pairs: Vec<(&str, InputValue)>) -> Vec<(ParameterName, InputValue)> { pairs .into_iter() - .map(|(k, v)| (PhpMixed::from(k), v)) + .map(|(k, v)| (ParameterName::of(k), v)) .collect() } /// ref: ReinstallCommandTest::caseProvider -fn cases() -> Vec<(&'static str, Vec<(&'static str, PhpMixed)>, &'static str)> { +fn cases() -> Vec<(&'static str, Vec<(&'static str, InputValue)>, &'static str)> { vec![ ( "reinstall a package by name", vec![( "packages", - PhpMixed::List(vec![ - PhpMixed::from("root/req"), - PhpMixed::from("root/anotherreq*"), - ]), + InputValue::Array(vec!["root/req".to_string(), "root/anotherreq*".to_string()]), )], "- Removing root/req (1.0.0) - Removing root/anotherreq2 (1.0.0) @@ -35,10 +33,7 @@ fn cases() -> Vec<(&'static str, Vec<(&'static str, PhpMixed)>, &'static str)> { ), ( "reinstall packages by type", - vec![( - "--type", - PhpMixed::List(vec![PhpMixed::from("metapackage")]), - )], + vec![("--type", InputValue::Array(vec!["metapackage".to_string()]))], "- Removing root/req (1.0.0) - Removing root/lala (1.0.0) - Removing root/anotherreq2 (1.0.0) @@ -52,7 +47,7 @@ fn cases() -> Vec<(&'static str, Vec<(&'static str, PhpMixed)>, &'static str)> { "reinstall a package that is not installed", vec![( "packages", - PhpMixed::List(vec![PhpMixed::from("root/unknownreq")]), + InputValue::Array(vec!["root/unknownreq".to_string()]), )], r#"Pattern "root/unknownreq" does not match any currently installed packages. Found no packages to reinstall, aborting."#, @@ -93,9 +88,9 @@ fn test_reinstall_command() { let mut app_tester = get_application_tester(); let mut args = vec![ - ("command", PhpMixed::from("reinstall")), - ("--no-progress", PhpMixed::from(true)), - ("--no-plugins", PhpMixed::from(true)), + ("command", InputValue::from("reinstall")), + ("--no-progress", InputValue::from(true)), + ("--no-plugins", InputValue::from(true)), ]; args.extend(options); app_tester.run(input(args), RunOptions::default()).unwrap(); diff --git a/crates/shirabe/tests/command/remove_command_test.rs b/crates/shirabe/tests/command/remove_command_test.rs index 9139bf26..377d78c0 100644 --- a/crates/shirabe/tests/command/remove_command_test.rs +++ b/crates/shirabe/tests/command/remove_command_test.rs @@ -9,18 +9,19 @@ use serial_test::serial; use shirabe::json::JsonFile; use shirabe::package::Link; use shirabe::package::handle::PackageInterfaceHandle; -use shirabe_php_shim::PhpMixed; use shirabe_semver::constraint::{AnyConstraint, MatchAllConstraint}; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; // Symfony\Component\Console\Command\Command exit codes. const SUCCESS: i32 = 0; const FAILURE: i32 = 1; const INVALID: i32 = 2; -fn input(pairs: Vec<(&str, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { +fn input(pairs: Vec<(&str, InputValue)>) -> Vec<(ParameterName, InputValue)> { pairs .into_iter() - .map(|(k, v)| (PhpMixed::from(k), v)) + .map(|(k, v)| (ParameterName::of(k), v)) .collect() } @@ -47,7 +48,7 @@ fn test_exception_running_with_no_remove_packages() { let mut app_tester = get_application_tester(); let err = app_tester .run( - input(vec![("command", PhpMixed::from("remove"))]), + input(vec![("command", InputValue::from("remove"))]), RunOptions::default(), ) .expect_err("expected InvalidArgumentException for missing packages argument"); @@ -68,8 +69,8 @@ fn test_exception_when_running_unused_without_lock_file() { let err = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("--unused", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("--unused", InputValue::from(true)), ]), RunOptions::default(), ) @@ -94,10 +95,10 @@ fn test_warning_when_removing_non_existent_package() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), + ("command", InputValue::from("remove")), ( "packages", - PhpMixed::List(vec![PhpMixed::from("vendor1/package1")]), + InputValue::Array(vec!["vendor1/package1".to_string()]), ), ]), RunOptions::default(), @@ -131,11 +132,11 @@ fn test_warning_when_removing_package_from_wrong_type() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("packages", PhpMixed::List(vec![PhpMixed::from("root/req")])), - ("--dev", PhpMixed::from(true)), - ("--no-update", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("packages", InputValue::Array(vec!["root/req".to_string()])), + ("--dev", InputValue::from(true)), + ("--no-update", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) @@ -170,11 +171,11 @@ fn test_warning_when_removing_package_with_deprecated_dependencies_flag() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("packages", PhpMixed::List(vec![PhpMixed::from("root/req")])), - ("--update-with-dependencies", PhpMixed::from(true)), - ("--no-update", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("packages", InputValue::Array(vec!["root/req".to_string()])), + ("--update-with-dependencies", InputValue::from(true)), + ("--no-update", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) @@ -238,10 +239,10 @@ fn test_message_output_when_no_unused_packages_to_remove() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("--unused", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("--unused", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) @@ -286,10 +287,10 @@ fn test_remove_unused_package() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("--unused", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("--unused", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) @@ -355,10 +356,10 @@ fn test_remove_package_by_name() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("packages", PhpMixed::List(vec![PhpMixed::from("root/req")])), - ("--no-audit", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("packages", InputValue::Array(vec!["root/req".to_string()])), + ("--no-audit", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) @@ -436,11 +437,11 @@ fn test_remove_package_by_name_with_dry_run() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("packages", PhpMixed::List(vec![PhpMixed::from("root/req")])), - ("--dry-run", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("packages", InputValue::Array(vec!["root/req".to_string()])), + ("--dry-run", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) @@ -522,10 +523,10 @@ fn test_remove_allowed_plugin_package_with_no_other_allowed_plugins() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("packages", PhpMixed::List(vec![PhpMixed::from("root/req")])), - ("--no-audit", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("packages", InputValue::Array(vec!["root/req".to_string()])), + ("--no-audit", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) @@ -574,10 +575,10 @@ fn test_remove_allowed_plugin_package_with_other_allowed_plugins() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("packages", PhpMixed::List(vec![PhpMixed::from("root/req")])), - ("--no-audit", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("packages", InputValue::Array(vec!["root/req".to_string()])), + ("--no-audit", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) @@ -629,11 +630,11 @@ fn test_remove_packages_by_vendor() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("packages", PhpMixed::List(vec![PhpMixed::from("root/*")])), - ("--no-install", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("packages", InputValue::Array(vec!["root/*".to_string()])), + ("--no-install", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) @@ -709,12 +710,12 @@ fn test_remove_packages_by_vendor_with_dry_run() { app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("packages", PhpMixed::List(vec![PhpMixed::from("root/*")])), - ("--dry-run", PhpMixed::from(true)), - ("--no-install", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("packages", InputValue::Array(vec!["root/*".to_string()])), + ("--dry-run", InputValue::from(true)), + ("--no-install", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) @@ -767,11 +768,11 @@ fn test_warning_when_removing_packages_by_vendor_from_wrong_type() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("packages", PhpMixed::List(vec![PhpMixed::from("root/*")])), - ("--dev", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), - ("--no-update", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("packages", InputValue::Array(vec!["root/*".to_string()])), + ("--dev", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), + ("--no-update", InputValue::from(true)), ]), RunOptions::default(), ) @@ -813,11 +814,11 @@ fn test_package_still_present_error_when_no_install_flag_used() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("packages", PhpMixed::List(vec![PhpMixed::from("root/req")])), - ("--no-install", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("packages", InputValue::Array(vec!["root/req".to_string()])), + ("--no-install", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) @@ -903,11 +904,11 @@ fn run_update_inherited_dependencies_flag_case( let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("remove")), - ("packages", PhpMixed::List(vec![PhpMixed::from("root/req")])), - (install_flag_name, PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--no-interaction", PhpMixed::from(true)), + ("command", InputValue::from("remove")), + ("packages", InputValue::Array(vec!["root/req".to_string()])), + (install_flag_name, InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--no-interaction", InputValue::from(true)), ]), RunOptions::default(), ) diff --git a/crates/shirabe/tests/command/repository_command_test.rs b/crates/shirabe/tests/command/repository_command_test.rs index 36b74cc8..a768dc91 100644 --- a/crates/shirabe/tests/command/repository_command_test.rs +++ b/crates/shirabe/tests/command/repository_command_test.rs @@ -3,7 +3,8 @@ use crate::test_case::{RunOptions, get_application_tester, init_temp_composer}; use serial_test::serial; use shirabe::json::JsonFile; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// Read the composer.json in the CWD and decode it. fn read_composer_json() -> serde_json::Value { @@ -21,8 +22,8 @@ fn test_list_with_no_repositories() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("list")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("list")), ], RunOptions::default(), ) @@ -59,8 +60,8 @@ fn test_list_with_repositories_as_list() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("list")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("list")), ], RunOptions::default(), ) @@ -98,8 +99,8 @@ fn test_list_with_repositories_as_assoc() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("list")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("list")), ], RunOptions::default(), ) @@ -126,13 +127,13 @@ fn test_add_repository_with_type_and_url() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("add")), - (PhpMixed::from("name"), PhpMixed::from("foo")), - (PhpMixed::from("arg1"), PhpMixed::from("vcs")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("add")), + (ParameterName::of("name"), InputValue::from("foo")), + (ParameterName::of("arg1"), InputValue::from("vcs")), ( - PhpMixed::from("arg2"), - PhpMixed::from("https://example.org/foo.git"), + ParameterName::of("arg2"), + InputValue::from("https://example.org/foo.git"), ), ], RunOptions::default(), @@ -161,12 +162,12 @@ fn test_add_repository_with_json() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("add")), - (PhpMixed::from("name"), PhpMixed::from("bar")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("add")), + (ParameterName::of("name"), InputValue::from("bar")), ( - PhpMixed::from("arg1"), - PhpMixed::from(r#"{"type":"composer","url":"https://repo.example.org"}"#), + ParameterName::of("arg1"), + InputValue::from(r#"{"type":"composer","url":"https://repo.example.org"}"#), ), ], RunOptions::default(), @@ -202,9 +203,9 @@ fn test_remove_repository() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("remove")), - (PhpMixed::from("name"), PhpMixed::from("foo")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("remove")), + (ParameterName::of("name"), InputValue::from("foo")), ], RunOptions::default(), ) @@ -240,10 +241,10 @@ fn run_set_and_get_url_assoc_case(name: &str, index: &str, new_url: &str) { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("set-url")), - (PhpMixed::from("name"), PhpMixed::from(name)), - (PhpMixed::from("arg1"), PhpMixed::from(new_url)), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("set-url")), + (ParameterName::of("name"), InputValue::from(name)), + (ParameterName::of("arg1"), InputValue::from(new_url)), ], RunOptions::default(), ) @@ -263,9 +264,9 @@ fn run_set_and_get_url_assoc_case(name: &str, index: &str, new_url: &str) { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("get-url")), - (PhpMixed::from("name"), PhpMixed::from(name)), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("get-url")), + (ParameterName::of("name"), InputValue::from(name)), ], RunOptions::default(), ) @@ -305,10 +306,10 @@ fn run_set_and_get_url_list_case(name: &str, index: usize, new_url: &str) { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("set-url")), - (PhpMixed::from("name"), PhpMixed::from(name)), - (PhpMixed::from("arg1"), PhpMixed::from(new_url)), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("set-url")), + (ParameterName::of("name"), InputValue::from(name)), + (ParameterName::of("arg1"), InputValue::from(new_url)), ], RunOptions::default(), ) @@ -333,9 +334,9 @@ fn run_set_and_get_url_list_case(name: &str, index: usize, new_url: &str) { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("get-url")), - (PhpMixed::from("name"), PhpMixed::from(name)), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("get-url")), + (ParameterName::of("name"), InputValue::from(name)), ], RunOptions::default(), ) @@ -366,9 +367,9 @@ fn test_disable_and_enable_packagist() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("disable")), - (PhpMixed::from("name"), PhpMixed::from("packagist")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("disable")), + (ParameterName::of("name"), InputValue::from("packagist")), ], RunOptions::default(), ) @@ -384,9 +385,9 @@ fn test_disable_and_enable_packagist() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("enable")), - (PhpMixed::from("name"), PhpMixed::from("packagist")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("enable")), + (ParameterName::of("name"), InputValue::from("packagist")), ], RunOptions::default(), ) @@ -404,12 +405,12 @@ fn test_invalid_arg_combination_throws() { let err = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), + (ParameterName::of("command"), InputValue::from("repo")), ( - PhpMixed::from("--file"), - PhpMixed::from("alt.composer.json"), + ParameterName::of("--file"), + InputValue::from("alt.composer.json"), ), - (PhpMixed::from("--global"), PhpMixed::from(true)), + (ParameterName::of("--global"), InputValue::from(true)), ], RunOptions::default(), ) @@ -438,11 +439,11 @@ fn test_prepend_repository_by_name_list_to_assoc() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("add")), - (PhpMixed::from("name"), PhpMixed::from("foo")), - (PhpMixed::from("arg1"), PhpMixed::from("path")), - (PhpMixed::from("arg2"), PhpMixed::from("foo/bar")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("add")), + (ParameterName::of("name"), InputValue::from("foo")), + (ParameterName::of("arg1"), InputValue::from("path")), + (ParameterName::of("arg2"), InputValue::from("foo/bar")), ], RunOptions::default(), ) @@ -478,12 +479,12 @@ fn test_append_repository_by_name_list_to_assoc() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("add")), - (PhpMixed::from("name"), PhpMixed::from("foo")), - (PhpMixed::from("arg1"), PhpMixed::from("path")), - (PhpMixed::from("arg2"), PhpMixed::from("foo/bar")), - (PhpMixed::from("--append"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("add")), + (ParameterName::of("name"), InputValue::from("foo")), + (ParameterName::of("arg1"), InputValue::from("path")), + (ParameterName::of("arg2"), InputValue::from("foo/bar")), + (ParameterName::of("--append"), InputValue::from(true)), ], RunOptions::default(), ) @@ -519,11 +520,11 @@ fn test_prepend_repository_assoc_with_packagist_disabled() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("add")), - (PhpMixed::from("name"), PhpMixed::from("foo")), - (PhpMixed::from("arg1"), PhpMixed::from("path")), - (PhpMixed::from("arg2"), PhpMixed::from("foo/bar")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("add")), + (ParameterName::of("name"), InputValue::from("foo")), + (ParameterName::of("arg1"), InputValue::from("path")), + (ParameterName::of("arg2"), InputValue::from("foo/bar")), ], RunOptions::default(), ) @@ -560,12 +561,12 @@ fn test_append_repository_assoc_with_packagist_disabled() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("add")), - (PhpMixed::from("name"), PhpMixed::from("foo")), - (PhpMixed::from("arg1"), PhpMixed::from("path")), - (PhpMixed::from("arg2"), PhpMixed::from("foo/bar")), - (PhpMixed::from("--append"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("add")), + (ParameterName::of("name"), InputValue::from("foo")), + (ParameterName::of("arg1"), InputValue::from("path")), + (ParameterName::of("arg2"), InputValue::from("foo/bar")), + (ParameterName::of("--append"), InputValue::from(true)), ], RunOptions::default(), ) @@ -608,15 +609,15 @@ fn test_add_before_and_after_by_name() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("add")), - (PhpMixed::from("name"), PhpMixed::from("beta")), - (PhpMixed::from("arg1"), PhpMixed::from("vcs")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("add")), + (ParameterName::of("name"), InputValue::from("beta")), + (ParameterName::of("arg1"), InputValue::from("vcs")), ( - PhpMixed::from("arg2"), - PhpMixed::from("https://example.org/b"), + ParameterName::of("arg2"), + InputValue::from("https://example.org/b"), ), - (PhpMixed::from("--before"), PhpMixed::from("omega")), + (ParameterName::of("--before"), InputValue::from("omega")), ], RunOptions::default(), ) @@ -628,15 +629,15 @@ fn test_add_before_and_after_by_name() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("add")), - (PhpMixed::from("name"), PhpMixed::from("gamma")), - (PhpMixed::from("arg1"), PhpMixed::from("vcs")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("add")), + (ParameterName::of("name"), InputValue::from("gamma")), + (ParameterName::of("arg1"), InputValue::from("vcs")), ( - PhpMixed::from("arg2"), - PhpMixed::from("https://example.org/g"), + ParameterName::of("arg2"), + InputValue::from("https://example.org/g"), ), - (PhpMixed::from("--after"), PhpMixed::from("alpha")), + (ParameterName::of("--after"), InputValue::from("alpha")), ], RunOptions::default(), ) @@ -670,13 +671,13 @@ fn test_add_same_name_replaces_existing() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("add")), - (PhpMixed::from("name"), PhpMixed::from("foo")), - (PhpMixed::from("arg1"), PhpMixed::from("vcs")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("add")), + (ParameterName::of("name"), InputValue::from("foo")), + (ParameterName::of("arg1"), InputValue::from("vcs")), ( - PhpMixed::from("arg2"), - PhpMixed::from("https://example.org/old"), + ParameterName::of("arg2"), + InputValue::from("https://example.org/old"), ), ], RunOptions::default(), @@ -689,15 +690,15 @@ fn test_add_same_name_replaces_existing() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("repo")), - (PhpMixed::from("action"), PhpMixed::from("add")), - (PhpMixed::from("name"), PhpMixed::from("foo")), - (PhpMixed::from("arg1"), PhpMixed::from("vcs")), + (ParameterName::of("command"), InputValue::from("repo")), + (ParameterName::of("action"), InputValue::from("add")), + (ParameterName::of("name"), InputValue::from("foo")), + (ParameterName::of("arg1"), InputValue::from("vcs")), ( - PhpMixed::from("arg2"), - PhpMixed::from("https://example.org/new"), + ParameterName::of("arg2"), + InputValue::from("https://example.org/new"), ), - (PhpMixed::from("--append"), PhpMixed::from(true)), + (ParameterName::of("--append"), InputValue::from(true)), ], RunOptions::default(), ) diff --git a/crates/shirabe/tests/command/require_command_test.rs b/crates/shirabe/tests/command/require_command_test.rs index 2a9a0411..a4f3bb9c 100644 --- a/crates/shirabe/tests/command/require_command_test.rs +++ b/crates/shirabe/tests/command/require_command_test.rs @@ -6,12 +6,13 @@ use crate::test_case::{ }; use serial_test::serial; use shirabe::json::JsonFile; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; -fn input(pairs: Vec<(&str, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { +fn input(pairs: Vec<(&str, InputValue)>) -> Vec<(ParameterName, InputValue)> { pairs .into_iter() - .map(|(k, v)| (PhpMixed::from(k), v)) + .map(|(k, v)| (ParameterName::of(k), v)) .collect() } @@ -34,12 +35,12 @@ fn test_require_throws_if_none_matches() { let err = app_tester .run( input(vec![ - ("command", PhpMixed::from("require")), - ("--dry-run", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), + ("command", InputValue::from("require")), + ("--dry-run", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), ( "packages", - PhpMixed::List(vec![PhpMixed::from("required/pkg")]), + InputValue::Array(vec!["required/pkg".to_string()]), ), ]), RunOptions::default(), @@ -81,12 +82,12 @@ fn test_require_warns_if_resolved_to_feature_branch() { app_tester .run( input(vec![ - ("command", PhpMixed::from("require")), - ("--dry-run", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), + ("command", InputValue::from("require")), + ("--dry-run", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), ( "packages", - PhpMixed::List(vec![PhpMixed::from("required/pkg")]), + InputValue::Array(vec!["required/pkg".to_string()]), ), ]), RunOptions { @@ -121,7 +122,7 @@ Are you sure you want to use this constraint (y) or would you rather abort (n) t fn provide_require() -> Vec<( &'static str, serde_json::Value, - Vec<(&'static str, PhpMixed)>, + Vec<(&'static str, InputValue)>, &'static str, )> { vec![ @@ -134,7 +135,7 @@ fn provide_require() -> Vec<( { "name": "required/pkg", "version": "1.0.0" }, ] } }, }), - vec![("packages", PhpMixed::List(vec![PhpMixed::from("required/pkg")]))], + vec![("packages", InputValue::Array(vec!["required/pkg".to_string()]))], "Cannot use required/pkg's latest version 1.2.0 as it requires ext-foobar ^1 which is missing from your platform. ./composer.json has been updated Running composer update required/pkg @@ -157,9 +158,9 @@ Using version ^1.0 for required/pkg", ] } }, }), vec![ - ("packages", PhpMixed::List(vec![PhpMixed::from("required/pkg")])), - ("--no-install", PhpMixed::from(true)), - ("-v", PhpMixed::from(true)), + ("packages", InputValue::Array(vec!["required/pkg".to_string()])), + ("--no-install", InputValue::from(true)), + ("-v", InputValue::from(true)), ], "Cannot use required/pkg's latest version 1.2.0 as it requires ext-foobar ^1 which is missing from your platform. Cannot use required/pkg 1.1.0 as it requires ext-foobar ^1 which is missing from your platform. @@ -184,8 +185,8 @@ Using version ^1.0 for required/pkg", ] } }, }), vec![ - ("packages", PhpMixed::List(vec![PhpMixed::from("required/pkg")])), - ("--no-install", PhpMixed::from(true)), + ("packages", InputValue::Array(vec!["required/pkg".to_string()])), + ("--no-install", InputValue::from(true)), ], "Cannot use required/pkg's latest version 1.1.0 as it requires php ^20 which is not satisfied by your platform. ./composer.json has been updated @@ -205,8 +206,8 @@ Using version ^1.0 for required/pkg", ] } }, }), vec![ - ("packages", PhpMixed::List(vec![PhpMixed::from("required/pkg")])), - ("--no-update", PhpMixed::from(true)), + ("packages", InputValue::Array(vec!["required/pkg".to_string()])), + ("--no-update", InputValue::from(true)), ], "Cannot use required/pkg's latest version 1.1.0 as it requires php ^20 which is not satisfied by your platform. Using version ^1.0 for required/pkg @@ -224,8 +225,8 @@ Using version ^1.0 for required/pkg "require": { "existing/dep": "^1" }, }), vec![ - ("packages", PhpMixed::List(vec![PhpMixed::from("required/pkg")])), - ("--no-install", PhpMixed::from(true)), + ("packages", InputValue::Array(vec!["required/pkg".to_string()])), + ("--no-install", InputValue::from(true)), ], "./composer.json has been updated Running composer update required/pkg @@ -245,9 +246,9 @@ Using version ^1.1 for required/pkg", ] } }, }), vec![ - ("packages", PhpMixed::List(vec![PhpMixed::from("required/pkg")])), - ("--no-install", PhpMixed::from(true)), - ("--fixed", PhpMixed::from(true)), + ("packages", InputValue::Array(vec!["required/pkg".to_string()])), + ("--no-install", InputValue::from(true)), + ("--fixed", InputValue::from(true)), ], "./composer.json has been updated Running composer update required/pkg @@ -268,9 +269,9 @@ fn test_require() { let mut app_tester = get_application_tester(); let mut args = vec![ - ("command", PhpMixed::from("require")), - ("--dry-run", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), + ("command", InputValue::from("require")), + ("--dry-run", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), ]; args.extend(command); app_tester.run(input(args), RunOptions::default()).unwrap(); @@ -357,19 +358,19 @@ fn test_inconsistent_require_keys() { let mut app_tester = get_application_tester(); let mut command = vec![ - ("command", PhpMixed::from("require")), - ("--no-audit", PhpMixed::from(true)), - ("--dev", PhpMixed::from(is_dev)), - ("--no-install", PhpMixed::from(true)), + ("command", InputValue::from("require")), + ("--no-audit", InputValue::from(true)), + ("--dev", InputValue::from(is_dev)), + ("--no-install", InputValue::from(true)), ( "packages", - PhpMixed::List(vec![PhpMixed::from("required/pkg")]), + InputValue::Array(vec!["required/pkg".to_string()]), ), ]; if is_interactive { app_tester.set_inputs(vec!["yes".to_string()]); } else { - command.push(("--no-interaction", PhpMixed::from(true))); + command.push(("--no-interaction", InputValue::from(true))); } app_tester diff --git a/crates/shirabe/tests/command/run_script_command_test.rs b/crates/shirabe/tests/command/run_script_command_test.rs index 992fc6e2..5c4a60f7 100644 --- a/crates/shirabe/tests/command/run_script_command_test.rs +++ b/crates/shirabe/tests/command/run_script_command_test.rs @@ -2,7 +2,8 @@ use crate::test_case::{RunOptions, get_application_tester, init_temp_composer}; use serial_test::serial; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// ref: RunScriptCommandTest::testDetectAndPassDevModeToEventAndToDispatching /// @@ -49,8 +50,8 @@ fn test_can_list_scripts() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("run-script")), - (PhpMixed::from("--list"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("run-script")), + (ParameterName::of("--list"), InputValue::from(true)), ], RunOptions::default(), ) @@ -95,9 +96,9 @@ fn test_can_define_aliases() { let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("test")), - (PhpMixed::from("--help"), PhpMixed::from(true)), - (PhpMixed::from("--format"), PhpMixed::from("json")), + (ParameterName::of("command"), InputValue::from("test")), + (ParameterName::of("--help"), InputValue::from(true)), + (ParameterName::of("--format"), InputValue::from("json")), ], RunOptions::default(), ) @@ -193,9 +194,12 @@ class MyCommand extends Command app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("test-direct")), - (PhpMixed::from("--outeropt"), PhpMixed::from(true)), - (PhpMixed::from("req-arg"), PhpMixed::from("lala")), + ( + ParameterName::of("command"), + InputValue::from("test-direct"), + ), + (ParameterName::of("--outeropt"), InputValue::from(true)), + (ParameterName::of("req-arg"), InputValue::from("lala")), ], RunOptions::default(), ) @@ -211,9 +215,9 @@ class MyCommand extends Command app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("test-ref")), - (PhpMixed::from("--outeropt"), PhpMixed::from(true)), - (PhpMixed::from("req-arg"), PhpMixed::from("lala")), + (ParameterName::of("command"), InputValue::from("test-ref")), + (ParameterName::of("--outeropt"), InputValue::from(true)), + (ParameterName::of("req-arg"), InputValue::from("lala")), ], RunOptions::default(), ) @@ -230,8 +234,8 @@ class MyCommand extends Command let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("run-script")), - (PhpMixed::from("--list"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("run-script")), + (ParameterName::of("--list"), InputValue::from(true)), ], RunOptions::default(), ) @@ -317,8 +321,8 @@ class MyCommandWithDefinitions extends Command app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from(cmd_name)), - (PhpMixed::from("req-arg"), PhpMixed::from("lala")), + (ParameterName::of("command"), InputValue::from(cmd_name)), + (ParameterName::of("req-arg"), InputValue::from("lala")), ], RunOptions::default(), ) @@ -331,10 +335,10 @@ class MyCommandWithDefinitions extends Command .run( vec![ ( - PhpMixed::from("command"), - PhpMixed::from(cmd_alias.as_str()), + ParameterName::of("command"), + InputValue::from(cmd_alias.as_str()), ), - (PhpMixed::from("req-arg"), PhpMixed::from("lala")), + (ParameterName::of("req-arg"), InputValue::from("lala")), ], RunOptions::default(), ) @@ -346,8 +350,8 @@ class MyCommandWithDefinitions extends Command let status_code = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("run-script")), - (PhpMixed::from("--list"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("run-script")), + (ParameterName::of("--list"), InputValue::from(true)), ], RunOptions::default(), ) diff --git a/crates/shirabe/tests/command/search_command_test.rs b/crates/shirabe/tests/command/search_command_test.rs index 7806ea0f..cc011d0f 100644 --- a/crates/shirabe/tests/command/search_command_test.rs +++ b/crates/shirabe/tests/command/search_command_test.rs @@ -2,7 +2,8 @@ use crate::test_case::{RunOptions, get_application_tester, init_temp_composer}; use serial_test::serial; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; fn repositories_json() -> serde_json::Value { serde_json::json!({ @@ -22,11 +23,11 @@ fn repositories_json() -> serde_json::Value { } /// ref: SearchCommandTest::testSearch (data provider rolled into one body). -fn run_search_case(command: Vec<(PhpMixed, PhpMixed)>, expected: &str) { +fn run_search_case(command: Vec<(ParameterName, InputValue)>, expected: &str) { let _tear_down = init_temp_composer(Some(&repositories_json()), None, None, true); - let mut input: Vec<(PhpMixed, PhpMixed)> = - vec![(PhpMixed::from("command"), PhpMixed::from("search"))]; + let mut input: Vec<(ParameterName, InputValue)> = + vec![(ParameterName::of("command"), InputValue::from("search"))]; input.extend(command); let mut app_tester = get_application_tester(); @@ -40,8 +41,8 @@ fn test_search() { // 'by name and description' run_search_case( vec![( - "tokens".into(), - PhpMixed::List(vec![PhpMixed::from("fancy")]), + ParameterName::of("tokens"), + InputValue::Array(vec!["fancy".to_string()]), )], "bar/baz ! Abandoned ! fancy baz\nvendor-2/fancy-package", ); @@ -49,8 +50,8 @@ fn test_search() { // 'by name and description with multiple tokens' run_search_case( vec![( - "tokens".into(), - PhpMixed::List(vec![PhpMixed::from("fancy"), PhpMixed::from("vendor")]), + ParameterName::of("tokens"), + InputValue::Array(vec!["fancy".to_string(), "vendor".to_string()]), )], "vendor-1/package-1 generic description\nbar/baz ! Abandoned ! fancy baz\nvendor-2/fancy-package", ); @@ -59,10 +60,10 @@ fn test_search() { run_search_case( vec![ ( - "tokens".into(), - PhpMixed::List(vec![PhpMixed::from("fancy")]), + ParameterName::of("tokens"), + InputValue::Array(vec!["fancy".to_string()]), ), - ("--only-name".into(), PhpMixed::from(true)), + (ParameterName::of("--only-name"), InputValue::from(true)), ], "vendor-2/fancy-package", ); @@ -70,8 +71,11 @@ fn test_search() { // 'by vendor only' run_search_case( vec![ - ("tokens".into(), PhpMixed::List(vec![PhpMixed::from("bar")])), - ("--only-vendor".into(), PhpMixed::from(true)), + ( + ParameterName::of("tokens"), + InputValue::Array(vec!["bar".to_string()]), + ), + (ParameterName::of("--only-vendor"), InputValue::from(true)), ], "bar", ); @@ -80,10 +84,10 @@ fn test_search() { run_search_case( vec![ ( - "tokens".into(), - PhpMixed::List(vec![PhpMixed::from("vendor")]), + ParameterName::of("tokens"), + InputValue::Array(vec!["vendor".to_string()]), ), - ("--type".into(), PhpMixed::from("foo")), + (ParameterName::of("--type"), InputValue::from("foo")), ], "vendor-2/fancy-package", ); @@ -92,10 +96,10 @@ fn test_search() { run_search_case( vec![ ( - "tokens".into(), - PhpMixed::List(vec![PhpMixed::from("vendor-2/fancy")]), + ParameterName::of("tokens"), + InputValue::Array(vec!["vendor-2/fancy".to_string()]), ), - ("--format".into(), PhpMixed::from("json")), + (ParameterName::of("--format"), InputValue::from("json")), ], "[\n {\n \"name\": \"vendor-2/fancy-package\",\n \"description\": null\n }\n]", ); @@ -103,8 +107,8 @@ fn test_search() { // 'no results' run_search_case( vec![( - "tokens".into(), - PhpMixed::List(vec![PhpMixed::from("invalid-package-name")]), + ParameterName::of("tokens"), + InputValue::Array(vec!["invalid-package-name".to_string()]), )], "", ); @@ -124,11 +128,14 @@ fn test_invalid_format() { let result = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("search")), - (PhpMixed::from("--format"), PhpMixed::from("test-format")), + (ParameterName::of("command"), InputValue::from("search")), + ( + ParameterName::of("--format"), + InputValue::from("test-format"), + ), ( - PhpMixed::from("tokens"), - PhpMixed::List(vec![PhpMixed::from("test")]), + ParameterName::of("tokens"), + InputValue::Array(vec!["test".to_string()]), ), ], RunOptions::default(), @@ -155,12 +162,12 @@ fn test_invalid_flags() { let err = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("search")), - (PhpMixed::from("--only-vendor"), PhpMixed::from(true)), - (PhpMixed::from("--only-name"), PhpMixed::from(true)), + (ParameterName::of("command"), InputValue::from("search")), + (ParameterName::of("--only-vendor"), InputValue::from(true)), + (ParameterName::of("--only-name"), InputValue::from(true)), ( - PhpMixed::from("tokens"), - PhpMixed::List(vec![PhpMixed::from("test")]), + ParameterName::of("tokens"), + InputValue::Array(vec!["test".to_string()]), ), ], RunOptions::default(), diff --git a/crates/shirabe/tests/command/self_update_command_test.rs b/crates/shirabe/tests/command/self_update_command_test.rs index 1f83af66..2248873f 100644 --- a/crates/shirabe/tests/command/self_update_command_test.rs +++ b/crates/shirabe/tests/command/self_update_command_test.rs @@ -4,6 +4,8 @@ use crate::test_case::{RunOptions, get_application_tester, init_temp_composer}; use indexmap::IndexMap; use serial_test::serial; use shirabe_php_shim::{PHP_BINARY, PhpMixed}; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; use shirabe_symfony_process::Process; /// ref: SelfUpdateCommandTest::setUp. The `composer-test.phar` copy PHP also performs here lives in @@ -108,8 +110,11 @@ fn test_update_with_invalid_option_throws_exception() { let err = app_tester .run( vec![ - (PhpMixed::from("command"), PhpMixed::from("self-update")), - (PhpMixed::from("invalid-option"), PhpMixed::from(true)), + ( + ParameterName::of("command"), + InputValue::from("self-update"), + ), + (ParameterName::of("invalid-option"), InputValue::from(true)), ], RunOptions::default(), ) diff --git a/crates/shirabe/tests/command/show_command_test.rs b/crates/shirabe/tests/command/show_command_test.rs index eb8176e9..3834b016 100644 --- a/crates/shirabe/tests/command/show_command_test.rs +++ b/crates/shirabe/tests/command/show_command_test.rs @@ -8,13 +8,13 @@ use serial_test::serial; use shirabe::package::Link; use shirabe::package::handle::PackageInterfaceHandle; use shirabe::repository::PlatformRepository; -use shirabe_php_shim::{PhpMixed, date_local}; +use shirabe_php_shim::date_local; -/// Build a `Vec<(PhpMixed, PhpMixed)>` command input from `(key, value)` pairs. -fn input(pairs: Vec<(&str, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { +/// Build a `Vec<(ParameterName, InputValue)>` command input from `(key, value)` pairs. +fn input(pairs: Vec<(&str, InputValue)>) -> Vec<(ParameterName, InputValue)> { pairs .into_iter() - .map(|(k, v)| (PhpMixed::from(k), v)) + .map(|(k, v)| (ParameterName::of(k), v)) .collect() } @@ -50,7 +50,11 @@ fn show_composer_json(requires: serde_json::Value) -> serde_json::Value { } /// ref: ShowCommandTest::testShow (one data-provider case). -fn run_show_case(command: Vec<(PhpMixed, PhpMixed)>, expected: &str, requires: serde_json::Value) { +fn run_show_case( + command: Vec<(ParameterName, InputValue)>, + expected: &str, + requires: serde_json::Value, +) { let _tear_down = init_temp_composer(Some(&show_composer_json(requires)), None, None, true); let pkg = get_complete_package("vendor/package", "v1.0.0"); @@ -76,12 +80,14 @@ fn run_show_case(command: Vec<(PhpMixed, PhpMixed)>, expected: &str, requires: s } use crate::test_case::{create_composer_lock, create_installed_json}; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; #[test] #[serial] fn test_show_default_shows_installed_with_version_and_description() { run_show_case( - input(vec![("command", PhpMixed::from("show"))]), + input(vec![("command", InputValue::from("show"))]), "outdated/major 1.0.0 outdated/minor 1.0.0 outdated/patch 1.0.0 @@ -95,9 +101,9 @@ vendor/package 1.0.0 description of installed package", fn test_show_with_installed_and_self() { run_show_case( input(vec![ - ("command", PhpMixed::from("show")), - ("--installed", PhpMixed::from(true)), - ("--self", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--installed", InputValue::from(true)), + ("--self", InputValue::from(true)), ]), "outdated/major 1.0.0 outdated/minor 1.0.0 @@ -113,9 +119,9 @@ vendor/package 1.0.0 description of installed package", fn test_show_with_locked_and_self() { run_show_case( input(vec![ - ("command", PhpMixed::from("show")), - ("--locked", PhpMixed::from(true)), - ("--self", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--locked", InputValue::from(true)), + ("--self", InputValue::from(true)), ]), "root/pkg 1.2.3 vendor/locked 3.0.0 description of locked package", @@ -128,8 +134,8 @@ vendor/locked 3.0.0 description of locked package", fn test_show_with_available() { run_show_case( input(vec![ - ("command", PhpMixed::from("show")), - ("-a", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("-a", InputValue::from(true)), ]), "outdated/major outdated/major v2.0.0 description outdated/minor outdated/minor v1.1.1 description @@ -144,8 +150,8 @@ vendor/package generic description", fn test_show_with_direct_shows_nothing_if_no_deps() { run_show_case( input(vec![ - ("command", PhpMixed::from("show")), - ("--direct", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--direct", InputValue::from(true)), ]), "", serde_json::json!({}), @@ -157,8 +163,8 @@ fn test_show_with_direct_shows_nothing_if_no_deps() { fn test_show_with_direct_shows_only_root_deps() { run_show_case( input(vec![ - ("command", PhpMixed::from("show")), - ("--direct", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--direct", InputValue::from(true)), ]), "outdated/major 1.0.0", serde_json::json!({"outdated/major": "*"}), @@ -169,7 +175,7 @@ fn test_show_with_direct_shows_only_root_deps() { #[serial] fn test_show_outdated_deps() { run_show_case( - input(vec![("command", PhpMixed::from("outdated"))]), + input(vec![("command", InputValue::from("outdated"))]), "Legend: ! patch or minor release available - update recommended ~ major release available - update possible @@ -191,8 +197,8 @@ outdated/patch 1.0.0 ! 1.0.1", fn test_show_outdated_deps_sorting_by_age() { run_show_case( input(vec![ - ("command", PhpMixed::from("outdated")), - ("--sort-by-age", PhpMixed::from(true)), + ("command", InputValue::from("outdated")), + ("--sort-by-age", InputValue::from(true)), ]), "Legend: ! patch or minor release available - update recommended @@ -214,8 +220,8 @@ outdated/major 1.0.0 ~ 2.0.0 from today", fn test_show_outdated_deps_with_direct_only_show_direct_deps_with_updated() { run_show_case( input(vec![ - ("command", PhpMixed::from("outdated")), - ("--direct", PhpMixed::from(true)), + ("command", InputValue::from("outdated")), + ("--direct", InputValue::from(true)), ]), "Legend: ! patch or minor release available - update recommended @@ -233,8 +239,8 @@ outdated/major 1.0.0 ~ 2.0.0", fn test_show_outdated_deps_with_direct_show_msg_if_all_up_to_date() { run_show_case( input(vec![ - ("command", PhpMixed::from("outdated")), - ("--direct", PhpMixed::from(true)), + ("command", InputValue::from("outdated")), + ("--direct", InputValue::from(true)), ]), "All your direct dependencies are up to date", serde_json::json!({"vendor/package": "*"}), @@ -246,8 +252,8 @@ fn test_show_outdated_deps_with_direct_show_msg_if_all_up_to_date() { fn test_show_outdated_deps_with_major_only() { run_show_case( input(vec![ - ("command", PhpMixed::from("outdated")), - ("--major-only", PhpMixed::from(true)), + ("command", InputValue::from("outdated")), + ("--major-only", InputValue::from(true)), ]), "Legend: ! patch or minor release available - update recommended @@ -267,8 +273,8 @@ outdated/major 1.0.0 ~ 2.0.0", fn test_show_outdated_deps_with_minor_only() { run_show_case( input(vec![ - ("command", PhpMixed::from("outdated")), - ("--minor-only", PhpMixed::from(true)), + ("command", InputValue::from("outdated")), + ("--minor-only", InputValue::from(true)), ]), "Legend: ! patch or minor release available - update recommended @@ -289,8 +295,8 @@ outdated/patch 1.0.0 ! 1.0.1", fn test_show_outdated_deps_with_patch_only() { run_show_case( input(vec![ - ("command", PhpMixed::from("outdated")), - ("--patch-only", PhpMixed::from(true)), + ("command", InputValue::from("outdated")), + ("--patch-only", InputValue::from(true)), ]), "Legend: ! patch or minor release available - update recommended @@ -334,7 +340,7 @@ fn test_outdated_filters_according_to_platform_reqs_and_warns() { let mut app_tester = get_application_tester(); app_tester .run( - input(vec![("command", PhpMixed::from("outdated"))]), + input(vec![("command", InputValue::from("outdated"))]), RunOptions::default(), ) .unwrap(); @@ -356,8 +362,8 @@ vendor/package 1.1.0 ~ 1.0.0", app_tester .run( input(vec![ - ("command", PhpMixed::from("outdated")), - ("--verbose", PhpMixed::from(true)), + ("command", InputValue::from("outdated")), + ("--verbose", InputValue::from(true)), ]), RunOptions::default(), ) @@ -406,7 +412,7 @@ fn test_outdated_filters_according_to_platform_reqs_without_warning_for_higher_v let mut app_tester = get_application_tester(); app_tester .run( - input(vec![("command", PhpMixed::from("outdated"))]), + input(vec![("command", InputValue::from("outdated"))]), RunOptions::default(), ) .unwrap(); @@ -455,9 +461,9 @@ fn test_show_direct_with_name_does_not_show_transient_dependencies() { let err = app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--direct", PhpMixed::from(true)), - ("package", PhpMixed::from("vendor/package")), + ("command", InputValue::from("show")), + ("--direct", InputValue::from(true)), + ("package", InputValue::from("vendor/package")), ]), RunOptions::default(), ) @@ -502,9 +508,9 @@ fn test_show_direct_with_name_only_shows_direct_dependents() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--direct", PhpMixed::from(true)), - ("package", PhpMixed::from("direct/dependent")), + ("command", InputValue::from("show")), + ("--direct", InputValue::from(true)), + ("package", InputValue::from("direct/dependent")), ]), RunOptions::default(), ) @@ -520,9 +526,9 @@ fn test_show_direct_with_name_only_shows_direct_dependents() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--direct", PhpMixed::from(true)), - ("package", PhpMixed::from("direct/dependent2")), + ("command", InputValue::from("show")), + ("--direct", InputValue::from(true)), + ("package", InputValue::from("direct/dependent2")), ]), RunOptions::default(), ) @@ -583,8 +589,8 @@ fn test_show_platform_only_shows_platform_packages() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("-p", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("-p", InputValue::from(true)), ]), RunOptions::default(), ) @@ -605,8 +611,8 @@ fn test_show_platform_works_without_composer_json() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("-p", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("-p", InputValue::from(true)), ]), RunOptions::default(), ) @@ -618,9 +624,9 @@ fn test_show_platform_works_without_composer_json() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("-p", PhpMixed::from(true)), - ("package", PhpMixed::from("php")), + ("command", InputValue::from("show")), + ("-p", InputValue::from(true)), + ("package", InputValue::from("php")), ]), RunOptions::default(), ) @@ -630,10 +636,10 @@ fn test_show_platform_works_without_composer_json() { let status_code = app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("-p", PhpMixed::from(true)), - ("-f", PhpMixed::from("json")), - ("package", PhpMixed::from("php")), + ("command", InputValue::from("show")), + ("-p", InputValue::from(true)), + ("-f", InputValue::from("json")), + ("package", InputValue::from("php")), ]), RunOptions::default(), ) @@ -688,9 +694,9 @@ fn test_outdated_with_zero_major() { app_tester .run( input(vec![ - ("command", PhpMixed::from("outdated")), - ("--direct", PhpMixed::from(true)), - ("--patch-only", PhpMixed::from(true)), + ("command", InputValue::from("outdated")), + ("--direct", InputValue::from(true)), + ("--patch-only", InputValue::from(true)), ]), RunOptions::default(), ) @@ -707,9 +713,9 @@ zero/patch 0.1.2 ! 0.1.2.1", app_tester .run( input(vec![ - ("command", PhpMixed::from("outdated")), - ("--direct", PhpMixed::from(true)), - ("--minor-only", PhpMixed::from(true)), + ("command", InputValue::from("outdated")), + ("--direct", InputValue::from(true)), + ("--minor-only", InputValue::from(true)), ]), RunOptions::default(), ) @@ -727,9 +733,9 @@ zero/patch 0.1.2 ! 0.1.2.1", app_tester .run( input(vec![ - ("command", PhpMixed::from("outdated")), - ("--direct", PhpMixed::from(true)), - ("--major-only", PhpMixed::from(true)), + ("command", InputValue::from("outdated")), + ("--direct", InputValue::from(true)), + ("--major-only", InputValue::from(true)), ]), RunOptions::default(), ) @@ -775,8 +781,8 @@ fn test_show_all_shows_all_sections() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--all", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--all", InputValue::from(true)), ]), RunOptions::default(), ) @@ -810,8 +816,8 @@ fn test_locked_requires_valid_lock_file() { let err = app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--locked", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--locked", InputValue::from(true)), ]), RunOptions::default(), ) @@ -838,8 +844,8 @@ fn test_locked_shows_all_locked() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--locked", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--locked", InputValue::from(true)), ]), RunOptions::default(), ) @@ -857,8 +863,8 @@ fn test_locked_shows_all_locked() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--locked", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--locked", InputValue::from(true)), ]), RunOptions::default(), ) @@ -873,57 +879,57 @@ vendor/locked2 2.0.0 description of locked2 package", #[test] #[serial] fn test_invalid_option_combinations() { - let combos: Vec> = vec![ + let combos: Vec> = vec![ vec![ - ("--direct", PhpMixed::from(true)), - ("--all", PhpMixed::from(true)), + ("--direct", InputValue::from(true)), + ("--all", InputValue::from(true)), ], vec![ - ("--direct", PhpMixed::from(true)), - ("--available", PhpMixed::from(true)), + ("--direct", InputValue::from(true)), + ("--available", InputValue::from(true)), ], vec![ - ("--direct", PhpMixed::from(true)), - ("--platform", PhpMixed::from(true)), + ("--direct", InputValue::from(true)), + ("--platform", InputValue::from(true)), ], vec![ - ("--tree", PhpMixed::from(true)), - ("--all", PhpMixed::from(true)), + ("--tree", InputValue::from(true)), + ("--all", InputValue::from(true)), ], vec![ - ("--tree", PhpMixed::from(true)), - ("--available", PhpMixed::from(true)), + ("--tree", InputValue::from(true)), + ("--available", InputValue::from(true)), ], vec![ - ("--tree", PhpMixed::from(true)), - ("--latest", PhpMixed::from(true)), + ("--tree", InputValue::from(true)), + ("--latest", InputValue::from(true)), ], vec![ - ("--tree", PhpMixed::from(true)), - ("--path", PhpMixed::from(true)), + ("--tree", InputValue::from(true)), + ("--path", InputValue::from(true)), ], vec![ - ("--patch-only", PhpMixed::from(true)), - ("--minor-only", PhpMixed::from(true)), + ("--patch-only", InputValue::from(true)), + ("--minor-only", InputValue::from(true)), ], vec![ - ("--patch-only", PhpMixed::from(true)), - ("--major-only", PhpMixed::from(true)), + ("--patch-only", InputValue::from(true)), + ("--major-only", InputValue::from(true)), ], vec![ - ("--minor-only", PhpMixed::from(true)), - ("--major-only", PhpMixed::from(true)), + ("--minor-only", InputValue::from(true)), + ("--major-only", InputValue::from(true)), ], vec![ - ("--minor-only", PhpMixed::from(true)), - ("--major-only", PhpMixed::from(true)), - ("--patch-only", PhpMixed::from(true)), + ("--minor-only", InputValue::from(true)), + ("--major-only", InputValue::from(true)), + ("--patch-only", InputValue::from(true)), ], - vec![("--format", PhpMixed::from("test"))], + vec![("--format", InputValue::from("test"))], ]; for combo in combos { - let mut pairs = vec![("command", PhpMixed::from("show"))]; + let mut pairs = vec![("command", InputValue::from("show"))]; pairs.extend(combo.clone()); let mut app_tester = get_application_tester(); let status_code = app_tester.run(input(pairs), RunOptions::default()).unwrap(); @@ -940,8 +946,8 @@ fn test_ignored_option_combinations() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--installed", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--installed", InputValue::from(true)), ]), RunOptions::default(), ) @@ -956,10 +962,10 @@ fn test_ignored_option_combinations() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), + ("command", InputValue::from("show")), ( "--ignore", - PhpMixed::List(vec![PhpMixed::from("vendor/package")]), + InputValue::Array(vec!["vendor/package".to_string()]), ), ]), RunOptions::default(), @@ -986,9 +992,9 @@ fn test_self_and_name_only() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--self", PhpMixed::from(true)), - ("--name-only", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--self", InputValue::from(true)), + ("--name-only", InputValue::from(true)), ]), RunOptions::default(), ) @@ -1009,9 +1015,9 @@ fn test_self_and_package_combination() { let mut app_tester = get_application_tester(); let result = app_tester.run( input(vec![ - ("command", PhpMixed::from("show")), - ("--self", PhpMixed::from(true)), - ("package", PhpMixed::from("vendor/package")), + ("command", InputValue::from("show")), + ("--self", InputValue::from(true)), + ("package", InputValue::from("vendor/package")), ]), RunOptions::default(), ); @@ -1045,8 +1051,8 @@ fn test_self() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--self", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--self", InputValue::from(true)), ]), RunOptions::default(), ) @@ -1091,7 +1097,7 @@ fn test_not_installed_error() { let mut app_tester = get_application_tester(); app_tester .run( - input(vec![("command", PhpMixed::from("show"))]), + input(vec![("command", InputValue::from("show"))]), RunOptions::default(), ) .unwrap(); @@ -1129,8 +1135,8 @@ fn test_no_dev_option() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--no-dev", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--no-dev", InputValue::from(true)), ]), RunOptions::default(), ) @@ -1169,8 +1175,8 @@ fn test_package_filter() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("package", PhpMixed::from("vendor/package")), + ("command", InputValue::from("show")), + ("package", InputValue::from("vendor/package")), ]), RunOptions::default(), ) @@ -1186,9 +1192,9 @@ fn test_package_filter() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("package", PhpMixed::from("company/*")), - ("--name-only", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("package", InputValue::from("company/*")), + ("--name-only", InputValue::from(true)), ]), RunOptions::default(), ) @@ -1202,7 +1208,7 @@ fn test_package_filter() { } /// ref: ShowCommandTest::testNotExistingPackage (one data-provider case). -fn run_not_existing_package_case(package: &str, options: Vec<(&str, PhpMixed)>, expected: &str) { +fn run_not_existing_package_case(package: &str, options: Vec<(&str, InputValue)>, expected: &str) { let _tear_down = init_temp_composer( Some(&serde_json::json!({ "require": {"vendor/package": "1.0.0"}, @@ -1216,8 +1222,8 @@ fn run_not_existing_package_case(package: &str, options: Vec<(&str, PhpMixed)>, create_composer_lock(&[pkg], &[]); let mut pairs = vec![ - ("command", PhpMixed::from("show")), - ("package", PhpMixed::from(package)), + ("command", InputValue::from("show")), + ("package", InputValue::from(package)), ]; pairs.extend(options); @@ -1248,7 +1254,7 @@ fn test_not_existing_package_with_no_options() { fn test_not_existing_package_with_all_option() { run_not_existing_package_case( "not/existing", - vec![("--all", PhpMixed::from(true))], + vec![("--all", InputValue::from(true))], "Package \"not/existing\" not found.", ); } @@ -1258,7 +1264,7 @@ fn test_not_existing_package_with_all_option() { fn test_not_existing_package_with_locked_option() { run_not_existing_package_case( "not/existing", - vec![("--locked", PhpMixed::from(true))], + vec![("--locked", InputValue::from(true))], "Package \"not/existing\" not found in lock file, try using --available (-a) to show all available packages.", ); } @@ -1268,7 +1274,7 @@ fn test_not_existing_package_with_locked_option() { fn test_not_existing_platform_with_platform_option() { run_not_existing_package_case( "ext-nonexisting", - vec![("--platform", PhpMixed::from(true))], + vec![("--platform", InputValue::from(true))], "Package \"ext-nonexisting\" not found, try using --available (-a) to show all available packages.", ); } @@ -1306,11 +1312,11 @@ fn test_not_existing_package_with_working_dir() { let err = app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("package", PhpMixed::from("not/existing")), + ("command", InputValue::from("show")), + ("package", InputValue::from("not/existing")), ( "--working-dir", - PhpMixed::from(dir.display().to_string().as_str()), + InputValue::from(dir.display().to_string().as_str()), ), ]), RunOptions::default(), @@ -1329,7 +1335,7 @@ fn test_not_existing_package_with_working_dir() { /// ref: ShowCommandTest::testSpecificPackageAndTree (one data-provider case). fn run_specific_package_and_tree_case( packages: Vec, - options: Vec<(&str, PhpMixed)>, + options: Vec<(&str, InputValue)>, expected: &str, ) { let _tear_down = init_temp_composer( @@ -1344,9 +1350,9 @@ fn run_specific_package_and_tree_case( create_installed_json(&packages, &[], true); let mut pairs = vec![ - ("command", PhpMixed::from("show")), - ("package", PhpMixed::from("vendor/package")), - ("--tree", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("package", InputValue::from("vendor/package")), + ("--tree", InputValue::from(true)), ]; pairs.extend(options); @@ -1416,7 +1422,7 @@ fn test_specific_package_and_tree_with_json_format() { let pkg = get_package("vendor/package", "1.0.0"); run_specific_package_and_tree_case( vec![pkg], - vec![("--format", PhpMixed::from("json"))], + vec![("--format", InputValue::from("json"))], "{ \"installed\": [ { @@ -1467,8 +1473,8 @@ fn test_name_only_prints_no_trailing_whitespace() { app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("-N", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("-N", InputValue::from(true)), ]), RunOptions::default(), ) @@ -1484,9 +1490,9 @@ vendor/somepackage", app_tester .run( input(vec![ - ("command", PhpMixed::from("show")), - ("--outdated", PhpMixed::from(true)), - ("-N", PhpMixed::from(true)), + ("command", InputValue::from("show")), + ("--outdated", InputValue::from(true)), + ("-N", InputValue::from(true)), ]), RunOptions::default(), ) diff --git a/crates/shirabe/tests/command/status_command_test.rs b/crates/shirabe/tests/command/status_command_test.rs index 32b8390a..a5571856 100644 --- a/crates/shirabe/tests/command/status_command_test.rs +++ b/crates/shirabe/tests/command/status_command_test.rs @@ -6,12 +6,13 @@ use crate::test_case::{ }; use serial_test::serial; use shirabe::package::handle::PackageInterfaceHandle; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; -fn input(pairs: Vec<(&str, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { +fn input(pairs: Vec<(&str, InputValue)>) -> Vec<(ParameterName, InputValue)> { pairs .into_iter() - .map(|(k, v)| (PhpMixed::from(k), v)) + .map(|(k, v)| (ParameterName::of(k), v)) .collect() } @@ -36,7 +37,7 @@ fn test_no_local_changes() { let mut app_tester = get_application_tester(); app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("status"))], + vec![(ParameterName::of("command"), InputValue::from("status"))], RunOptions::default(), ) .unwrap(); @@ -59,7 +60,7 @@ struct LocallyModifiedPackageData { /// ref: StatusCommandTest::testLocallyModifiedPackages (data provider rolled into a helper). fn run_locally_modified_packages_case( composer_json: serde_json::Value, - command_flags: Vec<(&str, PhpMixed)>, + command_flags: Vec<(&str, InputValue)>, package_data: LocallyModifiedPackageData, ) { let _tear_down = init_temp_composer(Some(&composer_json), None, None, true); @@ -84,7 +85,7 @@ fn run_locally_modified_packages_case( let mut app_tester = get_application_tester(); app_tester .run( - input(vec![("command", PhpMixed::from("install"))]), + input(vec![("command", InputValue::from("install"))]), RunOptions::default(), ) .unwrap(); @@ -99,7 +100,7 @@ fn run_locally_modified_packages_case( ) .unwrap(); - let mut status_input = vec![("command", PhpMixed::from("status"))]; + let mut status_input = vec![("command", InputValue::from("status"))]; status_input.extend(command_flags); app_tester .run(input(status_input), RunOptions::default()) @@ -135,7 +136,7 @@ fn test_locally_modified_packages_from_source() { fn test_locally_modified_packages_from_dist() { run_locally_modified_packages_case( serde_json::json!({ "require": { "smarty/smarty": "^3.1" } }), - vec![("--verbose", PhpMixed::from(true))], + vec![("--verbose", InputValue::from(true))], LocallyModifiedPackageData { name: "smarty/smarty", version: "3.1.7", diff --git a/crates/shirabe/tests/command/suggests_command_test.rs b/crates/shirabe/tests/command/suggests_command_test.rs index dd793c40..6236e3f9 100644 --- a/crates/shirabe/tests/command/suggests_command_test.rs +++ b/crates/shirabe/tests/command/suggests_command_test.rs @@ -8,7 +8,8 @@ use indexmap::IndexMap; use serial_test::serial; use shirabe::package::Link; use shirabe::package::handle::{CompletePackageHandle, PackageInterfaceHandle}; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// ref: SuggestsCommandTest::getPackageWithSuggestAndRequires fn get_package_with_suggest_and_requires( @@ -82,7 +83,7 @@ fn test_installed_packages_with_no_suggestions() { let mut app_tester = get_application_tester(); let status_code = app_tester .run( - vec![(PhpMixed::from("command"), PhpMixed::from("suggest"))], + vec![(ParameterName::of("command"), InputValue::from("suggest"))], RunOptions::default(), ) .unwrap(); @@ -171,7 +172,7 @@ fn suggest_packages() -> (Vec, Vec = - vec![(PhpMixed::from("command"), PhpMixed::from("suggest"))]; + let mut input: Vec<(ParameterName, InputValue)> = + vec![(ParameterName::of("command"), InputValue::from("suggest"))]; for (k, v) in command { - input.push((PhpMixed::from(*k), v.clone())); + input.push((ParameterName::of(k), v.clone())); } let mut app_tester = get_application_tester(); @@ -216,7 +217,7 @@ fn run_suggest_case(has_lock_file: bool, command: &[(&str, PhpMixed)], expected: #[test] #[serial] fn test_suggest() { - let t = PhpMixed::from(true); + let t = InputValue::from(true); let by_package = ("--by-package", t.clone()); let by_suggestion = ("--by-suggestion", t.clone()); let no_dev = ("--no-dev", t.clone()); @@ -359,7 +360,7 @@ vendor3/suggested is suggested by: true, &[( "packages", - PhpMixed::List(vec![PhpMixed::from("vendor2/package2")]), + InputValue::Array(vec!["vendor2/package2".to_string()]), )], for_pkg, ); @@ -367,7 +368,7 @@ vendor3/suggested is suggested by: false, &[( "packages", - PhpMixed::List(vec![PhpMixed::from("vendor2/package2")]), + InputValue::Array(vec!["vendor2/package2".to_string()]), )], for_pkg, ); diff --git a/crates/shirabe/tests/command/update_command_test.rs b/crates/shirabe/tests/command/update_command_test.rs index 3aa42880..6fe8f927 100644 --- a/crates/shirabe/tests/command/update_command_test.rs +++ b/crates/shirabe/tests/command/update_command_test.rs @@ -6,13 +6,14 @@ use crate::test_case::{ }; use serial_test::serial; use shirabe::package::Link; -use shirabe_php_shim::PhpMixed; use shirabe_semver::constraint::{AnyConstraint, MatchAllConstraint}; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; -fn input(pairs: Vec<(&str, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { +fn input(pairs: Vec<(&str, InputValue)>) -> Vec<(ParameterName, InputValue)> { pairs .into_iter() - .map(|(k, v)| (PhpMixed::from(k), v)) + .map(|(k, v)| (ParameterName::of(k), v)) .collect() } @@ -75,7 +76,7 @@ fn root_dep_and_transitive_dep() -> serde_json::Value { fn provide_updates() -> Vec<( &'static str, serde_json::Value, - Vec<(&'static str, PhpMixed)>, + Vec<(&'static str, InputValue)>, &'static str, bool, )> { @@ -98,7 +99,7 @@ Package operations: 2 installs, 0 updates, 0 removals ( "simple update with very verbose output", root_dep_and_transitive_dep(), - vec![("-vv", PhpMixed::from(true))], + vec![("-vv", InputValue::from(true))], "Loading composer repositories with package information Updating dependencies Dependency resolution completed in %f seconds @@ -119,8 +120,8 @@ Installs: dep/pkg:1.0.2, root/req:1.0.0 "update with temporary constraint + --no-install", root_dep_and_transitive_dep(), vec![ - ("--with", PhpMixed::List(vec![PhpMixed::from("dep/pkg:1.0.0")])), - ("--no-install", PhpMixed::from(true)), + ("--with", InputValue::Array(vec!["dep/pkg:1.0.0".to_string()])), + ("--no-install", InputValue::from(true)), ], "Loading composer repositories with package information Updating dependencies @@ -132,7 +133,7 @@ Lock file operations: 2 installs, 0 updates, 0 removals ( "update with temporary constraint failing resolution", root_dep_and_transitive_dep(), - vec![("--with", PhpMixed::List(vec![PhpMixed::from("dep/pkg:^2")]))], + vec![("--with", InputValue::Array(vec!["dep/pkg:^2".to_string()]))], "Loading composer repositories with package information Updating dependencies Your requirements could not be resolved to an installable set of packages. @@ -145,7 +146,7 @@ Your requirements could not be resolved to an installable set of packages. ( "update with temporary constraint failing resolution on root package", root_dep_and_transitive_dep(), - vec![("--with", PhpMixed::List(vec![PhpMixed::from("root/req:^2")]))], + vec![("--with", InputValue::Array(vec!["root/req:^2".to_string()]))], "The temporary constraint \"^2\" for \"root/req\" must be a subset of the constraint in your composer.json (1.*) Run `composer require root/req` or `composer require root/req:^2` instead to replace the constraint", false, @@ -153,7 +154,7 @@ Run `composer require root/req` or `composer require root/req:^2` instead to rep ( "update & bump", root_dep_and_transitive_dep(), - vec![("--bump-after-update", PhpMixed::from(true))], + vec![("--bump-after-update", InputValue::from(true))], "Loading composer repositories with package information Updating dependencies Lock file operations: 2 installs, 0 updates, 0 removals @@ -174,8 +175,8 @@ No requirements to update in ./composer.json.", "update & bump with lock", root_dep_and_transitive_dep(), vec![ - ("--bump-after-update", PhpMixed::from(true)), - ("--lock", PhpMixed::from(true)), + ("--bump-after-update", InputValue::from(true)), + ("--lock", InputValue::from(true)), ], "Loading composer repositories with package information Updating dependencies @@ -187,7 +188,7 @@ Nothing to install, update or remove", ( "update & bump dev only", root_dep_and_transitive_dep(), - vec![("--bump-after-update", PhpMixed::from("dev"))], + vec![("--bump-after-update", InputValue::from("dev"))], "Loading composer repositories with package information Updating dependencies Lock file operations: 2 installs, 0 updates, 0 removals @@ -205,8 +206,8 @@ No requirements to update in ./composer.json.", "update & dump with failing update", root_dep_and_transitive_dep(), vec![ - ("--with", PhpMixed::List(vec![PhpMixed::from("dep/pkg:^2")])), - ("--bump-after-update", PhpMixed::from(true)), + ("--with", InputValue::Array(vec!["dep/pkg:^2".to_string()])), + ("--bump-after-update", InputValue::from(true)), ], "Loading composer repositories with package information Updating dependencies @@ -220,7 +221,7 @@ Your requirements could not be resolved to an installable set of packages. ( "update with replaced name filter fails to resolve", root_dep_and_transitive_dep(), - vec![("--with", PhpMixed::List(vec![PhpMixed::from("replaced/pkg:^2")]))], + vec![("--with", InputValue::Array(vec!["replaced/pkg:^2".to_string()]))], "Loading composer repositories with package information Updating dependencies Your requirements could not be resolved to an installable set of packages. @@ -245,9 +246,9 @@ fn test_update() { let mut app_tester = get_application_tester(); let mut args = vec![ - ("command", PhpMixed::from("update")), - ("--dry-run", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), + ("command", InputValue::from("update")), + ("--dry-run", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), ]; args.extend(command); app_tester.run(input(args), RunOptions::default()).unwrap(); @@ -286,14 +287,14 @@ fn test_update_with_patch_only() { app_tester .run( input(vec![ - ("command", PhpMixed::from("update")), - ("--dry-run", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--no-install", PhpMixed::from(true)), - ("--patch-only", PhpMixed::from(true)), + ("command", InputValue::from("update")), + ("--dry-run", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--no-install", InputValue::from(true)), + ("--patch-only", InputValue::from(true)), ( "--with", - PhpMixed::List(vec![PhpMixed::from("root/req:^1.1")]), + InputValue::Array(vec!["root/req:^1.1".to_string()]), ), ]), RunOptions::default(), @@ -317,21 +318,18 @@ Your requirements could not be resolved to an installable set of packages. app_tester .run( input(vec![ - ("command", PhpMixed::from("update")), - ("--dry-run", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--no-install", PhpMixed::from(true)), - ("--patch-only", PhpMixed::from(true)), + ("command", InputValue::from("update")), + ("--dry-run", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--no-install", InputValue::from(true)), + ("--patch-only", InputValue::from(true)), ( "--with", - PhpMixed::List(vec![PhpMixed::from("root/req:^1.0.1")]), + InputValue::Array(vec!["root/req:^1.0.1".to_string()]), ), ( "packages", - PhpMixed::List(vec![ - PhpMixed::from("root/req"), - PhpMixed::from("root/req2"), - ]), + InputValue::Array(vec!["root/req".to_string(), "root/req2".to_string()]), ), ]), RunOptions::default(), @@ -365,8 +363,8 @@ fn test_interactive_mode_throws_if_no_package_to_update() { let err = app_tester .run( input(vec![ - ("command", PhpMixed::from("update")), - ("--interactive", PhpMixed::from(true)), + ("command", InputValue::from("update")), + ("--interactive", InputValue::from(true)), ]), RunOptions::default(), ) @@ -396,8 +394,8 @@ fn test_interactive_mode_throws_if_no_package_entered() { let err = app_tester .run( input(vec![ - ("command", PhpMixed::from("update")), - ("--interactive", PhpMixed::from(true)), + ("command", InputValue::from("update")), + ("--interactive", InputValue::from(true)), ]), RunOptions::default(), ) @@ -492,10 +490,10 @@ fn test_interactive_tmp() { app_tester .run( input(vec![ - ("command", PhpMixed::from("update")), - ("--interactive", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--dry-run", PhpMixed::from(true)), + ("command", InputValue::from("update")), + ("--interactive", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--dry-run", InputValue::from(true)), ]), RunOptions { interactive: Some(true), @@ -550,10 +548,10 @@ fn test_no_security_blocking_allows_insecure_packages() { app_tester .run( input(vec![ - ("command", PhpMixed::from("update")), - ("--dry-run", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--no-install", PhpMixed::from(true)), + ("command", InputValue::from("update")), + ("--dry-run", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--no-install", InputValue::from(true)), ]), RunOptions::default(), ) @@ -573,11 +571,11 @@ fn test_no_security_blocking_allows_insecure_packages() { app_tester .run( input(vec![ - ("command", PhpMixed::from("update")), - ("--dry-run", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--no-install", PhpMixed::from(true)), - ("--no-security-blocking", PhpMixed::from(true)), + ("command", InputValue::from("update")), + ("--dry-run", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--no-install", InputValue::from(true)), + ("--no-security-blocking", InputValue::from(true)), ]), RunOptions::default(), ) @@ -610,10 +608,10 @@ fn test_bump_after_update_without_lockfile() { app_tester .run( input(vec![ - ("command", PhpMixed::from("update")), - ("--dry-run", PhpMixed::from(true)), - ("--no-audit", PhpMixed::from(true)), - ("--bump-after-update", PhpMixed::from("dev")), + ("command", InputValue::from("update")), + ("--dry-run", InputValue::from(true)), + ("--no-audit", InputValue::from(true)), + ("--bump-after-update", InputValue::from("dev")), ]), RunOptions::default(), ) diff --git a/crates/shirabe/tests/command/validate_command_test.rs b/crates/shirabe/tests/command/validate_command_test.rs index 67370df0..fb05b423 100644 --- a/crates/shirabe/tests/command/validate_command_test.rs +++ b/crates/shirabe/tests/command/validate_command_test.rs @@ -5,7 +5,8 @@ use crate::test_case::{ }; use serial_test::serial; use shirabe::util::platform::Platform; -use shirabe_php_shim::PhpMixed; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; /// ref: ValidateCommandTest::MINIMAL_VALID_CONFIGURATION fn minimal_valid_configuration() -> serde_json::Value { @@ -31,8 +32,8 @@ fn minimal_valid_configuration() -> serde_json::Value { }) } -fn validate_input(command: Vec<(PhpMixed, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed)> { - let mut input = vec![(PhpMixed::from("command"), PhpMixed::from("validate"))]; +fn validate_input(command: Vec<(ParameterName, InputValue)>) -> Vec<(ParameterName, InputValue)> { + let mut input = vec![(ParameterName::of("command"), InputValue::from("validate"))]; input.extend(command); input } @@ -40,7 +41,7 @@ fn validate_input(command: Vec<(PhpMixed, PhpMixed)>) -> Vec<(PhpMixed, PhpMixed struct ValidateCase { name: &'static str, composer_json: serde_json::Value, - command: Vec<(PhpMixed, PhpMixed)>, + command: Vec<(ParameterName, InputValue)>, expected: &'static str, } @@ -86,7 +87,10 @@ fn provide_validate_tests() -> Vec { ValidateCase { name: "passing without publish-check", composer_json: publish_data_stripped, - command: vec![(PhpMixed::from("--no-check-publish"), PhpMixed::Bool(true))], + command: vec![( + ParameterName::of("--no-check-publish"), + InputValue::Bool(true), + )], expected: "./composer.json is valid, but with a few warnings\nSee https://getcomposer.org/doc/04-schema.md for details on the schema\n# General warnings\n- No license specified, it is recommended to do so. For closed-source software you may use \"proprietary\" as license.", }, ] diff --git a/crates/shirabe/tests/common/test_case.rs b/crates/shirabe/tests/common/test_case.rs index 3be2df24..bdf7561e 100644 --- a/crates/shirabe/tests/common/test_case.rs +++ b/crates/shirabe/tests/common/test_case.rs @@ -21,11 +21,13 @@ use shirabe::util::http_downloader::HttpDownloader; use shirabe::util::r#loop::Loop; use shirabe::util::platform::Platform; use shirabe::util::process_executor::ProcessExecutor; -use shirabe_php_shim::{PhpMixed, PhpResource}; +use shirabe_php_shim::PhpResource; use shirabe_semver::VersionParser; use shirabe_semver::constraint::{AnyConstraint, SimpleConstraint}; use shirabe_symfony_console::input::ArrayInput; use shirabe_symfony_console::input::InputInterface; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; use shirabe_symfony_console::input::StreamableInputInterface; use shirabe_symfony_console::output::ConsoleOutput; use shirabe_symfony_console::output::ConsoleOutputInterface; @@ -355,7 +357,7 @@ impl ApplicationTester { pub fn run( &mut self, - input: Vec<(PhpMixed, PhpMixed)>, + input: Vec<(ParameterName, InputValue)>, options: RunOptions, ) -> anyhow::Result { let prev_shell_verbosity = shirabe_php_shim::getenv("SHELL_VERBOSITY"); diff --git a/crates/shirabe/tests/installer_test.rs b/crates/shirabe/tests/installer_test.rs index 4d24186f..6907758c 100644 --- a/crates/shirabe/tests/installer_test.rs +++ b/crates/shirabe/tests/installer_test.rs @@ -9,6 +9,7 @@ mod test_case; use config_stub::ConfigStubBuilder; use serial_test::serial; +use shirabe_symfony_console::input::InputValue; use test_case::{get_package, get_version_constraint}; use indexmap::IndexMap; @@ -52,7 +53,6 @@ use shirabe_symfony_console::command::CommandData; use shirabe_symfony_console::input::InputArgument; use shirabe_symfony_console::input::InputInterface; use shirabe_symfony_console::input::InputOption; -use shirabe_symfony_console::input::InputOptionValue; use shirabe_symfony_console::input::StringInput; use shirabe_symfony_console::output::StreamOutput; use shirabe_symfony_console::output::{OutputInterface, VERBOSITY_NORMAL}; @@ -829,9 +829,9 @@ fn ignore_platform_reqs_value(input: &dyn InputInterface) -> PhpMixed { } let list = input .get_option("ignore-platform-req") - .unwrap_or(InputOptionValue::Bool(false)); + .unwrap_or(InputValue::Bool(false)); match &list { - InputOptionValue::Array(items) if !items.is_empty() => list.into(), + InputValue::Array(items) if !items.is_empty() => list.into(), _ => PhpMixed::Bool(false), } } @@ -970,37 +970,37 @@ fn do_test_integration(case: &IntegrationCase, expect_output: Option<&str>) { install_ref .add_option( "ignore-platform-reqs", - PhpMixed::Null, + None, Some(InputOption::VALUE_NONE), "", - PhpMixed::Null, + InputValue::Null, ) .unwrap(); install_ref .add_option( "ignore-platform-req", - PhpMixed::Null, + None, Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "", - PhpMixed::Null, + InputValue::Null, ) .unwrap(); install_ref .add_option( "no-dev", - PhpMixed::Null, + None, Some(InputOption::VALUE_NONE), "", - PhpMixed::Null, + InputValue::Null, ) .unwrap(); install_ref .add_option( "dry-run", - PhpMixed::Null, + None, Some(InputOption::VALUE_NONE), "", - PhpMixed::Null, + InputValue::Null, ) .unwrap(); let installer_cl = installer.clone(); @@ -1053,16 +1053,16 @@ fn do_test_integration(case: &IntegrationCase, expect_output: Option<&str>) { ("prefer-lowest", InputOption::VALUE_NONE), ] { update_ref - .add_option(name, PhpMixed::Null, Some(mode), "", PhpMixed::Null) + .add_option(name, None, Some(mode), "", InputValue::Null) .unwrap(); } update_ref .add_option( "ignore-platform-req", - PhpMixed::Null, + None, Some(InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY), "", - PhpMixed::Null, + InputValue::Null, ) .unwrap(); update_ref @@ -1070,7 +1070,7 @@ fn do_test_integration(case: &IntegrationCase, expect_output: Option<&str>) { "packages", Some(InputArgument::IS_ARRAY | InputArgument::OPTIONAL), "", - PhpMixed::Null, + InputValue::Null, ) .unwrap(); let installer_cl = installer; @@ -1078,11 +1078,8 @@ fn do_test_integration(case: &IntegrationCase, expect_output: Option<&str>) { let run_result_cl = run_result.clone(); update_ref.set_code(Box::new(move |input, _output| { let packages: Vec = - match input.get_argument("packages").unwrap_or(PhpMixed::Null) { - PhpMixed::List(items) => items - .into_iter() - .filter_map(|v| v.as_string().map(|s| s.to_string())) - .collect(), + match input.get_argument("packages").unwrap_or(InputValue::Null) { + InputValue::Array(items) => items, _ => vec![], }; let filtered: Vec = packages diff --git a/crates/shirabe/tests/question/strict_confirmation_question_test.rs b/crates/shirabe/tests/question/strict_confirmation_question_test.rs index 0c163c84..5d84f309 100644 --- a/crates/shirabe/tests/question/strict_confirmation_question_test.rs +++ b/crates/shirabe/tests/question/strict_confirmation_question_test.rs @@ -4,6 +4,8 @@ use shirabe::question::StrictConfirmationQuestion; use shirabe_php_shim::PhpMixed; use shirabe_symfony_console::helper::{QuestionHelper, QuestionHelperInterface}; use shirabe_symfony_console::input::ArrayInput; +use shirabe_symfony_console::input::InputValue; +use shirabe_symfony_console::input::ParameterName; use shirabe_symfony_console::input::StreamableInputInterface; use shirabe_symfony_console::output::OutputInterface; use shirabe_symfony_console::output::StreamOutput; @@ -117,8 +119,8 @@ fn create_output_interface() -> std::rc::Rc (ArrayInput, QuestionHelper) { let mut input = ArrayInput::new( vec![( - PhpMixed::Int(0), - PhpMixed::String("--no-interaction".to_string()), + ParameterName::Index(0), + InputValue::String("--no-interaction".to_string()), )], None, ) -- cgit v1.3.1-4-g156e