conductor

package module
v0.0.11 Latest Latest
Warning

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

Go to latest
Published: Jul 6, 2026 License: MIT Imports: 16 Imported by: 0

README

Conductor

One App struct wires up:

  • clib - themed help, shell completions
  • clog - structured logging
  • clive - versioning, self-update

Direct use of the underlying libraries is never blocked.

Packages

Package Description
conductor App/Runtime core: logging defaults, flags, notify, version
cli/cobra Cobra integration
cli/kong Kong integration
cli/urfave urfave/cli integration

Installation

go get github.com/gechr/conductor

Usage

app := conductor.New(conductor.App{
    Name:        "demo",
    Description: "Demo application.",
    Module:      "github.com/you/demo",
    Updater: brew.New(
        clive.Info{Module: "github.com/you/demo"},
        brew.WithFormula("demo"),
        brew.WithTap("you/tap"),
    ),
})

var cli CLI // your kong grammar, embedding ckong.Flags
prog, err := ckong.New(app, &cli)
if err != nil {
    clog.Fatal().Err(err).Msg("Failed to build CLI")
}
os.Exit(prog.Run(os.Args[1:]))

See the runnable kong, cobra and urfave demo apps.

Lifecycle

  1. conductor.New(App) - env prefix on clog and clib, LogDefaults (stderr, auto color, human-friendly durations), your ConfigureLog hook, theme detection, help renderer.
  2. Adapter New(app, ...) - parser/command tree with themed help, standard flags, -V/version, completions, update hook.
  3. Program.Run(...) - completion preflight, parse, apply --verbose/--quiet/--color, update check, dispatch, hint flush, error → exit code. Pass the result to os.Exit.

Standard flags

Every adapter provides the same trio plus completion management:

Flag Effect
-v, --verbose clog.SetVerbose(true)
-q, --quiet clog.SetLevel(clog.LevelError)
--color <mode> clog.SetColorMode (auto default)
-V, --version Print the version

Version stamping

No per-app version var - stamp clive's linker variables (unstamped builds fall back to Go module build info, then the VCS revision):

go build -ldflags "-X github.com/gechr/clive.version=$(VERSION) -X github.com/gechr/clive.buildTime=$(BUILD_TIME)"

Update notifications

  • Set App.Updater to any updater.Tool (brew.New, goinstall.New, github.New) to enable the passive "update available" hint, cached and rate-limited by clive; <APP>_NO_UPDATE_CHECK disables it.
  • The standard update subcommand (UpdateCmd for kong; UpdateCommand for cobra/urfave) self-updates via whichever install method App.Updater uses, with --check, --stable, --dev and --no-uninstall (the latter two are Homebrew-specific).

Escape hatches

A thin layer over the same public APIs you would call yourself:

  • App.ConfigureLog runs after LogDefaults - the place for direct clog customisation (symbols, styles, parts, custom levels).
  • App.SkipLogDefaults opts out of the house style; the standalone conductor.LogDefaults() opts into it without the rest.
  • Runtime.Theme/Runtime.Renderer and every Program field are exported and replaceable before Run.
  • Adapter options (WithKongOptions, WithSections, WithGenerator, WithExitCode, ...) append after conductor's defaults, so they can override anything.
  • conductor.SignalContext() - opt-in SIGINT/SIGTERM context for commands that should abort cleanly on Ctrl-C.
  • Tools with bespoke needs skip the relevant piece (don't embed the flags, provide your own update command) and keep the rest.

Documentation

Overview

Package conductor wires up the gechr CLI libraries (clib, clog, clive) in one shot. A consumer fills in an App at program start, calls New, and inherits the house logging style, a themed help renderer, unified env-var prefixes, version plumbing, and passive update notifications - while remaining free to call any of the underlying libraries directly.

Index

Constants

View Source
const EnvPrefixNone = "-"

EnvPrefixNone disables env-prefix unification, leaving clog and clib on their own defaults (CLOG and CLIB).

Variables

This section is empty.

Functions

func ExitCode

func ExitCode(err error, custom func(error) int) int

ExitCode maps a command error to a process exit code, shared by all framework adapters: nil is 0; updater.ErrReported is 1 without further output (the failure is already on screen); otherwise the optional custom mapper decides, falling back to logging the error and returning 1.

func LogDefaults

func LogDefaults()

LogDefaults applies the house clog style shared by every tool: stderr output with automatic color detection, space-separated slices, and human-friendly duration fields. It is exported so a tool that skips Conductor entirely can still opt into the house style.

func SignalContext added in v0.0.2

func SignalContext() (context.Context, context.CancelFunc)

SignalContext returns a context cancelled on SIGINT or SIGTERM, for commands that block on external interaction (network calls, hardware prompts) and should abort cleanly on Ctrl-C. Opt-in: create it in main and thread it through the framework adapter's Run or command bindings. The stop function releases the signal registration; defer it.

Types

type App

type App struct {
	// Name is the binary name, e.g. "demo". Required.
	Name string
	// DisplayName is the stylised human-facing name, e.g. "Demo", used in
	// human-facing text such as the standard update command's description.
	// Defaults to Name.
	DisplayName string
	// Description is the one-line description used in help output.
	Description string

	// EnvPrefix unifies clog.SetEnvPrefix and clib theme.SetEnvPrefix under a
	// single application prefix. It defaults to Name upper-cased with dashes
	// mapped to underscores. Set [EnvPrefixNone] to leave both libraries on
	// their own defaults.
	EnvPrefix string

	// Module is the Go module path, e.g. "github.com/gechr/demo". It enables
	// clive release links and latest-version lookups.
	Module string
	// Repo is the GitHub "owner/name"; derived from Module when empty.
	Repo string
	// Private resolves latest-version lookups via GOPRIVATE-scoped version
	// control instead of the public module proxy.
	Private bool

	// Updater enables the passive update notification; nil disables it. Any
	// [updater.Tool] works, e.g. brew.New(...), goinstall.New(...) or
	// github.New(...).
	Updater updater.Tool
	// NotifyOptions are appended after Conductor's own notify options.
	NotifyOptions []notify.Option
	// NotifySkip lists extra command verbs that suppress the update check, in
	// addition to the built-in "update", "version", "help" and completion
	// verbs.
	NotifySkip []string
	// NotifyOnly, when non-empty, restricts the update check to exactly these
	// command verbs.
	NotifyOnly []string

	// Theme overrides the help theme; nil means [theme.Auto].
	Theme *theme.Theme
	// HelpOptions are passed to [help.NewRenderer].
	HelpOptions []help.RendererOption
	// HelpShort is the terse description of -h (default "Print short help").
	HelpShort string
	// HelpLong is the terse description of --help (default "Print long
	// help, including examples").
	HelpLong string

	// SkipLogDefaults skips [LogDefaults] for tools with a fully bespoke
	// logging setup.
	SkipLogDefaults bool
	// ConfigureLog runs after [LogDefaults] and before anything logs; the
	// place for direct clog customisation (symbols, styles, custom levels).
	ConfigureLog func()
}

App declares everything Conductor needs to initialize a CLI tool. Name is required; every other field has a sensible zero value.

func (App) HelpLongDesc

func (a App) HelpLongDesc() string

HelpLongDesc returns the terse --help description, defaulted.

func (App) HelpShortDesc

func (a App) HelpShortDesc() string

HelpShortDesc returns the terse -h description, defaulted.

type FlagSource

type FlagSource interface {
	ConductorFlags() Flags
}

FlagSource is implemented by CLI values that expose the standard flags, usually by embedding a framework adapter's flag struct. Adapters apply the flags automatically after parsing when the CLI value implements it.

type Flags

type Flags struct {
	Verbose bool
	Quiet   bool
	Color   clog.ColorMode
}

Flags are the framework-neutral post-parse flag values shared by every tool: verbosity and color mode.

type Runtime

type Runtime struct {
	App      App
	Info     clive.Info
	Theme    *theme.Theme
	Renderer *help.Renderer
}

Runtime is everything New builds. All fields are exported and may be replaced before handing the Runtime to a framework adapter.

func New

func New(app App) *Runtime

New initializes the libraries in dependency order and returns the shared Runtime. It must run before anything logs so that env prefixes, output and theme detection settle first. It panics when app.Name is empty - a programmer error on par with an invalid CLI grammar.

func (*Runtime) ApplyFlags

func (r *Runtime) ApplyFlags(f Flags)

ApplyFlags is the post-parse phase: it maps the standard flags onto clog. Tools with bespoke verbosity semantics skip FlagSource and call clog directly instead.

func (*Runtime) Notify

func (r *Runtime) Notify(command string) func()

Notify starts the passive update check for the resolved command and returns a flush function - never nil - that the caller runs after the command completes, so the hint trails normal output. The check is skipped when App.Updater is nil, when the command's verb is one of the built-in skip verbs or App.NotifySkip, or when App.NotifyOnly is set and does not contain the verb. clive's <APP>_NO_UPDATE_CHECK kill switch still applies underneath.

func (*Runtime) PrintVersion

func (r *Runtime) PrintVersion(detailed bool)

PrintVersion writes the version to stdout: the bare string, or a labelled table of build details (with release hyperlinks when Module/Repo is set) when detailed is true.

func (*Runtime) Version

func (r *Runtime) Version() string

Version returns the running binary's version via clive.Current: ldflag-injected, module build info, or VCS revision - whichever resolves first - with a friendly placeholder when nothing resolves.

type SelfUpdater added in v0.0.3

type SelfUpdater interface {
	SelfUpdateRequested() bool
}

SelfUpdater is implemented by CLI grammars that opt into the hidden --self-update flag, usually by embedding an adapter's SelfUpdateFlag.

Directories

Path Synopsis
cli
cobra
Package cobra adapts Conductor to cobra-based CLIs: one call wires themed help, shell completions, standard flags, version output and update notifications onto an existing root command, mirroring the conventions of clib's cli/cobra package.
Package cobra adapts Conductor to cobra-based CLIs: one call wires themed help, shell completions, standard flags, version output and update notifications onto an existing root command, mirroring the conventions of clib's cli/cobra package.
kong
Package kong adapts Conductor to kong-based CLIs: one call builds the parser with themed help, shell completions, version wiring and update notifications, mirroring the conventions of clib's cli/kong package.
Package kong adapts Conductor to kong-based CLIs: one call builds the parser with themed help, shell completions, version wiring and update notifications, mirroring the conventions of clib's cli/kong package.
urfave
Package urfave adapts Conductor to urfave/cli v3 CLIs: one call wires themed help, shell completions, standard flags, version output and update notifications onto an existing root command, mirroring the conventions of clib's cli/urfave package.
Package urfave adapts Conductor to urfave/cli v3 CLIs: one call wires themed help, shell completions, standard flags, version output and update notifications onto an existing root command, mirroring the conventions of clib's cli/urfave package.
examples
cobra command
Command demo shows the Conductor cobra integration: one App struct plus one Program call replaces the usual hand-rolled logger, help, completion, version and update-check bootstrap.
Command demo shows the Conductor cobra integration: one App struct plus one Program call replaces the usual hand-rolled logger, help, completion, version and update-check bootstrap.
kong command
Command demo shows the Conductor kong integration: one App struct plus one Program call replaces the usual hand-rolled logger, help, completion, version and update-check bootstrap.
Command demo shows the Conductor kong integration: one App struct plus one Program call replaces the usual hand-rolled logger, help, completion, version and update-check bootstrap.
urfave command
Command demo shows the Conductor urfave/cli integration: one App struct plus one Program call replaces the usual hand-rolled logger, help, completion, version and update-check bootstrap.
Command demo shows the Conductor urfave/cli integration: one App struct plus one Program call replaces the usual hand-rolled logger, help, completion, version and update-check bootstrap.
internal
update
Package update holds the self-update logic shared by the framework adapters' update commands, driven through the updater.Updater interface so any install method (Homebrew, `go install`, GitHub release) works.
Package update holds the self-update logic shared by the framework adapters' update commands, driven through the updater.Updater interface so any install method (Homebrew, `go install`, GitHub release) works.

Jump to

Keyboard shortcuts

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