Documentation
¶
Overview ¶
Package workspace prepares the directory a run works in from a source git checkout — the checkout itself at HEAD, a clean worktree, or a worktree carrying the source's uncommitted work — and syncs folder state between workspaces as git snapshots.
A snapshot is a commit of the working state (tracked and untracked files, never gitignored ones) stored under refs/snapshots/<name>. It is built in a private index, so taking one never touches HEAD, the index or the stash. Pushing and pulling snapshots uses git itself as the folder sync protocol.
Index ¶
- Constants
- Variables
- func LooksSecret(path string) bool
- func NewContext(ctx context.Context, ws *Workspace) context.Context
- func RegisterGate(name string, factory GateFactory)
- type Adapter
- type Change
- type Check
- type CommitMode
- type CommitOptions
- type CommitResult
- type DiffOptions
- type DiffResult
- type Gate
- type GateError
- type GateFactory
- type GateSpec
- type Hook
- type Kind
- type Options
- type Phase
- type PullOptions
- type PushOptions
- type Signature
- type Snapshot
- type Status
- type Workspace
- func (w *Workspace) Changes(ctx context.Context) ([]string, error)
- func (w *Workspace) Commit(ctx context.Context, opts CommitOptions) (*CommitResult, error)
- func (w *Workspace) Diff(ctx context.Context, opts DiffOptions) (*DiffResult, error)
- func (w *Workspace) IsExcluded(path string) bool
- func (w *Workspace) Outgoing(ctx context.Context, from, to string) ([]Change, error)
- func (w *Workspace) Pull(ctx context.Context, opts PullOptions) (*Snapshot, error)
- func (w *Workspace) Push(ctx context.Context, opts PushOptions) error
- func (w *Workspace) Release() error
- func (w *Workspace) Snapshot(ctx context.Context, name string) (*Snapshot, error)
Constants ¶
const ( SecretNamesGateName = "secret-names" MaxSizeGateName = "max-size" )
const ExcludesGateName = "excludes"
ExcludesGateName is the one gate that always runs: content cloned from the source's gitignored files never leaves the workspace.
Variables ¶
var ErrNothingStaged = errors.New("workspace: nothing staged to commit")
ErrNothingStaged is returned when, after excludes are dropped, there is nothing to commit.
Functions ¶
func LooksSecret ¶
LooksSecret reports whether a repo-relative path names a credential file, by base name (including the .env.production family) or by extension.
func NewContext ¶
NewContext returns ctx carrying ws, for code that resolves the directory it works in from the context.
func RegisterGate ¶
func RegisterGate(name string, factory GateFactory)
RegisterGate makes a host gate (a linter, a secret scanner) selectable by name. It panics on a duplicate or reserved name, as a registration mistake.
Types ¶
type Adapter ¶
type Adapter interface {
Prepare(ctx context.Context, source string, opts Options) (*Workspace, error)
}
Adapter prepares one kind of workspace.
type Change ¶
type Change struct {
Status Status `json:"status"`
Path string `json:"path"`
From string `json:"from,omitempty"`
}
Change is one changed path; From is the original path of a rename or copy.
type Check ¶
Check is what a gate inspects. For a commit, Paths is the staged set and Changes the index against From (HEAD). For a push, From..To is the outgoing range, Paths every path any commit in it touched — including ones a later commit removed, which still travel in history — and Changes the net diff.
type CommitMode ¶
type CommitMode string
CommitMode is how Commit records the staged change.
const ( CommitNew CommitMode = "commit" CommitFixup CommitMode = "fixup" CommitAmend CommitMode = "amend" )
type CommitOptions ¶
type CommitOptions struct {
// Paths are staged before committing; nil stages every Change. Excluded
// paths are always dropped.
Paths []string
Mode CommitMode
// Anchor is the commit a fixup targets.
Anchor string
// Message is required for a new commit; an amend keeps the old message
// when it is empty.
Message string
Trailers []string
// Author overrides the configured identity for author and committer.
Author *Signature
Hooks []Hook
Gates []Gate
// GitHooks runs the repository's own git hooks; off by default because the
// workspace pipeline is the hook/gate mechanism.
GitHooks bool
}
CommitOptions configures Commit.
type CommitResult ¶
CommitResult is the commit Commit made and the paths it carried.
type DiffOptions ¶
type DiffOptions struct {
From, To string
// Patch also renders a binary-safe unified diff.
Patch bool
}
DiffOptions selects the two states to compare. Each is a revision — a snapshot commit, refs/snapshots/<name>, or any commit-ish — and empty means the workspace's current working state.
type DiffResult ¶
type Gate ¶
Gate inspects a Check and may block it; it never mutates the workspace.
func ResolveGates ¶
ResolveGates builds the configured gates. No spec means no gates beyond the built-in excludes gate; an unknown name fails.
type GateFactory ¶
GateFactory builds a gate from its configuration; it must reject keys it does not understand.
type GateSpec ¶
type GateSpec struct {
Name string `json:"name" yaml:"name"`
Config map[string]any `json:"config,omitempty" yaml:"config,omitempty"`
}
GateSpec selects a registered gate by name, with its configuration.
type Hook ¶
Hook runs before a commit's gates and may rewrite files (formatters, tidy). The pipeline restages the commit's paths after every hook has run.
type Kind ¶
type Kind string
Kind names how a workspace relates to its source checkout.
const ( // KindHead is the source checkout itself, used in place. KindHead Kind = "head" // KindClean is a new git worktree at Base with none of the source's // uncommitted work. KindClean Kind = "clean" // KindDirty is a new git worktree that also carries the source's staged, // unstaged and untracked work. KindDirty Kind = "dirty" )
type Options ¶
type Options struct {
Source string
Kind Kind
// BaseDir holds generated worktrees (BaseDir/worktrees/<branch>-<uuid>)
// unless Path names the worktree directory explicitly.
BaseDir string
Path string
// Branch is the branch the worktree creates, or with Existing the branch it
// checks out as-is. Unset, a new branch is named <Prefix>/<uuid>.
Branch string
Prefix string
Existing bool
// Base is the commit-ish a new branch starts from (default: the source's
// HEAD).
Base string
// Ignored copy-on-write clones the source's gitignored content
// (node_modules/, build caches, .env) into the worktree. Cloned paths are
// recorded in Workspace.Ignored and never enter a snapshot.
Ignored bool
// Keep leaves the worktree on disk when the workspace is released.
Keep bool
}
Options configures Prepare. Source is any directory inside the source checkout; every other field applies only to worktree kinds.
type PullOptions ¶
type PullOptions struct {
Remote string
Name string
// Force overwrites local changes the snapshot does not descend from.
Force bool
}
PullOptions configures Workspace.Pull. With Remote empty the snapshot is read from this repository's own refs, which every worktree of it shares.
type PushOptions ¶
type PushOptions struct {
Remote string
Ref string
// Source is the commit-ish pushed (default HEAD), e.g. a snapshot commit.
Source string
// Lease is the SHA Ref must still hold on the remote; set, the push may
// rewrite history, but only over exactly that SHA (--force-with-lease).
Lease string
// From is the lower bound of the outgoing range the gates inspect. Unset it
// is Lease, else Ref's current tip on Remote; when neither is known
// locally, the gates see the whole of Source.
From string
Atomic bool
ServerOptions []string
Gates []Gate
}
PushOptions configures Push. Remote is a remote name, URL or repository path; Ref is the full ref written there (refs/heads/x, refs/snapshots/x).
type Snapshot ¶
type Snapshot struct {
Name string
Ref string
Commit string
Tree string
Base string
Previous string
}
Snapshot is a commit of a workspace's working state. Its first parent is Base, the commit the state is relative to; its second parent, when set, is the Previous snapshot under the same name, so successive snapshots form a chain that fast-forwards.
type Workspace ¶
type Workspace struct {
Kind Kind
// Source is the root of the source checkout.
Source string
// Dir is the root the run works in: Source for KindHead, else the worktree.
Dir string
Branch string
// Base is the commit Dir's HEAD pointed at when it was prepared.
Base string
// Carried lists the source's uncommitted paths copied in (KindDirty).
Carried []string
// Ignored lists the gitignored content cloned in from the source as
// compact entries: a file, or a directory ending in "/". It is recorded in
// the worktree's manifest, and IsExcluded keeps it out of every commit,
// snapshot and push even where the worktree's branch does not ignore it.
Ignored []string
// contains filtered or unexported fields
}
Workspace is a prepared directory and what it was prepared from.
func FromContext ¶
FromContext returns the workspace NewContext attached to ctx.
func Open ¶
Open returns the workspace dir belongs to. A worktree Prepare created is reopened from its manifest with the excludes recorded then; any other checkout is a head workspace with none. The returned workspace does not own the directory: Release on it is a no-op.
func Prepare ¶
Prepare resolves opts.Source to its checkout root and prepares the workspace opts.Kind names.
func (*Workspace) Changes ¶
Changes lists every path with uncommitted work — staged, unstaged or untracked — except gitignored and excluded content.
func (*Workspace) Commit ¶
func (w *Workspace) Commit(ctx context.Context, opts CommitOptions) (*CommitResult, error)
Commit stages opts.Paths, runs the hooks and restages, runs the gates over the final staged set, and commits. A refusing gate leaves HEAD untouched.
func (*Workspace) Diff ¶
func (w *Workspace) Diff(ctx context.Context, opts DiffOptions) (*DiffResult, error)
Diff compares two states of the workspace.
func (*Workspace) IsExcluded ¶
IsExcluded reports whether path is content the workspace cloned from the source's gitignored files, which no commit, snapshot or push may carry.
func (*Workspace) Outgoing ¶
Outgoing is the net change between two commits; an empty from means the empty tree, so every path in to is reported as added.
func (*Workspace) Pull ¶
Pull makes the working state match a snapshot: files it holds are written, files it lacks are removed, and gitignored content is left alone. HEAD and the index are not moved, so the pulled state shows as uncommitted work.
Without Force a pull must fast-forward: HEAD must be the snapshot's Base and the working state must be clean or equal to a snapshot this one descends from. Anything else fails, naming the local changes that would be lost.
func (*Workspace) Push ¶
func (w *Workspace) Push(ctx context.Context, opts PushOptions) error
Push runs the gates over everything the push would send, then pushes. A refusing gate sends nothing.
func (*Workspace) Release ¶
Release tears the workspace down: a worktree is removed unless kept, and the source checkout of a head workspace is never touched.
func (*Workspace) Snapshot ¶
Snapshot records the working state — tracked and untracked files, never gitignored ones or the paths in Ignored — as refs/snapshots/<name>. HEAD, the index and the working tree are left untouched. An unchanged state returns the existing snapshot instead of cutting a new one.