engine

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 15, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package engine is the runtime adapter — the only engine-bound code in m-cli (spec §8). Everything else (fmt/lint/lsp) is engine-neutral source work; this package is where "run M" lives, and the only place the YottaDB-vs-IRIS difference appears. `m test`/`m coverage`/the `m watch` run-half drive it.

The YDB-vs-IRIS difference is just the *invocation shim* — the M code itself (TESTRUN.m, ^STDASSERT, …) is pure M and runs unchanged on both. Each Engine builds the right command line; how that command actually executes (locally, in a docker container, over SSH) is the injectable Runner seam, so this package is testable without a live engine and transports can be added later.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DockerStage

func DockerStage(ctx context.Context, container, stageDir string, files []string) error

DockerStage creates stageDir inside the container and copies files into it (via `docker cp`, which works regardless of bind-mount ownership on the host).

func DockerUnstage

func DockerUnstage(ctx context.Context, container, stageDir string)

DockerUnstage removes stageDir from the container (best-effort).

func IrisStageLoad

func IrisStageLoad(ctx context.Context, eng Engine, container, stageDir string, files []string) error

IrisStageLoad wraps each routine file in the IRIS UDL header (`ROUTINE <stem> [Type=MAC]`), copies it into stageDir in the container, then compiles them all with one `$SYSTEM.OBJ.Load(...,"ck")` pass via eng (an IrisEngine over a docker transport). Unlike YottaDB, IRIS has no compile-from-path, so every routine — suites and deps like ^STDASSERT — must be loaded before any suite runs. Returns an error if a load reports failure.

Types

type Config

type Config struct {
	Flag          string // --engine value ("" if unset)
	Env           string // $M_ENGINE
	IrisOnPath    bool   // `iris` resolvable on $PATH
	IscInstallDir string // $ISC_PACKAGE_INSTALLDIR
}

Config carries the inputs to the engine-selection consensus (spec §2.1).

func DetectConfig

func DetectConfig(flag string) Config

DetectConfig reads the ambient selection inputs, layering flag on top.

type Engine

type Engine interface {
	Kind() Kind
	EnsureLoaded(ctx context.Context, path string) error
	RunRoutine(ctx context.Context, entryref string, args ...string) (Result, error)
	RunXCmd(ctx context.Context, mcmd string) (Result, error)
	// RunScript runs a multi-line M script in direct mode (fed on stdin). Used
	// for compound operations like the coverage trace pass (view "TRACE" … →
	// zwrite ^ycov … halt).
	RunScript(ctx context.Context, script string) (Result, error)
}

Engine is the runtime adapter. EnsureLoaded makes a routine file known to the engine (a no-op on YDB, an OBJ.Load on IRIS); RunRoutine runs an entryref; RunXCmd runs a one-off M command line.

func New

func New(kind Kind, opts Options) Engine

New builds the Engine for kind with opts (zero values defaulted).

type IrisEngine

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

IrisEngine runs M on InterSystems IRIS via the `iris` binary (the VA target engine). Routine source lives in IRIS.DAT, so EnsureLoaded imports a .mac from the irissync mirror before it can run.

Note on charset: Options.Chset has no effect on IRIS — byte mode is INHERENT here. A Unicode IRIS instance round-trips all 256 byte values in-memory ($char(200) is one char with $ascii 200), and IRIS has no process-wide $ydb_chset analog to export. So `--chset m` is satisfied as a no-op and the flag is accepted only to keep the CLI surface uniform across engines. (Raw binary *device* I/O is a per-OPEN translation concern owned by the routine.)

func (*IrisEngine) EnsureLoaded

func (e *IrisEngine) EnsureLoaded(ctx context.Context, path string) error

EnsureLoaded compiles a routine file into the namespace via $SYSTEM.OBJ.Load(path,"ck") — the IRIS analog of YDB's auto-compile.

func (*IrisEngine) Kind

func (e *IrisEngine) Kind() Kind

Kind implements Engine.

func (*IrisEngine) RunRoutine

func (e *IrisEngine) RunRoutine(ctx context.Context, entryref string, _ ...string) (Result, error)

