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

script

package
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package script runs user Go scripts with the yaegi interpreter, exposing the sdb API plus the Go standard library.

Index

Constants

View Source
const (
	SevError   = "error"
	SevWarning = "warning"
)

The two severities. An error means Run would fail (or never start); a warning is legal Go that probably does not do what was meant.

View Source
const NotOnSymbol = "rename works on a name the script declares: a variable, constant, type, function, method, field, label or import"

NotOnSymbol is the sentence for a caret on nothing renamable, shared with the editor's rename box so both say it in the same words.

Variables

This section is empty.

Functions

func HasError added in v0.9.0

func HasError(diags []Diag) bool

HasError reports whether any diag is an error rather than a warning.

func Run

func Run(path string, s *sdb.S) error

Run interprets the Go script at path and invokes its Run(s *sdb.S) error.

func RunSource added in v0.9.0

func RunSource(name, src string, s *sdb.S) error

RunSource is Run for a script that is text rather than a file: a sample built into the binary, run by `dbc script NAME` without being copied out first. name stands in for the path in errors.

Types

type Diag added in v0.9.0

type Diag struct {
	Line     int    `json:"line"`
	Col      int    `json:"col"`
	Severity string `json:"severity"` // SevError or SevWarning
	Msg      string `json:"msg"`
}

Diag is one problem Check found, at a 1-based line and column (column 0 when only the line is known).

func Check added in v0.9.0

func Check(name, src string) []Diag

Check finds what is wrong with a script without running it, so an editor can mark errors on their lines as the user types, and `dbc script --check` can gate a scripts repo in CI. It never executes the script: not Run, not init(), not a package-level initializer.

src ─► 1. parse (go/parser) ── syntax errors? ──► those, and stop
        │                                         (the passes below need a tree)
        ├► 2. signature: package main, func Run(s *sdb.S) error, from the AST
        ├► 3. lint: m[k], _ = …  (yaegi drops the write)
        └► 4. compile (yaegi, newInterp + Compile, no Execute)

Why each pass:

  1. go/parser first, because its positions are exact and it reports up to ten errors; yaegi stops at its first and words it less helpfully.
  2. Run's signature from the AST, not the interpreter: asking yaegi for main.Run needs Execute first, which runs init() and the package's var initializers — exactly what a check must never do.
  3. The lint is the one case that has cost real time: yaegi compiles and runs a two-value assignment into a map element and stores nothing (traefik/yaegi#1655). Without types it cannot tell a map from a slice, so it flags both and says so; a slice there is rare.
  4. yaegi's compile pass (type analysis and control flow, no code run) catches what the parser cannot: an undefined name, a type mismatch, an import a script cannot have. It is the same interpreter Run builds (newInterp), so the two agree on what a script may import. It reports only its first error, and does not catch everything the Go compiler would (an unused variable passes).

Diags come back sorted by position. A clean script is nil.

func (Diag) String added in v0.9.0

func (d Diag) String() string

String is the diag as a compiler prints one, after the file name: "12:5: undefined: foo", with "warning: " before a warning's message.

type Edit added in v0.12.0

type Edit struct {
	From int    `json:"from"`
	To   int    `json:"to"`
	Text string `json:"text"`
}

Edit replaces [From, To) of the script with Text. From == To inserts.

func Rename added in v0.12.0

func Rename(src string, caret int, name string) (edits []Edit, err error)

Rename is the edits that rename the symbol at byte offset caret of src to name. The error is a sentence for the user: nothing renamable there, the symbol cannot be renamed (Symbol.Fixed), the name is not a Go name, or the renamed script would mean something else.

type Span added in v0.11.0

type Span struct {
	From int `json:"from"`
	To   int `json:"to"`
}

Span is a byte range of the script, [From, To).

type Symbol added in v0.11.0

type Symbol struct {
	Kind string `json:"kind"` // var, const, type, func, method, field, package, label, builtin
	Name string `json:"name"`
	At   Span   `json:"at"`  // the occurrence under the caret
	Def  *Span  `json:"def"` // nil: declared outside the script
	Uses []Span `json:"uses"`
	// Fixed says why F2 cannot rename it; "" when it can (rename.go).
	Fixed string `json:"fixed,omitempty"`
}

Symbol is what the caret is on. Kind "" means nothing that resolves (a keyword, a literal, white space): the editor has nowhere to go. Def is nil when the declaration is not in the script (a builtin such as len or error, or a member of an imported package); Uses then still lists every occurrence. Uses includes the declaration itself, in buffer order.

func Resolve added in v0.11.0

func Resolve(src string, caret int) (sym Symbol)

Resolve finds the symbol at byte offset caret of src. A caret just past a name (where it rests after typing one) counts as on it.

A script with syntax errors still resolves: go/parser hands back the tree it could build, and the checker binds what is in it. A panic deep in the checker over odd input is a symbol with no kind, never a crash of the server that asked.

Jump to

Keyboard shortcuts

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