diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-18 08:37:30 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-18 08:37:30 +0900 |
| commit | 4856f05e870ec5d2daaa74bf9a86a1519a813614 (patch) | |
| tree | ab81b7a9d59340c4d05ecaf3b6b1a81106cc8355 | |
| parent | 5aaa92f760a975c6617b5d1fb7af8e58fed127b7 (diff) | |
| download | php-shirabe-4856f05e870ec5d2daaa74bf9a86a1519a813614.tar.gz php-shirabe-4856f05e870ec5d2daaa74bf9a86a1519a813614.tar.zst php-shirabe-4856f05e870ec5d2daaa74bf9a86a1519a813614.zip | |
fix(input): return a bool|string|string[]|null enum from get_option
`InputInterface::get_option` returned `PhpMixed`, so the negation branch
of `Input::get_option` reproduced PHP's `return !$value;` as
`!value.as_bool().unwrap_or(false)`, which inverts the result for a
string value instead of leaving it `false`. It now returns
`InputOptionValue`, whose `to_bool` is PHP's truthiness cast.
The narrowing also removes the `Vec<PhpMixed>` element handling the
commands carried for array options: `as_array` hands back `&[String]`,
so the `filter_map(|v| v.as_string())` chains at eight call sites
collapse. Its other accessors keep `PhpMixed`'s names and meanings
(`is_null`, `as_bool`, `as_string`, `to_bool`), and
`From<InputOptionValue> for PhpMixed` covers the callers that feed the
value back into an `IndexMap<String, PhpMixed>` or a `PhpMixed`
parameter.
`Input` keeps its parsed options and `InputOption` its defaults as
`PhpMixed`, so `Input::get_option` is where the narrowing happens and
where a value outside the domain panics.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
19 files changed, 189 insertions, 97 deletions
diff --git a/crates/shirabe-symfony-console/src/command/complete_command.rs b/crates/shirabe-symfony-console/src/command/complete_command.rs index dc418178..432888b6 100644 --- a/crates/shirabe-symfony-console/src/command/complete_command.rs +++ b/crates/shirabe-symfony-console/src/command/complete_command.rs @@ -78,19 +78,26 @@ impl CompleteCommand { input: &dyn InputInterface, ) -> anyhow::Result<CompletionInput> { let current_index = input.get_option("current")?; - if !current_index.to_bool() || !shirabe_php_shim::ctype_digit(¤t_index.to_string()) { + if !current_index.to_bool() + || !shirabe_php_shim::ctype_digit(current_index.as_string().unwrap_or_default()) + { anyhow::bail!(shirabe_php_shim::RuntimeException::new( "The \"--current\" option must be set and it must be an integer.".to_string() )); } - let tokens: Vec<String> = match input.get_option("input")?.as_list() { - Some(list) => list.iter().map(|v| v.to_string()).collect(), - None => Vec::new(), - }; + let tokens: Vec<String> = input + .get_option("input")? + .as_array() + .map(<[String]>::to_vec) + .unwrap_or_default(); let mut completion_input = CompletionInput::from_tokens( tokens, - current_index.to_string().parse::<i64>().unwrap_or(0), + current_index + .as_string() + .unwrap_or_default() + .parse::<i64>() + .unwrap_or(0), )?; // try { $completionInput->bind(...); } catch (ExceptionInterface $e) {} @@ -254,13 +261,13 @@ impl Command for CompleteCommand { let completion_output = self .completion_outputs - .get(&shell.to_string()) + .get(shell.as_string().unwrap_or_default()) .cloned() .unwrap_or(PhpMixed::Bool(false)); if !completion_output.to_bool() { anyhow::bail!(shirabe_php_shim::RuntimeException::new(format!( "Shell completion is not supported for your shell: \"{}\" (supported: \"{}\").", - shell, + shell.as_string().unwrap_or_default(), self.completion_outputs .keys() .cloned() diff --git a/crates/shirabe-symfony-console/src/command/help_command.rs b/crates/shirabe-symfony-console/src/command/help_command.rs index 4f1447cb..2081e0e1 100644 --- a/crates/shirabe-symfony-console/src/command/help_command.rs +++ b/crates/shirabe-symfony-console/src/command/help_command.rs @@ -149,8 +149,14 @@ impl Command for HelpCommand { let mut helper = DescriptorHelper::new(); let object = DescribableObject::Command(self.command.borrow().clone().unwrap()); let mut options = indexmap::IndexMap::new(); - options.insert("format".to_string(), input.borrow().get_option("format")?); - options.insert("raw_text".to_string(), input.borrow().get_option("raw")?); + options.insert( + "format".to_string(), + input.borrow().get_option("format")?.into(), + ); + options.insert( + "raw_text".to_string(), + input.borrow().get_option("raw")?.into(), + ); helper.describe2(output.clone(), object, options)?; *self.command.borrow_mut() = None; diff --git a/crates/shirabe-symfony-console/src/command/list_command.rs b/crates/shirabe-symfony-console/src/command/list_command.rs index ead84d44..6074b49a 100644 --- a/crates/shirabe-symfony-console/src/command/list_command.rs +++ b/crates/shirabe-symfony-console/src/command/list_command.rs @@ -147,13 +147,22 @@ impl Command for ListCommand { let mut helper = DescriptorHelper::new(); let object = DescribableObject::Application(self.get_application().unwrap()); let mut options = indexmap::IndexMap::new(); - options.insert("format".to_string(), input.borrow().get_option("format")?); - options.insert("raw_text".to_string(), input.borrow().get_option("raw")?); + options.insert( + "format".to_string(), + input.borrow().get_option("format")?.into(), + ); + options.insert( + "raw_text".to_string(), + input.borrow().get_option("raw")?.into(), + ); options.insert( "namespace".to_string(), input.borrow().get_argument("namespace")?, ); - options.insert("short".to_string(), input.borrow().get_option("short")?); + options.insert( + "short".to_string(), + input.borrow().get_option("short")?.into(), + ); helper.describe2(output.clone(), object, options)?; Ok(0) diff --git a/crates/shirabe-symfony-console/src/completion/completion_input.rs b/crates/shirabe-symfony-console/src/completion/completion_input.rs index e7f1e0a2..c667ef60 100644 --- a/crates/shirabe-symfony-console/src/completion/completion_input.rs +++ b/crates/shirabe-symfony-console/src/completion/completion_input.rs @@ -350,7 +350,7 @@ impl crate::input::InputInterface for CompletionInput { crate::input::InputInterface::get_options(&self.inner) } - fn get_option(&self, name: &str) -> anyhow::Result<PhpMixed> { + fn get_option(&self, name: &str) -> anyhow::Result<crate::input::InputOptionValue> { crate::input::InputInterface::get_option(&self.inner, name) } diff --git a/crates/shirabe-symfony-console/src/input/argv_input.rs b/crates/shirabe-symfony-console/src/input/argv_input.rs index 94e5299d..6138c195 100644 --- a/crates/shirabe-symfony-console/src/input/argv_input.rs +++ b/crates/shirabe-symfony-console/src/input/argv_input.rs @@ -4,6 +4,7 @@ use crate::exception::RuntimeException; use crate::input::Input; use crate::input::InputDefinition; use crate::input::InputInterface; +use crate::input::InputOptionValue; use crate::input::StreamableInputInterface; use indexmap::IndexMap; use shirabe_php_shim::{PhpMixed, php_regex, preg_match}; @@ -593,7 +594,7 @@ impl InputInterface for ArgvInput { self.inner.get_options() } - fn get_option(&self, name: &str) -> anyhow::Result<PhpMixed> { + fn get_option(&self, name: &str) -> anyhow::Result<InputOptionValue> { self.inner.get_option(name) } diff --git a/crates/shirabe-symfony-console/src/input/array_input.rs b/crates/shirabe-symfony-console/src/input/array_input.rs index a032432b..c9bc9dce 100644 --- a/crates/shirabe-symfony-console/src/input/array_input.rs +++ b/crates/shirabe-symfony-console/src/input/array_input.rs @@ -5,6 +5,7 @@ use crate::exception::InvalidOptionException; use crate::input::Input; use crate::input::InputDefinition; use crate::input::InputInterface; +use crate::input::InputOptionValue; use crate::input::StreamableInputInterface; use indexmap::IndexMap; use shirabe_php_shim::PhpMixed; @@ -336,7 +337,7 @@ impl InputInterface for ArrayInput { self.inner.get_options() } - fn get_option(&self, name: &str) -> anyhow::Result<PhpMixed> { + fn get_option(&self, name: &str) -> anyhow::Result<InputOptionValue> { self.inner.get_option(name) } diff --git a/crates/shirabe-symfony-console/src/input/input.rs b/crates/shirabe-symfony-console/src/input/input.rs index 88bb9f94..795e9c81 100644 --- a/crates/shirabe-symfony-console/src/input/input.rs +++ b/crates/shirabe-symfony-console/src/input/input.rs @@ -3,6 +3,7 @@ use crate::exception::InvalidArgumentException; use crate::exception::RuntimeException; use crate::input::InputDefinition; +use crate::input::InputOptionValue; use indexmap::IndexMap; use shirabe_php_shim::{PhpMixed, PhpResource, php_regex, preg_is_match}; @@ -156,14 +157,14 @@ impl Input { ) } - pub fn get_option(&self, name: &str) -> anyhow::Result<PhpMixed> { + pub fn get_option(&self, name: &str) -> anyhow::Result<InputOptionValue> { if self.definition.has_negation(name) { let value = self.get_option(&self.definition.negation_to_name(name)?)?; - if matches!(value, PhpMixed::Null) { + if value.is_null() { return Ok(value); } - return Ok(PhpMixed::Bool(!value.as_bool().unwrap_or(false))); + return Ok(InputOptionValue::Bool(!value.to_bool())); } if !self.definition.has_option(name) { @@ -174,10 +175,11 @@ impl Input { .into()); } - Ok(if self.options.contains_key(name) { - self.options[name].clone() + Ok(if let Some(value) = self.options.get(name) { + InputOptionValue::from_php_mixed(value) } else { - self.definition.get_option(name)?.get_default().clone() + let option = self.definition.get_option(name)?; + InputOptionValue::from_php_mixed(option.get_default()) }) } diff --git a/crates/shirabe-symfony-console/src/input/input_interface.rs b/crates/shirabe-symfony-console/src/input/input_interface.rs index 4491ca8c..3c3ec2d5 100644 --- a/crates/shirabe-symfony-console/src/input/input_interface.rs +++ b/crates/shirabe-symfony-console/src/input/input_interface.rs @@ -1,6 +1,7 @@ //! ref: composer/vendor/symfony/console/Input/InputInterface.php use crate::input::InputDefinition; +use crate::input::InputOptionValue; use crate::input::StreamableInputInterface; use shirabe_php_shim::PhpMixed; @@ -33,7 +34,7 @@ pub trait InputInterface: std::fmt::Debug + shirabe_php_shim::AsAny { fn get_options(&self) -> indexmap::IndexMap<String, PhpMixed>; - fn get_option(&self, name: &str) -> anyhow::Result<PhpMixed>; + fn get_option(&self, name: &str) -> anyhow::Result<InputOptionValue>; fn set_option(&mut self, name: &str, value: PhpMixed) -> anyhow::Result<()>; diff --git a/crates/shirabe-symfony-console/src/input/input_option.rs b/crates/shirabe-symfony-console/src/input/input_option.rs index 3b24d914..d37e18ae 100644 --- a/crates/shirabe-symfony-console/src/input/input_option.rs +++ b/crates/shirabe-symfony-console/src/input/input_option.rs @@ -191,3 +191,90 @@ 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<String>), +} + +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<bool> { + 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<InputOptionValue> 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/string_input.rs b/crates/shirabe-symfony-console/src/input/string_input.rs index bdd21577..9fcb3fc8 100644 --- a/crates/shirabe-symfony-console/src/input/string_input.rs +++ b/crates/shirabe-symfony-console/src/input/string_input.rs @@ -4,6 +4,7 @@ use crate::exception::InvalidArgumentException; use crate::input::ArgvInput; use crate::input::InputDefinition; use crate::input::InputInterface; +use crate::input::InputOptionValue; use crate::input::StreamableInputInterface; use indexmap::IndexMap; use shirabe_php_shim::{PhpMixed, php_regex, preg_match}; @@ -177,7 +178,7 @@ impl InputInterface for StringInput { InputInterface::get_options(&self.inner) } - fn get_option(&self, name: &str) -> anyhow::Result<PhpMixed> { + fn get_option(&self, name: &str) -> anyhow::Result<InputOptionValue> { self.inner.get_option(name) } diff --git a/crates/shirabe/src/command/audit_command.rs b/crates/shirabe/src/command/audit_command.rs index b6a3a150..d067e074 100644 --- a/crates/shirabe/src/command/audit_command.rs +++ b/crates/shirabe/src/command/audit_command.rs @@ -243,12 +243,8 @@ impl Command for AuditCommand { let mut ignore_severities: indexmap::IndexMap<String, Option<String>> = indexmap::IndexMap::new(); let cli_severities = input.borrow().get_option("ignore-severity")?; - if let Some(list) = cli_severities.as_list() { - for sev in list { - if let Some(s) = sev.as_string() { - ignore_severities.insert(s.to_string(), None); - } - } + for severity in cli_severities.as_array().unwrap_or_default() { + ignore_severities.insert(severity.clone(), None); } for (k, v) in audit_config.ignore_severity_for_audit.clone() { ignore_severities.insert(k, v); diff --git a/crates/shirabe/src/command/base_command.rs b/crates/shirabe/src/command/base_command.rs index d7f935c1..8ec9f350 100644 --- a/crates/shirabe/src/command/base_command.rs +++ b/crates/shirabe/src/command/base_command.rs @@ -20,7 +20,7 @@ use crate::util::Platform; use indexmap::IndexMap; use shirabe_php_shim::{ InvalidArgumentException, LogicException, PhpClass, PhpMixed, RuntimeException, - UnexpectedValueException, count, explode, in_array_strict, is_string, + UnexpectedValueException, count, explode, in_array_strict, }; use shirabe_symfony_console::Terminal; use shirabe_symfony_console::command::{Command, CommandData, SetDefinitionArg}; @@ -445,7 +445,11 @@ impl BaseCommand for BaseCommandData { } if input.borrow().has_option("prefer-install") - && is_string(&input.borrow().get_option("prefer-install")?) + && input + .borrow() + .get_option("prefer-install")? + .as_string() + .is_some() { if input .borrow() @@ -556,7 +560,7 @@ impl BaseCommand for BaseCommandData { return Ok(PlatformRequirementFilterFactory::ignore_all()); } - let ignores = input.borrow().get_option("ignore-platform-req")?; + let ignores: PhpMixed = input.borrow().get_option("ignore-platform-req")?.into(); if count(&ignores) > 0 { return PlatformRequirementFilterFactory::from_bool_or_list(ignores); } @@ -906,8 +910,9 @@ pub fn base_command_initialize( { let ignore_platform_req_env = Platform::get_env("COMPOSER_IGNORE_PLATFORM_REQ"); let ignore_str = ignore_platform_req_env.clone().unwrap_or_default(); - if 0 == count(&input.borrow().get_option("ignore-platform-req")?) - && ignore_platform_req_env.is_some() + if 0 == count(&PhpMixed::from( + input.borrow().get_option("ignore-platform-req")?, + )) && ignore_platform_req_env.is_some() && !ignore_str.is_empty() { input.borrow_mut().set_option( diff --git a/crates/shirabe/src/command/create_project_command.rs b/crates/shirabe/src/command/create_project_command.rs index b2842d9d..eb23ffff 100644 --- a/crates/shirabe/src/command/create_project_command.rs +++ b/crates/shirabe/src/command/create_project_command.rs @@ -926,15 +926,12 @@ impl Command for CreateProjectCommand { let repository_opt = input.borrow().get_option("repository")?; let repository_url_opt = input.borrow().get_option("repository-url")?; - let repositories = if repository_opt - .as_list() - .map(|l| !l.is_empty()) - .unwrap_or(false) - { - Some(repository_opt) - } else { - Some(repository_url_opt) - }; + let repositories: Option<PhpMixed> = + if repository_opt.as_array().is_some_and(|l| !l.is_empty()) { + Some(repository_opt.into()) + } else { + Some(repository_url_opt.into()) + }; self.install_project( io, diff --git a/crates/shirabe/src/command/init_command.rs b/crates/shirabe/src/command/init_command.rs index 2205b852..d1b5dbe5 100644 --- a/crates/shirabe/src/command/init_command.rs +++ b/crates/shirabe/src/command/init_command.rs @@ -527,12 +527,8 @@ impl Command for InitCommand { let repositories: Vec<String> = input .borrow() .get_option("repository")? - .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 (repositories.len() as i64) > 0 { let config = std::rc::Rc::new(std::cell::RefCell::new(Factory::create_config( @@ -790,12 +786,8 @@ impl Command for InitCommand { let repositories: Vec<String> = input .borrow() .get_option("repository")? - .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 (repositories.len() as i64) > 0 { let config = std::rc::Rc::new(std::cell::RefCell::new(Factory::create_config( @@ -1048,7 +1040,7 @@ impl Command for InitCommand { "Package Type (e.g. library, project, metapackage, composer-plugin) [<comment>{}</comment>]: ", type_str ), - type_val, + type_val.into(), )?; if type_value.as_string() == Some("") || matches!(type_value, PhpMixed::Bool(false)) { type_value = PhpMixed::Null; @@ -1126,12 +1118,8 @@ impl Command for InitCommand { let require: Vec<String> = input .borrow() .get_option("require")? - .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 requirements = if (require.len() as i64) > 0 || io.ask_confirmation(question, true) { @@ -1156,12 +1144,8 @@ impl Command for InitCommand { let require_dev: Vec<String> = input .borrow() .get_option("require-dev")? - .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_requirements = if (require_dev.len() as i64) > 0 || io.ask_confirmation(question, true) { diff --git a/crates/shirabe/src/command/outdated_command.rs b/crates/shirabe/src/command/outdated_command.rs index 3994ab64..a89a1cd8 100644 --- a/crates/shirabe/src/command/outdated_command.rs +++ b/crates/shirabe/src/command/outdated_command.rs @@ -187,7 +187,7 @@ impl Command for OutdatedCommand { } args.insert( "--ignore-platform-req".to_string(), - input.borrow().get_option("ignore-platform-req")?, + input.borrow().get_option("ignore-platform-req")?.into(), ); if input .borrow() @@ -197,8 +197,14 @@ impl Command for OutdatedCommand { { args.insert("--ignore-platform-reqs".to_string(), PhpMixed::Bool(true)); } - args.insert("--format".to_string(), input.borrow().get_option("format")?); - args.insert("--ignore".to_string(), input.borrow().get_option("ignore")?); + args.insert( + "--format".to_string(), + input.borrow().get_option("format")?.into(), + ); + args.insert( + "--ignore".to_string(), + input.borrow().get_option("ignore")?.into(), + ); let input = ArrayInput::new( args.into_iter() diff --git a/crates/shirabe/src/command/reinstall_command.rs b/crates/shirabe/src/command/reinstall_command.rs index 010d2b5d..43978191 100644 --- a/crates/shirabe/src/command/reinstall_command.rs +++ b/crates/shirabe/src/command/reinstall_command.rs @@ -91,7 +91,7 @@ impl Command for ReinstallCommand { let mut package_names_to_reinstall: Vec<String> = vec![]; let type_option = input.borrow().get_option("type")?; - let type_count = type_option.as_list().map_or(0, |l| l.len()); + 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()); @@ -104,12 +104,8 @@ impl Command for ReinstallCommand { .into()); } let filter_types: Vec<String> = type_option - .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 package in local_repo.get_canonical_packages()? { if filter_types.contains(&package.get_type()) { diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs index 34b84fd8..3cc80b4c 100644 --- a/crates/shirabe/src/command/show_command.rs +++ b/crates/shirabe/src/command/show_command.rs @@ -1489,8 +1489,8 @@ impl Command for ShowCommand { } else if input .borrow() .get_option("ignore")? - .as_list() - .map_or(0, |l| l.len()) + .as_array() + .map_or(0, <[String]>::len) > 0 { self.get_io().write_error("<warning>You are using the option \"ignore\" for action other than \"outdated\", it will be ignored.</warning>"); @@ -2180,12 +2180,8 @@ impl Command for ShowCommand { &input .borrow() .get_option("ignore")? - .as_list() - .map(|l| { - l.iter() - .filter_map(|v| v.as_string().map(strtolower)) - .collect::<Vec<_>>() - }) + .as_array() + .map(|l| l.iter().map(|v| strtolower(v)).collect::<Vec<_>>()) .unwrap_or_default(), "{^(?:%s)$}iD", ); diff --git a/crates/shirabe/src/command/update_command.rs b/crates/shirabe/src/command/update_command.rs index 213ac248..d2e380ac 100644 --- a/crates/shirabe/src/command/update_command.rs +++ b/crates/shirabe/src/command/update_command.rs @@ -365,12 +365,8 @@ impl Command for UpdateCommand { input .borrow() .get_option("with")? - .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(), )?; @@ -708,7 +704,8 @@ impl Command for UpdateCommand { .as_bool() .unwrap_or(false) { - let mut bump_after_update = input.borrow().get_option("bump-after-update")?; + let mut bump_after_update: PhpMixed = + input.borrow().get_option("bump-after-update")?.into(); // PHP: false === $bumpAfterUpdate (strict) if matches!(bump_after_update, PhpMixed::Bool(false)) { bump_after_update = composer.get_config().borrow().get("bump-after-update"); diff --git a/crates/shirabe/tests/installer_test.rs b/crates/shirabe/tests/installer_test.rs index 05776557..4d24186f 100644 --- a/crates/shirabe/tests/installer_test.rs +++ b/crates/shirabe/tests/installer_test.rs @@ -52,6 +52,7 @@ 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}; @@ -828,10 +829,9 @@ fn ignore_platform_reqs_value(input: &dyn InputInterface) -> PhpMixed { } let list = input .get_option("ignore-platform-req") - .unwrap_or(PhpMixed::Bool(false)); + .unwrap_or(InputOptionValue::Bool(false)); match &list { - PhpMixed::List(items) if !items.is_empty() => list, - PhpMixed::Array(map) if !map.is_empty() => list, + InputOptionValue::Array(items) if !items.is_empty() => list.into(), _ => PhpMixed::Bool(false), } } |
