engine

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Jun 16, 2026 License: Apache-2.0 Imports: 34 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultCachePath = platformDefaultCachePath

DefaultCachePath returns the platform default directory for cached fact groups.

View Source
var DefaultConfigPath = platformDefaultConfigPath

DefaultConfigPath returns the platform default facter-compatible facter.conf path, read when no facts-native config file exists.

View Source
var ErrFactNotFound = errors.New("fact not found")

ErrFactNotFound reports a query that no fact resolved. A fact that resolved to a nil value is found: Value returns (nil, nil) for it.

View Source
var ErrNullByte = errors.New("external fact contains a null byte reference")

ErrNullByte reports an external fact name or value containing a NUL byte.

View Source
var ErrUnknownOS = errors.New("unknown os")

ErrUnknownOS reports that a Ruby host_os value does not map to a Facter OS identifier.

View Source
var NativeDefaultConfigPath = platformNativeDefaultConfigPath

NativeDefaultConfigPath returns the platform default facts-native facts.conf path, consulted before the facter-compatible default.

View Source
var Version = "dev" // ponytail: var, not const, so the build pipeline can inject the git tag

Version is overridden at release time via -ldflags "-X github.com/ncode/facts/internal/engine.Version=<git tag>". The literal below is the dev-build fallback when no tag is injected.

Functions

func BlocklistedFactsForFiltering

func BlocklistedFactsForFiltering(entries []string, configured []FactGroup) map[string]bool

BlocklistedFactsForFiltering expands config blocklist entries for resolver filtering.

func BlocklistedFactsWithGroups

func BlocklistedFactsWithGroups(entries []string, configured []FactGroup) map[string]bool

BlocklistedFactsWithGroups expands config blocklist entries into concrete fact names using the built-in group catalog plus any configured groups.

func Collection

func Collection(facts []ResolvedFact) map[string]any

Collection builds the structured fact tree used when no explicit query is provided.

func CollectionWithDottedFacts

func CollectionWithDottedFacts(facts []ResolvedFact, includeTypedDotted bool) map[string]any

CollectionWithDottedFacts builds the structured fact tree and optionally merges dotted custom and external facts into existing structured facts.

func ConfigBlocklist

func ConfigBlocklist(path string) ([]string, error)

ConfigBlocklist returns fact and group names from a Facter config blocklist.

func ConstructOSHierarchy

func ConstructOSHierarchy(hierarchy []any, searchedOS string) []string

ConstructOSHierarchy returns the Ruby-compatible OS inheritance path for searchedOS.

func CurrentDefaultExternalFactDirs

func CurrentDefaultExternalFactDirs() []string

CurrentDefaultExternalFactDirs returns the default external fact directories (facts-native first, facter-compatible after) for the current process environment.

func CustomValueContainsNullByte

func CustomValueContainsNullByte(value any) bool

CustomValueContainsNullByte reports whether any string within value contains a null byte, which the input contract rejects.

func DefaultExternalFactDirs

func DefaultExternalFactDirs(windows, root bool, home, windowsDataDir string) []string

DefaultExternalFactDirs returns the default external fact directories: the facts-native locations first, then Ruby Facter's compatible locations. Facts found in both follow normal directory precedence.

func DetectOSHierarchy

func DetectOSHierarchy(hierarchy []any, identifier, family string) []string

DetectOSHierarchy returns Ruby's detected OS hierarchy for an identifier.

func DetectOSIdentifier

func DetectOSIdentifier(hostOS, linuxDistroID string) (string, error)

DetectOSIdentifier maps Ruby's RbConfig host_os value to Facter's OS identifier.

func ExternalFactResolutionRunning

func ExternalFactResolutionRunning() bool

ExternalFactResolutionRunning reports whether Facts is already resolving executable external facts in this process tree.

func FactGroupName

func FactGroupName(groups []FactGroup, fact string) (string, bool)

FactGroupName returns the name of the group containing fact.

func FormatFactGroups

func FormatFactGroups(groups []FactGroup) string

FormatFactGroups renders groups in the same YAML-like shape as Ruby Facter.

func FormatHOCON

func FormatHOCON(facts []ResolvedFact) string

FormatHOCON renders facts using Facter's HOCON presentation contract.

func FormatHOCONWithDottedFacts

