drift

package
v1.0.5-0...-7826c6c Latest Latest
Warning

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

Go to latest
Published: Sep 22, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package drift decides what a run should do with a file that has changed since dotfiles last wrote it.

Comparing the repository against the disk answers only whether the two differ, not which of them moved. Three versions answer that: the base, meaning exactly what dotfiles last wrote and recorded; the current file on disk; and what the repository would write now. From those, an edit the user made is distinguishable from an update to the source, and only the case where both moved needs a decision at all.

Index

Constants

View Source
const (
	LabelLocal    = "local"
	LabelDotfiles = "dotfiles"
)

Labels name the two sides of a conflict in the markers left in the file.

Variables

This section is empty.

Functions

func UnifiedDiff

func UnifiedDiff(oldLabel, newLabel, oldText, newText string) string

UnifiedDiff produces a unified diff string between oldText and newText. If both texts are identical, it returns an empty string.

Types

type Action

type Action string

Action is the single thing a run does to the file.

const (
	ActionNothing   Action = "nothing"
	ActionWrite     Action = "write"
	ActionKeep      Action = "keep"
	ActionMerge     Action = "merge"
	ActionOverwrite Action = "overwrite"
	ActionPrompt    Action = "prompt"
)

func Decide

func Decide(state State, policy Policy) Action

Decide turns a state and the declared policy into the one action to take.

Only a state where both sides moved lets the policy decide anything. The rest have exactly one answer that does not discard somebody's work, and a policy cannot ask for a different one.

type Inspector

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

Inspector evaluates the drift state of all declared files and blocks.

func NewInspector

func NewInspector(fsys fs.FS, reg *registry.Registry, projCfg *config.ProjectConfig) *Inspector

NewInspector creates a new drift inspector.

func (*Inspector) InspectAll

func (ins *Inspector) InspectAll(ctx context.Context, tools []*config.ToolConfig) ([]Item, error)

InspectAll inspects all provided tools.

func (*Inspector) InspectTool

func (ins *Inspector) InspectTool(ctx context.Context, tool *config.ToolConfig) ([]Item, error)

InspectTool inspects drift for a single tool configuration.

type Item

type Item struct {
	ToolName       string `json:"toolName"`
	FilePath       string `json:"filePath"`
	BlockID        string `json:"blockId,omitempty"`
	Type           string `json:"type"` // "symlink", "copy", "template", "block"
	State          State  `json:"state"`
	Diff           string `json:"diff,omitempty"`
	CurrentContent string `json:"currentContent,omitempty"`
	DesiredContent string `json:"desiredContent,omitempty"`
}

Item represents the drift status and diff for a single managed or declared artifact.

type MergeResult

type MergeResult struct {
	Merged    string
	Conflicts int
}

MergeResult is a merged file and how many places could not be merged.

func Merge

func Merge(base, local, desired string) (MergeResult, error)

Merge combines the change made on disk with the change made in the repository, against the version dotfiles last wrote.

Conflicts are marked with the seven-character markers git writes, rather than with the nine-character ones the underlying library emits, because that is what every editor, `git diff` and mergetool recognises. A file left with markers no tool understands would be a conflict the user has to resolve by hand twice.

type Policy

type Policy string

Policy is what an author asked for when the disk and the source disagree.

const (
	// PolicyMerge is the default for text: combine both sides, and mark the lines
	// where that cannot be done.
	PolicyMerge Policy = "merge"
	// PolicyKeepLocal leaves the file on disk as it is.
	PolicyKeepLocal Policy = "keep-local"
	// PolicyOverwrite replaces the file, keeping what was there as a backup.
	PolicyOverwrite Policy = "overwrite"
	// PolicyPrompt asks.
	PolicyPrompt Policy = "prompt"
)

type State

type State string

State is what comparing the three versions found.

const (
	// StateNew is a file that has never been written and is not on disk.
	StateNew State = "new"
	// StateInSync is a file that already holds what would be written.
	StateInSync State = "in-sync"
	// StateUnmanaged is a file that was already on disk holding content dotfiles
	// never wrote. There is no base to measure against, so nothing can be merged.
	StateUnmanaged State = "unmanaged"
	// StateMissing is a file dotfiles wrote and recorded that is no longer there.
	StateMissing State = "missing"
	// StateUpstreamUpdate is an untouched file whose source has moved on.
	StateUpstreamUpdate State = "upstream-update"
	// StateLocalDrift is an edited file whose source has not moved.
	StateLocalDrift State = "local-drift"
	// StateConflict is a file where both the disk and the source moved, differently.
	StateConflict State = "conflict"
)

func Evaluate

func Evaluate(v Versions) State

Evaluate reports which of the three versions moved.

type Versions

type Versions struct {
	Base    string
	Current string
	Desired string
}

Versions are the three content hashes a state is derived from. An empty hash means the version does not exist: no record for Base, no file for Current.

Jump to

Keyboard shortcuts

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