migrate

package
v0.1.0-dev.20260131033123 Latest Latest
Warning

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

Go to latest
Published: Jan 31, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildMigrationGraph

func BuildMigrationGraph(sourceRoot string, mappings []DirectoryMapping) *execution.Graph

BuildMigrationGraph constructs an execution graph from directory mappings. The graph contains rename operations for directories that need to change from legacy naming (project-Platform) to writ naming (project.Platform).

The graph is the executable artifact; MigrationAnalysis provides the non-executable understanding. Together they replace the legacy MigrationPlan.

func Classify

func Classify(entries []InventoryEntry)

Classify assigns a FileClass to each inventory entry based on path, name, and file attributes. It modifies entries in place.

func Execute

func Execute(w io.Writer, graph *execution.Graph, analysis *MigrationAnalysis) error

Execute performs the directory renames specified in the execution graph. It writes progress to stderr using standard cli output functions. The w parameter is kept for API compatibility but is not used.

func FormatMigrationExplain

func FormatMigrationExplain(ctx context.Context, w io.Writer, analysis *MigrationAnalysis, provider model.Provider) error

FormatMigrationExplain uses AI to generate a natural language explanation of the migration analysis. This provides a conversational summary that highlights key findings and actionable recommendations.

func FormatMigrationPlan

func FormatMigrationPlan(w io.Writer, graph *execution.Graph, analysis *MigrationAnalysis, format string) error

FormatMigrationPlan renders the execution Graph and MigrationAnalysis as human-readable output. This is the derived view that replaces the legacy MigrationPlan struct.

Supported formats: "text" (default), "yaml", "json" For "explain" format, use FormatMigrationExplain which requires an AI provider.

func UniquePlatforms

func UniquePlatforms(entries []InventoryEntry) []string

UniquePlatforms returns a sorted list of unique platform values from entries.

func UniqueProjects

func UniqueProjects(entries []InventoryEntry) []string

UniqueProjects returns a sorted list of unique project names from entries.

Types

type DetectedInstall

type DetectedInstall struct {
	Line        int    `json:"line" yaml:"line"`
	Manager     string `json:"manager" yaml:"manager"`
	Name        string `json:"name" yaml:"name"`
	Command     string `json:"command" yaml:"command"`
	LorePackage string `json:"lore_package,omitempty" yaml:"lore_package,omitempty"`
}

DetectedInstall represents a package installation detected in a script.

func (DetectedInstall) IsResolved

func (d DetectedInstall) IsResolved() bool

IsResolved returns true if this install maps to a known lore package.

type DetectionResult

type DetectionResult struct {
	System     SourceSystem
	Confidence float64
	Matches    []MarkerMatch
}

DetectionResult holds the outcome of signature-based detection.

func DetectWithSignatures

func DetectWithSignatures(root string, signatures []Signature) []DetectionResult

DetectWithSignatures uses registry signatures to identify the source system. Returns all matches sorted by confidence (highest first).

type DirectoryMapping

type DirectoryMapping struct {
	SourceDir string // e.g., "all-Darwin"
	TargetDir string // e.g., "all.Darwin"
	Project   string // e.g., "all"
	Platform  string // e.g., "Darwin"
}

DirectoryMapping represents a rename from legacy to writ naming.

func BuildMappings

func BuildMappings(root string) ([]DirectoryMapping, error)

BuildMappings generates the directory rename mappings for all directories that use the <project>-<Platform> convention.

type EncryptionSystem

type EncryptionSystem string

EncryptionSystem identifies the secret encryption tool in use.

const (
	EncryptGitCrypt     EncryptionSystem = "git-crypt"
	EncryptBlackbox     EncryptionSystem = "blackbox"
	EncryptTranscrypt   EncryptionSystem = "transcrypt"
	EncryptGPG          EncryptionSystem = "gpg"
	EncryptAge          EncryptionSystem = "age"
	EncryptAnsibleVault EncryptionSystem = "ansible-vault"
	EncryptSOPS         EncryptionSystem = "sops"
	EncryptNone         EncryptionSystem = "none"
)

func DetectEncryptedFile

func DetectEncryptedFile(path string) EncryptionSystem

DetectEncryptedFile checks a single file's content for encryption signatures.

func DetectEncryption

func DetectEncryption(root string) []EncryptionSystem

DetectEncryption identifies encryption systems in use in the repository. Returns a list of detected systems (there may be multiple).

type ExecutionPlan

