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

transform

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package transform exposes the Serialize entry point that renders an *ast.Script back to bash source. It is the inverse of parser.Parse.

Phase 4 scope

Serialize prefers the Origin back-reference parsed scripts carry: when present, it hands the original *syntax.File to mvdan.cc/sh/v3/syntax.Printer for byte-faithful round-trip. This is the path the Phase 4 round-trip acceptance test exercises.

For plugin-synthesized scripts (Origin == nil, arriving in Phase 13 when the transform plugin pipeline lands), we fall back to astToFile — a best-effort inverse translator that reconstructs a *syntax.File from our typed AST and lets the printer fill in default positions. Phase 4 ships only the minimal set of node reconstructors needed to keep the surface honest; later phases extend coverage as new node types come online.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Serialize

func Serialize(s *ast.Script) (string, error)

Serialize renders s back to a bash source string. It prefers the Origin pointer parsed scripts carry; falls back to astToFile for plugin-synthesized scripts.

func WordLit

func WordLit(w *syntax.Word) string

WordLit returns the literal text of w when every part of the word is statically known (plain literals, single-quoted, or double-quoted runs of literals). It returns "" for a nil word or as soon as it encounters any dynamic part (parameter/command/arithmetic expansion), since the literal value is then unknowable at transform time.

Plugins use this to recover a command name or argument from a *syntax.Word without evaluating the script.

Types

type BashTransformResult

type BashTransformResult struct {
	Script   string
	AST      *ast.Script
	Metadata map[string]any
}

BashTransformResult is the return type of Pipeline.Transform. Script is the re-serialized source after every plugin has run; AST is the final post-transform typed AST; Metadata is the keyed bag.

type Context

type Context struct {
	AST      *ast.Script
	Metadata map[string]any
}

Context is the per-Exec, per-plugin invocation payload handed to Plugin.Transform. AST is the typed AST the parser produced. Metadata is the running bag accumulated by previous plugins in the pipeline, keyed by plugin Name — plugins may read prior plugins' results here.

type Pipeline

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

Pipeline is the ordered plugin orchestrator.

func New

func New() *Pipeline

New returns an empty Pipeline.

func (*Pipeline) Plugins

func (p *Pipeline) Plugins() []Plugin

Plugins returns the registered plugin slice in registration order. The returned slice is a copy; the caller may mutate it freely.

func (*Pipeline) Transform

func (p *Pipeline) Transform(script string) (*BashTransformResult, error)

Transform parses the given script, dispatches every registered plugin in order, then re-serializes the post-transform AST back to bash source. Returns the BashTransformResult bundle: the new Script, the post-transform AST, and the plugin-keyed Metadata bag.

When zero plugins are registered, Transform is a thin parse+serialize pass-through (the script flows out untouched, modulo printer-driven whitespace normalization).

Parse errors are returned as *parser.ParseError (aliased to gobash.ParseError at the top-level package).

func (*Pipeline) TransformAST

func (p *Pipeline) TransformAST(parsed *ast.Script) (*BashTransformResult, error)

TransformAST runs the pipeline on an already-parsed AST. The AST must have a non-nil Origin (i.e. it must come from parser.Parse); plugin-synthesized ASTs without an Origin can still be passed, but Serialize will fall back to the limited astToFile path.

func (*Pipeline) Use

func (p *Pipeline) Use(plugin Plugin) *Pipeline

Use appends a plugin to the pipeline and returns the same pipeline for fluent chaining: New().Use(a).Use(b).

type Plugin

type Plugin interface {
	Name() string
	Transform(ctx Context) Result
}

Plugin is the closed interface implemented by every transform-pipeline plugin. Plugins observe (and optionally rewrite) the AST of a script before it is handed to the runtime, and may attach plugin-scoped metadata that surfaces in BashExecResult.Metadata under the plugin's Name.

Mutating the AST

The Context exposes the typed *ast.Script the parser produced. Most of go-bash's AST round-trip serialization is driven by Script.Origin (the *syntax.File the mvdan/sh parser produced) — see transform.Serialize. Plugins that need to rewrite source therefore mutate Origin in place (rather than rebuilding the typed AST). This keeps the inverse-translator surface small and lets the round-trip always go through mvdan/sh's printer for byte-faithful output.

Plugins that only inspect the AST should return Result.AST == ctx.AST unchanged.

type Result

type Result struct {
	AST      *ast.Script
	Metadata any
}

Result is what a Plugin.Transform returns. AST is the (possibly same, possibly mutated) AST the pipeline continues with; nil is treated as "no change" and the prior AST flows through. Metadata is the plugin's own metadata payload — the pipeline stores it under the plugin's Name in the shared bag, exposed to subsequent plugins (via Context.Metadata) and to the host (via BashExecResult.Metadata).

Directories

Path Synopsis
plugins
collector
Package collector implements the CommandCollectorPlugin: a read-only transform plugin that walks the parsed AST and reports the command name of every leaf SimpleCommand it encounters.
Package collector implements the CommandCollectorPlugin: a read-only transform plugin that walks the parsed AST and reports the command name of every leaf SimpleCommand it encounters.
tee
Package tee implements the TeePlugin: a transform plugin that wraps every non-trivial pipeline stage with `| tee /OUT/<idx>-<cmd>.stdout.txt` so the host can post-mortem the per-stage output of a script.
Package tee implements the TeePlugin: a transform plugin that wraps every non-trivial pipeline stage with `| tee /OUT/<idx>-<cmd>.stdout.txt` so the host can post-mortem the per-stage output of a script.

Jump to

Keyboard shortcuts

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