Documentation
¶
Overview ¶
Package mise: bootstrap config translation — emits [bootstrap.*] sections for mise bootstrap convergence.
Package mise bootstraps the mise binary and runs mise operations.
Index ¶
- Constants
- func CompareVersions(a, b string) (int, error)
- func GenerateApplyConfig(plan *resolve.Plan, profileRoot string, f *facts.Facts, interactive bool) string
- func GenerateBootstrapAccounts(group string, users []string) string
- func GenerateBootstrapDirectories(paths []string) string
- func GenerateBootstrapFiles(files []BootstrapFile) string
- func GenerateBootstrapPackages(install []string, backend string) string
- func GenerateBootstrapServices(services []BootstrapService) string
- func GenerateConfig(plan *resolve.Plan) string
- func GenerateDotfiles(entries []resolve.DotfileEntry) string
- func GenerateHookTasks(hooks resolve.HooksStep, profileRoot string, f *facts.Facts, interactive bool) string
- func GenerateTools(versions map[string]string) string
- func MisePluginsDir(xdgDataHome string) string
- func PluginsDirFromEnv() string
- func PrefixedPackages(names []string, backend string) []string
- func SystemDotfileEntries(files []BootstrapFile) []resolve.DotfileEntry
- type BootstrapFile
- type BootstrapService
- type DotfilesStep
- type DotfilesSystemStep
- type ExecMise
- func (e *ExecMise) Bootstrap(ctx context.Context, configPath string, yes bool, only ...string) error
- func (e *ExecMise) Current(ctx context.Context, tool string) (string, error)
- func (e *ExecMise) DotfilesApply(ctx context.Context, configPath string, yes, force bool) error
- func (e *ExecMise) DotfilesApplySudo(ctx context.Context, configPath string, yes bool) error
- func (e *ExecMise) EnsureAndInstall(ctx context.Context, configPath string) error
- func (e *ExecMise) RunTask(ctx context.Context, configPath, taskName string) error
- type FakeRunner
- type HooksStep
- type InstallKind
- type Mise
- type Runner
- type ToolsStep
Constants ¶
const InstallerURL = "https://mise.run"
InstallerURL is the official mise installer.
const MinMiseVersion = "2026.8.2"
MinMiseVersion is the hardcoded minimum mise version required by dotdrift.
Variables ¶
This section is empty.
Functions ¶
func CompareVersions ¶
CompareVersions compares calendar-style versions like 2026.6.6. Returns -1 if a < b, 0 if equal, 1 if a > b. A version carrying a pre-release/build suffix (e.g. "2025.1.0-rc1", "2025.1.0+build.5") compares below the plain release. Unparseable input is an error.
func GenerateApplyConfig ¶ added in v0.2.0
func GenerateApplyConfig(plan *resolve.Plan, profileRoot string, f *facts.Facts, interactive bool) string
GenerateApplyConfig emits the full apply-time mise.toml: tools, dotfiles, and hook tasks. The hook tasks need facts and the absolute profile root, so only apply uses this; onboard keeps using GenerateConfig. interactive flows through to GenerateHookTasks.
func GenerateBootstrapAccounts ¶ added in v0.10.0
GenerateBootstrapAccounts emits [bootstrap.groups] and [bootstrap.users] for the samba group and its users.
func GenerateBootstrapDirectories ¶ added in v0.10.0
GenerateBootstrapDirectories emits a [bootstrap.directories] section so mise creates mount-point directories before units are enabled.
func GenerateBootstrapFiles ¶ added in v0.10.0
func GenerateBootstrapFiles(files []BootstrapFile) string
GenerateBootstrapFiles emits a [bootstrap.files] section. copy/symlink modes become content copies (symlink→copy is a deliberate improvement for system files); template mode adds template = true.
func GenerateBootstrapPackages ¶ added in v0.10.0
GenerateBootstrapPackages emits a [bootstrap.packages] section. Bare names get the backend prefix; explicit prefixes pass through. Every entry is pinned to "latest" (mise's package-plugin API does not support version pins for AUR). Returns "" when the list is empty.
func GenerateBootstrapServices ¶ added in v0.10.0
func GenerateBootstrapServices(services []BootstrapService) string
GenerateBootstrapServices emits a [bootstrap.services] section.
func GenerateConfig ¶
GenerateConfig emits a complete mise.toml with tools and dotfiles sections.
func GenerateDotfiles ¶
func GenerateDotfiles(entries []resolve.DotfileEntry) string
GenerateDotfiles emits a mise.toml [dotfiles] section from the resolved plan. Whole-file entries emit { source, mode }; edit entries emit the form mise's dotfiles phase parses: { line }, { block[, comment] }, or { source, template }. The map key is the entry Target verbatim — for an edit entry that is the full "<file-path>/<edit-id>" string.
func GenerateHookTasks ¶ added in v0.2.0
func GenerateHookTasks(hooks resolve.HooksStep, profileRoot string, f *facts.Facts, interactive bool) string
GenerateHookTasks emits one mise task per hook command, named <phase>-<index> ("hooks-pre-0", "hooks-pre-1", "hooks-post-0", ...). One task per command lets HooksStep run and tolerate them individually while preserving order (an optional hook that fails does not skip later ones). Each task runs from dir (the absolute profile root) with the DOTDRIFT_* facts environment. When interactive is true each task is marked `interactive = true` so mise connects it to the terminal's stdin/stdout/ stderr — a hook running an interactive command (e.g. sudo) can then reach a controlling terminal and disable echo instead of echoing the password. Returns "" when both lists are empty.
func GenerateTools ¶
GenerateTools emits a mise.toml [tools] section from the resolved plan.
func MisePluginsDir ¶ added in v0.13.0
MisePluginsDir returns mise's package-plugin registry directory ($XDG_DATA_HOME/mise/plugins), where mise discovers installed plugins. dotdrift copies its embedded paru plugin here as real files (see paru.EnsureInstalled), the same on-disk shape as any other mise plugin.
func PluginsDirFromEnv ¶ added in v0.21.0
func PluginsDirFromEnv() string
PluginsDirFromEnv resolves the mise plugin registry directory from the environment ($XDG_DATA_HOME/mise/plugins, falling back to ~/.local/share/mise/plugins). Returns the empty string when no home directory can be determined.
func PrefixedPackages ¶ added in v0.10.0
PrefixedPackages translates package specs into mise `manager:pkg` keys.
Rules (issue 0003): an explicit `manager:pkg` spec (anything containing a colon) passes through unchanged — mise's built-in managers (pacman, apt, dnf) and other plugins are respected. An `aur/<pkg>` spec is dotdrift's AUR marker; it always maps to the paru plugin (the only AUR-capable manager), with the marker stripped so pacman -Q / paru -S see the real package name. A bare name (no colon, no aur/) gets the detected backend's manager prefix (paru on Arch, apt on Debian, dnf on Fedora). On Arch that means bare names default to paru — not mise's built-in pacman, which has no AUR support.
func SystemDotfileEntries ¶ added in v0.19.0
func SystemDotfileEntries(files []BootstrapFile) []resolve.DotfileEntry
SystemDotfileEntries converts resolved bootstrap files into dotfile entries for [dotfiles] emission, applying the symlink→copy safety translation: system files become content copies (mode = "copy") regardless of the declared mode — a symlink from /etc into a user's profile directory is fragile (a moved profile or changed user breaks it). Template entries keep their mode. symlink-each entries are pre-expanded by ResolveBootstrapFiles, so each child arrives here as an individual file.
Types ¶
type BootstrapFile ¶ added in v0.10.0
type BootstrapFile struct {
Target string
Source string
Mode string // copy | symlink | symlink-each | template (informative; GenerateBootstrapFiles ignores it)
Template bool
}
BootstrapFile is one concrete file target for [bootstrap.files].
func ResolveBootstrapFiles ¶ added in v0.10.0
func ResolveBootstrapFiles(entries []resolve.DotfileEntry, sourceRoot, homeDir string) ([]BootstrapFile, error)
ResolveBootstrapFiles expands system-scope dotfile entries into individual file targets. symlink-each entries are expanded by listing the source directory. sourceRoot must be an absolute path to the profile root.
type BootstrapService ¶ added in v0.10.0
type BootstrapService struct {
Name string // unit name, e.g. "mnt-data.mount"
Enabled bool
Running bool
}
BootstrapService is one systemd unit to converge via [bootstrap.services].
type DotfilesStep ¶
DotfilesStep runs mise dotfiles apply for the dotfiles in the resolved plan.
func (*DotfilesStep) Name ¶
func (s *DotfilesStep) Name() string
type DotfilesSystemStep ¶ added in v0.2.0
type DotfilesSystemStep struct {
Exec *ExecMise
Entries []resolve.DotfileEntry
ConfigPath string
Yes bool
}
DotfilesSystemStep applies system-scope dotfile entries with root privileges. It takes the concrete ExecMise (like HooksStep) because the sudo-aware entry point is deliberately not part of the Runner interface. cmd/apply.go only constructs it when at least one system-scope entry exists; Run also no-ops on an empty list as a second line of defense.
func (*DotfilesSystemStep) Name ¶ added in v0.2.0
func (s *DotfilesSystemStep) Name() string
type ExecMise ¶
type ExecMise struct {
// contains filtered or unexported fields
}
ExecMise wraps a Mise value so it can be used as a Runner by step code.
func NewExecMise ¶
NewExecMise creates a Runner backed by a Mise instance.
func (*ExecMise) Bootstrap ¶ added in v0.10.0
func (e *ExecMise) Bootstrap(ctx context.Context, configPath string, yes bool, only ...string) error
Bootstrap invokes `mise bootstrap --yes` against the config. It runs the full declarative convergence (packages, files, services, etc.) in one call. dotdrift's resume orchestrator may instead drive `--only`/`--skip` slices.
func (*ExecMise) Current ¶ added in v0.14.0
Current returns the active version of a tool per `mise current <tool>`. Probe-only: resolves the binary via LookPath (never installs) and runs through the probe runner (never streamed/echoed). Any failure is an error; callers report the tool as unknown.
func (*ExecMise) DotfilesApply ¶
func (*ExecMise) DotfilesApplySudo ¶ added in v0.2.0
DotfilesApplySudo applies system-scope dotfiles with root privileges. When the process is not already root it invokes sudo (failing loudly if sudo is missing or authentication fails); as root it applies directly.
func (*ExecMise) EnsureAndInstall ¶
type FakeRunner ¶
type FakeRunner struct {
InstallCalled bool
DotfilesCalled bool
BootstrapCalled bool
Yes bool
Force bool
Err error
}
func (*FakeRunner) DotfilesApply ¶
func (*FakeRunner) EnsureAndInstall ¶
func (f *FakeRunner) EnsureAndInstall(ctx context.Context, configPath string) error
type HooksStep ¶
type HooksStep struct {
Exec *ExecMise
Commands []profile.HookCommand
ConfigPath string
Task string // mise task-name prefix, e.g. "hooks-pre"; per-command tasks are <Task>-<i>
StepName string // pipeline step name, e.g. "hooks-pre"
}
HooksStep runs each pre/post hook command as its own mise task from the generated apply config. Per-command execution preserves hook order while allowing individual hooks to opt out of fail-fast: a command marked Optional that exits non-zero is logged at warn and the next command runs. cmd/apply.go only constructs HooksSteps for non-empty command lists; Run also no-ops on an empty list as a second line of defense.
Each command maps to a mise task named <Task>-<index> (e.g. hooks-pre-0), which GenerateHookTasks emits in lockstep with this loop.
type InstallKind ¶
type InstallKind int
InstallKind classifies how a mise binary is managed.
const ( InstallKindUnknown InstallKind = iota InstallKindSystemWide InstallKindUserManaged )
func ClassifyInstall ¶
func ClassifyInstall(path string) InstallKind
ClassifyInstall determines whether a mise binary is system-wide or user-managed.
System-wide (no auto-upgrade):
- DOTDRIFT_MISE_SYSTEM=1
- path under /usr/bin, /usr/local/bin, /bin, /sbin, /usr/sbin, /opt
- path under $HOME but not writable by the current user
User-managed (may auto-upgrade):
- path under $HOME and writable by the current user
func (InstallKind) String ¶
func (k InstallKind) String() string
type Mise ¶
type Mise struct {
LookPath func(string) (string, error)
Run func(string, ...string) (string, error)
RunContext func(context.Context, string, ...string) (string, error)
Install func() (string, error)
Classify func(string) InstallKind
// Env is extra environment ("KEY=value") appended to the subprocess
// environment on the real exec path; fakes (Run/RunContext) bypass it.
Env []string
// Verbose streams operation subprocesses (install/dotfiles/tasks) live to
// Out/Err and echoes each command line set -x-style ("+ argv") to Err
// before it runs. Interactive applies (both Out and Err are terminals)
// also stream — to keep the child's own color output — but omit the
// "+ argv" trace, which stays a Verbose affordance; a non-verbose, piped
// run captures instead (see runOp). Version probes always stay captured
// unechoed (their output is parsed).
Verbose bool
// Out/Err are the Verbose streaming destinations; nil defaults to
// os.Stdout/os.Stderr.
Out io.Writer
Err io.Writer
// contains filtered or unexported fields
}
Mise finds, installs, or upgrades a mise binary.
RunContext is preferred over the legacy Run; both are kept so existing fakes that only set Run keep working. The result of the first Ensure call is memoized for the lifetime of the struct.
func DefaultMise ¶
func DefaultMise() *Mise
DefaultMise returns a Mise configured with real OS dependencies. Run and RunContext stay nil so runner() uses the env-aware real exec path.