Documentation
¶
Overview ¶
Package resolve implements ADR-0016's cross-language reference resolver: an open scheme registry where each scheme (mod, gomod, npm, git, ...) has an independent Resolver that turns a locator into the graph it names.
This file is the contract every scheme's resolver builds on (mache-bd97d9). Pure Go, no CGO or tree-sitter dependency at this layer — individual resolvers (in their own files) may depend on more; this file depends on the public graph package only.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNotResolvable = errors.New("resolve: locator not resolvable")
ErrNotResolvable is returned by a Resolver when the locator is syntactically in its scheme but does not resolve to anything — e.g. an import path with no matching module, or a relative path that escapes its anchor. Distinct from ErrSchemeUnknown, which the Registry returns when no Resolver is registered for the scheme at all.
var ErrSchemeUnknown = errors.New("resolve: unknown scheme")
ErrSchemeUnknown is returned by Registry.Resolve when no Resolver has been registered for the requested scheme.
Functions ¶
func IsLocalRelativeLocator ¶
IsLocalRelativeLocator reports whether the locator should be resolved against the local filesystem. Conservative: only ./ and ../ prefixes. Bare paths like "foo/bar" are ambiguous (could be a registry slug); those are treated as remote until a registry resolver is added.
Exported (moved from cmd/serve_resolve_ref.go, mache-be0b9f) so both this resolver and the resolve_ref MCP handler's own pre-flight local-path listing share one definition of "local".
Types ¶
type GoModResolver ¶
type GoModResolver struct {
// WorkDir is the directory `go list` runs from, which determines which
// module's go.mod (and therefore which module graph) resolution
// happens against. Required.
WorkDir string
// contains filtered or unexported fields
}
GoModResolver resolves a Go import path to the graph of its defining module, for the `gomod:` scheme ADR-0016 names but never implements.
It deliberately does NOT hand-roll go.mod parsing, replace-directive handling, or semver resolution — `go list` is Go's own first-party module-resolution tool and already gets those right. This is the resolver-body pattern the companion ADR (docs/adr/0025) documents: shell out to the ecosystem's own canonical tool, don't reimplement its resolution semantics.
Once `go list` names the resolved package's directory, that directory is indexed with build.Parse (leyline parse, this session's library facade — see docs/CHANGELOG under mache-3edd21) and opened with graph.Open, so LookupDef/QueryRefs/GetCallers work on the result exactly as they do on any other mache-produced .db.
type LocalPathResolver ¶
type LocalPathResolver struct {
// Anchor is the absolute directory a relative locator (./X, ../X) is
// resolved against. Required for relative locators; ignored for
// locators that are already absolute (a caller that has already
// anchored the path itself, e.g. resolve_ref's base_path handling).
Anchor string
// contains filtered or unexported fields
}
LocalPathResolver resolves `./X` / `../X` locators (and, for callers that have already done the joining themselves, absolute paths) to the graph of the directory they name — the `mod` scheme ADR-0016 names for local-relative references such as a Terraform `module { source = "./x" }`.
Like GoModResolver, it deliberately does not hand-roll ingestion: once a locator resolves to a directory, build.Parse (leyline parse) + graph.Open index and open it exactly as any other mache-produced .db, so the result supports LookupDef/QueryRefs/GetCallers immediately.
func (*LocalPathResolver) Resolve ¶
Resolve implements Resolver for the mod scheme. A relative locator is joined against Anchor and rejected with ErrNotResolvable if it escapes it (e.g. "../../../etc"); an absolute locator is used as-is — the caller (not this resolver) is responsible for having validated it.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry routes a (scheme, locator) pair to the Resolver registered for that scheme. It is an explicit object, not package-level state — callers construct one, register schemes, and pass it to whatever needs resolution (an MCP handler, a resolver that itself composes other resolvers), so tests never fight init-order or global mutation.
func NewRegistry ¶
func NewRegistry() *Registry
NewRegistry returns an empty Registry ready for Register calls.
func (*Registry) Register ¶
Register associates scheme with res. A later call for the same scheme replaces the earlier registration — the last registration for a scheme wins, matching sync.Map's Store semantics; callers that need register-once should check first with their own bookkeeping.