aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-registry/src/resolver.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-03 23:31:31 +0900
committernsfisis <nsfisis@gmail.com>2026-05-03 23:31:31 +0900
commite37b12d6e2d95b4d3924859732513e125fc552e0 (patch)
tree555b049cdca81814b4adc74d542ef39833cf5f5d /crates/mozart-registry/src/resolver.rs
parent26af378d81da76c50593674fa86ed4911aa0e46f (diff)
downloadphp-mozart-e37b12d6e2d95b4d3924859732513e125fc552e0.tar.gz
php-mozart-e37b12d6e2d95b4d3924859732513e125fc552e0.tar.zst
php-mozart-e37b12d6e2d95b4d3924859732513e125fc552e0.zip
feat(registry): support type: path repositories
Adds a `mozart-php-serialize` crate (a byte-compatible port of PHP's `serialize()`) and a `mozart-registry::path_repository` module that expands `type: path` entries into synthetic `type: package` repositories. Each synthesized package carries the same SHA-1 dist reference Composer computes (`sha1(\$json . serialize(\$options))`) so the lockfile and trace lines match Composer byte-for-byte. Two latent bugs surfaced once the path-repo flow exercised real resolutions: - `apply_partial_update` swapped path-repo packages back to their locked version, defeating Composer's "path repos always reload" rule (`PoolBuilder` treats them as canonical, not lock-bound). Mirror the path-repo skip already used when constructing `locked_packages`. - `normalize_root_alias_atom` returned the raw input string for stable numeric atoms (e.g. `1.1.1`), so the alias matcher's `input.version \!= alias.version_normalized` check — comparing against pool inputs that carry the 4-segment normalized form — silently never matched. Run the parsed Version through Display so both sides are in the same shape. `install/update::run` gain a `path_repo_base_override: Option<&Path>` parameter for the in-process test harness: Composer's PHPUnit `InstallerTest::setUp` does `chdir(__DIR__)` so relative path-repo URLs resolve against `composer/tests/Composer/Test/`, but the Rust harness writes `composer.json` into a per-test tempdir and can't chdir safely under parallel tests. Production callers pass `None` and resolve against `working_dir`. Greens 3 ignored installer fixtures: partial_update_loads_root_aliases_for_path_repos alias_in_lock alias_in_lock2
Diffstat (limited to 'crates/mozart-registry/src/resolver.rs')
-rw-r--r--crates/mozart-registry/src/resolver.rs7
1 files changed, 6 insertions, 1 deletions
diff --git a/crates/mozart-registry/src/resolver.rs b/crates/mozart-registry/src/resolver.rs
index b323764..d9fe900 100644
--- a/crates/mozart-registry/src/resolver.rs
+++ b/crates/mozart-registry/src/resolver.rs
@@ -265,7 +265,12 @@ fn normalize_root_alias_atom(atom: &str) -> Option<String> {
if let Some(rest) = lower.strip_prefix("dev-") {
return Some(format!("dev-{rest}"));
}
- parse_normalized(trimmed).map(|_| trimmed.to_string())
+ // Stable numeric atoms (e.g. `1.1.1`) need to come back in the
+ // four-segment form `Version::Display` produces, so the alias
+ // matcher's `input.version != alias.version_normalized` check lines
+ // up with pool inputs (which carry the 4-segment normalized form).
+ // Returning the raw input here would silently never match.
+ parse_normalized(trimmed).map(|v| v.to_string())
}
/// A root-level alias declared via the `require: "X as Y"` shorthand on the