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-44 — Preflight for --source=opencode
internal/source/all.go:37-53 — newOptionalOpencodeSource for --source=all
Both implement the same shape: on ErrDBNotFound with OPENCODE_DB unset, check for legacy storage and branch.
Task
- 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.
- 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.)
- Rewrite both call sites as thin switches over the classification; keep the user-facing error messages byte-identical.
- 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.
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_DBoverride rule) exists in two places ininternal/sourceand can drift.Current state
internal/source/opencode.go:27-44—Preflightfor--source=opencodeinternal/source/all.go:37-53—newOptionalOpencodeSourcefor--source=allBoth implement the same shape: on
ErrDBNotFoundwithOPENCODE_DBunset, check for legacy storage and branch.Task
internal/opencode, e.g.:OPENCODE_DB, fake legacy layout). Check existing tests ininternal/sourcefor these paths and de-duplicate.Acceptance criteria
--source=opencodewithout a DB are unchanged (test-asserted).go test ./...,go vet ./...,golangci-lint runpass.