type ExecutionPlan struct {
	Description string   `json:"description"`
	Actions     []string `json:"actions"`
	Approved    bool     `json:"-"`
}

ExecutionPlan represents a plan proposed by the AI for user approval.

type FileClass

type FileClass string

FileClass categorizes a file by its role in the environment.

const (
	ClassStaticConfig    FileClass = "static-config"
	ClassLifecycleScript FileClass = "lifecycle-script"
	ClassScript          FileClass = "script"
	ClassSecret          FileClass = "secret"
	ClassTemplate        FileClass = "template"
	ClassFont            FileClass = "font"
	ClassManPage         FileClass = "man-page"
	ClassCompletion      FileClass = "completion"
	ClassBinary          FileClass = "binary"
)

type InventoryEntry

type InventoryEntry struct {
	RelPath      string // Relative path from source root
	AbsPath      string // Absolute path
	Project      string // Parsed from directory name
	Platform     string // Parsed from directory name (empty if base)
	Class        FileClass
	IsExecutable bool
	SizeBytes    int64
	Observations []string
}

InventoryEntry represents a single file discovered during inventory.

func Inventory

func Inventory(root string) ([]InventoryEntry, error)

Inventory walks the source root and builds a list of all files with their project and platform assignments.

type Marker

type Marker struct {
	Type        string  `yaml:"type"`        // file, directory, file_pattern, directory_pattern, file_contains, file_magic
	Path        string  `yaml:"path"`        // for file, directory types
	Pattern     string  `yaml:"pattern"`     // for *_pattern types, or content pattern for file_contains
	Bytes       []byte  `yaml:"bytes"`       // for file_magic type
	Confidence  float64 `yaml:"confidence"`  // 0.0-1.0
	Description string  `yaml:"description"` // human-readable explanation
}

Marker defines a single detection rule.

type MarkerMatch

type MarkerMatch struct {
	Marker     Marker
	MatchedAt  string // path or pattern that matched
	Confidence float64
}

MarkerMatch records a single marker that matched.

type MigratedMarker

type MigratedMarker struct {
	Timestamp string   `yaml:"timestamp"`
	System    string   `yaml:"system"`
	Renames   []Rename `yaml:"renames"`
}

MigratedMarker records what was done during execution.

type Migration

type Migration struct {
	Issue    string   // what's wrong
	Commands []string // suggested git commands to fix it
}

Migration describes a recommended migration step.

type MigrationAnalysis

type MigrationAnalysis struct {
	// SourceRoot is the absolute path to the source repository.
	SourceRoot string `json:"source_root" yaml:"source_root"`

	// System is the detected source system (tuckr, stow, chezmoi, etc.).
	System SourceSystem `json:"system" yaml:"system"`

	// SystemConfidence is the detection confidence (0.0-1.0) when using
	// signature-based detection. Zero for heuristic detection.
	SystemConfidence float64 `json:"system_confidence,omitempty" yaml:"system_confidence,omitempty"`

	// RepoLayer indicates the precedence layer (base, team, personal).
	RepoLayer RepoLayer `json:"repo_layer" yaml:"repo_layer"`

	// EncryptionSystems lists detected encryption tools (git-crypt, sops, etc.).
	EncryptionSystems []EncryptionSystem `json:"encryption_systems" yaml:"encryption_systems"`

	// Projects lists unique project names found in the repository.
	Projects []string `json:"projects" yaml:"projects"`

	// Platforms lists unique platform names found in the repository.
	Platforms []string `json:"platforms" yaml:"platforms"`

	// Scripts contains analysis of lifecycle scripts.
	Scripts []ScriptAnalysis `json:"scripts,omitempty" yaml:"scripts,omitempty"`

	// SecretFindings contains detected secrets with explanations.
	SecretFindings []SecretFinding `json:"secret_findings,omitempty" yaml:"secret_findings,omitempty"`

	// Observations are insights about the repository structure.
	Observations []string `json:"observations,omitempty" yaml:"observations,omitempty"`

	// Warnings are concerns that may need attention before/after migration.
	Warnings []string `json:"warnings,omitempty" yaml:"warnings,omitempty"`

	// Recommendations are suggested actions after migration.
	Recommendations []string `json:"recommendations,omitempty" yaml:"recommendations,omitempty"`

	// Stats provides summary counts derived from the inventory.
	Stats MigrationStats `json:"stats" yaml:"stats"`
}

MigrationAnalysis holds non-executable understanding of a source repository. This is the "why" and "what to watch out for" — separate from the execution Graph which specifies "what to do".

