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 ExtractSyntaxBodyImports(body syntax.FactoryBody) (map[string]ImportRef, []error)
- func GitRef(ref *RemoteImport) string
- func HasCompositeExports(s *Source) bool
- func HashTree(fsys fs.FS) (string, error)
- func IsGoLibrary(s *Source) bool
- 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 ValidateGoModulePath(r *RemoteImport, modulePath string) error
- func ValidateSyntaxCompositeBody(kind, typeName string, body syntax.FactoryBody) []error
- func WithDefaultScheme(url string) string
- type CompositeEntry
- type ContextResolver
- 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 ExtractSyntaxBodyImports ¶
func ExtractSyntaxBodyImports(body syntax.FactoryBody) (map[string]ImportRef, []error)
ExtractSyntaxBodyImports parses the imports declared by a typed factory body.
func GitRef ¶
func GitRef(ref *RemoteImport) string
GitRef returns the first git ref used to fetch ref.
func HasCompositeExports ¶
HasCompositeExports reports whether s has source-declared composite exports.
func HashTree ¶
hashTree returns a stable sha256 of the file tree rooted at fsys. Files are walked in sorted order; per file, the hash absorbs the path, the size, and the body. Directories themselves contribute no bytes - the file paths carry the structure. HashTree returns a stable sha256 of a source tree.
func IsGoLibrary ¶
IsGoLibrary reports whether s looks like a Go library package or module.
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 ValidateGoModulePath ¶
func ValidateGoModulePath(r *RemoteImport, modulePath string) error
ValidateGoModulePath checks a discovered Go module path against a remote import version.
func ValidateSyntaxCompositeBody ¶
func ValidateSyntaxCompositeBody(kind, typeName string, body syntax.FactoryBody) []error
ValidateSyntaxCompositeBody checks a typed composite body against the requirements for its declared kind.
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 CompositeEntry ¶
type CompositeEntry struct {
Kind string
Name string
SyntaxBody syntax.FactoryBody
}
type ContextResolver ¶
ContextResolver resolves an import from the package source that declared it.
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.
func (*LocalResolver) Resolve ¶
func (r *LocalResolver) Resolve(ref ImportRef) (*Source, error)
Resolve implements Resolver. The ref must be a *LocalImport; remote refs return an error so a misrouted call is reported clearly.
func (*LocalResolver) ResolveFrom ¶
func (r *LocalResolver) ResolveFrom(ref ImportRef, parent *Source) (*Source, error)
ResolveFrom resolves local refs relative to the package that declared them. Remote refs still return an error because LocalResolver handles only local filesystem paths.
type RemoteImport ¶
type RemoteImport struct {
URL string
Subdir string
ProjectSubdir string
PackageSubdir string
Version string
}
RemoteImport names an importable repo by host + owner/name and an optional package subdir within the repo. The import string has no version; Version is filled in from lock.ub as the walk descends. ProjectSubdir and PackageSubdir are set after manifest or lock lookup when the owning project differs from the imported package.
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
ModulePath string
ModuleRootPath string
GoImportPath 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 ¶
type Source struct {
FS fs.FS
Path string
Commit string
Hash string
ProjectFS fs.FS
ProjectPath string
ProjectSubdir string
PackageSubdir string
ModuleRootPath string
ModulePath string
GoImportPath string
}
Source is the file tree of a resolved import, rooted at the imported package directory. 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 package directory the dev CLI uses for compile-time inspection of Go-library source.
func ResolveLocalSource ¶
func ResolveLocalSource(li *LocalImport, parent *Source) (*Source, error)
ResolveLocalSource resolves a local import from the package source that declared it. On-disk sources resolve through their Path; virtual sources resolve paths that stay within their fs.FS root.
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 {
SyntaxBodies map[string]map[string]syntax.FactoryBody
BodyImports map[string]map[string][]Resolution
}
UBLibrary has everything the visitor needs about a UB library the first time the walker reaches it. SyntaxBodies maps node kind and composite name to typed source declarations. 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.
func (*UBLibrary) CompositeEntries ¶
func (l *UBLibrary) CompositeEntries() []CompositeEntry
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, modulePath, 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.