cli

package
v2.314.2 Latest Latest
Warning

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

Go to latest
Published: Mar 29, 2026 License: MIT Imports: 11 Imported by: 13

Documentation

Overview

Package cli provides helpers for building command-line applications with go-service.

This package wraps the command framework used by this module (github.com/cristalhq/acmd) and provides a small layer of conveniences for wiring subcommands using go-service DI (Fx/Dig via the `di` package).

Entry points

Start with `NewApplication` to construct an `Application` and register subcommands via a `RegisterFunc`. Most applications then call either:

  • `(*Application).Run` to execute the CLI and return any error, or
  • `(*Application).ExitOnError` to log failures and invoke `cli.Exit` with a non-zero status code.

Subcommands and DI wiring

Subcommands are added via `Commander` methods:

  • `(*Application).AddServer` creates a long-running server-style command. It starts the DI app and then blocks until the DI app signals completion, stopping it afterwards.
  • `(*Application).AddClient` creates a short-lived client-style command. It starts the DI app, then stops it immediately after startup completes.

Each added subcommand returns a `*Command`, which embeds a `*flag.FlagSet`. You can define and parse flags on that `FlagSet`; the command implementation wires the flag set into DI so constructors can read parsed values. Command names must be unique across the application.

Environment-derived metadata

The CLI name and version are derived from environment helpers in `env` and exposed via package variables (`Name` and `Version`) so they can be reused consistently.

Index

Constants

This section is empty.

Variables

View Source
var (
	// FS is the filesystem used by CLI helpers for configuration lookup and reading sources.
	//
	// It defaults to an `*os.FS` rooted in the host filesystem (see `os.NewFS`). Tests may override
	// this variable to control filesystem reads performed during CLI setup.
	FS = os.NewFS()

	// Name is the CLI application name derived from the environment.
	//
	// The name is resolved via `env.NewName(FS)` and is used by `Application.Run` to populate the
	// command runner's app metadata (for example help text and descriptions).
	Name = env.NewName(FS)

	// Version is the CLI application version derived from the environment.
	//
	// The version is resolved via `env.NewVersion()` and is used by `Application.Run` to populate the
	// command runner's version information.
	Version = env.NewVersion()
)
View Source
var ErrCommandRegistered = errors.New("command already registered")

ErrCommandRegistered indicates a subcommand name has already been registered on an Application.

View Source
var Exit = os.Exit

Exit is invoked by (*Application).ExitOnError after logging a startup failure.

Tests may replace this variable to avoid terminating the test process.

Functions

This section is empty.

Types

type Application

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

Application is a command-line application composed of subcommands.

An Application maintains a set of commands and delegates parsing/execution to the underlying command framework (github.com/cristalhq/acmd).

func NewApplication

func NewApplication(register RegisterFunc) *Application

NewApplication constructs an Application and invokes register to add subcommands.

The returned Application is pre-populated with module-level Name and Version derived from the environment (see cli.Name and cli.Version).

func (*Application) AddClient

func (a *Application) AddClient(name, description string, opts ...Option) *Command

AddClient adds a short-lived client subcommand with DI lifecycle wiring.

The returned *Command embeds a *flag.FlagSet. The flag set is parsed before DI startup and is then provided into the DI container so constructors can consume parsed flag values. Command names must be unique across the application.

Execution semantics:

  • parse the command args into the command's FlagSet
  • build a DI application with the provided options, plus the command's module
  • start the DI application
  • stop the DI application immediately after startup completes

Any start/stop error is wrapped with the subcommand name for easier attribution.

func (*Application) AddServer

func (a *Application) AddServer(name, description string, opts ...Option) *Command

AddServer adds a long-running server subcommand with DI lifecycle wiring.

The returned *Command embeds a *flag.FlagSet. The flag set is parsed before DI startup and is then provided into the DI container so constructors can consume parsed flag values. Command names must be unique across the application.

Execution semantics:

  • parse the command args into the command's FlagSet
  • build a DI application with the provided options, plus the command's module and runtime.Module
  • start the DI application
  • block until the DI application's Done channel is closed
  • stop the DI application

Any start/stop error is wrapped with the subcommand name for easier attribution.

func (*Application) ExitOnError

func (a *Application) ExitOnError(ctx context.Context)

ExitOnError runs the application and terminates the process with exit status 1 if Run returns an error.

The error is logged using the telemetry logger before Exit is invoked.

func (*Application) Run

func (a *Application) Run(ctx context.Context) error

Run executes the application using the configured command set.

Run configures the underlying command runner with:

  • app name/description derived from a.name
  • version derived from a.version
  • sanitized process arguments (see os.SanitizeArgs)
  • the provided context

It returns any execution error from the underlying runner or command ExecFunc.

type Command

type Command struct {
	*flag.FlagSet
}

Command wraps a `*flag.FlagSet` and provides DI wiring for CLI subcommands.

The embedded FlagSet is intended to be configured with flags by the caller, then parsed by the subcommand execution path. The `module` method exposes providers for the filesystem/name/version metadata and the command's FlagSet.

func NewCommand added in v2.66.0

func NewCommand(name string) *Command

NewCommand creates a new CLI Command with the given name.

The returned Command embeds a `*flag.FlagSet` that you can use to define CLI flags. Application subcommands call `(*flag.FlagSet).Parse` before starting DI, and the Command's `module` wires the parsed FlagSet into the DI container so constructors can read flag values.

type Commander

type Commander interface {
	// AddServer registers a long-running server-style subcommand.
	//
	// Command names must be unique across the entire application.
	//
	// The subcommand:
	//   - parses command args into the returned `*Command`'s FlagSet,
	//   - starts a DI application built from opts plus server-specific wiring,
	//   - blocks until the DI application signals completion,
	//   - then stops the DI application.
	AddServer(name, description string, opts ...Option) *Command

	// AddClient registers a short-lived client-style subcommand.
	//
	// Command names must be unique across the entire application.
	//
	// The subcommand:
	//   - parses command args into the returned `*Command`'s FlagSet,
	//   - starts a DI application built from opts plus client-specific wiring,
	//   - then stops the DI application immediately after startup completes.
	AddClient(name, description string, opts ...Option) *Command
}

Commander registers CLI subcommands on an application.

Implementations typically add subcommands that build and run a DI application using go-service's `di` package. The returned `*Command` embeds a `*flag.FlagSet` so you can define command-specific flags before execution.

type Option

type Option = di.Option

Option is an alias for di.Option.

type RegisterFunc

type RegisterFunc = func(commander Commander)

RegisterFunc registers subcommands on a Commander.

A RegisterFunc is invoked by NewApplication to populate the application's command set. Implementations typically call commander.AddServer and/or commander.AddClient.

Jump to

Keyboard shortcuts

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