The execution Graph and MigrationAnalysis are produced together by BuildMigration(). FormatMigrationPlan() renders both as human-readable output.

func BuildMigration

func BuildMigration(ctx context.Context, opts Options) (*execution.Graph, *MigrationAnalysis, error)

BuildMigration performs detection, inventory, and analysis, returning an execution Graph and MigrationAnalysis. This is the primary API that separates executable operations from non-executable understanding.

The Graph contains rename operations for directory structure changes. The Analysis contains observations, warnings, and recommendations.

func BuildMigrationAnalysis

func BuildMigrationAnalysis(
	sourceRoot string,
	system SourceSystem,
	systemConfidence float64,
	entries []InventoryEntry,
	mappings []DirectoryMapping,
	encSystems []EncryptionSystem,
	sigIdx SignatureIndex,
) *MigrationAnalysis

BuildMigrationAnalysis constructs the analysis artifact from detection results and inventory data. This is the non-executable understanding of the source repo.

type MigrationStats

type MigrationStats struct {
	TotalFiles       int `json:"total_files" yaml:"total_files"`
	StaticConfigs    int `json:"static_configs" yaml:"static_configs"`
	Scripts          int `json:"scripts" yaml:"scripts"`
	LifecycleScripts int `json:"lifecycle_scripts" yaml:"lifecycle_scripts"`
	Secrets          int `json:"secrets" yaml:"secrets"`
	Fonts            int `json:"fonts" yaml:"fonts"`
	Templates        int `json:"templates" yaml:"templates"`
	Completions      int `json:"completions" yaml:"completions"`
	ManPages         int `json:"man_pages" yaml:"man_pages"`
	Binaries         int `json:"binaries" yaml:"binaries"`
	Projects         int `json:"projects" yaml:"projects"`
	Platforms        int `json:"platforms" yaml:"platforms"`
	Renames          int `json:"renames" yaml:"renames"`
}

MigrationStats summarizes the migration numerically.

type Options

type Options struct {
	SourceRoot string
	TargetRoot string // empty = rename in place
	Execute    bool
	Verbose    bool
	Format     string // "json" (default), "yaml", "text"
	Provider   model.Provider
	RegClient  *lorepackage.Registry
}

Options controls migration behavior.

type ProjectInfo

type ProjectInfo struct {
	Name      string
	Path      string
	Segment   string // segment suffix (e.g., "Darwin", "Unix")
	FileCount int
	Templates int
	Secrets   int
}

ProjectInfo describes a detected project directory.

type Rename

type Rename struct {
	From string `yaml:"from"`
	To   string `yaml:"to"`
}

Rename records a single directory rename.

type RepoLayer

type RepoLayer string

RepoLayer indicates the precedence layer of a repository. Precedence: base (lowest) → team → personal (highest).

const (
	LayerBase     RepoLayer = "base"
	LayerTeam     RepoLayer = "team"
	LayerPersonal RepoLayer = "personal"
)

type ScanResult

type ScanResult struct {
	Path string

	// Git information
	IsGit    bool
	Remote   string
	Branch   string
	Dirty    int // count of uncommitted changes
	GitError string

	// Structure detection
	Structure     SourceStructure
	HomePath      string // path to detected Home-equivalent directory
	Projects      []ProjectInfo
	NestedUnder   string // non-empty if projects are nested (e.g., "Configs")
	TemplateCount int
	SecretCount   int
	HasRecipients bool

	// Migration guidance
	Migrations []Migration
}

ScanResult holds the results of scanning a source directory for migration.

func ScanSource

func ScanSource(path string) *ScanResult

ScanSource inspects a directory and reports on its suitability for writ migration.

func (*ScanResult) NeedsMigration

func (r *ScanResult) NeedsMigration() bool

NeedsMigration returns true if the scan found issues that require migration.

func (*ScanResult) PrintReport

func (r *ScanResult) PrintReport()

PrintReport outputs the scan result to stderr.

type ScriptAnalysis

type ScriptAnalysis struct {
	RelPath       string            `json:"rel_path" yaml:"rel_path"`
	Name          string            `json:"name" yaml:"name"`
	Phase         string            `json:"phase" yaml:"phase"`
	PlatformGuard string            `json:"platform_guard,omitempty" yaml:"platform_guard,omitempty"`
	LineCount     int               `json:"line_count" yaml:"line_count"`
	Resolved      []DetectedInstall `json:"resolved,omitempty" yaml:"resolved,omitempty"`
	Unresolved    []DetectedInstall `json:"unresolved,omitempty" yaml:"unresolved,omitempty"`
	Observations  []string          `json:"observations,omitempty" yaml:"observations,omitempty"`
}

