Documentation
¶
Overview ¶
Package selector detects the host and selects directory names by platform: the one selector API writ and lore share (#944).
A name reads, in order, `[<project>][.<os>][.<arch>][.<extra>...]`. The OS part is one word of the host's chain (Unix, Linux, a distribution in its lineage), the architecture part one spelling of its architecture (arm64 or aarch64), and each extra one value of a segment declared in configuration, in configured order. Selection answers which of a list of names this machine includes, in the order to apply them, and reports every name that breaks the grammar. docs/guides/selectors.md is the design.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var Builtins = []string{"OS", "DISTRO", "ARCH"}
Builtins are the segment names detection supplies. No declared segment may use one.
Functions ¶
func DistroWord ¶
DistroWord spells an os-release ID as a selector word.
Parameters:
- `id`: the ID, lowercase, as os-release gives it: ubuntu, rhel, linuxmint.
Returns:
- `string`: the word the table gives (Ubuntu, RHEL, Mint), or, for an ID the table doesn't list, the ID with its first letter uppercased (pop gives Pop).
func OSWord ¶
OSWord spells an operating system as a selector word.
Parameters:
- `goos`: the operating system, as runtime.GOOS names it: darwin, linux, windows.
Returns:
- `string`: the word the table gives (Darwin, Linux, Windows, FreeBSD), or, for another operating system, its name with the first letter uppercased.
func ValidateSegments ¶
ValidateSegments checks declared segments: names unique and none a built-in; values unique across every segment and none a word of the OS or architecture parts; each current value one of its segment's values.
Values must be unique because a name carries values, never segment names, so a value is attributed to the only part whose vocabulary holds it.
Parameters:
- `segments`: the declared segments, in configured order.
Returns:
- `error`: every problem found, joined; nil when there is none.
Types ¶
type GrammarError ¶
type GrammarError struct {
// Name is the directory name.
Name string
// Word is the word that breaks the grammar.
Word string
// Violation is the rule the word breaks.
Violation Violation
// Part is the part the word belongs to; empty for an unknown word.
Part string
}
GrammarError is a name that breaks the grammar. The caller refuses the run, naming every one.
func (*GrammarError) Error ¶
func (e *GrammarError) Error() string
Error describes the name, the word, and the rule it breaks.
Returns:
- `string`: the description.
type Host ¶
type Host struct {
// OS is the operating system's word: Linux, Darwin, Windows.
OS string
// Distro is the distribution's word, from os-release's ID: Ubuntu. Empty off Linux, and on a Linux host whose
// os-release names no distribution.
Distro string
// Lineage is the words of the distributions Distro is like, most general first: os-release's ID_LIKE reversed.
// Ubuntu's is Debian.
Lineage []string
// Chain is the OS part's words, most general first. On Linux it follows the lineage the distribution states in
// os-release: Unix, Linux, ID_LIKE reversed, then ID, so Ubuntu's is Unix, Linux, Debian, Ubuntu.
Chain []string
// Arch is the architecture, as runtime.GOARCH names it: arm64, amd64.
Arch string
}
Host is what a selector word can name on one machine: its operating system and that system's lineage, and its architecture.
func Detect ¶
func Detect() Host
Detect describes this machine.
Detection has no side effects and never fails: an os-release it cannot read means "Linux, distribution unknown", and the chain stops at Linux.
Returns:
- `Host`: this machine.
func NewHost ¶
NewHost describes a machine from its operating system, architecture and os-release.
Parameters:
- `goos`: the operating system, as runtime.GOOS names it.
- `goarch`: the architecture, as runtime.GOARCH names it.
- `release`: the machine's os-release; the zero value when it has none. Read only on Linux.
Returns:
- `Host`: the machine.
func NewHostFromWords ¶
NewHostFromWords describes a machine from its words: the ones a user states when overriding detection, or a test states to describe a machine it isn't running on.
Parameters:
- `os`: the operating system's word: Linux.
- `distro`: the distribution's word: Ubuntu. Empty for none.
- `lineage`: the words of the distributions it is like, most general first: Debian. Ignored when distro is empty.
- `arch`: the architecture, in either spelling: arm64 or aarch64.
Returns:
- `Host`: the machine. Its chain is Unix when the OS is a Unix, the OS, then the lineage and the distribution, each word once, at its most specific position.
type OSRelease ¶
type OSRelease struct {
// ID is the distribution's identifier, lowercase: ubuntu, debian, rhel. Empty when the file has none.
ID string
// IDLike lists the distributions this one is like, closest first: Rocky's is rhel, centos, fedora.
IDLike []string
// VersionID is the distribution's version: 26.04.
VersionID string
// VariantID names a variant of the distribution: server, workstation.
VariantID string
}
OSRelease holds the os-release fields selection and package-manager detection read.
os-release is the freedesktop.org specification that virtually every current Linux distribution ships. ID names the distribution; ID_LIKE is the distribution's own statement of its lineage, closest first.
func ParseOSRelease ¶
ParseOSRelease reads os-release content.
Each line is KEY=VALUE. A value may be bare, in double quotes, where a backslash escapes the character after it, or in single quotes, which take everything literally. Blank lines and lines that begin with # are ignored.
Parameters:
- `r`: the content.
Returns:
- `OSRelease`: the fields read; a field the content doesn't carry is empty.
- `error`: non-nil when r cannot be read.
func ReadOSRelease ¶
ReadOSRelease reads the first os-release file of the paths given that can be read.
Parameters:
- `paths`: the files to try, in order; `/etc/os-release` then `/usr/lib/os-release` when none is given.
Returns:
- `OSRelease`: the fields read.
- `bool`: false when no file could be read, which on Linux means the distribution is unknown.
type Rank ¶
type Rank struct {
// Project is the project's position in the order projects are applied.
Project int
// Link is the OS word's position in the host's chain, most general first; 0 when the name has no OS word.
Link int
// Arch reports whether the name names the architecture.
Arch bool
// Extras reports, for each segment in configured order, whether the name names it.
Extras []bool
}
Rank orders the names a selection includes. Compare it field by field, in field order.
type Segment ¶
type Segment struct {
// Name is the segment's name: ROLE.
Name string
// Values are the values it may take: desktop, server. A directory name carries one of them.
Values []string
// Value is this machine's value; empty when unset, and then the segment matches no name.
Value string
}
Segment is an extra segment, declared in configuration with the values it may take.
type Selected ¶
type Selected struct {
// Name is the directory name.
Name string
// Project is the project it begins with; empty when names carry no project.
Project string
// Rank is its place in the order of application.
Rank Rank
}
Selected is a name a selection includes.
type Selector ¶
type Selector struct {
// Host is the machine selected for.
Host Host
// Projects are the projects a name may begin with, in the order they're applied: writ's names carry one. Empty when
// names carry no project, as lore's don't.
Projects []string
// Base is the name with no selector words, when names carry no project: lore's Common.
Base string
// Segments are the extras, in configured order.
Segments []Segment
}
Selector selects directory names for one host.
func (Selector) Select ¶
func (s Selector) Select(names []string) ([]Selected, []*GrammarError)
Select chooses the names this machine includes, in the order to apply them, and finds every name that breaks the grammar.
A name is included when each of its words names this machine: its OS word is in the host's chain, its architecture is the host's, and each extra's value is the segment's current value. A well-formed name for another machine is excluded silently. The order is the projects' order, then the platform ranking within each project: the OS word's depth in the chain, then the architecture, then each extra in configured order, each part narrowing the one to its left; then the name, so the order never depends on the order names were listed in.
Parameters:
- `names`: directory names.
Returns:
- `[]Selected`: the names included, in the order to apply them; the last applied wins.
- `[]*GrammarError`: every name that breaks the grammar. A caller refuses the run when there is one.
type Violation ¶
type Violation int
Violation is a rule of the grammar a name breaks.
const ( // UnknownWord is a word no part's vocabulary holds: a misspelling, or a distribution the table doesn't know. UnknownWord Violation = iota + 1 // OutOfOrder is a word whose part comes before a part the name has already named. OutOfOrder // RepeatedPart is a second word for one part: two OS words, two architectures, or two values of one segment. RepeatedPart )