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

shellcore

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 29 Imported by: 0

Documentation

Overview

Package shellcore is the evaluator, formatter and built-in helpers behind the public shell package. Nothing here is covered API.

Index

Constants

View Source
const (
	ExitOK    = 0
	ExitError = 1
	ExitUsage = 2
)

Exit statuses of a session.

View Source
const (
	// ExitInterrupted is the exit status of a session that Ctrl-C ended in
	// the middle of an evaluation.
	ExitInterrupted = 130
)
View Source
const HelperQualifier = "project"

HelperQualifier is how a session reaches the project's own helpers: project.Name(...).

View Source
const StartupPointer = "Go console: help() lists the helpers and `tango shell --help` what the interpreter cannot run."

StartupPointer is the one line a session prints when it starts.

Variables

View Source
var ErrReadOnly = errors.New("the shell is read-only (--readonly)")

ErrReadOnly is wrapped by every write verb of a read-only session.

View Source
var Limitations = []Limitation{
	{
		Feature:    "the min and max builtins",
		Workaround: "compare with if, or write a small function",
		Examples:   []Example{{Code: "min(1, 2)"}, {Code: "max(1, 2)"}},
		// contains filtered or unexported fields
	},
	{
		Feature:    "the clear builtin",
		Workaround: "delete the keys in a loop: for k := range m { delete(m, k) }",
		Examples:   []Example{{Setup: []string{`m := map[string]int{"a": 1}`}, Code: "clear(m)"}},
		// contains filtered or unexported fields
	},
	{
		Feature:    "inferring the type arguments of a generic function whose result type differs from its argument types",
		Workaround: "give the type arguments explicitly, as in Map[int, string](xs, f)",
		Examples: []Example{{
			Setup: []string{"func Map[T, U any](xs []T, f func(T) U) []U { var out []U; for _, x := range xs { out = append(out, f(x)) }; return out }"},
			Code:  `Map([]int{1}, func(i int) string { return "x" })`,
		}},
		// contains filtered or unexported fields
	},
	{
		Feature:    "ranging over a function, or over an integer (for i := range 3)",
		Workaround: "use a counting for loop, or call the function with a callback",
		Examples: []Example{
			{Code: "for v := range func(yield func(int) bool) { yield(1) } { _ = v }"},
			{Code: "for i := range 3 { _ = i }"},
		},
		// contains filtered or unexported fields
	},
}

Limitations lists what is known not to run, in the order the help shows it.

Functions

func Balanced

func Balanced(src string) bool

Balanced reports whether src has no open bracket, string or comment, so that a line of input can be evaluated rather than continued on the next. Brackets inside strings, runes and comments do not count.

func ExportHelpers

func ExportHelpers(session *Session, helpers map[string]any) error

ExportHelpers makes a project's helpers callable as project.Name. Every name must be an exported Go identifier, and a nil value is refused. A helper that is a function is called like any function; anything else is a constant of the session. Only plain values (primitives, maps, slices and errors) are supported across the boundary: a value of a project type arrives, but using its fields or methods from the session is not something the shell promises.

func Format

func Format(v any, limit int) string

Format renders v the way the shell prints results: deterministic, one line per value, one line per row for a list of maps. A zero v prints nothing. limit is the most runes a single line may hold before it is cut with an ellipsis; 0 never truncates.

func Help

func Help(projectHelpers []string) string

Help is the text of help(): the helpers, the project's own helpers and the limits of the interpreter.

func Run

func Run(ctx context.Context, s IO, boot Boot, args []string) int

Run executes one shell session for args and returns the process exit code. Results go to s.Out; errors, the database line and everything else a script should not parse go to s.Err.

func Usage

func Usage() string

Usage is the text of `tango shell --help`: the options and what the interpreter cannot run.

Types

type Boot

type Boot struct {
	Registry *tango.Registry
	Store    *db.Store

	ReadOnly      bool
	Helpers       map[string]any
	DatabaseLabel string
}

Boot is the booted project a session works on.

type Example

type Example struct {
	Setup []string
	Code  string
}

Example is code that shows a Limitation.

type History

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

History keeps the lines typed at the prompt, newest first for the terminal's up-arrow, and appends each to a file so the next session in the same project starts with them. It implements golang.org/x/term's History.

The file can hold secrets typed into the shell, so it is private to the user (mode 0600, in a 0700 directory).

func OpenHistory

func OpenHistory(dir string, warn io.Writer) *History

OpenHistory loads the history for the project in dir, from the user's cache directory. TANGO_SHELL_HISTORY=off, or a cache directory that cannot be used, leaves it in memory only; the second case is reported once to warn.

func (*History) Add

func (h *History) Add(entry string)

Add records a typed line. Blank lines and a repeat of the previous line are not kept.

func (*History) At

func (h *History) At(idx int) string

func (*History) Entries

