Documentation
¶
Overview ¶
Package migrate plans and applies declarative source migrations.
Index ¶
- Constants
- func Apply(plan Plan) error
- func CleanupCampaignWorktrees(githubDir, migrationID string) ([]string, error)
- func WriteCampaignReports(dir string, report CampaignReport) error
- func WriteReports(dir string, report Report) error
- type CampaignModuleReport
- type CampaignOptions
- type CampaignReport
- type CampaignRepositoryReport
- type FileChange
- type Finding
- type GoModuleRelease
- type GoModuleRequire
- type Plan
- type RemoteCheck
- type Report
- type ReportFile
- type ReportFinding
- type ReportMigration
- type ReviewRule
- type Scope
- type Spec
- type Step
- type StructuralAdapter
- type Verification
- type VerificationResult
Constants ¶
const MigrationFormatV1 = "https://sneat.dev/workbench/formats/migration/v1"
MigrationFormatV1 is the format contract for HCL migration specifications. It is deliberately a stable public URL so it can become human-readable documentation without teaching the runner a second, implicit versioning system.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
Apply writes all planned changes, refusing to overwrite a source file that changed after planning. Each individual file write is atomic.
func CleanupCampaignWorktrees ¶
CleanupCampaignWorktrees removes clean, dedicated worktrees for one migration. It never removes canonical clones, branches, reports, or a worktree with uncommitted changes.
func WriteCampaignReports ¶
func WriteCampaignReports(dir string, report CampaignReport) error
WriteCampaignReports writes both report formats to dir.
func WriteReports ¶
WriteReports writes the Markdown and YAML representations to dir. It is opt-in so a dry-run never creates files unless the caller asks for a report.
Types ¶
type CampaignModuleReport ¶
type CampaignModuleReport struct {
Path string `yaml:"path"`
WorktreeDir string `yaml:"worktree_dir,omitempty"`
MigrationEnabled bool `yaml:"migration_enabled"`
PlanState string `yaml:"plan_state"`
ChangedFiles *int `yaml:"changed_files,omitempty"`
ManifestChanged bool `yaml:"manifest_changed"`
PublishableManifest bool `yaml:"publishable_manifest,omitempty"`
ReviewItems int `yaml:"review_items"`
MigrationReportPath string `yaml:"migration_report_path,omitempty"`
Verifications []VerificationResult `yaml:"verifications,omitempty"`
Status string `yaml:"status"`
}
CampaignModuleReport identifies the submodule work done inside a repository.
type CampaignOptions ¶
type CampaignOptions struct {
GitHubDir string
Ref string
ModuleRefs map[string]string
Apply bool
Resume bool
Verify Verification
Commit bool
Push bool
PR bool
Merge bool
Parallel int
ReportDir string
// CloneURL overrides the canonical GitHub clone URL for a repository. It is
// primarily useful for hermetic integration tests; normal campaigns use
// https://<repository>.git.
CloneURL func(repository string) string
}
CampaignOptions controls a hierarchical migration. Canonical clones are never checked out or altered; PR and merge phases are strictly opt-in.
type CampaignReport ¶
type CampaignReport struct {
SchemaVersion int `yaml:"schema_version"`
Migration ReportMigration `yaml:"migration"`
Status string `yaml:"status"`
SourceRoot string `yaml:"source_root"`
GitHubDir string `yaml:"github_dir"`
BaseRef string `yaml:"base_ref"`
Verification Verification `yaml:"verification"`
Parallel int `yaml:"parallel"`
Repositories []CampaignRepositoryReport `yaml:"repositories"`
}
CampaignReport is the Markdown/YAML index for a migration campaign.
func RunCampaign ¶
func RunCampaign(spec Spec, sourceRoot string, options CampaignOptions) (CampaignReport, error)
RunCampaign plans or applies a hierarchy-aware Go migration. On apply it clones missing repositories into <github-dir>/<org>/<repo>, creates one dedicated worktree per repository, and modifies only those worktrees.
func (CampaignReport) Markdown ¶
func (r CampaignReport) Markdown() string
Markdown renders the campaign index for human review and AI agents.
func (CampaignReport) YAML ¶
func (r CampaignReport) YAML() ([]byte, error)
YAML renders the deterministic campaign manifest.
type CampaignRepositoryReport ¶
type CampaignRepositoryReport struct {
Repository string `yaml:"repository"`
CanonicalDir string `yaml:"canonical_dir"`
WorktreeDir string `yaml:"worktree_dir"`
Branch string `yaml:"branch"`
Ref string `yaml:"ref"`
Actions []string `yaml:"actions"`
ChangedFiles *[]string `yaml:"changed_files,omitempty"`
Modules []CampaignModuleReport `yaml:"modules"`
Commit string `yaml:"commit,omitempty"`
Pushed bool `yaml:"pushed,omitempty"`
PR string `yaml:"pr,omitempty"`
RequiredChecks []RemoteCheck `yaml:"required_checks,omitempty"`
Merged bool `yaml:"merged,omitempty"`
}
CampaignRepositoryReport records the isolated worktree used for one GitHub repository. Modules can share a repository/worktree when a repo contains more than one go.mod.
type FileChange ¶
type FileChange struct {
Path string `json:"path"`
Language string `json:"language"`
OriginalSHA256 string `json:"original_sha256"`
Updated []byte `json:"-"`
Steps []string `json:"steps"`
}
FileChange describes one planned, atomic file replacement.
type Finding ¶
type Finding struct {
Path string `json:"path"`
Language string `json:"language"`
RuleID string `json:"rule_id"`
Message string `json:"message"`
Lines []int `json:"lines"`
}
Finding is a semantic-review item discovered while building a plan.
type GoModuleRelease ¶
GoModuleRelease declares the published version that replaces a temporary campaign worktree replacement before a branch may become a pull request. It is intentionally separate from GoModuleRequire: an existing dependency may need an upgrade without being newly introduced by source edits.
type GoModuleRequire ¶
GoModuleRequire declares a module made newly necessary by the migration. It is acted on only by a hierarchical Go campaign; ordinary source-only migration deliberately leaves package manifests alone.
type Plan ¶
type Plan struct {
MigrationID string `json:"migration_id"`
Changes []FileChange `json:"changes"`
Findings []Finding `json:"findings"`
}
Plan is an immutable preview of the edits a migration would make.
type RemoteCheck ¶
RemoteCheck is the required-check state reported by GitHub before --merge performs any merge. WB records it so a campaign report explains a block.
type Report ¶
type Report struct {
SchemaVersion int `yaml:"schema_version"`
Migration ReportMigration `yaml:"migration"`
Status string `yaml:"status"`
Files []ReportFile `yaml:"files"`
ReviewItems []ReportFinding `yaml:"review_items,omitempty"`
}
Report is the portable index of a migration plan. It intentionally records files and operations, rather than embedding a large diff: reviewers and AI agents can ask Git for the exact diff at the repository and path named here.
func NewReport ¶
NewReport converts a plan into a sorted, deterministic report. Status is normally "planned" or "applied".
type ReportFile ¶
type ReportFile struct {
Root string `yaml:"root"`
Path string `yaml:"path"`
AbsolutePath string `yaml:"absolute_path"`
Language string `yaml:"language"`
Operations []string `yaml:"operations"`
OriginalSHA256 string `yaml:"original_sha256"`
GitDiffCommand string `yaml:"git_diff_command"`
}
ReportFile identifies one changed file and the Git command that reveals its detailed patch after an apply operation.
type ReportFinding ¶
type ReportFinding struct {
Root string `yaml:"root"`
Path string `yaml:"path"`
AbsolutePath string `yaml:"absolute_path"`
Language string `yaml:"language"`
RuleID string `yaml:"rule_id"`
Message string `yaml:"message"`
Lines []int `yaml:"lines"`
}
ReportFinding is a semantic-review item linked to a local source file.
type ReportMigration ¶
type ReportMigration struct {
ID string `yaml:"id"`
Title string `yaml:"title,omitempty"`
Format string `yaml:"format"`
}
ReportMigration identifies the migration that produced a report.
type ReviewRule ¶
type ReviewRule struct {
ID string
Language string
Pattern string
ExcludePattern string
Message string
}
ReviewRule identifies a source pattern that needs semantic review after the mechanical plan. It is reported with affected files and line numbers, but never changes source code itself.
func (ReviewRule) Validate ¶
func (r ReviewRule) Validate() error
type Scope ¶
Scope limits the files to which a migration applies. Empty Languages means every language known to the runner.
type Spec ¶
type Spec struct {
Format string
ID string
Title string
Scope Scope
Steps []Step
Review []ReviewRule
GoModuleRequires []GoModuleRequire
GoModuleReleases []GoModuleRelease
}
Spec is a format-versioned, language-neutral migration definition.
The core owns discovery, planning, application, and reporting. Individual adapters own structural edits for their language.
type Step ¶
type Step struct {
Kind string
Language string
From string
To string
Import string
AddImport string
AddImportAs string
Rewrites map[string]string
}
Step is one declarative edit. Kinds are intentionally small:
- text.replace applies an exact replacement to a selected file;
- import.replace delegates an import-path rewrite to a language adapter;
- selector.rewrite delegates a qualified-symbol rewrite to an adapter.
- selector.rename renames one qualified symbol without changing imports.
- composite_field.rename renames a keyed field in typed composite literals.
More language capabilities can be added without changing the runner's plan and apply protocol.
type StructuralAdapter ¶
type StructuralAdapter interface {
Transform(source []byte, filename string, step Step) (updated []byte, changed bool, err error)
}
StructuralAdapter performs syntax-aware migration operations for one language. The engine deliberately does not attempt to normalize Go, Python, and TypeScript ASTs into one representation; each adapter owns correctness for its syntax, imports, and name binding.
type Verification ¶
type Verification string
Verification selects the built-in, non-arbitrary checks a hierarchical Go campaign runs after applying changes. Full is the default for apply runs.
const ( VerifyNone Verification = "none" VerifyCompile Verification = "compile" VerifyTest Verification = "test" VerifyFull Verification = "full" )
type VerificationResult ¶
type VerificationResult struct {
Command string `yaml:"command"`
Passed bool `yaml:"passed"`
Detail string `yaml:"detail,omitempty"`
}
VerificationResult is deliberately compact: command output remains in the process terminal while this index gives reviewers and agents the result.