Documentation
¶
Overview ¶
Package deps models a factory's dependencies. It reads manifest.ub, which lists each direct dependency and the lowest version the factory accepts for it, and drives pkg/resolve to fetch them.
Index ¶
- Constants
- func EncodeManifest(m *Manifest) []byte
- func EncodeSourceLock(lock *Lock) ([]byte, error)
- func FindManifestDir(start string) (string, error)
- func Highest(vs []string) string
- func ImportedRepos(root string) (map[Dependency]bool, error)
- func Resolve(root *Manifest, fetch Fetcher) (map[Dependency]string, error)
- func ResolveVersion(dep Dependency, query string, tags []string) (string, error)
- func Verify(lock *Lock, resolver resolve.Resolver) ([]string, error)
- func Versions(dep Dependency, tags []string) []string
- func WriteManifest(path string, m *Manifest) error
- func WriteSourceLock(path string, lock *Lock) error
- type Dependency
- type Fetcher
- type Lock
- type LockKind
- type LockedDep
- type Manifest
- type Selection
Constants ¶
const CurrentLockVersion = 1
CurrentLockVersion is the schema version this package reads and writes. A different version errors on read, since this build cannot guarantee a correct interpretation.
const ManifestFileName = "manifest.ub"
ManifestFileName is the dependency manifest filename.
const SourceLockFileName = "lock.ub"
SourceLockFileName is the dependency lock filename.
Variables ¶
This section is empty.
Functions ¶
func EncodeManifest ¶ added in v0.6.0
EncodeManifest renders a parseable manifest.ub draft.
func EncodeSourceLock ¶
EncodeSourceLock serializes lock as canonical lock.ub source.
func FindManifestDir ¶ added in v0.6.0
FindManifestDir walks up from start to the nearest ancestor directory holding a manifest and returns that directory: the root of the project that governs start. start may be any path inside the project, a directory or a file. It stops at the filesystem root and returns an error wrapping fs.ErrNotExist when no manifest is found.
func Highest ¶ added in v0.6.0
Highest returns the greatest version in vs by semver order, or "" when vs is empty.
func ImportedRepos ¶ added in v0.6.0
func ImportedRepos(root string) (map[Dependency]bool, error)
ImportedRepos scans every .ub file under root and returns the set of repositories named by remote imports. The version on an import is not read here: a repository's version floor lives in manifest.ub, not in the import string. Local imports are intra-project and contribute no repository. Hidden directories (a leading dot, such as .git) are skipped.
func Resolve ¶ added in v0.6.0
func Resolve(root *Manifest, fetch Fetcher) (map[Dependency]string, error)
Resolve runs minimal version selection over the dependency graph rooted at a manifest. It selects the highest floor for each dependency, fetches it at that version to read its own requirements, and repeats until the selection stops changing. A dependency whose version is later raised is re-fetched, since a higher version may declare different requirements; the walk terminates at any dependency with no manifest. The result maps each dependency to its selected version -- the lock, keyed per imported library, is built separately by the import walk.
func ResolveVersion ¶ added in v0.6.0
func ResolveVersion(dep Dependency, query string, tags []string) (string, error)
ResolveVersion turns a `deps get` query into a concrete version of dep, chosen among the repository's tags. An empty query or "latest" picks the highest available version; a full version (vX.Y.Z) is used as-is once confirmed present; a partial version (v1 or v1.2) picks the highest available version under that prefix.
func Verify ¶ added in v0.6.0
Verify re-fetches every ub-kind dependency in lock at its pinned commit and checks the content hash against the recorded one. A mismatch means the source changed under a pinned commit. Go dependencies are skipped: their integrity rides the generated go.sum, not a content hash here. It returns one message per dependency whose hash no longer matches, in id order.
func Versions ¶ added in v0.6.0
func Versions(dep Dependency, tags []string) []string
Versions returns the versions of dep found among a repository's tags, in increasing semver order. A tag qualifies only when it carries dep's prefix and the remainder is a valid semver string, so tags for other subdirectories and non-semver tags are ignored. The prefix is stripped: each returned element is a bare version, the form a manifest records.
func WriteManifest ¶ added in v0.6.0
WriteManifest serializes m as canonical manifest.ub source and atomically replaces the file at path.
func WriteSourceLock ¶
WriteSourceLock serializes lock as canonical lock.ub source and atomically replaces the file at path.
Types ¶
type Dependency ¶
Dependency identifies an importable unit by its repository URL and an optional subdirectory within that repository. It is the manifest's notion of "a dependency"; a resolved version (a git tag) is paired with it elsewhere, not stored on the identity.
func ParseDependency ¶ added in v0.6.0
func ParseDependency(id string) (Dependency, error)
ParseDependency parses a dependency id of the form `repo-url` or `repo-url//subdir`, the same `//` separator imports use but without a trailing `@version`.
func (Dependency) String ¶ added in v0.6.0
func (d Dependency) String() string
String renders the dependency back to its id form, the inverse of ParseDependency.
func (Dependency) Tag ¶ added in v0.6.0
func (d Dependency) Tag(version string) string
Tag returns the git tag that names a version of this dependency: the bare version for a repo-root dependency, or `<subdir>/<version>` for a subdirectory dependency.
func (Dependency) TagPrefix ¶ added in v0.6.0
func (d Dependency) TagPrefix() string
TagPrefix returns the git tag prefix for this dependency. A subdirectory dependency uses `<subdir>/` (the monorepo convention Go submodules also follow); a repo-root dependency uses no prefix.
type Fetcher ¶ added in v0.6.0
type Fetcher interface {
Fetch(dep Dependency, version string) (*Manifest, error)
}
Fetcher fetches a dependency's manifest at a selected version, for the version walk. It returns nil when the dependency declares no manifest: a leaf with no further dependencies, such as a Go library or a UB library that imports nothing remote.
func NewFetcher ¶ added in v0.6.0
NewFetcher returns a Fetcher that reads dependency manifests through resolver. It is the production Fetcher behind unobin deps; tests pass a fake resolver.
type Lock ¶ added in v0.6.0
Lock is the on-disk schema for the dependency lock. It pins the full resolved set so compiles are reproducible without re-running selection. Deps is keyed by dependency id (a repo URL with an optional `//subdir`), the same form a manifest `requires:` key uses.
func DecodeSourceLock ¶
DecodeSourceLock parses a grammar-first lock.ub from bytes.
func LockFromImports ¶ added in v0.6.0
func LockFromImports( rootFS fs.FS, selection map[Dependency]string, resolver resolve.Resolver, replace map[Dependency]string, ) (*Lock, error)
LockFromImports builds the lock for the project rooted at rootFS. It walks every .ub file under the root -- factory.ub, library files at the root, or libraries in subdirectories -- and through remote UB libraries their imports too. Each remote library becomes one lock entry, keyed by `repo//subdir`. Local imports are not locked and need no following: the walk already visits every file under the root, so a local library's own imports are reached directly. A library's version is its repository's selected version; a repository the selection does not cover is an error (it is imported but no floor reached it). Kind and content hash come from the fetched library subtree, so a Go library and a UB library in the same repo are recorded distinctly. A repository named in replace is read from its local path and never locked; a replaced UB library's own remote dependencies are still walked.
func NewLock ¶ added in v0.6.0
func NewLock() *Lock
NewLock returns an empty lock at the current schema version.
func ReadLock ¶ added in v0.6.0
ReadLock reads and parses lock.ub from fsys. A missing file returns an error wrapping fs.ErrNotExist, which callers can detect with errors.Is.
func (*Lock) RepoVersions ¶ added in v0.6.0
RepoVersions maps each repository to its selected version, derived from the per-library entries (every library of a repo shares its version). Compile feeds this to the import walk so versionless imports resolve at the locked version.
type LockKind ¶ added in v0.6.0
type LockKind string
LockKind records how a locked dependency's integrity is guaranteed: a `ub` dependency holds a content hash of its source tree, while a `go` dependency rides the generated module's go.sum and records only a commit.
type LockedDep ¶ added in v0.6.0
LockedDep is one resolved dependency. Version is the selected git tag; the floor lives in the manifest and is never copied here. Hash is the source-tree content hash for `ub` dependencies and is omitted for `go`.
type Manifest ¶ added in v0.6.0
type Manifest struct {
UnobinVersion string
Requires map[Dependency]string
Replace map[Dependency]string
}
Manifest is a parsed dependency manifest. Requires maps each direct dependency to the lowest version (a git tag) the factory accepts for it; resolution may select a higher one to satisfy the whole set. The factory's own version is its git tag, not recorded here. Replace maps a dependency's URL to a local path: the resolver reads that dependency from the path instead of fetching it, and the dependency needs no floor or lock entry. UnobinVersion, when set, pins the toolchain: only a CLI of exactly that version compiles the project, since the unobin runtime is not a dependency whose version resolution selects.
type Selection ¶ added in v0.6.0
type Selection struct {
// contains filtered or unexported fields
}
Selection performs minimal version selection incrementally. Add records that some manifest requires a dependency at a floor version, and Selection keeps the highest floor seen for each dependency -- Go's max-of-minimums. A walker feeds it every requirement across the dependency graph; the highest floor per dependency is the selected version. Floors must be valid semver, which the manifest reader guarantees.
func NewSelection ¶ added in v0.6.0
func NewSelection() *Selection
NewSelection returns an empty Selection.
func (*Selection) Add ¶ added in v0.6.0
func (s *Selection) Add(dep Dependency, floor string) bool
Add records a required floor for dep and reports whether it raised the selected version: true the first time dep is seen, or when floor is higher than the current selection. A walker uses the result to decide whether it must read dep's manifest at the new version, since a higher version may declare different requirements.
func (*Selection) Chosen ¶ added in v0.6.0
func (s *Selection) Chosen() map[Dependency]string
Chosen returns a copy of the selected version for every dependency added so far.
func (*Selection) Version ¶ added in v0.6.0
func (s *Selection) Version(dep Dependency) string
Version returns the selected version for dep, or "" if dep has not been added.