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

core

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Overview

Package core provides the shared language runner runtime: profile loading, alias resolution, interpreter discovery and installation, source materialization, and byte-oriented execution. Language-specific profiles and templates are owned by their respective language packages and composed into the public RunnerFiles() view used by runtime integrations.

Package lang provides reusable language runner discovery, registration, installation, and byte-oriented execution primitives. Flow-specific syntax and stream conversion live in the nexssflow subpackage.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFound = xerr.NotFound("interpreter not found")

ErrNotFound is the sentinel from lookPathCmd. Tests assert against this rather than a string match.

View Source
var Registry = map[string]*Language{}

Registry is the process-global table of known languages. Populated at init() by LoadRunners (from embedded runners/*.nflow) and at parse time by RegisterDefine (define.go) when @lang.define is used.

Keyed by (ID, Version) — versioned variants of the same language (python "", python "2", python "3") are distinct entries. The unversioned Lookup(id, "") returns the default variant.

Two languages with the same (ID, Version) panic — silent override would let a stale registration win and produce confusing runtime behavior.

Functions

func AutoInstallDisabled

func AutoInstallDisabled(ctx context.Context) bool

AutoInstallDisabled reports whether automatic interpreter installation is disabled in ctx.

func Execute

func Execute(ctx context.Context, program Program, stdin []byte, executor Executor) (stdout, stderr string, err error)

Execute runs a Program using raw stdin bytes and returns raw stdout bytes as a string. Value serialization/deserialization is intentionally left to the host adapter. Inline source is materialized in a private temporary directory; file-backed programs use their original path and contents.

func Install

func Install(id, version string) (cmd string, args []string, err error)

Install is the package-level entry point used by `nflow lang install <id>`. Wraps installEnsure so callers don't construct the type.

func LoadRunners

func LoadRunners() error

LoadRunners parses every runners/*.nflow profile from the embed and registers each as a Language. The package calls this once at init; manual repeated calls return a duplicate-registration error.

func Register

func Register(l Language)

Register adds a language to the Registry. Duplicate (ID, Version) panic, matching the project rule: "collisions panic; missing contracts fail loudly."

func RegisterDefine

func RegisterDefine(d Define) error

RegisterDefine adds a user-defined language to the Registry.

Called by the @lang.define directive. Go hosts may also register a language directly before compiling flows.

Returns an error rather than panicking: user-defined languages fail gracefully, while builtins (which the developer shipped intentionally) panic on duplicate registration via Register.

func RegisterRunnerSpec

func RegisterRunnerSpec(spec *RunnerSpec) error

RegisterRunnerSpec validates and registers a runner profile and all of its aliases. Duplicate IDs or aliases return a Kernel Conflict error without partial mutation.

func Resolve

func Resolve(lang *Language, version string) (cmd string, args []string, err error)

Resolve is the default runtime entry point for "give me a runnable command."

It tries a find-only selector, preferring SelectContext when available. On miss, it calls ensureHook, which installs and re-resolves by default or returns a NotInstalledError if the runner has no recipe or installation fails. Context-scoped internal callers may disable installation without changing this production default. Preflight uses the find-only selector directly and never triggers installation.

func ResolveAlias

func ResolveAlias(tag string) (id, version string, ok bool)

ResolveAlias maps a runner keyword to its canonical language ID and version. The returned ok is false for an unknown alias.

func RunnerFiles

func RunnerFiles() fs.FS

RunnerFiles returns the embedded runner profile filesystem. Paths are rooted at "runners/" so adapters can expose the profiles as source modules.

func WithAutoInstallDisabled

func WithAutoInstallDisabled(ctx context.Context) context.Context

WithAutoInstallDisabled marks a context so Resolve and execution report missing interpreters without invoking package managers.

Types

type Alias

type Alias struct {
	Tag     string
	ID      string
	Version string
}

Alias maps a runner keyword (for example, "py") to a canonical language ID and version. Aliases are derived from runner profiles, not hand-maintained.

func Aliases

func Aliases() []Alias

Aliases returns a sorted copy of the aliases currently registered.

type Check

type Check struct {
	ID      string
	Version string
	Tag     string
	Cmd     string
	Err     error
}

Check is one language examined during preflight.

type DefaultExecutor

type DefaultExecutor struct{}

DefaultExecutor runs the selected interpreter with os/exec. Hosts can inject a different Executor into Execute to centralize subprocess policy.

func (DefaultExecutor) Run

func (DefaultExecutor) Run(ctx context.Context, cmd string, args []string, stdin []byte) (stdoutText, stderrText string, runErr error)

Run implements Executor.

type Define

type Define struct {
	ID           string   // required, e.g. "gleam"
	Version      string   // optional, e.g. "3"
	Ext          string   // required, including dot, e.g. ".gleam"
	Aliases      []string // optional, e.g. ["gleam", "beam"]
	Find         []string // required, e.g. ["gleam", "run"]
	Stdin        string   // "json" (default) | "text" | "raw"
	Stdout       string   // "json" (default) | "text" | "raw"
	FileTemplate string   // optional JSON-in/JSON-out source for .file :autocreate
	Install      OSRecipe // optional, per-OS install commands
	Deps         string   // optional command template containing {file}
	DepsMarker   string   // optional source marker that selects Deps
}

Define is the in-flow @lang.define directive's data model.

It lets users register a language the bundle doesn't ship built-in, without forking the repo or writing a runner file. Example DSL:

@lang.define "gleam" {
  ext: ".gleam"
  aliases: ["gleam"]
  find: ["gleam run"]
  stdin: "json"
  stdout: "text"
}
{ "value": "x" } -> gleam"..."

This is the runtime equivalent of a runners/*.nflow file — same fields, same RunnerSpec underneath. Definitions update the process-wide registry and remain registered for the process lifetime; each (ID, Version) and alias must be declared only once.

type Ensure

type Ensure interface {
	Ensure(lang *Language, version string) (cmd string, args []string, err error)
}

Ensure is the auto-install seam.

Resolve calls Ensure when a language's Select (find-only) fails. The default installEnsure runs the runner's per-OS recipe and re-resolves the interpreter; tests or hosts can replace the hook when needed.

Pure Go: no nexssp/ensure, no Node.js. Recipes call winget/brew/apt/npm directly. See install.go.

func DefaultEnsure

func DefaultEnsure() Ensure

DefaultEnsure returns the production installer, which executes the current platform's recipe declared by the runner profile and then resolves again.

type EnsureFunc

type EnsureFunc func(*Language, string) (string, []string, error)

EnsureFunc adapts a function to the Ensure interface.

func (EnsureFunc) Ensure

func (f EnsureFunc) Ensure(language *Language, version string) (cmd string, args []string, err error)

Ensure implements Ensure.

type ExecError

type ExecError struct {
	ID     string
	Cmd    string
	Cause  error
	Stderr string
}

ExecError is returned when an interpreter process exits unsuccessfully.

func (*ExecError) Error

func (e *ExecError) Error() string

func (*ExecError) Unwrap

func (e *ExecError) Unwrap() error

type Executor

type Executor interface {
	Run(ctx context.Context, cmd string, args []string, stdin []byte) (stdout, stderr string, err error)
}

Executor runs one resolved program and returns stdout and stderr as strings. Implementations must honor context cancellation.

type ExecutorFunc

type ExecutorFunc func(context.Context, string, []string, []byte) (string, string, error)

ExecutorFunc adapts a function to the Executor interface.

func (ExecutorFunc) Run

func (f ExecutorFunc) Run(ctx context.Context, cmd string, args []string, stdin []byte) (stdout, stderr string, err error)

Run implements Executor.

type Language

type Language struct {
	// ID is the canonical language identifier, e.g. "python".
	ID string

	// Ext is the file extension used when materializing source to disk,
	// including the leading dot, e.g. ".py".
	Ext string

	// Select is the legacy context-free, find-only selector for languages
	// registered directly. Runner profiles use SelectContext instead.
	Select func(version string) (cmd string, args []string, err error)
	// SelectContext resolves a version while honoring the caller's context.
	// Runtime and preflight resolution prefer this selector when available.
	SelectContext func(ctx context.Context, version string) (cmd string, args []string, err error)

	// Encode serializes the incoming stream value to bytes for stdin.
	// JSON is the default; shell/raw languages use text.
	Encode func(v any) ([]byte, error)

	// Decode parses stdout back into a typed value the next atom sees.
	// Takes string (not []byte) to avoid the []byte(string) copy from
	// external.ExecResult.Stdout. JSON is the default; shell/raw return string.
	Decode func(s string) (any, error)
	// contains filtered or unexported fields
}

Language is the runtime view of a runner spec. One per (language, version). Tags are gone by here — runner file aliases are applied at parse time, and from this struct onward every code path speaks the canonical ID ("python"), never the tag ("py").

One struct, every language. New languages add a runners/<id>.nflow file, zero Go changes. See runners.go.

func Lookup

func Lookup(id, version string) (*Language, error)

Lookup returns the registered language for an (ID, Version) pair. The exact version is matched — Lookup("python", "3") returns the v3 variant, Lookup("python", "") returns the default.

func (*Language) Spec

func (l *Language) Spec() (RunnerSpec, bool)

Spec returns a copy of the language's runner profile. Languages registered directly without a RunnerSpec return the zero value and false.

func (*Language) Version

func (l *Language) Version() string

Version returns the language's version string. Reads from spec.Version when a spec is attached (the runner-file path); "" otherwise (the @lang.define path stores version on the spec too via RegisterDefine).

type NotInstalledError

type NotInstalledError struct {
	ID, Version string
	Cause       error // optional: why an auto-install attempt failed
}

NotInstalledError is the unified "interpreter missing" error. Preflight groups these into a single Report; the CLI prints the report and aborts.

func (*NotInstalledError) Error

func (e *NotInstalledError) Error() string

func (*NotInstalledError) Unwrap

func (e *NotInstalledError) Unwrap() error

type OSRecipe

type OSRecipe struct {
	Windows []string `json:"windows,omitempty"`
	Darwin  []string `json:"darwin,omitempty"`
	Linux   []string `json:"linux,omitempty"`
}

OSRecipe holds per-OS install commands. Each entry is a full command line; the first element is the binary, the rest are args.

func (OSRecipe) RecipeFor

func (r OSRecipe) RecipeFor() []string

RecipeFor returns the install command for the current OS, or nil if no recipe is defined. Pure Go: callers run it via os/exec.

type Preflight

type Preflight struct {
	// Installer, if non-nil, is invoked for missing interpreters. A nil
	// Installer keeps preflight find-only.
	Installer Ensure
}

Preflight checks interpreter availability for a set of programs. It has no compiler or AST dependency; host adapters decide when and how to invoke it.

func (Preflight) Run

func (p Preflight) Run(programs []Program) Report

Run checks each distinct (ID, Version) pair in programs, sorting results for deterministic diagnostics. When configured, Installer handles missing interpreters before the report is returned.

func (Preflight) RunContext

func (p Preflight) RunContext(ctx context.Context, programs []Program) Report

RunContext checks interpreter availability using the caller's context.

type Program

type Program struct {
	ID         string
	Version    string
	Source     string
	Tag        string
	SourceFile string
}

Program describes source to execute with a registered language runner. It contains no parser- or compiler-specific data.

func FileProgramForTag

func FileProgramForTag(tag, sourceFile, source string) (Program, error)

FileProgramForTag resolves a runner alias and constructs a program backed by an existing source file. The caller resolves the path relative to its own source file and supplies contents for preflight/dependency-marker inspection.

func ProgramForTag

func ProgramForTag(tag, source string) (Program, error)

ProgramForTag resolves a runner alias and constructs a generic program. Interpreter discovery is intentionally deferred to Resolve or Execute.

type Report

type Report struct {
	Checked []Check
	Missing []Check
}

Report is the result of a preflight pass. Zero Missing entries means every requested interpreter is available (or was installed successfully).

func (Report) Error

func (r Report) Error() string

Error formats a concise report suitable for wrapping in a host diagnostic.

func (Report) OK

func (r Report) OK() bool

OK reports whether every requested language was resolved.

func (Report) SelfTestSkipReason

func (r Report) SelfTestSkipReason() string

SelfTestSkipReason returns a skip reason only when missing interpreter tooling is the sole failure; unknown language/configuration errors remain failures.

type RunnerSpec

type RunnerSpec struct {
	ID               string   `json:"id,omitempty"`
	Version          string   `json:"version,omitempty"`
	Ext              string   `json:"ext"`
	Aliases          []string `json:"aliases,omitempty"`
	Find             []string `json:"find"`
	Stdin            string   `json:"stdin,omitempty"`
	Stdout           string   `json:"stdout,omitempty"`
	FileTemplate     string   `json:"file_template,omitempty"`
	FileTemplateFile string   `json:"file_template_file,omitempty"`
	FilePathMode     string   `json:"file_path_mode,omitempty"`
	Install          OSRecipe `json:"install,omitzero"`
	Deps             string   `json:"deps,omitempty"`
	DepsMarker       string   `json:"deps_marker,omitempty"`
}

RunnerSpec is the data model parsed from a @lang.runner block in a .nflow file. One RunnerSpec per (language, version). The Go side is generic — adding a language means shipping a runner profile and optional template asset, with no runtime-specific Go changes.

Native profile example:

@description "Python runner with JSON streams"
@lang.runner "python" {
  ext: ".py"
  aliases: ["py", "python"]
  find: ["python3", "python", "py -3"]
  stdin: "json"
  stdout: "json"
  file_template_file: "templates/python.py"
}

func ParseRunner

func ParseRunner(src string) (*RunnerSpec, error)

ParseRunner parses one @lang.runner or @lang.define block using native NFlow key/value and list syntax.

func (RunnerSpec) Decode

func (s RunnerSpec) Decode() (func(string) (any, error), error)

Decode resolves the stdout codec name to a function.

func (RunnerSpec) Encode

func (s RunnerSpec) Encode() (func(any) ([]byte, error), error)

Encode resolves the stdin codec name to a function.

func (RunnerSpec) FindCmd

func (s RunnerSpec) FindCmd() (cmd string, args []string, err error)

FindCmd tries each entry in Find via lookPathCmd. The first candidate that resolves to a usable interpreter wins; on Windows, py.exe is probed with its selected version and WSL is probed for a registered Bash distribution.

Each Find entry is split on whitespace; the first token is the binary, the rest are pre-args (for example, "py -3" becomes cmd="py", args=["-3"]). The materialized source path is appended later by the runtime.

func (RunnerSpec) FindCmdContext

func (s RunnerSpec) FindCmdContext(ctx context.Context) (cmd string, args []string, err error)

FindCmdContext probes interpreter candidates while honoring cancellation.

type UnknownLanguageError

type UnknownLanguageError struct {
	ID, Version string
}

UnknownLanguageError is returned by Lookup and ParseTag when the alias resolves to an (ID, Version) pair the Registry has no entry for. It surfaces as a compile-time SourceError via the parser hook.

func (*UnknownLanguageError) Error

func (e *UnknownLanguageError) Error() string

func (*UnknownLanguageError) Unwrap

func (e *UnknownLanguageError) Unwrap() error

type UnknownTagError

type UnknownTagError struct{ Tag string }

UnknownTagError reports an alias which is not registered by a runner.

func (*UnknownTagError) Error

func (e *UnknownTagError) Error() string

Jump to

Keyboard shortcuts

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