func (h *History) Entries() []string

Entries returns the kept lines, oldest first.

func (*History) Len

func (h *History) Len() int

Len and At let the terminal walk the history, index 0 being the newest.

type IO

type IO struct {
	In       io.Reader
	Out, Err io.Writer
}

IO is where a shell session reads and writes.

type Invocation

type Invocation struct {
	// Eval holds the -c expression; HasEval distinguishes "-c ”" from no -c.
	Eval     string
	HasEval  bool
	ReadOnly bool
	Help     bool
}

Invocation is what the command line of a shell session asks for.

func ParseArgs

func ParseArgs(args []string) (Invocation, error)

ParseArgs reads the shell's command line: -c EXPR, --readonly, --help.

type Limitation

type Limitation struct {
	// Feature names what does not work.
	Feature string
	// Workaround says what to write instead.
	Workaround string
	// Examples each fail today; Setup runs first, one chunk per element.
	Examples []Example
	// contains filtered or unexported fields
}

Limitation is a piece of Go the interpreter (Yaegi, pinned at v0.16.1) cannot run, which a person can reasonably type. The table of these is the single source for the hint printed after a failure, for help(), for `tango shell --help` and for the regression test that notices when a release of the interpreter starts supporting one. The guide's table must say the same.

type PanicError

type PanicError struct {
	Value any
	// Interpreted is true for a panic the program itself raised (a panic
	// call in typed code, or a helper that panicked) and false for one the
	// interpreter raised because it could not run the Go it was given.
	Interpreted bool
}

PanicError is a panic recovered from the interpreter. The session that raised it is still usable.

func (*PanicError) Error

func (e *PanicError) Error() string

type Session

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

Session is one interpreter whose variables and imports persist across Eval calls.

func NewSession

func NewSession(in io.Reader, out, errOut io.Writer, limit int) (*Session, error)

NewSession starts an interpreter that writes what interpreted code prints to out and errOut, and reads from in.

func (*Session) Eval

func (s *Session) Eval(code string) (printed string, err error)

Eval runs code and returns what to print for it: the formatted value of a final expression, and nothing for declarations, assignments and nil. A non-nil error value, whether returned by a call or the value of the expression, comes back as the error. A panic in the interpreter comes back as a *PanicError.

func (*Session) Export

func (s *Session) Export(qualifier string, funcs map[string]any) error

Export makes funcs callable from interpreted code: by bare name when qualifier is empty, otherwise as qualifier.Name. A call to one of them as the last expression of a line shows every value it returns, including a non-nil error, which the interpreter would otherwise drop.

type UsageError

type UsageError struct{ Message string }

UsageError reports a command line the shell cannot accept; the caller exits with status 2.

func (*UsageError) Error

func (e *UsageError) Error() string

type Verbs

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

Verbs are the built-in, map-based helpers a session can call by bare name: Models, Describe, Get, List, Count, Create, Update, Delete and Context. Rows are map[string]any keyed by Go field name; models are addressed as app.Model.

func NewVerbs

func NewVerbs(ctx context.Context, models *model.Registry, store *db.Store, readOnly bool) *Verbs

NewVerbs returns the verbs over models and store. readOnly makes the verbs that write fail.

func (*Verbs) Context

func (v *Verbs) Context() context.Context

Context is the context of the shell session.

func (*Verbs) Count

func (v *Verbs) Count(name string, query ...map[string]any) (int, error)

Count returns how many rows of model match the where key of an optional query map; order, limit and offset do not affect it.

func (*Verbs) Create

func (v *Verbs) Create(name string, row map[string]any) (map[string]any, error)

Create stores a new row built from the field-to-value map and returns the stored row, including the primary key the database assigned.

func (*Verbs) Delete

func (v *Verbs) Delete(name string, pk any) error

Delete removes the row whose primary key is pk.

func (*Verbs) Describe

func (v *Verbs) Describe(name string) ([]map[string]any, error)

Describe lists the fields of a model, one row per field.

func (*Verbs) Functions

func (v *Verbs) Functions() map[string]any

Functions are the verbs by the bare name a session calls them by.

func (*Verbs) Get

func (v *Verbs) Get(name string, pk any) (map[string]any, error)

Get returns the row of model whose primary key is pk.

func (*Verbs) List

func (v *Verbs) List(name string, query ...map[string]any) ([]map[string]any, error)

List returns the rows of model matching an optional query map with the keys where (field to value, equality only), order (field names, "-" prefix for descending), limit and offset.

func (*Verbs) Models

func (v *Verbs) Models() []string

Models lists every registered model as app.Model, sorted.

func (*Verbs) Update

func (v *Verbs) Update(name string, pk any, changes map[string]any) (map[string]any, error)

Update changes the given fields of the row whose primary key is pk and returns the stored row.

Jump to

Keyboard shortcuts

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