app

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2026 License: MIT Imports: 8 Imported by: 0

README

go-app

A urfave/cli/v3 application framework and run harness shared by gomatic CLIs.

go-app supplies the generic, command-agnostic glue — the Runner/Default action combinators, the logger-in-metadata convention, the standard global flags, and the signal-aware Run harness — and nothing tied to any one command. Command-specific flags, errors, and command trees stay in their own repositories. It composes go-log and go-output on top of urfave/cli/v3.

Install

go get github.com/gomatic/go-app

Usage

Define a Runner for your command's work, bind it into a cli action with Default, and run the root command through Run for signal-aware (SIGINT/SIGTERM) cancellation:

package main

import (
	"context"
	"log/slog"
	"os"

	app "github.com/gomatic/go-app"
	"github.com/gomatic/go-log"
	"github.com/urfave/cli/v3"
)

type config struct{}

type result struct {
	Message string `json:"message" yaml:"message"`
}

// greet is the command's work: it receives the bound config and positional
// arguments and returns a result the action combinator encodes.
func greet(_ context.Context, logger *slog.Logger, _ config, args ...string) (result, error) {
	logger.Info("greeting", "args", args)
	return result{Message: "hello"}, nil
}

func main() {
	var cfg config
	var logCfg log.LoggerConfig
	logFlags := app.LoggerFlags{Config: &logCfg, EnvPrefix: "GREETER_"}

	cmd := &cli.Command{
		Name:     "greeter",
		Metadata: map[string]any{},
		Flags: []cli.Flag{
			logFlags.LevelFlag(),
			logFlags.FormatFlag(log.FormatText),
			app.OutputFlag("GREETER_"),
		},
		Before: app.LoggerBefore(func(*cli.Command) *slog.Logger {
			return logCfg.NewLogger(os.Stderr)
		}),
		Action: app.Default(&cfg, greet),
	}

	app.Run(context.Background(), cmd, os.Args, os.Exit)
}

The global flags resolve from --flag, the matching GREETER_* environment variables, or their defaults. OutputFlag selects the result encoding (json or yaml), which the Default action applies when writing the runner's result.

API

  • Run(ctx, cmd, args, exit) — runs a *cli.Command with SIGINT/SIGTERM cancellation, logging any error and exiting non-zero via the injected exit.
  • Default(cfg, runner) — binds a config pointer and a Runner into a cli action that encodes the result via the output flag.
  • Runner[CONFIG, RESULT] — the function type for a command's work.
  • LoggerFlags (LevelFlag, FormatFlag), OutputFlag — the standard global flags; LoggerFlags binds the logging flags to a shared log.LoggerConfig.
  • GetLogger, LoggerBefore, LoggerMetadataKey — the logger-in-metadata convention.

See the full reference with go doc -all github.com/gomatic/go-app.

Documentation

Overview

Package app is the urfave/cli/v3 framework shared by gomatic CLIs. It supplies the generic, command-agnostic glue — the runner/action combinators, the logger-in-metadata convention, the standard global flags, and the run harness — and nothing tied to any one command. Command-specific flags, errors, and trees stay in their own repositories.

Index

Constants

View Source
const LoggerMetadataKey = "logger"

LoggerMetadataKey is the cli.Command metadata key under which the configured logger is stored for retrieval by command actions.

Variables

This section is empty.

Functions

func Default

func Default[C, R any](cfg *C, runner Runner[C, R]) func(context.Context, *cli.Command) error

Default binds a config pointer and runner into a cli action function.

func GetLogger

func GetLogger(c *cli.Command) *slog.Logger

GetLogger returns the logger stored in the root command metadata, or slog.Default when absent or the command is nil.

func LoggerBefore

func LoggerBefore(getLogger GetLoggerFunc) func(context.Context, *cli.Command) (context.Context, error)

LoggerBefore returns a cli Before hook that stores the logger built by getLogger in the root command metadata, where GetLogger then finds it.

func OutputFlag

func OutputFlag(envPrefix EnvPrefix) cli.Flag

OutputFlag returns the standard --output/-o global flag selecting the result encoding, sourced from <envPrefix>OUTPUT and defaulting to json. The action combinator reads it to encode each command's result.

func Run

func Run(ctx context.Context, cmd *cli.Command, args []string, exit func(int))

Run executes cmd with signal-aware cancellation (SIGINT/SIGTERM), logging a non-nil error under the command's name and exiting non-zero via exit. The args and exit function are injected so a main can be exercised in tests.

Types

type EnvPrefix

type EnvPrefix string

EnvPrefix is the namespace prepended to each standard flag's environment variable source (e.g. "APP_" yields APP_LOG_LEVEL, APP_LOG_FORMAT, APP_OUTPUT).

type GetLoggerFunc

type GetLoggerFunc func(*cli.Command) *slog.Logger

GetLoggerFunc retrieves a logger for a command; injected so mains and tests can substitute one.

type LoggerFlags

type LoggerFlags struct {
	// Config receives the parsed flag values; it must be non-nil.
	Config *log.LoggerConfig
	// EnvPrefix namespaces the flags' environment variable sources.
	EnvPrefix EnvPrefix
}

LoggerFlags binds the standard logging flags to a shared logger configuration. The config pointer is carried as a field (the binder pattern) so the flag constructors take no pointer parameters; each flag's Destination still writes through to Config as the command line is parsed.

func (LoggerFlags) FormatFlag

func (f LoggerFlags) FormatFlag(def log.Format) cli.Flag

FormatFlag returns the standard --log-format global flag, sourced from <EnvPrefix>LOG_FORMAT, bound to Config, defaulting to def (consumers differ: a CLI defaults to text, a daemon to json).

func (LoggerFlags) LevelFlag

func (f LoggerFlags) LevelFlag() cli.Flag

LevelFlag returns the standard --log-level global flag, sourced from <EnvPrefix>LOG_LEVEL and bound to Config.

type Runner

type Runner[CONFIG any, RESULT any] func(context.Context, *slog.Logger, CONFIG, ...string) (RESULT, error)

Runner executes a command's work: it receives the bound config and positional arguments and returns a result to be encoded. Implementations live in the orchestration (domain) packages of each consumer.

Jump to

Keyboard shortcuts

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