diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-23 12:36:15 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-23 12:36:15 +0900 |
| commit | 890a50de2a740cc4c4edba12b37cc9aa4d0efdc5 (patch) | |
| tree | e9925bfa7874680dde9d229bc869867ad7779b8e | |
| parent | 2f07bd12c0c77e8985646a9f21a62a91311d82c0 (diff) | |
| download | php-shirabe-890a50de2a740cc4c4edba12b37cc9aa4d0efdc5.tar.gz php-shirabe-890a50de2a740cc4c4edba12b37cc9aa4d0efdc5.tar.zst php-shirabe-890a50de2a740cc4c4edba12b37cc9aa4d0efdc5.zip | |
fix(config-command): print config values PHP would stringify
`config --list` and `config <key>` rendered a value with `as_string()`,
which yields None for everything but a string, so every int-valued
setting printed as an empty string: `cache-ttl`, `cache-files-ttl` and
the resolved value of `cache-files-maxsize`. PHP builds that output by
concatenating the value into the message, which casts it, so the ports
now go through `php_to_string`.
Two more differences in the same rendering path:
The `[a, b]` branch flattened the array through `as_list()`, which sees
only `PhpMixed::List`, so a keyed array reaching it rendered as `[]`.
PHP takes that branch whenever the first key is numeric, so the values
now come from `array_values_mixed`, which covers both representations.
The raw-vs-resolved comparison deciding between `raw (value)` and
`value` compared the two as strings. PHP compares with `!==`, which
also compares the type: with a `cache-ttl` of `"15552000"` in
composer.json, the raw string and the resolved int are not identical
and Composer prints `15552000 (15552000)`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
| -rw-r--r-- | crates/shirabe-php-shim/src/array.rs | 8 | ||||
| -rw-r--r-- | crates/shirabe/src/command/config_command.rs | 60 |
2 files changed, 33 insertions, 35 deletions
diff --git a/crates/shirabe-php-shim/src/array.rs b/crates/shirabe-php-shim/src/array.rs index 3870d59e..ec9adb26 100644 --- a/crates/shirabe-php-shim/src/array.rs +++ b/crates/shirabe-php-shim/src/array.rs @@ -6,6 +6,14 @@ pub fn array_values<V: Clone>(array: &IndexMap<String, V>) -> Vec<V> { array.values().cloned().collect() } +pub fn array_values_mixed(value: &PhpMixed) -> Vec<PhpMixed> { + match value { + PhpMixed::List(items) => items.clone(), + PhpMixed::Array(map) => map.values().cloned().collect(), + _ => panic!("array_values(): Argument #1 ($array) must be of type array"), + } +} + pub fn array_keys<V>(array: &IndexMap<String, V>) -> Vec<String> { array.keys().cloned().collect() } diff --git a/crates/shirabe/src/command/config_command.rs b/crates/shirabe/src/command/config_command.rs index 53e1fe7c..2f3c5fd7 100644 --- a/crates/shirabe/src/command/config_command.rs +++ b/crates/shirabe/src/command/config_command.rs @@ -20,10 +20,10 @@ use crate::util::Silencer; use indexmap::IndexMap; use shirabe_php_shim::{ InvalidArgumentException, PhpMixed, RuntimeException, array_is_list, array_merge, - escapeshellcmd, exec, explode, file_exists, impl_php_class, implode, in_array_loose, - in_array_strict, is_array, is_bool, is_dir, is_numeric, is_object, is_string, json_encode, - php_regex, preg_is_match, preg_match, preg_replace, str_replace, strpos, strtolower, system, - touch, var_export, + array_values_mixed, escapeshellcmd, exec, explode, file_exists, impl_php_class, implode, + in_array_loose, in_array_strict, is_array, is_bool, is_dir, is_numeric, is_object, is_string, + json_encode, php_regex, php_to_string, preg_is_match, preg_match, preg_replace, str_replace, + strpos, strtolower, system, touch, var_export, }; use shirabe_semver::VersionParser; use shirabe_symfony_console::command::Command; @@ -199,7 +199,7 @@ impl ConfigCommand { let raw_val = raw_contents_arr.get(key).cloned().unwrap_or(PhpMixed::Null); - let value_inner = value.clone(); + let mut value_inner = value.clone(); if is_array(&value_inner) && (!is_numeric(&key_first_key(&value_inner).unwrap_or_default().into()) @@ -224,27 +224,23 @@ impl ConfigCommand { continue; } - let value_display: String = if is_array(&value_inner) { - let arr_strs: Vec<String> = value_inner - .as_list() - .map(|l| { - l.iter() - .map(|val| { - if is_array(val) { - json_encode(val).unwrap_or_default() - } else { - val.as_string().unwrap_or("").to_string() - } - }) - .collect::<Vec<_>>() + if is_array(&value_inner) { + let arr_strs: Vec<String> = array_values_mixed(&value_inner) + .iter() + .map(|val| { + if is_array(val) { + json_encode(val).unwrap_or_default() + } else { + php_to_string(val) + } }) - .unwrap_or_default(); - format!("[{}]", implode(", ", &arr_strs)) - } else if is_bool(&value_inner) { - var_export(&value_inner, true) - } else { - value_inner.as_string().unwrap_or("").to_string() - }; + .collect(); + value_inner = PhpMixed::String(format!("[{}]", implode(", ", &arr_strs))); + } + + if is_bool(&value_inner) { + value_inner = PhpMixed::String(var_export(&value_inner, true)); + } let source = if show_source { format!( @@ -278,13 +274,7 @@ impl ConfigCommand { let id = preg_replace(php_regex!("{-+}"), "-", &id); format!("https://getcomposer.org/doc/06-config.md#{}", id) }; - if is_string(&raw_val) - && raw_val - .as_string() - .map(|s| s.to_string()) - .unwrap_or_default() - != value_display - { + if is_string(&raw_val) && raw_val.as_string() != value_inner.as_string() { self.get_io().write3( &format!( "[<fg=yellow;href={}>{}{}</>] <info>{} ({})</info>{}", @@ -292,7 +282,7 @@ impl ConfigCommand { k.clone().unwrap_or_default(), key, raw_val.as_string().unwrap_or(""), - value_display, + php_to_string(&value_inner), source ), true, @@ -305,7 +295,7 @@ impl ConfigCommand { link, k.clone().unwrap_or_default(), key, - value_display, + php_to_string(&value_inner), source ), true, @@ -843,7 +833,7 @@ impl Command for ConfigCommand { }, )? } else { - value.as_string().unwrap_or("").to_string() + php_to_string(&value) }; let mut source_of_config_value = String::new(); |