func FormatHOCONWithDottedFacts(facts []ResolvedFact, includeTypedDotted bool) string

FormatHOCONWithDottedFacts renders HOCON and optionally merges dotted custom and external facts.

func FormatJSON

func FormatJSON(facts []ResolvedFact) (string, error)

FormatJSON renders facts using Facter's JSON presentation contract.

func FormatJSONWithDottedFacts

func FormatJSONWithDottedFacts(facts []ResolvedFact, includeTypedDotted bool) (string, error)

FormatJSONWithDottedFacts renders JSON and optionally merges dotted custom and external facts.

func FormatLegacy

func FormatLegacy(facts []ResolvedFact) string

FormatLegacy renders facts using the original key => value text format.

func FormatLegacyColored

func FormatLegacyColored(facts []ResolvedFact, includeTypedDotted, colorize bool) string

FormatLegacyColored renders legacy text and, when colorize is set, wraps each key in an ANSI color chosen by its nesting depth. The rendering replicates Ruby Facter's LegacyFactFormatter byte for byte: pretty-printed JSON rewritten through Ruby's exact transform pipeline, quirks included.

func FormatYAML

func FormatYAML(facts []ResolvedFact) string

FormatYAML renders facts using Facter's YAML presentation contract.

func FormatYAMLWithDottedFacts

func FormatYAMLWithDottedFacts(facts []ResolvedFact, includeTypedDotted bool) string

FormatYAMLWithDottedFacts renders YAML and optionally merges dotted custom and external facts.

func GroupTTLSeconds

func GroupTTLSeconds(ttls []FactTTL, fact string) (int64, bool)

GroupTTLSeconds returns the configured TTL for fact in seconds.

func NormalizeCustomValue

func NormalizeCustomValue(value any) any

NormalizeCustomValue canonicalizes a custom fact value: time.Time values become RFC 3339 strings and string-keyed maps become map[string]any, so the canonical tree holds only tree-shaped data.

func PuppetPluginFactDirs

func PuppetPluginFactDirs() []string

PuppetPluginFactDirs returns Puppet's default plugin-fact destination (pluginfactdest, vardir/facts.d) paths that exist on this system. Under --puppet these directories are searched for external facts, matching the external-fact half of Ruby Facter's Puppet plugin loading.

func SetDebugHandler

func SetDebugHandler(handler func(string))

SetDebugHandler registers a process-wide debug callback for internal diagnostics.

func SetErrorHandler

func SetErrorHandler(handler func(string))

SetErrorHandler registers a process-wide error callback for internal diagnostics.

func SetWarningHandler

func SetWarningHandler(handler func(string))

SetWarningHandler registers a process-wide warning callback for internal diagnostics.

func ValueForQuery

func ValueForQuery(fact ResolvedFact) any

ValueForQuery returns the value selected by fact.UserQuery from fact.Value.

func WarnPuppetRubyPluginFacts

func WarnPuppetRubyPluginFacts()

WarnPuppetRubyPluginFacts emits the documented --puppet deviation warning when Puppet has synced Ruby plugin custom facts (vardir/lib/facter) that Ruby Facter would have loaded; the Go port does not evaluate Ruby and skips them.

Types

type ConfigOptions

type ConfigOptions struct {
	ExternalDirs       []string
	Debug              bool
	Verbose            bool
	LogLevel           string
	NoExternalFacts    bool
	ForceDotResolution bool
	Sequential         bool
	SequentialSet      bool
}

ConfigOptions contains Facter options loaded from a config file.

func ConfigFileOptions

func ConfigFileOptions(path string) (ConfigOptions, error)

ConfigFileOptions returns supported Facter options from a config file.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine is an immutable unit of fact-discovery configuration. All registration happens at construction; resolution happens only through Discover, and concurrent use is safe because nothing mutates after NewEngine except the once-only diagnostic dedup set, which has its own lock.

func NewEngine

func NewEngine(cfg EngineConfig) (*Engine, error)

NewEngine validates and freezes cfg into an Engine.

func (*Engine) Discover

func (e *Engine) Discover(ctx context.Context, queries ...string) (*Snapshot, error)

Discover runs the configured resolvers and returns an immutable Snapshot of the canonical tree. Query matching follows the CLI's dot-notation semantics.

