profile

package
v0.17.1 Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package profile loads and selects modules from a profile.

Index

Constants

View Source
const (
	ScopeUser   = "user"
	ScopeSystem = "system"
)

Scope values for ModuleConfig.Scope. Scope is module-level: it decides whether the module's dotfiles are applied as the invoking user (into ~/) or with root privileges (into /etc and other system paths).

View Source
const FilterReason = "module filter"

FilterReason is the Skip.Reason stamped on modules excluded by the positional module filter.

Variables

This section is empty.

Functions

func ModuleDir

func ModuleDir(root, layer, id string) string

ModuleDir returns the path to a module directory under the given profile root.

func ParseModuleFilter added in v0.4.0

func ParseModuleFilter(args []string) []string

ParseModuleFilter normalizes positional module-filter args: each arg is split on commas, whitespace is trimmed, empties are dropped, and duplicates collapse keeping first-seen order. Empty input returns nil.

Types

type Config

type Config struct {
	Modules ModulesConfig `toml:"modules"`
}

Config is the top-level dotdrift.toml configuration.

type Dotfile

type Dotfile struct {
	Source   string `toml:"source"`
	Mode     string `toml:"mode"`
	Line     string `toml:"line"`     // edit: ensure exact line exists
	Block    string `toml:"block"`    // edit: marker-delimited block
	Comment  string `toml:"comment"`  // edit: comment prefix for a block (mise default: #)
	Template string `toml:"template"` // edit: engine name (e.g. "tera"); requires source
}

Dotfile describes a single managed path. Whole-file entries use Source+Mode (symlink, symlink-each, copy, template). Edit entries are partial edits to a file something else owns, keyed by "<file-path>/<edit-id>" in the [dotfiles] map: a `line` ensures an exact line exists, a `block` wraps content in mise marker delimiters, and a `source`+`template` renders a block via an engine (e.g. "tera"). The syntax mirrors mise's edit-entry vocabulary exactly (see https://mise.jdx.dev/dotfiles.html, "Edit entries").

func (Dotfile) IsEdit added in v0.17.0

func (d Dotfile) IsEdit() bool

IsEdit reports whether the entry is a partial edit (line/block/template, or mode = "edit" with a source file) rather than a whole-file entry. An empty line/block/template and a mode other than "edit" means the entry is whole-file (an ensure-empty-line edit is nonsense; mise is the backstop).

type HookCommand added in v0.12.0

type HookCommand struct {
	Command  string `toml:"command"`
	Optional bool   `toml:"optional"`
}

HookCommand is a single pre/post hook shell command. It runs from the profile root with the DOTDRIFT_* facts in the environment. Optional = true makes a non-zero exit non-fatal: the failure is logged at warn and the apply step continues, so a flaky/best-effort hook cannot abort the run.

Two TOML spellings decode into the same value: the legacy string array (`pre = ["echo hi"]`, all required) and the structured table array (`[[hooks.pre]] command = "..." optional = true`). UnmarshalText makes the string form work without a custom Hooks decoder.

func (*HookCommand) UnmarshalTOML added in v0.12.0

func (h *HookCommand) UnmarshalTOML(v any) error

UnmarshalTOML accepts both spellings. The legacy form feeds each array element as a string; the structured form feeds a map with command/optional.

type Hooks added in v0.2.0

type Hooks struct {
	Pre  []HookCommand `toml:"pre"`
	Post []HookCommand `toml:"post"`
}

Hooks declares pre/post apply shell commands for a module. Unlike packages/tools/dotfiles, hooks are ordered sequences: layers merge by appending base → host → user (see internal/resolve).

type Module

type Module struct {
	ID     string
	App    string
	Path   string
	Config ModuleConfig
}

Module is a discovered module with its resolved identity and path.

type ModuleConfig

type ModuleConfig struct {
	ID       string               `toml:"id"`
	App      string               `toml:"app"`
	Scope    string               `toml:"scope"`
	When     When                 `toml:"when"`
	Packages Packages             `toml:"packages"`
	Tools    map[string]string    `toml:"tools"`
	Dotfiles map[string]Dotfile   `toml:"dotfiles"`
	Hooks    Hooks                `toml:"hooks"`
	Mounts   map[string]MountSpec `toml:"mounts"`
	Smb      SmbSpec              `toml:"smb"`
}

