aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-18 08:37:30 +0900
committernsfisis <nsfisis@gmail.com>2026-08-18 08:37:30 +0900
commit4856f05e870ec5d2daaa74bf9a86a1519a813614 (patch)
treeab81b7a9d59340c4d05ecaf3b6b1a81106cc8355
parent5aaa92f760a975c6617b5d1fb7af8e58fed127b7 (diff)
downloadphp-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>
-rw-r--r--crates/shirabe-symfony-console/src/command/complete_command.rs23
-rw-r--r--crates/shirabe-symfony-console/src/command/help_command.rs10
-rw-r--r--crates/shirabe-symfony-console/src/command/list_command.rs15
-rw-r--r--crates/shirabe-symfony-console/src/completion/completion_input.rs2
-rw-r--r--crates/shirabe-symfony-console/src/input/argv_input.rs3
-rw-r--r--crates/shirabe-symfony-console/src/input/array_input.rs3
-rw-r--r--crates/shirabe-symfony-console/src/input/input.rs14
-rw-r--r--crates/shirabe-symfony-console/src/input/input_interface.rs3
-rw-r--r--crates/shirabe-symfony-console/src/input/input_option.rs87
-rw-r--r--crates/shirabe-symfony-console/src/input/string_input.rs3
-rw-r--r--crates/shirabe/src/command/audit_command.rs8
-rw-r--r--crates/shirabe/src/command/base_command.rs15
-rw-r--r--crates/shirabe/src/command/create_project_command.rs15
-rw-r--r--crates/shirabe/src/command/init_command.rs34
-rw-r--r--crates/shirabe/src/command/outdated_command.rs12
-rw-r--r--crates/shirabe/src/command/reinstall_command.rs10
-rw-r--r--crates/shirabe/src/command/show_command.rs12
-rw-r--r--crates/shirabe/src/command/update_command.rs11
-rw-r--r--crates/shirabe/tests/installer_test.rs6
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(&current_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),
}
}