The Snapshot is valid even when err != nil: discovery failures are partial, and err is the join of every per-source failure (including ctx.Err() when the context ends discovery early). Not-applicable facts are absent, never errors.

type EngineConfig

type EngineConfig struct {
	// ConfigFile opts into reading the given facter.conf, honoring its
	// global.external-dir, no-external-facts toggle, fact blocklists,
	// and cache TTLs with CLI-identical semantics.
	ConfigFile string
	// ExternalDirs opts into loading external facts from exactly these
	// directories (no environment variables, no default directories).
	ExternalDirs []string
	// UseCache opts into the persistent fact cache with facter.conf TTL
	// semantics.
	UseCache bool
	// SystemDefaults selects full CLI-equivalent system-following behavior:
	// the default config file (facts.conf first, facter.conf second),
	// default external fact directories (facts-native locations first), and
	// FACTS_*/FACTER_* environment facts (FACTS_* wins name collisions).
	SystemDefaults bool
	// Logger receives engine diagnostics; nil discards them.
	Logger *slog.Logger
	// Facts are registered facts, fixed at construction.
	Facts []ProgrammaticFact

	// CLICompat selects the CLI's loader and error semantics: FACTS_*/FACTER_*
	// environment facts whenever external facts are on, silent skips for
	// failing external executables, and fail-fast on the first hard source
	// error.
	CLICompat bool
	// NoExternalFacts skips external-fact loading (--no-external-facts).
	NoExternalFacts bool
	// Puppet appends Puppet facts to the core set (--puppet).
	Puppet bool
	// BlockedFacts overrides the config-derived blocklist when non-nil.
	BlockedFacts map[string]bool
}

EngineConfig is the configuration an Engine is frozen from. The zero value is the hermetic default: core facts only — no config file, no fact directories, no script execution, no environment facts, no persistent cache.

type FactCache

type FactCache struct {
	// contains filtered or unexported fields
}

FactCache reads and writes Facter-compatible cached fact groups.

func NewFactCache

func NewFactCache(dir string, ttls []FactTTL, groups []FactGroup) *FactCache

NewFactCache returns a cache using configured TTLs and custom fact groups.

func (*FactCache) CacheFacts

func (fc *FactCache) CacheFacts(facts []ResolvedFact) error

CacheFacts writes resolved facts into configured cache groups.

func (*FactCache) ResolveFacts

func (fc *FactCache) ResolveFacts(searched []ResolvedFact) ([]ResolvedFact, []ResolvedFact)

ResolveFacts returns facts still requiring resolution plus facts loaded from a fresh cache.

type FactGroup

type FactGroup struct {
	Name  string
	Facts []string
}

FactGroup is a named set of facts used by Facter's block/cache group CLI.

func BuiltinFactGroups

func BuiltinFactGroups() []FactGroup

BuiltinFactGroups returns the static fact group catalog for the Go port.

func ConfigFactGroups

func ConfigFactGroups(path string) ([]FactGroup, error)

ConfigFactGroups returns configured fact groups from facter.conf.

func ExternalFactGroups

func ExternalFactGroups(dirs []string) ([]FactGroup, error)

ExternalFactGroups returns fact group entries for loadable external fact files.

func MergeFactGroups

func MergeFactGroups(defaults, configured []FactGroup) []FactGroup

MergeFactGroups returns defaults with configured groups replacing same-name defaults.

type FactTTL

type FactTTL struct {
	Fact string
	TTL  string
}

FactTTL is a configured cache duration for a fact or fact group.

func ConfigTTLs

func ConfigTTLs(path string) ([]FactTTL, error)

ConfigTTLs returns configured cache TTLs from the facts section.

type FormatOptions

type FormatOptions struct {
	JSON  bool
	YAML  bool
	HOCON bool
}

FormatOptions selects the presentation format for resolved facts.

type Formatter

type Formatter interface {
	Name() string
	Format([]ResolvedFact) (string, error)
}

Formatter renders resolved facts in one presentation format.

func BuildFormatter

func BuildFormatter(opts FormatOptions) Formatter

BuildFormatter selects a formatter using Ruby's formatter factory precedence.

type ProgrammaticFact

type ProgrammaticFact struct {
	Name    string
	Resolve func(ctx context.Context) (any, error)
}

ProgrammaticFact is a fact registered on an Engine at construction. A nil Resolve registers a fact that resolves to nil. The resolved value is normalized like every registered fact value (times to RFC 3339, string-keyed maps to map[string]any); values containing null bytes are rejected with a warning and resolve to nil.

type ResolvedFact

type ResolvedFact struct {
	Name      string
	Value     any
	UserQuery string
	Type      string
	File      string
}

ResolvedFact is a fact value after resolution and before presentation.

func CoreFacts

func CoreFacts(s *Session) []ResolvedFact

CoreFacts returns the small cross-platform fact set used by the initial Go CLI.

func CoreFactsWithRuby

func CoreFactsWithRuby(s *Session, includeRuby bool) []ResolvedFact

CoreFactsWithRuby returns core facts, optionally omitting facts that require Ruby.

func FilterBlockedFacts

func FilterBlockedFacts(facts []ResolvedFact, blocked map[string]bool) []ResolvedFact

FilterBlockedFacts removes facts whose root name is blocklisted.

func LoadExternalFacts

func LoadExternalFacts(s *Session, dirs []string) ([]ResolvedFact, error)

LoadExternalFacts loads static external facts from the provided directories.

func LoadExternalFactsFromDirs

func LoadExternalFactsFromDirs(s *Session, dirs []string, blocked map[string]bool) ([]ResolvedFact, error)

LoadExternalFactsFromDirs loads external facts from exactly the given directories — no environment variables — returning every fact that loaded together with the per-source failures joined. Library engines use this to keep opted-in sources hermetic and discovery failures partial.

func LoadExternalFactsWithBlocklist

func LoadExternalFactsWithBlocklist(s *Session, dirs []string, blocked map[string]bool) ([]ResolvedFact, error)

LoadExternalFactsWithBlocklist loads external facts from dirs plus the FACTS_*/FACTER_* environment variables — the CLI's system-following semantics — skipping files whose base name is blocklisted by the Facter config.

func PuppetFacts

func PuppetFacts() []ResolvedFact

PuppetFacts returns facts discovered from an installed Puppet executable.

func Select

func Select(facts []ResolvedFact, queries []string) []ResolvedFact

Select returns resolved facts for the user-provided queries.

func SelectWithDottedFacts

func SelectWithDottedFacts(facts []ResolvedFact, queries []string, includeTypedDotted bool) []ResolvedFact

SelectWithDottedFacts returns resolved facts and optionally merges dotted custom and external facts into structured facts for partial queries.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session carries the state of one resolution run: memoized host probes and resolution-scoped caches. Resolvers share a Session so facts derived from the same probe agree within a run; a fresh Session re-reads the host, which is how discovery stays current and how independent engines stay isolated.

func NewSession

func NewSession() *Session

NewSession returns an empty Session; probes run on first use.

func NewSessionContext

func NewSessionContext(ctx context.Context) *Session

NewSessionContext returns an empty Session whose command executions and metadata requests are bound to ctx.

func (*Session) Context

func (s *Session) Context() context.Context

Context returns the context this session's resolution work runs under.

type Snapshot

type Snapshot struct {
	// contains filtered or unexported fields
}

Snapshot is the immutable result of one discovery run: the canonical tree plus pure query operations over it. Safe for concurrent use.

func (*Snapshot) All

func (sn *Snapshot) All() iter.Seq2[string, any]

All iterates the top-level canonical-tree entries in sorted name order. Yielded values are copies; mutating them does not affect the Snapshot.

func (*Snapshot) Facts

func (sn *Snapshot) Facts() []ResolvedFact

Facts returns the resolved facts backing the Snapshot, for the CLI's formatter pipeline.

func (*Snapshot) Tree

func (sn *Snapshot) Tree() map[string]any

Tree returns a copy of the canonical tree. Mutating the returned value does not affect the Snapshot.

func (*Snapshot) Value

func (sn *Snapshot) Value(query string) (any, error)

Value returns the canonical-tree node selected by the dot-notation query — the same value the CLI reports for the same query. A query no fact resolved returns an error satisfying errors.Is(err, ErrFactNotFound); a custom or external fact that legitimately resolved to nil returns (nil, nil).

Jump to

Keyboard shortcuts

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