Help us shape the future of Go! Take the 2026 Go Developer Survey

codemod

package
v1.0.14 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package codemod holds forge's deterministic rewrites of a project's OWN files: the mechanical half of a release that changed a shape the project wrote down. Each codemod is keyed to the release that broke the shape — the same key its migration skill (skills/forge/migrations/<version>) carries — and is reachable two ways:

  • `forge fix <name>` runs one on request (`--dry-run` lists what it would rewrite);
  • `forge project upgrade` runs every codemod marked Upgrade whose release the project's baseline predates, before it touches a template.

A codemod is idempotent and decides from the tree, never from a version: on a project that does not have the old shape it rewrites nothing and reports nothing. That is what lets upgrade run it on every crossing, and what makes a second run a no-op.

The intent-bearing half of a migration — the choices only a person or an agent can make — stays prose, in the migration skill. A codemod that cannot decide something says so in its report rather than guessing.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Codemod

type Codemod struct {
	// Name is the `forge fix <name>` subcommand.
	Name string
	// Version is the release that broke the shape this rewrites. It names
	// the migration skill that tells the rest of the story
	// (skills/forge/migrations/<Version>).
	Version string
	// Short is the one-line summary `forge fix --help` prints.
	Short string
	// Long is the subcommand's help body.
	Long string
	// Upgrade marks a codemod `forge project upgrade` runs on its own when
	// the project's baseline predates Version. Only a rewrite that keeps the
	// program's meaning exactly — a rename, a moved symbol — qualifies; a
	// restructuring is run on request, after the person running it has read
	// what it does.
	Upgrade bool
	// CleanTree marks a codemod that replaces files wholesale: `forge fix`
	// refuses to run it over uncommitted changes (unless --allow-dirty), so
	// `git diff` is the review and `git checkout .` the undo.
	CleanTree bool
	// Scoped marks a codemod that honours Options.Scope: `forge fix <name>
	// --scope <path>` rewrites only the files under the paths named, while
	// whatever it analyses to decide a rewrite still reads the whole
	// project. A codemod whose rewrite is one decision over the whole tree
	// (a restructuring) leaves it false, and `forge fix` offers no --scope.
	Scoped bool
	// Run rewrites the project at dir, as opts asks.
	Run func(dir string, opts Options) (Report, error)
}

Codemod is one deterministic rewrite.

func All

func All() []Codemod

All returns every codemod, by release and then name.

func Lookup

func Lookup(name string) (Codemod, bool)

Lookup returns the codemod named name.

type Options

type Options struct {
	// Write false changes nothing: the run reports what it would rewrite.
	Write bool
	// Scope restricts the files the run may rewrite (and reports on) to
	// those under its paths. Nil is the whole project. Only a Scoped
	// codemod is handed one.
	Scope *Scope
}

Options is how one codemod run is asked to behave.

type Report

type Report struct {
	// Rewrites are the mechanical rewrites, one human-readable line each
	// ("internal/app/lifecycle.go: lifecyclekit.Run → operatorkit.Run"),
	// in the order they were made.
	Rewrites []string
	// Next is what the codemod could not decide, as the exact edits left to
	// make, in order. Empty when the rewrite is the whole job.
	Next []string
	// Blocked are the shapes that stop a restructuring codemod from
	// writing anything — each with its file:line and the edit that clears
	// it. A codemod that reports any rewrites nothing: a conversion that
	// compiles but silently changes what a process does is worse than none.
	Blocked []string
	// Verify are the commands that prove the result. Empty means the
	// default: go build, forge generate, forge lint.
	Verify []string
}

Report is what one codemod run did, or (dry run) would do.

func (Report) Changed

func (r Report) Changed() bool

Changed reports whether the run rewrote (or would rewrite) anything.

type Scope

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

Scope is a set of project-relative paths — directories or files — that bounds the files a run rewrites. Parallel lanes in one checkout each run a codemod over their own slice, as `forge lint --scope` lints one. A nil *Scope is the whole project, and every method is nil-safe.

func ParseScope

func ParseScope(root string, raw []string) (*Scope, error)

ParseScope validates raw scope paths against the project at root. Each must exist and lie inside the project: a typo would otherwise scope the run to nothing and report it clean.

func (*Scope) Contains

func (s *Scope) Contains(rel string) bool

Contains reports whether rel — a project-relative path — lies under the scope. Everything does under a nil scope.

func (*Scope) Paths

func (s *Scope) Paths() []string

Paths returns the scope's project-relative paths, none for the whole project.

func (*Scope) String

func (s *Scope) String() string

String lists the scope's paths, "" for the whole project.

Jump to

Keyboard shortcuts

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