aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-registry/src/inline_package.rs
AgeCommit message (Collapse)Author
2026-05-03fix(resolver): cap inline package loads by root require constraintnsfisis
Mirror Composer's PoolBuilder::markPackageNameForLoading: when the root requires a name with a version constraint, loads of that name (seed and transitive) are filtered down to candidates whose own version (or any emitted branch-alias version) satisfies the constraint. Without this, the actual package at a non-matching version slips into the pool alongside a provider satisfying the root require, masking what should be a conflict (provider-gets-picked-together-with-other-version-of- provided-conflict.test). Also restore the Composer v1 compat path in inline_package: when the JSON sets version_normalized to the legacy 9999999-dev sentinel, re-normalize from the human-readable version field so a root require for `dev-master` matches the loaded package. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03fix(resolver): honor config.audit.block-insecure security-advisory filternsfisis
Mozart silently ignored the `security-advisories` block on inline `type: package` repositories and the `config.audit.block-insecure` audit flag, so a `composer update` succeeded with packages a Composer run would have refused to load. Mirror Composer's `SecurityAdvisoryPoolFilter` for the slice that feeds the pool: - Plumb a `security-advisories` field through `RawRepository` and a `block_insecure` flag through `ResolveRequest`, lifted off `composer.json`'s `config.audit.block-insecure`. - Collect every advisory's `affectedVersions` constraint at resolve time. When `block_insecure` is set and an inline package's normalized version satisfies the constraint, drop it from the pool before solving — root requires with no unaffected candidate then fail with the standard "could not be resolved" error.
2026-05-03feat(repository): support only/exclude/canonical repo filtersnsfisis
Composer's FilterRepository wraps a repository with three knobs: `only` / `exclude` to drop packages by name, and `canonical: false` to relax the repo's authoritative claim on its package names so lower-priority repos can still answer. Mozart was ignoring all three, so first-listed inline / composer-repo entries always shadowed later repos and `only` / `exclude` lists were silently no-ops. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03refactor: switch internal maps/sets from HashMap to IndexMapnsfisis
Adopt indexmap workspace-wide so iteration order is deterministic and follows insertion order. The non-deterministic order of std HashMap otherwise leaks into resolver decisions when multiple valid solutions exist (e.g. cyclic require pairs under prefer-lowest), making behavior flaky and divergent from Composer's PHP-array semantics. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03fix(registry): respect priority order across inline package reposnsfisis
When a `type: package` repository declares a name already declared by a higher-priority `type: package` entry, drop it. Mirrors Composer's RepositorySet first-repo-wins semantics so duplicate names across inline repositories cannot promote a lower-priority version into the pool. Greens 4 installer fixtures: install_prefers_repos_over_package_versions, repositories_priorities2, repositories_priorities4, update_package_present_in_lower_repo_prio_but_not_main_due_to_min_stability. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01feat(registry): support inline 'type: package' repositoriesnsfisis
Composer's PackageRepository lets composer.json embed full package metadata under repositories[].package, mirroring the on-disk Packagist response shape. The vast majority of installer fixtures under composer/tests/Composer/Test/Fixtures/installer (179 of 189) rely on this — they declare every package they need inline rather than hitting the network. Three pieces wire this into Mozart: 1. mozart-core::package::RawRepository: relax `url` to Option<String> (Composer enforces presence per repo type, not at JSON parse) and add `package: Option<Value>` to receive the inline definition, which can be a single object or an array. 2. mozart-registry::inline_package: a new module that walks `&[RawRepository]`, picks out type=package entries, and reshapes each `package` payload into a PackagistVersion (auto-computing version_normalized when omitted, matching Packagist's output). 3. resolver::resolve and lockfile::generate_lock_file: feed inline packages into the SAT pool builder and short-circuit the Packagist fetch when generating the lock entry for a resolved inline package. The package-name set is shared with the existing VCS-skip logic so the seed and transitive loops don't double-fetch. One additional install-time change: in install_from_lock, packages that have neither dist nor source are now skipped silently instead of bailing with "no dist or source information". This mirrors Composer's MetapackageInstaller (no installer for type=metapackage) and is also what Composer's own AllFunctionalTest exercises via InstallationManagerMock — most inline-package fixtures define synthetic packages with no download metadata, expecting the install operation to be recorded but not actually run. Net effect: installer fixture scoreboard jumps from 7/187 to 103/187. The 84 fixtures still ignored hit issues unrelated to inline-package plumbing — aliases, replace/provide chains, dev-reference handling, allow-list updates, etc. — and are tracked separately. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>