selector

package
v0.1.0-dev.20260930194506 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 30, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

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

View Source
var Builtins = []string{"OS", "DISTRO", "ARCH"}

Builtins are the segment names detection supplies. No declared segment may use one.

Functions

func DistroWord

func DistroWord(id string) string

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

func OSWord(goos string) string

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

func ValidateSegments(segments []Segment) error

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

func NewHost(goos, goarch string, release OSRelease) Host

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

func NewHostFromWords(os, distro string, lineage []string, arch string) Host

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

func ParseOSRelease(r io.Reader) (OSRelease, error)

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

func ReadOSRelease(paths ...string) (OSRelease, bool)

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.

func (Rank) Compare

func (r Rank) Compare(other Rank) int

Compare orders two ranks: project, then the OS word's depth, then the architecture, then each extra in configured order.

Parameters:

  • `other`: the rank to compare with.

Returns:

  • `int`: negative when r is applied before other, positive when after, 0 when they rank alike.

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
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL