aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--crates/shirabe-php-shim/src/lib.rs27
-rw-r--r--crates/shirabe/src/autoload/autoload_generator.rs15
-rw-r--r--crates/shirabe/src/command/check_platform_reqs_command.rs43
-rw-r--r--crates/shirabe/src/config.rs20
-rw-r--r--crates/shirabe/src/repository/installed_repository.rs21
5 files changed, 69 insertions, 57 deletions
diff --git a/crates/shirabe-php-shim/src/lib.rs b/crates/shirabe-php-shim/src/lib.rs
index 77e51ac..acc81d9 100644
--- a/crates/shirabe-php-shim/src/lib.rs
+++ b/crates/shirabe-php-shim/src/lib.rs
@@ -1079,10 +1079,37 @@ pub fn array_fill_keys(_keys: PhpMixed, _value: PhpMixed) -> PhpMixed {
todo!()
}
+/// PHP `array_merge`.
+///
+/// Must reproduce PHP's mixed integer/string key semantics:
+/// - string keys: a later array's value overwrites an earlier one, keeping the
+/// earlier key's position;
+/// - integer-like keys ("0","1",...): values are appended and renumbered
+/// sequentially across all inputs (they are NOT overwritten by key).
+///
+/// A naive per-entry `IndexMap::insert` is INCORRECT for inputs that mix string
+/// and integer keys (e.g. an AliasPackage's provides/replaces, where
+/// self.version expansion appends links under "0","1",... keys). See the typed
+/// [`array_merge_map`] variant used by such call sites.
pub fn array_merge(_array1: PhpMixed, _array2: PhpMixed) -> PhpMixed {
todo!()
}
+/// PHP `array_merge` for a string-keyed map that MAY also contain integer-like
+/// keys. Typed counterpart of [`array_merge`] for `IndexMap<String, V>` values
+/// (e.g. `Link` maps from `getProvides`/`getReplaces`).
+///
+/// Must reproduce the same mixed-key semantics as [`array_merge`]: string keys
+/// overwrite in place (later wins), integer-like keys ("0","1",...) are appended
+/// and renumbered sequentially across both inputs. A naive `IndexMap::insert`
+/// per entry is INCORRECT because it would collide on shared integer keys.
+pub fn array_merge_map<V>(
+ _array1: IndexMap<String, V>,
+ _array2: IndexMap<String, V>,
+) -> IndexMap<String, V> {
+ todo!()
+}
+
pub fn substr_replace(_string: &str, _replace: &str, _start: usize, _length: usize) -> String {
todo!()
}
diff --git a/crates/shirabe/src/autoload/autoload_generator.rs b/crates/shirabe/src/autoload/autoload_generator.rs
index c36125f..6505510 100644
--- a/crates/shirabe/src/autoload/autoload_generator.rs
+++ b/crates/shirabe/src/autoload/autoload_generator.rs
@@ -8,11 +8,11 @@ use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_external_packages::symfony::component::console::formatter::OutputFormatter;
use shirabe_php_shim::{
E_USER_DEPRECATED, InvalidArgumentException, PhpMixed, RuntimeException, array_filter,
- array_keys, array_map, array_merge, array_merge_recursive, array_reverse, array_shift,
- array_slice, array_slice_strs, array_unique, bin2hex, explode, file_exists, file_get_contents,
- hash, implode, in_array, is_array, krsort, ksort, ltrim, preg_quote, random_bytes, realpath,
- sprintf, str_contains, str_replace, str_starts_with, strlen, strpos, strtr, substr,
- substr_count, trigger_error, trim, unlink, var_export,
+ array_keys, array_map, array_merge, array_merge_map, array_merge_recursive, array_reverse,
+ array_shift, array_slice, array_slice_strs, array_unique, bin2hex, explode, file_exists,
+ file_get_contents, hash, implode, in_array, is_array, krsort, ksort, ltrim, preg_quote,
+ random_bytes, realpath, sprintf, str_contains, str_replace, str_starts_with, strlen, strpos,
+ strtr, substr, substr_count, trigger_error, trim, unlink, var_export,
};
use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::Bound;
@@ -1104,10 +1104,7 @@ impl AutoloadGenerator {
for item in package_map {
let package = &item.0;
- let mut links = package.get_replaces();
- for (k, v) in package.get_provides() {
- links.insert(k, v);
- }
+ let links = array_merge_map(package.get_replaces(), package.get_provides());
for (_k, link) in &links {
let mut matches: IndexMap<CaptureKey, String> = IndexMap::new();
if Preg::match3("{^ext-(.+)$}iD", link.get_target(), Some(&mut matches))
diff --git a/crates/shirabe/src/command/check_platform_reqs_command.rs b/crates/shirabe/src/command/check_platform_reqs_command.rs
index 14b3be2..5225f7e 100644
--- a/crates/shirabe/src/command/check_platform_reqs_command.rs
+++ b/crates/shirabe/src/command/check_platform_reqs_command.rs
@@ -4,7 +4,7 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::symfony::component::console::input::InputInterface;
use shirabe_external_packages::symfony::component::console::output::OutputInterface;
-use shirabe_php_shim::{PhpMixed, strip_tags};
+use shirabe_php_shim::{PhpMixed, array_merge_map, strip_tags};
use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::SimpleConstraint;
@@ -153,28 +153,27 @@ impl CheckPlatformReqsCommand {
if !candidates.is_empty() {
let mut req_results: Vec<CheckResult> = vec![];
'candidates: for candidate in &candidates {
- let candidate_constraint: Option<AnyConstraint> =
- if candidate.get_name() == *require {
- let c = SimpleConstraint::new(
- "=".to_string(),
- candidate.get_version().to_string(),
- Some(candidate.get_pretty_version().to_string()),
- );
- Some(c.into())
- } else {
- let mut found: Option<AnyConstraint> = None;
- for (_, link) in candidate
- .get_provides()
- .iter()
- .chain(candidate.get_replaces().iter())
- {
- if link.get_target() == require {
- found = Some(link.get_constraint().clone());
- break;
- }
+ let candidate_constraint: Option<AnyConstraint> = if candidate.get_name()
+ == *require
+ {
+ let c = SimpleConstraint::new(
+ "=".to_string(),
+ candidate.get_version().to_string(),
+ Some(candidate.get_pretty_version().to_string()),
+ );
+ Some(c.into())
+ } else {
+ let mut found: Option<AnyConstraint> = None;
+ let provides_and_replaces =
+ array_merge_map(candidate.get_provides(), candidate.get_replaces());
+ for (_, link) in &provides_and_replaces {
+ if link.get_target() == require {
+ found = Some(link.get_constraint().clone());
+ break;
}
- found
- };
+ }
+ found
+ };
let candidate_constraint = match candidate_constraint {
Some(c) => c,
diff --git a/crates/shirabe/src/config.rs b/crates/shirabe/src/config.rs
index b3460e8..1cfb8cc 100644
--- a/crates/shirabe/src/config.rs
+++ b/crates/shirabe/src/config.rs
@@ -12,7 +12,7 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_php_shim::{
E_USER_DEPRECATED, FILTER_VALIDATE_URL, PHP_URL_HOST, PHP_URL_SCHEME, PhpMixed,
- RuntimeException, array_key_exists, array_merge_recursive, array_reverse, array_search_mixed,
+ RuntimeException, array_key_exists, array_merge, array_reverse, array_search_mixed,
array_unique, current, empty, filter_var, implode, in_array, is_array, is_int, is_string, key,
max, parse_url, reset, rtrim, strtolower, strtoupper, strtr, substr, trigger_error,
};
@@ -334,10 +334,8 @@ impl Config {
) && self.config.contains_key(key)
{
let existing = self.config.get(key).cloned().unwrap_or(PhpMixed::Null);
- self.config.insert(
- key.clone(),
- array_merge_recursive(vec![existing, val.clone()]),
- );
+ self.config
+ .insert(key.clone(), array_merge(existing, val.clone()));
self.set_source_of_config_value(&val, key, source);
} else if in_array(
PhpMixed::String(key.clone()),
@@ -354,7 +352,7 @@ impl Config {
let existing = self.config.get(key).cloned().unwrap_or(PhpMixed::Null);
self.config.insert(
key.clone(),
- array_merge_recursive(vec![val.clone(), existing, val.clone()]),
+ array_merge(array_merge(val.clone(), existing), val.clone()),
);
self.set_source_of_config_value(&val, key, source);
} else if in_array(
@@ -367,7 +365,7 @@ impl Config {
) && self.config.contains_key(key)
{
let existing = self.config.get(key).cloned().unwrap_or(PhpMixed::Null);
- let merged = array_merge_recursive(vec![existing, val.clone()]);
+ let merged = array_merge(existing, val.clone());
let unique_list: Vec<String> = match &merged {
PhpMixed::List(l) => l
.iter()
@@ -406,7 +404,7 @@ impl Config {
}
let cur = self.config.get(key).cloned().unwrap_or(PhpMixed::Null);
self.config
- .insert(key.clone(), array_merge_recursive(vec![cur, val.clone()]));
+ .insert(key.clone(), array_merge(cur, val.clone()));
self.set_source_of_config_value(&val, key, source);
// the full match pattern needs to be last
let has_wildcard = matches!(
@@ -433,10 +431,10 @@ impl Config {
.cloned()
.map(|b| *b)
.unwrap_or(PhpMixed::List(vec![]));
- let merged = array_merge_recursive(vec![
+ let merged = array_merge(
self.config.get("audit").cloned().unwrap_or(PhpMixed::Null),
val.clone(),
- ]);
+ );
self.config.insert(key.clone(), merged);
self.set_source_of_config_value(&val, key, source);
let val_ignore = match &val {
@@ -447,7 +445,7 @@ impl Config {
.unwrap_or(PhpMixed::List(vec![])),
_ => PhpMixed::List(vec![]),
};
- let new_ignores = array_merge_recursive(vec![current_ignores, val_ignore]);
+ let new_ignores = array_merge(current_ignores, val_ignore);
if let Some(PhpMixed::Array(audit)) = self.config.get_mut("audit") {
audit.insert("ignore".to_string(), Box::new(new_ignores));
}
diff --git a/crates/shirabe/src/repository/installed_repository.rs b/crates/shirabe/src/repository/installed_repository.rs
index e199556..e6f022e 100644
--- a/crates/shirabe/src/repository/installed_repository.rs
+++ b/crates/shirabe/src/repository/installed_repository.rs
@@ -2,6 +2,7 @@
use indexmap::IndexMap;
use shirabe_php_shim::LogicException;
+use shirabe_php_shim::array_merge_map;
use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MatchAllConstraint;
use shirabe_semver::constraint::SimpleConstraint;
@@ -84,16 +85,9 @@ impl InstalledRepository {
continue;
}
- let provides = candidate.get_provides();
- let replaces = candidate.get_replaces();
- let mut provides_and_replaces: Vec<&Link> = vec![];
- for link in provides.values() {
- provides_and_replaces.push(link);
- }
- for link in replaces.values() {
- provides_and_replaces.push(link);
- }
- for link in provides_and_replaces {
+ let provides_and_replaces =
+ array_merge_map(candidate.get_provides(), candidate.get_replaces());
+ for link in provides_and_replaces.values() {
if name == link.get_target()
&& (constraint.is_none()
|| constraint.as_ref().unwrap().matches(link.get_constraint()))
@@ -313,11 +307,8 @@ impl InstalledRepository {
.into();
if link.get_target() != pkg.get_name().as_str() {
- let mut replaces_and_provides: IndexMap<String, Link> =
- pkg.get_replaces();
- for (k, v) in pkg.get_provides() {
- replaces_and_provides.entry(k).or_insert(v);
- }
+ let replaces_and_provides =
+ array_merge_map(pkg.get_replaces(), pkg.get_provides());
for prov in replaces_and_provides.values() {
if link.get_target() == prov.get_target() {
version = prov.get_constraint().clone();