Skip to main content

Crate vivacity_resolver

Crate vivacity_resolver 

Source
Expand description

vivacity-resolver: port of Composer 2.10.3’s dependency resolution: versions and constraints (composer/semver), Packagist v2 metadata, pool construction, then the solver. Each module is a port of the source vendored under docs/reference/resolver/, checked by an oracle against the phar.

Modules§

config_source
Port of Composer\Config\JsonConfigSource for composer.json (not auth.json): every edit goes through JsonManipulator on the file text; if the manipulator gives up (false), Composer re-reads the file, applies the same modification to the decoded array and rewrites everything with JsonFile::write (detected indentation, empty arrays rendered as {} for keys that are objects in the schema).
constraint
Port of Composer\Semver\Constraint\* and VersionParser::parseConstraints (docs/reference/resolver/semver-Constraint.php, semver-MultiConstraint.php, semver-Bound.php, semver-VersionParser.php). A constraint is a tree: leaf (operator, normalized version), conjunction/disjunction, match-all, match-none. matches reproduces Constraint::matchSpecific (and thus CompilingMatcher::match, which is merely a compiled form of it).
decisions
Port of Composer\DependencyResolver\Decisions: the decision map (package -> +/-level) and the decision queue with its rules.
flex_filter
Port of Symfony\Flex\PackageFilter (symfony/flex 2.11): Flex’s PRE_POOL_CREATE listener (Flex::truncatePackages) that removes from the pool, before it is created, the versions of the packages listed in symfony/symfony that do not match extra.symfony.require (SYMFONY_REQUIRE wins; a trailing .x becomes .x-dev). The data comes from the Flex endpoints’ index.json, key versions (splits: package → versions it ships in; next: the branch .x resolves to), merged first endpoint wins. Fetching and caching are the command layer’s business (vivacity::flex); this module is pure.
intervals
Port of Composer\Semver\Intervals (docs/reference/resolver/ semver-Intervals.php): a constraint becomes a list of numeric intervals [bound, bound] plus a set of branches (dev-*) that are either included or excluded; isSubsetOf, haveIntersections and compactConstraint derive from it. PoolBuilder uses it to know whether an already loaded package covers a new constraint, and to merge constraints.
json_manipulator
Port of Composer\Json\JsonManipulator (docs/reference/JsonManipulator.php) for the scope reached by require and remove: textual editing of composer.json through regular expressions, so as to touch only the modified part and preserve the file’s formatting.
loader
Port of Composer\Package\Loader\ArrayLoader (docs/reference/resolver/ ArrayLoader.php) restricted to the model’s fields, and of MetadataMinifier::expand. A JSON entry (p2 version or lock entry) becomes a Package, plus its branch alias if any.
lockfile
Lock writing: port of ArrayDumper::dump (from the raw metadata and the model, with ArrayLoader’s normalizations), of Locker::lockPackages and of Locker::setLockData; JsonFile encoding.
merge_plugin
Emulation of wikimedia/composer-merge-plugin v2.1.0 (v2.0.1 alike; docs/reference/plugins/composer-merge-plugin/, MIT) for an install and an autoload dump: the composer.json files named by extra.merge-plugin.include / require (PHP glob() patterns, no flags) are merged into the root package — require / require-dev, autoload / autoload-dev (paths re-based on each file’s directory), conflict / replace / provide, extra with merge-extra — in the order and with the duplicate rules of ExtraPackage::mergeInto / mergeDevInto, recursively (recurse).
metacache
Metadata cache of a composer repository, in Composer’s format and location (Cache on cache-repo-dir/<sanitized url>/): same file names (packages.json, provider-<vendor>~<name>[~dev].json), same content (the JSON re-encoded with last-modified injected when the server sent the header, the raw body otherwise). A cache written by one is read by the other, and vice versa.
optimizer
Port of Composer\DependencyResolver\PoolOptimizer: removes from the pool the versions whose dependencies are identical to a preferred version, and those a locked package makes impossible.
package
Package model of the resolver: port of Composer\Package\{BasePackage, Package, CompletePackage, AliasPackage, Link} reduced to what the pool and the solver read, plus the raw JSON of the version (to write the lock identically). Packages live in an arena (Vec<Package>) and refer to each other by index, as Composer does by object identity.
path_repo
Composer\Repository\PathRepository (docs/reference/PathRepository.php): every directory matched by the url glob that holds a composer.json becomes a package with a path dist. The dist reference is sha1(json . serialize(options)) (the raw file bytes and the repository options with relative auto-appended), replaced by the HEAD commit when the directory has a .git of its own and reference is auto, null with reference: none. The version comes, in this order, from options.versions[name], the package’s version, COMPOSER_ROOT_VERSION (when the directory and the project share the same HEAD), the git guess (a feature branch adds the branch AND its parent as two packages), else dev-main.
phpver
Exact port of PHP’s version_compare() (ext/standard/versioning.c): canonicalization (-, _, + -> ., a . inserted at every digit/non-digit transition), then component-by-component comparison; the special forms are ordered dev < alpha = a < beta = b < RC = rc < # < pl = p, a number counting as #. This is the ordering that Constraint::versionCompare, the bounds and version sorting rely on.
platform
Port of Composer\Repository\PlatformRepository: the platform packages (composer*, php*, ext-, lib-, hhvm) in Composer’s exact order, with the config.platform overrides. Probing the current PHP is done by assets/platform-probe.php (a transcription of initialize(), raw versions); normalization and its fallbacks are replayed here with the exact port of VersionParser.
platform_filter
Port of Composer\Filter\PlatformRequirementFilter\*: what --ignore-platform-reqs / --ignore-platform-req remove from the rules.
policy
Port of Composer\DependencyResolver\DefaultPolicy: the choice of preferred versions (stability, highest/lowest, root alias, replacement, same vendor, pool id).
policy_config
Port of Composer\Policy\PolicyConfig and the policy classes (docs/reference/policy/*.php): what config.policy and the legacy config.audit say about the three pool filters (security advisories, filter lists (malware), abandoned packages) after the global/project merge of Config::merge, the environment variables (COMPOSER_POLICY, COMPOSER_POLICY_*_BLOCK, COMPOSER_NO_BLOCKING…) and --no-blocking.
pool
Port of Composer\DependencyResolver\{Request, PoolBuilder, Pool} and Composer\Repository\RepositorySet (docs/reference/resolver/). The pool is the ordered list of packages the solver will see: the order is Composer’s, index by index, because the literal ids depend on it.
pool_filters
The filters PoolBuilder::buildPool applies to the pool before the optimizer: SecurityAdvisoryPoolFilter (security advisories and abandoned packages) then FilterListPoolFilter (filter lists, with Packagist’s malware list first), driven by crate::policy_config::PolicyConfig.
problem
Composer’s explanations of an unsolvable set: port of SolverProblemsException::getPrettyString, Problem::getPrettyString (with getMissingPackageReason, getPackageList, formatDeduplicatedRules…) and Rule::getPrettyString (docs/reference/resolver/). The text is Composer’s --no-ansi rendering: the output styles (<error>, <warning>, <info>, <comment>, <href=…>) are stripped, any other angle-bracket text is kept verbatim.
repository
Repositories as seen by the pool: ComposerRepository v2 (metadata-url, minified p2 files, ~dev), the lock repository (LockArrayRepository), the root and the platform (lists of already loaded packages). Port of docs/reference/resolver/ComposerRepository.php (v2 path only: v1 providers-url/provider-includes -> rejected).
root
The root package as RootPackageLoader::load builds it (docs/reference/RootPackageLoader.php): version (composer.json, COMPOSER_ROOT_VERSION, git, otherwise 1.0.0+no-version-set), links, minimum-stability, prefer-stable, and the three extractions from the require constraints: aliases (X as Y), stability flags (@dev, branches), references (#sha).
rule
Port of Rule, GenericRule, Rule2Literals, MultiConflictRule and RuleSet (docs/reference/resolver/). Rules live in the RuleSet and are referred to by their ruleById; literals are signed pool ids.
rules_gen
Port of Composer\DependencyResolver\RuleSetGenerator.
session
Setup of an update: what Factory::createComposer then Installer::doUpdate do before createPool: root, platform, repositories (global config + composer.json, same merge rules as Config::merge), lock repository, Request. Rust-side replica of tools/oracle-pool.php.
solver
Port of Composer\DependencyResolver\Solver (CDCL) and of the skeleton of Problem (the offending rules; messages come with R5).
transaction
Port of Transaction and LockTransaction: the packages kept by the decisions, the operations relative to the present lock, the packages to write into the lock.
version
Port of Composer\Semver\VersionParser (docs/reference/resolver/ semver-VersionParser.php): normalize, normalizeBranch, parseStability, parseNumericAliasPrefix, with the same PCRE expressions (pcre2), so that every string is accepted or rejected exactly as Composer does.
version_selector
Port of Composer\Package\Version\VersionSelector (docs/reference/VersionSelector.php): the best candidate for a name (preferred stability, then descending version, filtered by platform requirements) and the recommended constraint for require (^x.y, @stability, branch alias).
watch
Port of RuleWatchGraph, RuleWatchNode, RuleWatchChain: two watched literals per rule (all of them for a MultiConflictRule), one chain per literal, inserted at the head of the list (unshift).