RunRoutine runs an entryref by piping `do <entryref> halt` to an interactive `iris session` (more reliable than passing the routine on argv). args are ignored for now (IRIS argument passing differs from YDB's $ZCMDLINE).

func (*IrisEngine) RunScript

func (e *IrisEngine) RunScript(ctx context.Context, script string) (Result, error)

RunScript pipes a multi-line script to an interactive `iris session` (the script should end with `halt`; one is appended if absent).

func (*IrisEngine) RunXCmd

func (e *IrisEngine) RunXCmd(ctx context.Context, mcmd string) (Result, error)

RunXCmd runs a one-off M command by piping it (plus halt) to an interactive `iris session` over stdin.

type Kind

type Kind string

Kind is the M engine implementation.

const (
	YDB  Kind = "ydb"
	IRIS Kind = "iris"
)

func Resolve

func Resolve(c Config) (kind Kind, explicit bool, err error)

Resolve applies the §2.1 consensus: --engine → $M_ENGINE → heuristic ($ISC_PACKAGE_INSTALLDIR / iris on PATH ⇒ iris) → default ydb. explicit is false only for the bare default (no flag/env/heuristic) — engine-bound commands must refuse (exit 4) when !explicit rather than assume ydb.

type Options

type Options struct {
	Runner    Runner // transport; default LocalRunner
	YdbBin    string // default "ydb"
	IrisBin   string // default "iris"
	Instance  string // IRIS instance name (default "IRIS")
	Namespace string // IRIS namespace (default "USER")
	// Chset selects the engine charset: "m" (byte mode — one char == one byte,
	// required by binary suites like STDCSPRNG/STDB64/STDHEX) or "utf-8". Empty
	// means "engine default" (YDB inherits its ambient $ydb_chset). On YDB this
	// exports ydb_chset; on IRIS it is a no-op (byte semantics are inherent —
	// see IrisEngine).
	Chset string
}

Options configure a constructed engine (defaults are filled by New).

type Result

type Result struct {
	Stdout   string
	Stderr   string
	ExitCode int
}

Result is the outcome of running an M command.

func LocalRunner

func LocalRunner(ctx context.Context, argv []string, stdin string) (Result, error)

LocalRunner runs argv on the host via os/exec. A non-zero engine exit is reported in Result.ExitCode (not as a Go error); a Go error means the command could not be run at all (e.g. binary not found).

type Runner

type Runner func(ctx context.Context, argv []string, stdin string) (Result, error)

Runner executes argv (with optional stdin) and returns the result. It is the transport seam: LocalRunner runs via os/exec; docker/SSH transports and tests substitute their own.

func DockerRunner

func DockerRunner(container, stageDir string) Runner

DockerRunner is a Runner transport that runs argv inside a running container via `docker exec -i <container> bash -lc …` — `bash -lc` loads the engine's shell env (e.g. YottaDB's $ydb_dist/$ydb_routines). When stageDir is non-empty it is prepended to $ydb_routines so routines staged there resolve and auto-compile (the m-test-engine bind-mounts $HOME/m-work → /m-work, but /m-work is not on the default $ydb_routines).

type VistaEngine

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

VistaEngine is the driver-backed engine: it satisfies Engine by delegating every verb to an m-<engine> driver binary over the neutral contract (the m-driver-sdk reference Client), instead of building a yottadb/iris argv for an in-process Runner. This is how the m-cli runner reaches a live FOIA VistA on either engine behind one contract — the driver owns the wire (m-ydb local/docker/SSH, m-iris Atelier REST), so m-cli stays vendor-neutral (driver-contract §1, §11).

It sits beside the in-process YdbEngine/IrisEngine (additive); the D3 cutover that retires those is a separate, conformance-gated step.

func NewVista

func NewVista(kind Kind, client *mdriver.Client) *VistaEngine

NewVista builds a driver-backed engine of kind (ydb|iris) over client.

func (*VistaEngine) EnsureLoaded

func (e *VistaEngine) EnsureLoaded(ctx context.Context, path string) error

EnsureLoaded stages + compiles a routine via `exec load`.

func (*VistaEngine) Kind

func (e *VistaEngine) Kind() Kind

Kind reports the engine the driver targets (ydb or iris).

func (*VistaEngine) Probe

func (e *VistaEngine) Probe(ctx context.Context) (mdriver.Status, error)

Probe is the reachability + identity gate (T0.1): `lifecycle status`, carrying running/healthy/version. It is the portable cross-engine equivalent of running `W $ZV` and reading the banner — IRIS exec does not capture device output, so status (not eval) is the uniform way to confirm a VistA is live and identify it.

func (*VistaEngine) RunRoutine

func (e *VistaEngine) RunRoutine(ctx context.Context, entryref string, args ...string) (Result, error)

RunRoutine runs an entryref via `exec run`; args become $ZCMDLINE.

func (*VistaEngine) RunScript

func (e *VistaEngine) RunScript(_ context.Context, _ string) (Result, error)

RunScript is not available over the driver transport: the exec axis has no multi-line direct-mode verb (load/run/eval/abort only). Compound work runs as a staged routine + RunRoutine, not a stdin script.

func (*VistaEngine) RunXCmd

func (e *VistaEngine) RunXCmd(ctx context.Context, mcmd string) (Result, error)

RunXCmd evaluates one M command via `exec eval`.

type YdbEngine

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

YdbEngine runs M on YottaDB via the `ydb` binary (the tooling-native engine).

func (*YdbEngine) EnsureLoaded

func (e *YdbEngine) EnsureLoaded(_ context.Context, _ string) error

EnsureLoaded is a no-op on YottaDB: routines compile on first reference ($ydb_routines auto-compile), so there is nothing to pre-load.

func (*YdbEngine) Kind

func (e *YdbEngine) Kind() Kind

Kind implements Engine.

func (*YdbEngine) RunRoutine

func (e *YdbEngine) RunRoutine(ctx context.Context, entryref string, args ...string) (Result, error)

RunRoutine runs an entryref via `ydb -run`. Extra args are passed through as $ZCMDLINE.

func (*YdbEngine) RunScript

func (e *YdbEngine) RunScript(ctx context.Context, script string) (Result, error)

RunScript runs a multi-line script in YDB direct mode (`ydb -direct`), feeding the script on stdin. The script should end with `halt`.

func (*YdbEngine) RunXCmd

func (e *YdbEngine) RunXCmd(ctx context.Context, mcmd string) (Result, error)

RunXCmd runs a one-off M command line via the %XCMD utility (which XECUTEs its $ZCMDLINE): `ydb -run %XCMD <mcmd>`.

Jump to

Keyboard shortcuts

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