Part of #1367 (Phase 3 — Dependency Engine v2).
Goal
Extend the dependency engine beyond JS/PHP/Actions/Docker/pkgx to the four most-requested ecosystems, plus close JS-side gaps. Renovate's breadth is its moat; each ecosystem we add compounds ours. Current inventory and writer paths live in src/scanner/package-scanner.ts (discovery), src/registry/registry-client.ts (versions), src/buddy.ts:generateAllFileUpdates:1108 (writers).
Ecosystems
1. Python — pyproject.toml (PEP 621 + poetry/uv), requirements*.txt
- Registry: PyPI JSON API (
https://pypi.org/pypi/{name}/json); version specifiers PEP 440 (NOT semver — needs apep440.tscomparator) - Lockfiles:
uv.lock,poetry.lockviaregenerateLockFilepattern (src/utils/lock-file.ts) when the tool is present - OSV ecosystem:
PyPI(extendtoOsvEcosysteminsrc/services/security-advisories.ts— currently npm+Packagist only)
2. Rust — Cargo.toml (+ workspace deps)
- Registry: crates.io API (
https://crates.io/api/v1/crates/{name}); semver-compatible caret semantics Cargo.lockregeneration viacargo update -pwhen available- OSV:
crates.io
3. Go — go.mod
- Registry: Go module proxy (
https://proxy.golang.org/{module}/@v/list+@latest); pseudo-versions and/v2+major-suffix paths handled - Writer: rewrite
requirelines;go.sumviago mod tidywhen toolchain present, else PR notes the needed command - OSV:
Go
4. Ruby — Gemfile
- Registry: RubyGems API (
https://rubygems.org/api/v1/versions/{name}/latest.json); pessimistic operator (~>) preserved Gemfile.lockviabundle lock --update <gem>when available- OSV:
RubyGems
JS-side gaps (same issue since they touch the same files)
- pnpm catalogs (#117): parse
pnpm-workspace.yamlcatalog:/catalogs:sections; update catalog entries and treatcatalog:protocol deps as resolvable - package.json
enginesbumping (with #1384 rules gating) — delivers #107 - yarn/npm
overrides/resolutionsawareness: don't propose updates that overrides pin (surface via resolution-drift, #1372)
Architecture requirement (do this first)
Introduce an EcosystemAdapter interface so each ecosystem is a pluggable module instead of more methods on Buddy:
interface EcosystemAdapter {
name: string
detect(dir): Promise<string[]> // manifest paths
parse(file): Promise<PackageDependency[]>
latest(dep, opts): Promise<VersionInfo | null> // registry lookup w/ caching
applyUpdate(fileContent, update): string // formatting-preserving write
postWrite?(dir): Promise<void> // lockfile regeneration
osvEcosystem?: string
}Migrate ONE existing ecosystem (composer is the cleanest) onto the interface as the reference implementation, then add the new four. Don't rewrite all existing ecosystems in this issue — follow-ups can migrate incrementally.
Tasks
EcosystemAdapterinterface + registry + composer migration (reference impl)- Python adapter (incl. PEP 440 comparator with test vectors from the spec)
- Rust, Go, Ruby adapters — each: fixtures, formatting-preservation tests, lockfile path, OSV wiring
- pnpm catalogs (#117) + engines (#107) + overrides awareness
- Grouping/labels: new ecosystem labels; PR body tables per ecosystem (extend
src/pr/pr-generator.tstable generation) - Docs: per-ecosystem pages under
docs/features/
Acceptance criteria
- Fixture repos for each ecosystem produce correct, formatting-preserving update PRs with working lockfile regeneration when the toolchain exists (and a clear note when not)
- OSV advisories surface for all four new ecosystems
- #117's catalog fixture updates correctly