ModuleConfig is the base module.toml configuration.

func LoadModuleConfig

func LoadModuleConfig(dir string) (*ModuleConfig, error)

LoadModuleConfig reads a module.toml from the given directory. It returns the parsed config and the resolved module path, or nil if no module.toml exists.

func (ModuleConfig) ScopeOrDefault added in v0.2.0

func (c ModuleConfig) ScopeOrDefault() string

ScopeOrDefault returns the module's dotfile scope, defaulting to user when the key is omitted. Validity is not checked here — resolve rejects unknown values loudly.

type ModulesConfig

type ModulesConfig struct {
	Disable []string `toml:"disable"`
}

ModulesConfig holds the [modules] table.

type MountSpec added in v0.2.0

type MountSpec struct {
	Source      string   `toml:"source"`
	Destination string   `toml:"destination"`
	Type        string   `toml:"type"`
	Options     []string `toml:"options"`
	StartAt     string   `toml:"startat"`
	State       string   `toml:"state"`
}

MountSpec describes a single filesystem attachment declared in module.toml under [mounts.<name>]. Resolve validates structure only (non-empty source/destination/type, known state); Type is never checked against any registry — the registry lives outside resolve and evolves independently.

type Packages

type Packages struct {
	Present []string `toml:"present"`
	Absent  []string `toml:"absent"`
}

Packages declares packages a module needs or forbids.

type Profile

type Profile struct {
	Root     string
	Config   Config
	Modules  []Module
	Selected []Module
	Skipped  []Skip
}

Profile is the loaded set of modules and selection state.

func Load

func Load(root string, f *facts.Facts) (*Profile, error)

Load reads a profile directory, unions dotdrift.toml layers, discovers modules, and runs selection against the provided facts.

func (*Profile) LimitTo added in v0.4.0

func (p *Profile) LimitTo(ids []string) error

LimitTo restricts the selection to the listed module ids. An empty list is a no-op. Every id must name a discovered module, and the filter never resurrects modules skipped for their own reason (disabled, when filter): naming one is an error carrying that reason. Selected modules not in ids move to Skipped with reason "module filter", preserving order.

func (*Profile) Select

func (p *Profile) Select(f *facts.Facts)

Select re-evaluates which modules are selected or skipped.

type ShareSpec added in v0.2.0

type ShareSpec struct {
	Path       string `toml:"path"`
	Comment    string `toml:"comment"`
	ValidUsers string `toml:"valid_users"`
	Writable   bool   `toml:"writable"`
	Public     bool   `toml:"public"`
}

ShareSpec describes one Samba share declared under [smb.shares.<name>]. A share's path may coincide with a mount's destination, but shares and mounts are declared independently — no derivation exists between them.

type Skip

type Skip struct {
	Module Module
	Reason string
}

Skip records a module that was not selected and why.

type SmbSpec added in v0.2.0

type SmbSpec struct {
	Group  string               `toml:"group"`
	Users  []string             `toml:"users"`
	Avahi  *bool                `toml:"avahi"`
	Shares map[string]ShareSpec `toml:"shares"`
}

SmbSpec is the [smb] table of a module.toml. Avahi is a *bool so an unset key (nil) is distinguishable from an explicit false; downstream consumers treat nil as the default (avahi enabled). Layers merge the scalar fields by replacement-when-set and Shares whole-entry by name (see internal/resolve).

type When

type When struct {
	Hosts  []string `toml:"hosts"`
	Users  []string `toml:"users"`
	OS     []string `toml:"os"`
	GPU    string   `toml:"gpu"`
	Kernel string   `toml:"kernel"`
}

When filters a module by host, user, os, gpu, or kernel. Empty fields are ignored; non-empty fields must all match. Kernel holds one "<op> <version>" constraint ("<", "<=", ">", ">=", "==", "!=") compared numerically per dotted segment against the running kernel release; an empty kernel fact never matches a non-empty constraint.

Jump to

Keyboard shortcuts

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