clio

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

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

Go to latest
Published: May 24, 2023 License: Apache-2.0 Imports: 20 Imported by: 0

README

CLIO

An easy way to bootstrap your application with batteries included.

Status

_Consider this project to be in alpha. The API is not stable and may change at any time._

What is included?

  • Pairs well with cobra and viper via fangs, covering CLI arg parsing and config file + env var loading.
  • Provides an event bus via partybus, enabling visibility deep in your execution stack as to what is happening.
  • Provides a logger via the logger interface, allowing you to swap out for any concrete logger you want and decorate with redaction capabilities.
  • Defines a generic UI interface that adapts well to TUI frameworks such as bubbletea.

Example

Here's a basic example of how to use clio + cobra to get a fully functional CLI application going:

package main

import (
	"io"
	"os"

	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
	"github.com/wagoodman/go-partybus"
	"github.com/nextlinux/clio"
)

// Define your per-command or entire application config as a struct
type MyCommandConfig struct {
	TimestampServer string `yaml:"timestamp-server" mapstructure:"timestamp-server"`
	// ...
}

// ... add cobra flags just as you are used to doing in any other cobra application
func (c *MyCommandConfig) AddFlags(flags *pflag.FlagSet) {
	flags.StringVarP(
		&c.TimestampServer, "timestamp-server", "", c.TimestampServer,
		"URL to a timestamp server to use for timestamping the signature",
	)
	// ...
}

func MyCommand(app clio.Application) *cobra.Command {
	cfg := &MyCommandConfig{
		TimestampServer: "https://somewhere.out/there", // a default value
	}

	return &cobra.Command{
		Use:     "my-command",
		PreRunE: app.Setup(cfg),
		RunE: func(cmd *cobra.Command, args []string) error {
			state := app.State()
			var log = state.Logger
			var bus partybus.Publisher = state.Bus

			log.Infof("hi! pinging the timestamp server: %s", cfg.TimestampServer)

			type myRichObject struct {
				data io.Reader
				// status progress.Progressable
			}

			bus.Publish(partybus.Event{
				Type: "something-notable",
				//Value:  myRichObject{...},
			})
			return nil
		},
	}
}

func main() {
	cfg := clio.NewConfig("awesome", "v1.0.0")
	app := clio.New(*cfg)

	cmd := MyCommand(app)
	if err := cmd.Execute(); err != nil {
		os.Exit(1)
	}
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultLogger

func DefaultLogger(clioCfg Config) (logger.Logger, error)

func VersionCommand

func VersionCommand(a Application, version Version) *cobra.Command

Types

type Application

type Application interface {
	Setup(cfgs ...any) func(cmd *cobra.Command, args []string) error
	Run(ctx context.Context, errs <-chan error) error
	State() State
	Config() Config
}

func New

func New(cfg Config) Application

type BusConstructor

type BusConstructor func(Config) *partybus.Bus

type Config

type Config struct {
	Name    string
	Version string

	AdditionalConfigs []interface{}
	Dev               *DevelopmentConfig
	Log               *LoggingConfig

	FangsConfig   fangs.Config
	ConfigFinders []fangs.Finder

	BusConstructor    BusConstructor
	LoggerConstructor LoggerConstructor
	UIConstructor     UIConstructor

	Initializers []Initializer
}

func NewConfig

func NewConfig(name, version string) *Config

func (Config) AddFlags

func (c Config) AddFlags(flags *pflag.FlagSet)

func (*Config) WithBusConstructor

func (c *Config) WithBusConstructor(constructor BusConstructor) *Config

func (*Config) WithConfigFinders

func (c *Config) WithConfigFinders(finders ...fangs.Finder) *Config

func (*Config) WithConfigs

func (c *Config) WithConfigs(cfg ...any) *Config

func (*Config) WithDevelopmentConfig

func (c *Config) WithDevelopmentConfig(cfg DevelopmentConfig) *Config

func (*Config) WithInitializers

func (c *Config) WithInitializers(initializers ...Initializer) *Config

func (*Config) WithLoggerConstructor

func (c *Config) WithLoggerConstructor(constructor LoggerConstructor) *Config

func (*Config) WithLoggingConfig

func (c *Config) WithLoggingConfig(cfg LoggingConfig) *Config

func (*Config) WithNoBus

func (c *Config) WithNoBus() *Config

func (*Config) WithNoLogging

func (c *Config) WithNoLogging() *Config

func (*Config) WithUIConstructor

func (c *Config) WithUIConstructor(constructor UIConstructor) *Config

type DevelopmentConfig

type DevelopmentConfig struct {
	Profile Profile `yaml:"profile" json:"profile"`
}

func (*DevelopmentConfig) PostLoad

func (d *DevelopmentConfig) PostLoad() error

type Initializer

type Initializer func(cfg Config, state State) error

type LoggerConstructor

type LoggerConstructor func(Config) (logger.Logger, error)

type LoggingConfig

type LoggingConfig struct {
	Quiet        bool         `yaml:"quiet" json:"quiet"` // -q, indicates to not show any status output to stderr
	Verbosity    int          `yaml:"-" json:"-" `        // -v or -vv , controlling which UI (ETUI vs logging) and what the log level should be
	Level        logger.Level `yaml:"level" json:"level"` // the log level string hint
	FileLocation string       `yaml:"file" json:"file"`   // the file path to write logs to
	// contains filtered or unexported fields
}

LoggingConfig contains all logging-related configuration options available to the user via the application config.

func (*LoggingConfig) AddFlags

func (l *LoggingConfig) AddFlags(flags *pflag.FlagSet)

func (*LoggingConfig) AllowUI

func (l *LoggingConfig) AllowUI(stdin fs.File) bool

func (*LoggingConfig) PostLoad

func (l *LoggingConfig) PostLoad() error

type Profile

type Profile string
const (
	CPUProfile      Profile = "cpu"
	MemProfile      Profile = "mem"
	DisabledProfile Profile = "none"
)

type State

type State struct {
	Bus          *partybus.Bus
	Subscription *partybus.Subscription
	Logger       logger.Logger
	UIs          []UI
}

type UI

type UI interface {
	Setup(subscription partybus.Unsubscribable) error
	partybus.Handler
	Teardown(force bool) error
}

type UIConstructor

type UIConstructor func(Config) ([]UI, error)

type Version

type Version struct {
	Version        string `json:"version,omitempty"`        // application semantic version
	GitCommit      string `json:"gitCommit,omitempty"`      // git SHA at build-time
	GitDescription string `json:"gitDescription,omitempty"` // indication of git tree (either "clean" or "dirty") at build-time
	BuildDate      string `json:"buildDate,omitempty"`      // date of the build
}

Version defines the application version details (generally from build information)

Jump to

Keyboard shortcuts

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