Skip to content

Tracking: dispatch vendored backends through one per-ecosystem table instead of string matches in core and the CLI #959

Description

[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: discussion #560 register.

Kind: tracking. Source: review §2.1, Part 5.2 and 5.8; register E21.

Problem (verified on 9c43dfc)

Vendored mode has no backend abstraction. The eight vendor ecosystems are a string vocabulary that is re-matched wherever a per-ecosystem decision is made, and backends are uniform only by naming convention (service_preflight, vendor_*, revert_*_opts, vendored_entry_in_use). Production sites that enumerate the ecosystems include:

Ecosystem identity has an alias. JVM entries are re-tagged "jvm" (maven_repo.rs#L1344). That forces "maven" | "jvm" handling at the CLI revert match, in path.rs#L92 and in redownload.rs#L71-L88.

The lists drift. #832 (NuGet and Maven) and #958 (Hatch) are both a per-ecosystem fact ("which files carry my references") kept in a table apart from the backend that writes those files.

Target design

One per-ecosystem dispatch point in core, keyed by the existing Ecosystem enum (minus Deno). The CLI and the core helpers ask it instead of matching strings:

// vendor/backend.rs
pub enum VendorBackend { Npm, Pypi, Gem, Cargo, Golang, Composer, Nuget, Maven }
impl VendorBackend {
    pub const ALL: [Self; 8];
    pub fn dir(self) -> &'static str;                  // ECOSYSTEM_DIRS derives from ALL
    pub fn of_entry(e: &VendorEntry) -> Option<Self>;  // owns the "jvm" alias
    pub async fn revert(self, e, root, opts) -> RevertOutcome;
    pub async fn in_use(self, e, root) -> Option<bool>;
    pub async fn preflight(self, ..) -> Option<PlannedDownload>;
    pub async fn vendor(self, ..) -> VendorOutcome;
    pub fn leaf_to_purl(self, leaf) -> Option<String>;
    pub fn wiring_files(self) -> &'static [&'static str];
}

This is an enum with match arms that call the existing backend functions, not a trait object: async dispatch stays static, and each step is mechanical. Part 5.8's batched plan/materialize trait is the later step, after the revert engine (E24) and the batched planners (E27).

Checklist (one PR each, in order)

Acceptance (for the tracking issue)

  • No production match on a vendor ecosystem string outside vendor/backend.rs and the ledger-load adapter. Enforce it with a source-scan architecture test like crawlers::architecture_tests.
  • The legacy-ledgers fixtures and the e2e_vendor_* suites stay green at every step.

Dependencies

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)priority:p3refactorStructural change: duplicated code or logic, missing abstraction, layering, dead code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions