| Age | Commit message (Collapse) | Author |
|
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>
|
|
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.
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|