cli

package module
v0.0.0-...-ba4adcd Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2026 License: MIT Imports: 43 Imported by: 0

Documentation

Overview

Package cli implements the waxflow command tree. It is deliberately thin: commands parse flags, resolve configuration, and delegate; behavior lives in the library packages.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Execute

func Execute(version string, args []string, stdout, stderr io.Writer) int

Execute runs the waxflow CLI with the given argument vector (excluding the program name) and returns the process exit code per the contract printed by `waxflow exit-codes`.

func ExecuteFlavor

func ExecuteFlavor(version string, args []string, stdout, stderr io.Writer, flavor Flavor) int

ExecuteFlavor is Execute for a build that customizes the command tree (see Flavor); the stock main passes the zero Flavor via Execute.

Types

type Flavor

type Flavor struct {
	// Name tags the version output: "catalog" prints waxflow-catalog.
	// Empty means stock.
	Name string

	// OpenResolver wraps opts.Next with this build's source schemes.
	// Every ref-taking command builds its resolver through it: server,
	// sign, probe, transcode, split, and doctor.
	//
	// The returned Closer, which may be nil, is closed after the
	// resolver's last use. Return a plain nil on error, having cleaned up
	// what was opened: a Closer returned alongside an error is closed
	// rather than leaked, so handing back one already closed is a double
	// close. A typed-nil pointer in a non-nil interface is not a nil
	// Closer and will be called. An implementation that is present but
	// unconfigured owns the refusal for its own schemes: it returns a
	// resolver that answers them with a message naming what is missing,
	// rather than passing them down to opts.Next and the stock
	// unsupported-source error.
	//
	// An implementation must not start background goroutines when
	// opts.Daemon is false: the command resolves one reference and
	// tears down, so nothing outlives it.
	//
	// The resolver it returns may implement PIDSourceReporter to say what
	// /caps advertises, and ReloadableResolver to be reconciled by a root
	// reload. Only the returned resolver is inspected for either, so a
	// resolver that wraps another must implement and forward the ones the
	// inner resolver needs.
	OpenResolver func(ctx context.Context, opts ResolverOptions) (source.Resolver, io.Closer, error)
}

Flavor customizes the command tree for a build that adds source schemes the stock binary cannot serve. The zero value is the stock build. A build that resolves pid:<ULID> against a WaxBin catalog injects one; no build in this repo does, so the seam is aimed at modules outside it, and examples/catalogcli is a worked example.

type PIDSourceReporter

type PIDSourceReporter interface {
	PIDSources() bool
}

PIDSourceReporter, when implemented by the resolver an OpenResolver returns, declares whether this build resolves pid:<ULID> references. `waxflow server` publishes the answer as delivery.pid in /caps.

Implementing it is optional. Without it the CLI infers support from catalogDB being configured, which is right for a resolver keyed on catalogDB -- the documented channel, and what ResolverOptions.CatalogDB carries -- and wrong for one that is not. A build that resolves pid: from somewhere else says so here rather than leaving /caps to deny a capability it has.

This only keeps the capability surface honest; whether a given pid reference resolves is the resolver's business either way.

type ReloadableResolver

type ReloadableResolver interface {
	ReloadSourceMaxBytes(maxBytes int64)
}

ReloadableResolver, when implemented by the resolver an OpenResolver returns, is reconciled by a root reload (POST /roots/reload) alongside the library roots: it receives the re-read source cap, so a build that caps its own sources -- a catalog resolver enforcing the cap on the pid: files it opens itself -- stays in step with a changed sourceMaxBytes instead of holding the value it snapshotted at open. This is what makes a reload's "byte-for-byte as a restart" promise hold for a Flavor build, not only the stock one.

Optional. A resolver that only delegates to ResolverOptions.Next needs nothing: Next is the reconciled roots, which enforce the live cap on their own sources. maxBytes is the resolved per-source cap, defaulted exactly as ResolverOptions.MaxBytes was.

It is called with no library lock held and concurrently with in-flight Resolve calls, so an implementation must synchronize the field it updates (an atomic, say). Only the resolver OpenResolver returned is checked, as with PIDSourceReporter: a resolver that wraps another must implement this and forward when the inner one caps its own sources.

type ResolverOptions

type ResolverOptions struct {
	// CatalogDB is the configured catalog database path, resolved
	// through the family precedence (flag > env > JSON file). Empty
	// means the operator configured none.
	CatalogDB string

	// MaxBytes caps each resolved source file, the cap the library
	// roots enforce on theirs. It is the value at open: a Flavor that caps
	// its own sources on it (rather than delegating to Next, whose roots a
	// reload reconciles in place) should implement ReloadableResolver to
	// stay in step with a runtime sourceMaxBytes change; without that, the
	// copied value is a restart-only snapshot.
	MaxBytes int64

	// Next serves every reference the implementation does not claim:
	// the configured library roots. Implementations delegate rather
	// than answer not-found.
	//
	// Next is live-mutable: a root reload (POST /roots/reload) mutates
	// the roots it points at in place, so an implementation must delegate
	// through the held Next reference and never snapshot its resolvable
	// set, or a runtime-added root would be invisible to this build's
	// resolver until restart.
	Next source.Resolver

	// Logger is never nil.
	Logger *slog.Logger

	// Daemon is true only under `waxflow server`, the one command whose
	// process outlives a single resolution. See OpenResolver.
	Daemon bool
}

ResolverOptions carries what an OpenResolver implementation needs from the resolved configuration. Every field is exported or stdlib, so a Flavor is constructible from any module.

Directories

Path Synopsis
cmd
waxflow command
Command waxflow is the WaxFlow CLI and daemon entry point.
Command waxflow is the WaxFlow CLI and daemon entry point.
Package label implements meta.Mapper over the waxlabel tag library.
Package label implements meta.Mapper over the waxlabel tag library.

Jump to

Keyboard shortcuts

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