Documentation
¶
Overview ¶
Package resolve handles import resolution and lock file management.
Resolves import paths (bare URLs, with // subdirs, local ./ paths) to concrete sources. Detects whether each import is a UB library (it has UB files at the root) or a Go library. Detects cycles at resolve time and reports them as compile errors. Enforces same-repo imports sharing a version.
Reads and writes dependency locks - pins git commits and content hashes per import for reproducible compiles.
Index ¶
- Variables
- func ContainsFactorySource(s *Source) bool
- func ExtractImports(f *lang.File) (map[string]ImportRef, []error)
- func IsUBLibrary(s *Source) bool
- func LocalGoImportError(alias, path string, source *Source) error
- func SplitRepoSubdir(s string) (url, subdir string, err error)
- func UBKey(ref ImportRef) string
- func ValidateCompositeBody(kind, typeName string, f *lang.File) []error
- func WithDefaultScheme(url string) string
- type ImportRef
- type LocalImport
- type LocalResolver
- type RemoteImport
- type RemoteResolver
- type Resolution
- type ResolutionKind
- type Resolver
- type Source
- type SyntaxImport
- type UBLibrary
- type UBVisitor
Constants ¶
This section is empty.
Variables ¶
var ErrEmptyImportRef = errors.New("empty import reference")
ErrEmptyImportRef is returned when the source string is empty.
Functions ¶
func ContainsFactorySource ¶
ContainsFactorySource reports whether s has a root file that declares a runnable factory instead of an importable library.
func ExtractImports ¶
ExtractImports walks the `imports:` block of f and parses each value into an ImportRef. Returns a map of alias to ref plus any per-import parse errors. Shape problems with the block itself are reported by `lang.ValidateImports` and silently skipped here so the two passes don't both report the same errors.
func IsUBLibrary ¶
IsUBLibrary reports whether s is a UB-implemented library: a directory with at least one source-declared composite export and no factory source. Manifest and lock files do not make a package importable by themselves. A malformed non-metadata `.ub` file is treated as a UB library candidate so the library parser can return the source diagnostic.
func LocalGoImportError ¶ added in v0.6.0
LocalGoImportError explains why a local import did not resolve to a UB library. When the local source is a Go module (it has a go.mod), a path import cannot work -- a Go library becomes a go.mod require, which needs a module path -- so the error shows how to import it by module path and replace it with the local path, naming the file each entry belongs in.
func SplitRepoSubdir ¶ added in v0.6.0
SplitRepoSubdir separates a repo URL from its optional subdir at the `//` separator. Without `//`, the whole input is the URL and there is no subdir.
func UBKey ¶
UBKey is the dedup key for a UB-library import. Remote imports key on URL, subdir, and version; the `//<subdir>` segment is included only when the import names a subdirectory, so root-of-repo refs read cleanly in cycle errors and other diagnostics. Local imports key on path.
func ValidateCompositeBody ¶
ValidateCompositeBody checks a composite body against the floor and ceiling rules for its kind, which comes from the file's `<kind>-` name prefix:
- data: at least one output, may hold data, no resources, no actions.
- action: at least one action, may hold data, no resources; outputs are optional.
- resource: at least one resource, may hold data and actions; outputs are optional.
typeName names the composite in the messages. Returns one error per violated rule, in a fixed order, so a body reports every problem at once. The resolver does not run this during the walk; the compile command runs it over each resolved library so that print-graph and fetch stay lenient.
func WithDefaultScheme ¶ added in v0.6.0
WithDefaultScheme prepends `https://` to a bare URL like `github.com/owner/repo` so go-git knows to fetch it over HTTPS. URLs that already include a scheme (`https://`, `http://`, `ssh://`, `file://`, ...) or look like SCP-style ssh (`user@host:path`) or look like a filesystem path are left alone.
Types ¶
type ImportRef ¶
type ImportRef interface {
// contains filtered or unexported methods
}
ImportRef is a parsed value from an `imports:` block.
func ParseImportRef ¶
ParseImportRef parses a string from an `imports:` block. Local imports start with `.` or `/`; remote imports name a repo URL and use the Terraform-style `//` separator to denote a subdirectory within the repo. Without `//` the whole string is the repo URL and the import has no subdir.
type LocalImport ¶
type LocalImport struct {
Path string
}
LocalImport names a sibling on the operator's filesystem. Local imports do not have pinned versions; their content is whatever the developer has at the path now. Compile from a clean checkout to make the result reproducible.
type LocalResolver ¶
type LocalResolver struct {
Root string
}
LocalResolver resolves *LocalImport refs against a working directory root. Relative paths in the import are joined to Root.
func NewLocalResolver ¶
func NewLocalResolver(root string) *LocalResolver
NewLocalResolver returns a LocalResolver rooted at root. Pass the directory containing the factory or library files that own the imports.
type RemoteImport ¶
RemoteImport names an importable repo by host + owner/name and an optional subdir within the repo. The import string has no version; Version is filled in from lock.ub as the walk descends.
type RemoteResolver ¶
type RemoteResolver struct {
CacheRoot string
}
RemoteResolver resolves *RemoteImport refs by fetching the named git repo at the requested constraint, caching the working tree under CacheRoot, and exposing the requested subdir as a Source.
CacheRoot is the directory holding `imports/<host>/<path>/<commit>/`. `NewRemoteResolver` defaults it to `<user-cache-dir>/unobin`.
func NewRemoteResolver ¶
func NewRemoteResolver() (*RemoteResolver, error)
NewRemoteResolver returns a RemoteResolver with CacheRoot set to the user's cache directory (XDG_CACHE_HOME or its platform default) joined with `unobin`.
func (*RemoteResolver) CleanImports ¶ added in v0.6.0
func (r *RemoteResolver) CleanImports() (string, error)
CleanImports removes the cached import sources and returns the directory that was removed. It is a no-op when nothing is cached.
func (*RemoteResolver) ImportsDir ¶ added in v0.6.0
func (r *RemoteResolver) ImportsDir() string
ImportsDir is the directory holding cached import sources, a sibling of the toolchain cache under CacheRoot.
type Resolution ¶
type Resolution struct {
Kind ResolutionKind
LocalAlias string
Ref ImportRef
Path string
Version string
CanonicalKey string
SourcePath string
}
Resolution describes one import after the walker reaches it. For Go imports, Path is the canonical Go-import path (URL plus subdir when present) and Version is the pinned version. For UB imports, CanonicalKey is the dedup key (see UBKey) and visitors look up their per-library state by that key. SourcePath is the on-disk directory where the resolver fetched the import, useful for compile-time inspection.
func WalkUB ¶
func WalkUB( refs map[string]ImportRef, resolver Resolver, v UBVisitor, versions map[string]string, ) ([]Resolution, error)
WalkUB walks refs and every UB library they transitively reach, invoking the visitor for each import. The returned slice mirrors refs in resolved form, alias-sorted, so callers can build their own alias-to-resolution map without per-site visitor callbacks. Cycles through UB libraries are reported as errors.
versions maps a repository URL to the version selected for it in the lock; every remote import is walked at its repository's selected version. A remote import whose repository is not in the map has no version and is an error: the lock must supply it.
type ResolutionKind ¶
type ResolutionKind int
ResolutionKind tags how an import was resolved.
const ( // ResolutionGo names a Go-library import: a remote ref whose resolved // source is not a UB library. ResolutionGo ResolutionKind = iota + 1 // ResolutionUB names a UB-library import: a ref whose resolved source // has importable UB files at its root. ResolutionUB )
type Resolver ¶
Resolver turns an ImportRef into a Source. Implementations cover one kind of import each (local filesystem, remote git, etc.); callers dispatch by type-switching on the ref.
type Source ¶
Source is the file tree of a resolved import, rooted at the import's subdirectory, or the repo root when there is no subdir. For remote imports, Commit and Hash record the resolved git commit and a content hash so the lock file can pin reproducibility. Local imports leave both empty since their content is whatever the developer has now. Path is the on-disk directory the source was fetched into, which the dev CLI uses for compile-time inspection of Go-library source.
type SyntaxImport ¶
SyntaxImport is one parsed import from a typed syntax file.
func ExtractSyntaxImports ¶
func ExtractSyntaxImports(f *syntax.File) ([]SyntaxImport, []error)
ExtractSyntaxImports walks a typed syntax file and parses every import.
type UBLibrary ¶
type UBLibrary struct {
Bodies map[string]map[string]*lang.File
BodyImports map[string]map[string][]Resolution
}
UBLibrary has everything the visitor needs about a UB library the first time the walker reaches it. Bodies maps node kind and composite name to the parsed body file; the name comes from a source-declared composite declaration. BodyImports maps the same kind and name to the resolved imports declared by that body, in alias-sorted order so callers see a stable view across runs.
type UBVisitor ¶
type UBVisitor interface {
// OnGoImport is called for every site whose import resolves to a
// Go library. May fire multiple times with the same path when the
// same library is imported from several sites; visitors that need
// uniqueness dedup themselves.
OnGoImport(alias, path, version string) error
// OnUBLibrary is called once per canonical key. alias is the local
// alias of whichever site first reached the library (which matters
// when the visitor names a directory or package after it).
OnUBLibrary(alias, canonicalKey string, ref ImportRef, lib *UBLibrary) error
}
UBVisitor is implemented by callers that want to consume the walked import graph. The walker invokes its methods as it descends.