Skip to content

refactor: dedupe the opencode DB preflight availability check #95

Description

@sorafujitani

Context

The decision "is the OpenCode DB usable, and if not, is it a hard error or just absent?" (including the legacy-storage detection and the OPENCODE_DB override rule) exists in two places in internal/source and can drift.

Current state

  • internal/source/opencode.go:27-44Preflight for --source=opencode
  • internal/source/all.go:37-53newOptionalOpencodeSource for --source=all

Both implement the same shape: on ErrDBNotFound with OPENCODE_DB unset, check for legacy storage and branch.

Task

  1. Read both functions and write down the exact decision table (error kind × env set × legacy present → outcome). The two callers want different outputs (hard error with guidance vs. silently-skip), so extract the classification, not the reaction.
  2. Add a single classifier to internal/opencode, e.g.:
    type Availability int
    const (
        Available Availability = iota
        NotFound          // no DB, no legacy storage
        LegacyOnly        // legacy storage present, new DB absent
        Misconfigured     // OPENCODE_DB set but unusable
    )
    func ClassifyAvailability() (Availability, error)
    (Adjust names/cases to match the real decision table from step 1.)
  3. Rewrite both call sites as thin switches over the classification; keep the user-facing error messages byte-identical.
  4. Add a table-driven test for the classifier using temp dirs / env overrides (OPENCODE_DB, fake legacy layout). Check existing tests in internal/source for these paths and de-duplicate.

Acceptance criteria

  • The legacy-detection logic exists in exactly one place.
  • Error messages for --source=opencode without a DB are unchanged (test-asserted).
  • go test ./..., go vet ./..., golangci-lint run pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueGood for newcomersimpact: lowLower or indirect user-visible impactrefactorInternal restructuring with no behavior change

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions