cli

package
v0.20.4 Latest Latest
Warning

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

Go to latest
Published: Dec 31, 2025 License: MIT Imports: 13 Imported by: 1

README

CLI Package

A lightweight framework for building command-line applications with consistent behavior.

Overview

The CLI package provides a standardized way to create command-line applications with common features:

  • Consistent flag parsing
  • Structured logging
  • Version information handling
  • Error handling
  • Builder pattern for configuration

Usage

Here's a simple example of how to use the CLI package:

package main

import (
	"context"
	"flag"
	"fmt"
	"os"

	"git.sr.ht/~jcmuller/tools/pkg/cli"
)

func main() {
	var name string

	app := cli.New(
		"hello-world",
		"A simple hello world application\n\nUsage:\n  %s [options]\n\nOptions:\n",
		cli.WithRunFunc(func(ctx context.Context) error {
			fmt.Printf("Hello, %s!\n", name)
			return nil
		}),
		cli.WithFlags(func(fs *flag.FlagSet) {
			fs.StringVar(&name, "name", "World", "Name to greet")
		}),
	)

	if err := app.Run(context.Background(), os.Args); err != nil {
		os.Exit(1)
	}
}

Features

Builder Pattern

The CLI package uses the builder pattern for configuration:

app := cli.New(
    "app-name",
    "app description",
    cli.WithRunFunc(run),
    cli.WithFlags(addFlags),
    cli.WithVersion("1.0.0"),  // Optional, defaults to version from tools package
    cli.WithLogConfig(logConfig),  // Optional, defaults to text output to stderr
)
Common Flags

All applications automatically get these flags:

  • --debug: Enable debug logging
  • --help: Show help and exit
  • --version: Show version and exit
  • --completion: Generate shell completion script for the specified shell (bash, zsh, fish)
Structured Logging

The CLI package uses log/slog for structured logging:

// Configure logging with options
config := cli.NewLogConfig(
    cli.WithLogLevel(slog.LevelDebug),
    cli.WithLogFormat("json"),
)

// Use in your application
app := cli.New(
    "app-name",
    "description",
    cli.WithLogConfig(config),
)
Shell Completion

The CLI package provides automatic shell completion generation for Bash, Zsh, and Fish shells. Users can generate completion scripts using the --completion flag.

Persistent Installation

For persistent installation, save the completion script to the appropriate directory for your shell. The generated scripts are self-updating, meaning they will automatically query the binary for the latest flags whenever completions are requested:

# Bash completion
$ your-app --completion=bash >~/.bash_completion.d/your-app

# Zsh completion
$ your-app --completion=zsh >~/.zsh/completions/_your-app

# Fish completion
$ your-app --completion=fish >~/.config/fish/completions/your-app.fish

With this approach, you won't need to regenerate completion scripts when your application's flags change.

Dynamic Loading

For temporary use or testing, you can dynamically load the completion in your current shell session:

# Zsh dynamic loading
$ eval "$(your-app --completion=zsh)"

# Bash dynamic loading
$ eval "$(your-app --completion=bash)"

# Fish dynamic loading (in fish shell)
$ your-app --completion=fish| source

The completion scripts will provide tab completion for all flags defined in your application.

Version Information

Version information is handled consistently:

// Use the default version from the tools package
app := cli.New("app-name", "description")

// Or specify a custom version
app := cli.New(
    "app-name",
    "description",
    cli.WithVersion("1.2.3"),
)

API Reference

App Creation
  • New(name, description string, opts ...AppOption) *App: Create a new CLI application
App Options
  • WithRunFunc(fn func(ctx context.Context) error) AppOption: Set the main function
  • WithFlags(flagFunc func(*flag.FlagSet)) AppOption: Add custom flags
  • WithVersion(version string) AppOption: Set a custom version
  • WithLogConfig(config LogConfig) AppOption: Set a custom logging configuration
Logging Configuration
  • NewLogConfig(opts ...LogOption) LogConfig: Create a new logging configuration
  • WithLogLevel(level slog.Level) LogOption: Set the minimum log level
  • WithLogOutput(output io.Writer) LogOption: Set where logs will be written
  • WithLogFormat(format string) LogOption: Set the log format (text or json)

Best Practices

  1. Keep the run function focused: The run function should only contain the core logic of your application.
  2. Use structured logging: Use slog.InfoContext, slog.DebugContext, etc. with key-value pairs for better log analysis.
  3. Handle errors properly: Return errors from your run function rather than calling os.Exit.
  4. Use the builder pattern: Use the builder pattern for configuration to make your code more readable.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var SetupLogging = func(config LogConfig) {
	var handler slog.Handler

	if config.Format == "json" {
		handler = slog.NewJSONHandler(config.Output, &slog.HandlerOptions{
			Level: config.Level,
		})
	} else {
		handler = slog.NewTextHandler(config.Output, &slog.HandlerOptions{
			Level: config.Level,
		})
	}

	logger := slog.New(handler)
	slog.SetDefault(logger)
}

SetupLogging configures the global logger based on the provided config It's a variable to allow for testing

Functions

func BuildInlineFormatMultiError added in v0.14.0

func BuildInlineFormatMultiError() *multierror.Error

Types

type App

type App struct {

	// Debug enables debug logging
	Debug bool

	// ExitFunc is used for testing
	ExitFunc func(int)
	// contains filtered or unexported fields
}

App represents a command-line application with common functionality

func New

func New(name, description string, opts ...AppOption) *App

New creates a new CLI application with common flags and behavior

func (*App) Args added in v0.15.0

func (a *App) Args() []string

func (*App) Context added in v0.15.0

func (a *App) Context() context.Context

func (*App) GenerateCompletion added in v0.11.0

func (a *App) GenerateCompletion(config CompletionConfig) error

GenerateCompletion generates shell completion for the app

func (*App) GetVersion added in v0.13.0

func (a *App) GetVersion() (VersionInfo, error)

func (*App) Run

func (a *App) Run(ctx context.Context, args []string) error

Run executes the application

func (*App) Stderr added in v0.14.0

func (a *App) Stderr() io.Writer

func (*App) Stdin added in v0.14.0

func (a *App) Stdin() io.Reader

func (*App) Stdout added in v0.14.0

func (a *App) Stdout() io.Writer

type AppOption

type AppOption func(*App)

AppOption is a function that configures an App

func WithFlags

func WithFlags(fn func(*flag.FlagSet)) AppOption

WithFlags adds custom flags to the application

func WithLogConfig

func WithLogConfig(config LogConfig) AppOption

WithLogConfig sets a custom logging configuration

func WithRequiredArguments added in v0.17.0

func WithRequiredArguments(i int) AppOption

WithRequiredArguments sets the minimum number of required arguments

func WithRunFunc

func WithRunFunc(fn RunFunc) AppOption

WithRunFunc sets the main function to execute

func WithStderr added in v0.14.0

func WithStderr(serr io.Writer) AppOption

WithStderr configures stderr for the application

func WithStdin added in v0.14.0

func WithStdin(sin io.Reader) AppOption

WithStdin configures stdin for the application

func WithStdout added in v0.14.0

func WithStdout(sout io.Writer) AppOption

WithStdout configures stdout for the application

func WithStreams added in v0.14.0

func WithStreams(sin io.Reader, sout, serr io.Writer) AppOption

WithStreams configures all streams

func WithVersion

func WithVersion(version string) AppOption

WithVersion sets a custom version for the application

type CompletionConfig added in v0.11.0

type CompletionConfig struct {
	// Shell is the type of shell to generate completion for
	Shell ShellType
	// Output is where to write the completion script
	Output io.Writer
}

CompletionConfig holds configuration for shell completion

func DefaultCompletionConfig added in v0.11.0

func DefaultCompletionConfig() CompletionConfig

DefaultCompletionConfig returns the default completion configuration

func NewCompletionConfig added in v0.11.0

func NewCompletionConfig(opts ...CompletionOption) CompletionConfig

NewCompletionConfig creates a new completion configuration with options

type CompletionOption added in v0.11.0

type CompletionOption func(*CompletionConfig)

CompletionOption configures the completion generator

func WithCompletionOutput added in v0.11.0

func WithCompletionOutput(output io.Writer) CompletionOption

WithCompletionOutput sets the output for the completion script

func WithCompletionShell added in v0.11.0

func WithCompletionShell(shell ShellType) CompletionOption

WithCompletionShell sets the shell type for completion

type LogConfig

type LogConfig struct {
	// Level is the minimum log level to output
	Level slog.Level

	// Output is where logs will be written (defaults to stderr)
	Output io.Writer

	// Format determines the log format (text or json)
	Format string
}

LogConfig holds configuration for setting up logging

func DefaultLogConfig

func DefaultLogConfig() LogConfig

DefaultLogConfig returns a default logging configuration

func NewLogConfig

func NewLogConfig(opts ...LogOption) LogConfig

NewLogConfig creates a new logging configuration with options

type LogOption

type LogOption func(*LogConfig)

LogOption is a function that configures a LogConfig

func WithLogFormat

func WithLogFormat(format string) LogOption

WithLogFormat sets the log format (text or json)

func WithLogLevel

func WithLogLevel(level slog.Level) LogOption

WithLogLevel sets the minimum log level

func WithLogOutput

func WithLogOutput(output io.Writer) LogOption

WithLogOutput sets where logs will be written

type RunFunc added in v0.14.0

type RunFunc func(app *App) error

type ShellType added in v0.11.0

type ShellType string

ShellType represents a supported shell for completion

const (
	// Bash shell
	Bash ShellType = "bash"
	// Zsh shell
	Zsh ShellType = "zsh"
	// Fish shell
	Fish ShellType = "fish"
)

type VersionInfo

type VersionInfo struct {
	Arch        string
	BuildTime   string
	Commit      string
	Dirty       string
	GoVersion   string
	Name        string
	OS          string
	Version     string
	GitTime     time.Time
	MainVersion string
}

VersionInfo holds version information for the application

func (VersionInfo) String

func (v VersionInfo) String() (string, error)

String returns a formatted version string

Jump to

Keyboard shortcuts

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