ScriptAnalysis captures information extracted from a lifecycle script.

func AnalyzeScripts

func AnalyzeScripts(entries []InventoryEntry, idx SignatureIndex) []ScriptAnalysis

AnalyzeScripts examines lifecycle script entries and extracts information about what they install and how.

type SecretFinding

type SecretFinding struct {
	RelPath          string           `json:"rel_path" yaml:"rel_path"`
	Encryption       EncryptionSystem `json:"encryption" yaml:"encryption"`
	Reason           string           `json:"reason" yaml:"reason"`
	SuggestedPattern string           `json:"suggested_pattern,omitempty" yaml:"suggested_pattern,omitempty"`
}

SecretFinding represents a detected secret file.

type Session

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

Session implements console.Session for interactive migration.

func NewSession

func NewSession(opts Options) *Session

NewSession creates a new migration session.

func NewSessionWithProvider

func NewSessionWithProvider(opts Options, provider model.Provider, regClient *lorepackage.Registry) *Session

NewSessionWithProvider creates a session with an AI provider.

func (*Session) Complete

func (s *Session) Complete() bool

Complete returns true if the session has finished.

func (*Session) Current

func (s *Session) Current() *console.Step

Current returns the current step.

func (*Session) Error

func (s *Session) Error() error

Error returns any error that terminated the session.

func (*Session) Next

func (s *Session) Next() *console.Step

Next advances the session and returns the next step.

func (*Session) Respond

func (s *Session) Respond(response string) error

Respond processes the user's input.

func (*Session) Result

func (s *Session) Result() any

Result returns the session result.

type SessionResult

type SessionResult struct {
	Graph       *execution.Graph
	Analysis    *MigrationAnalysis
	Executed    bool
	ReceiptPath string
}

SessionResult is the final output of a migration session.

type SessionState

type SessionState int

SessionState represents a state in the migration session.

const (
	StateAnalyzing SessionState = iota
	StateConversing
	StatePlanProposed
	StateExecuting
	StateComplete
	StateError
)

type Signature

type Signature struct {
	Name        string   `yaml:"name"`
	Description string   `yaml:"description"`
	Markers     []Marker `yaml:"markers"`
}

Signature defines detection markers for a source system.

func LoadSignatures

func LoadSignatures(client *lorepackage.Registry) ([]Signature, error)

LoadSignatures loads all detection signatures from the lorepackage. It reads the index.yaml manifest to discover available signature files, then loads and parses each one.

type SignatureIndex

type SignatureIndex map[string]map[string]string

SignatureIndex maps manager → package_name → lore_package. This is the inverted index built from all lifecycle.yaml signatures. Load via Registry.SignatureIndex() from the lorepackage client.

func (SignatureIndex) HasPackages

func (idx SignatureIndex) HasPackages() bool

HasPackages returns true if the index has any entries.

func (SignatureIndex) Resolve

func (idx SignatureIndex) Resolve(manager, name string) string

Resolve looks up a package name for a given manager. Returns the lore package name if found, empty string otherwise.

type SourceStructure

type SourceStructure int

SourceStructure describes the detected source directory layout.

const (
	StructureUnknown    SourceStructure = iota
	StructureCompatible                 // Home/<project>/ with "." segments
	StructurePartial                    // Has Home/ but needs migration
	StructureFlat                       // Dot-prefixed files at root (e.g., .bashrc, .vimrc)
	StructureStow                       // GNU Stow directory with packages
)

func (SourceStructure) String

func (s SourceStructure) String() string

String returns a human-readable label for the structure type.

type SourceSystem

type SourceSystem string

SourceSystem identifies the dotfile management approach used in the source repository.

const (
	SystemNative      SourceSystem = "native" // Already writ-compatible (Home/ or System/)
	SystemTuckr       SourceSystem = "tuckr"
	SystemStow        SourceSystem = "stow"
	SystemChezmoi     SourceSystem = "chezmoi"
	SystemYadm        SourceSystem = "yadm"
	SystemBareGit     SourceSystem = "bare-git"
	SystemScriptBased SourceSystem = "script-based"
	SystemUnknown     SourceSystem = "unknown"
)

func Detect

func Detect(root string) (SourceSystem, error)

Detect identifies the source system used in the given directory. It checks for tool-specific markers first, then falls back to native/unknown.

Jump to

Keyboard shortcuts

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