Documentation
¶
Overview ¶
Package cmd defines structures and implements functionality required for creating and managing the command-line interface (CLI) of an application. It leverages the Kong library to parse CLI arguments and execute the associated commands. The package provides common CLI components such as version information and license display, ensuring consistency and reusability throughout the application's command-line utilities.
Struct tags use "name" for CLI flag binding. To also support environment variables, use kong.DefaultEnvars when creating the Kong parser. This automatically maps flags to environment variables (e.g. --postgres-host becomes POSTGRES_HOST).
Usage:
type CLI struct {
cmd.Commons
cmd.HTTPServer `embed:"" prefix:""`
cmd.Postgres `embed:"" prefix:""`
}
func main() {
var cli CLI
ctx := kong.Parse(&cli, kong.DefaultEnvars("MYAPP"))
// ...
_ = ctx.Run()
}
Index ¶
- type Commons
- type Config
- type DBOption
- type HTTPServer
- type Licence
- type Option
- type PoolOption
- func WithAfterConnect(fn func(context.Context, *pgx.Conn) error) PoolOption
- func WithAfterRelease(fn func(*pgx.Conn) bool) PoolOption
- func WithBeforeClose(fn func(*pgx.Conn)) PoolOption
- func WithBeforeConnect(fn func(context.Context, *pgx.ConnConfig) error) PoolOption
- func WithHealthCheckPeriod(d time.Duration) PoolOption
- func WithMaxConnIdleTime(d time.Duration) PoolOption
- func WithMaxConnLifetime(d time.Duration) PoolOption
- func WithMaxConnLifetimeJitter(d time.Duration) PoolOption
- func WithMaxConns(n int32) PoolOption
- func WithMinConns(n int32) PoolOption
- func WithMinIdleConns(n int32) PoolOption
- func WithPrepareConn(fn func(context.Context, *pgx.Conn) (bool, error)) PoolOption
- func WithShouldPing(fn func(context.Context, pgxpool.ShouldPingParams) bool) PoolOption
- type Postgres
- type Printer
- type SQLite
- type Version
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Commons ¶
type Commons struct {
Development bool `short:"D" env:"DEBUG,DEV,DEVELOPMENT" help:"Set to true to enable development mode with debug-level logging."`
Level string `short:"l" env:"LOG_LEVEL" help:"Specify the logging level, options are: debug, info, warn, error, fatal." default:"info"`
Lang string `env:"LANG" help:"Specify the print lang for tailored message." default:"en"`
Version Version `cmd:"" help:"Display version information."`
Licence Licence `cmd:"" help:"Show the application's licence."`
}
Commons defines the common flags and embedded commands shared across all CLI applications. It provides development mode toggling, log level configuration, language selection, and built-in version/licence subcommands.
Usage:
type CLI struct {
cmd.Commons
Run RunCmd `cmd:"" default:"withargs" help:"Start the application."`
}
type RunCmd struct{}
func (r *RunCmd) Run(commons *cmd.Commons) error {
logger := commons.MustLogger()
defer logger.Sync()
logger.Info("starting application")
return nil
}
func main() {
var cli CLI
ctx := kong.Parse(&cli, kong.DefaultEnvars("MYAPP"))
_ = ctx.Run()
}
func (*Commons) Logger ¶
Logger initializes a new zap.Logger based on the Development and Level fields in the commons struct. It returns the configured logger or an error if the logging level is invalid or the logger cannot be created.
func (*Commons) MustLogger ¶
MustLogger will panic if a logger can't be provided.
type Config ¶
type Config struct {
ConfigFile kong.ConfigFlag `json:"config" name:"config" short:"c" help:"Full path to a user-supplied config file"`
// contains filtered or unexported fields
}
Config provides automatic YAML configuration file loading for Kong CLI applications. It exposes a `--config` / `-c` flag for an explicit override, and otherwise looks for files in host-scoped `/etc/...` and user-scoped `~/...` locations.
Lookup order at startup, first match wins:
- `--config <path>` (the [Config.ConfigFile] flag)
- user-scoped — `~/.<group>/<name>.yaml`, or `~/.<name>/config.yaml` when no group is set
- host-scoped — `/etc/<group>/<name>.yaml`, or `/etc/<name>/config.yaml` when no group is set
`<name>` defaults to the kong application name (the binary name); override with WithName. `<group>` is unset by default; set it with WithGroup to colocate the config alongside other state on disk.
Usage:
type CLI struct {
cmd.Commons
Run RunCmd `cmd:"" default:"withargs" help:"Start the application."`
}
func main() {
// Defaults: ~/.<binary>/config.yaml + /etc/<binary>/config.yaml
cfg := cmd.NewConfig()
// With group, colocates under a shared state dir:
// ~/.<group>/<binary>.yaml + /etc/<group>/<binary>.yaml
cfg = cmd.NewConfig(cmd.WithGroup("mygroup"))
// With group + name, fully custom:
// ~/.<group>/<name>.yaml + /etc/<group>/<name>.yaml
cfg = cmd.NewConfig(cmd.WithGroup("mygroup"), cmd.WithName("config"))
var cli CLI
ctx := kong.Parse(&cli,
kong.DefaultEnvars("MYAPP"),
kong.Bind(cfg),
)
_ = ctx.Run()
}
type DBOption ¶
func WithConnMaxIdleTime ¶
func WithConnMaxLifetime ¶
func WithMaxIdleConns ¶
func WithMaxOpenConns ¶
type HTTPServer ¶
type HTTPServer struct {
Host string `name:"http-host" help:"Host to bind the server to" default:"0.0.0.0"`
Port int `name:"http-port" help:"Port to bind the server to" default:"8080"`
ReadHeaderTimeout time.Duration `name:"http-read-header-timeout" help:"Max duration for reading the request header" default:"5s"`
ReadTimeout time.Duration `name:"http-read-timeout" help:"Max duration for reading the entire request" default:"30s"`
WriteTimeout time.Duration `name:"http-write-timeout" help:"Max duration for writing the response" default:"60s"`
IdleTimeout time.Duration `name:"http-idle-timeout" help:"Max duration to wait for the next request" default:"120s"`
GracefulPeriod time.Duration `name:"http-graceful-period" help:"Period to wait for graceful shutdown" default:"5s"`
}
HTTPServer provides CLI flags for configuring an HTTP server. It handles binding, timeouts, and graceful shutdown.
Usage:
type CLI struct {
cmd.Commons
cmd.HTTPServer `embed:"" prefix:""`
Run RunCmd `cmd:"" default:"withargs" help:"Start the application."`
}
type RunCmd struct{}
func (r *RunCmd) Run(srv *cmd.HTTPServer) error {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
return srv.Start(ctx, zap.L(), mux)()
}
func main() {
var cli CLI
ctx := kong.Parse(&cli, kong.DefaultEnvars("MYAPP"))
_ = ctx.Run()
}
func NewHTTPServer ¶
func NewHTTPServer() *HTTPServer
func (*HTTPServer) Addr ¶
func (srv *HTTPServer) Addr() string
type Licence ¶
type Licence struct {
// contains filtered or unexported fields
}
Licence holds the licence content of an application. It is automatically registered as a subcommand when embedded via Commons.
Usage:
//go:embed LICENSE
var license string
func main() {
var cli CLI
ctx := kong.Parse(&cli,
kong.DefaultEnvars("MYAPP"),
kong.Bind(cmd.NewLicence(license)),
)
_ = ctx.Run()
}
Then run:
$ myapp licence MIT License ...
func NewLicence ¶
NewLicence creates a new Licence instance with the provided licence content.
type Option ¶
type Option func(c *Config)
func WithGroup ¶
WithGroup namespaces the config under a parent directory. Setting a group changes the lookup paths from the per-binary defaults to a shared parent: `~/.<group>/<name>.yaml` and `/etc/<group>/<name>.yaml`.
Use a group when several binaries share state on disk and you want their config files to live alongside that data — e.g. a daemon `myapp` whose state lives at `~/.myapp/` and a sibling CLI `myapp-cli` can both read from `~/.myapp/<binary>.yaml` by constructing their `Config` with `WithGroup("myapp")`.
Pass an empty group (or skip the option) for single-binary projects — the default lookup is `~/.<binary>/config.yaml` and `/etc/<binary>/config.yaml`, which is enough for most CLIs.
func WithName ¶
WithName overrides the config file's basename. Without this option the basename comes from the parsed kong application name (`kong.Model.Name`, normally the binary name). Override when the binary name and the desired config filename should differ — most often to colocate a binary's config under a state directory owned by its broader project, with a generic basename.
Combines with WithGroup:
- `WithGroup("myapp") + WithName("config")` → `~/.myapp/config.yaml`, `/etc/myapp/config.yaml`
- `WithGroup("myapp")` alone → `~/.myapp/<binary>.yaml`, `/etc/myapp/<binary>.yaml`
- `WithName("config")` alone → `~/.config.yaml`, `/etc/config.yaml` (rarely useful; prefer pairing with `WithGroup`)
Empty string is treated as "no override" — the binary name wins.
type PoolOption ¶
func WithAfterConnect ¶
func WithAfterRelease ¶
func WithAfterRelease(fn func(*pgx.Conn) bool) PoolOption
func WithBeforeClose ¶
func WithBeforeClose(fn func(*pgx.Conn)) PoolOption
func WithBeforeConnect ¶
func WithBeforeConnect(fn func(context.Context, *pgx.ConnConfig) error) PoolOption
func WithHealthCheckPeriod ¶
func WithHealthCheckPeriod(d time.Duration) PoolOption
func WithMaxConnIdleTime ¶
func WithMaxConnIdleTime(d time.Duration) PoolOption
func WithMaxConnLifetime ¶
func WithMaxConnLifetime(d time.Duration) PoolOption
func WithMaxConnLifetimeJitter ¶
func WithMaxConnLifetimeJitter(d time.Duration) PoolOption
func WithMaxConns ¶
func WithMaxConns(n int32) PoolOption
func WithMinConns ¶
func WithMinConns(n int32) PoolOption
func WithMinIdleConns ¶
func WithMinIdleConns(n int32) PoolOption
func WithPrepareConn ¶
func WithShouldPing ¶
func WithShouldPing(fn func(context.Context, pgxpool.ShouldPingParams) bool) PoolOption
type Postgres ¶
type Postgres struct {
Host string `name:"postgres-host" help:"PostgreSQL host" default:"localhost"`
Port int `name:"postgres-port" help:"PostgreSQL port" default:"5432"`
User string `name:"postgres-user" help:"PostgreSQL user" default:"postgres"`
Password string `name:"postgres-password" help:"PostgreSQL password"`
Database string `name:"postgres-database" help:"PostgreSQL database"`
SSLMode string `name:"postgres-ssl-mode" help:"PostgreSQL SSL mode" default:"disable"`
MaxConns int32 `name:"postgres-max-conns" help:"Max number of connections" default:"10"`
MinConns int32 `name:"postgres-min-conns" help:"Min number of connections" default:"2"`
MaxConnLifetime time.Duration `name:"postgres-max-conn-lifetime" help:"Max lifetime of a connection" default:"1h"`
MaxConnIdleTime time.Duration `name:"postgres-max-conn-idle-time" help:"Max idle time of a connection" default:"30m"`
}
Postgres provides CLI flags for configuring a PostgreSQL connection pool.
Usage:
type CLI struct {
cmd.Commons
cmd.Postgres `embed:"" prefix:""`
Run RunCmd `cmd:"" default:"withargs" help:"Start the application."`
}
type RunCmd struct{}
func (r *RunCmd) Run(ctx context.Context, pg *cmd.Postgres) error {
pool, err := pg.Pool(ctx)
if err != nil {
return err
}
defer pool.Close()
// ...
return nil
}
func main() {
var cli CLI
ctx := kong.Parse(&cli, kong.DefaultEnvars("MYAPP"))
_ = ctx.Run()
}
func NewPostgres ¶
func NewPostgres() *Postgres
type SQLite ¶
type SQLite struct {
Path string `name:"sqlite-path" help:"SQLite database file path" default:":memory:"`
JournalMode string `name:"sqlite-journal-mode" help:"SQLite journal mode" default:"wal"`
BusyTimeout int `name:"sqlite-busy-timeout" help:"Busy timeout in milliseconds" default:"5000"`
ForeignKeys bool `name:"sqlite-foreign-key" help:"Enable foreign keys" default:"true"`
Synchronous string `name:"sqlite-synchronous" help:"Synchronous mode" default:"normal"`
CacheSize int `name:"sqlite-cache-size" help:"Cache size in pages (negative for KiB)" default:"-2000"`
MaxOpenConns int `name:"sqlite-max-open-conns" help:"Max number of open connections" default:"10"`
MaxIdleConns int `name:"sqlite-max-idle-conns" help:"Max number of idle connections" default:"5"`
ConnMaxLifetime time.Duration `name:"sqlite-conn-max-lifetime" help:"Max lifetime of a connection" default:"1h"`
ConnMaxIdleTime time.Duration `name:"sqlite-conn-max-idle-time" help:"Max idle time of a connection" default:"30m"`
}
SQLite provides CLI flags for configuring a SQLite database connection.
Usage:
type CLI struct {
cmd.Commons
cmd.SQLite `embed:"" prefix:""`
Run RunCmd `cmd:"" default:"withargs" help:"Start the application."`
}
type RunCmd struct{}
func (r *RunCmd) Run(sq *cmd.SQLite) error {
db, err := sq.Open()
if err != nil {
return err
}
defer db.Close()
// ...
return nil
}
func main() {
var cli CLI
ctx := kong.Parse(&cli, kong.DefaultEnvars("MYAPP"))
_ = ctx.Run()
}
type Version ¶
Version holds detailed build information for an application, including the name, the specific version string, commit hash, the source of the build, and the build date. It is automatically registered as a subcommand when embedded via Commons.
Usage:
var (
version = "dev"
commit = "none"
buildSource = "unknown"
date = "unknown"
)
func main() {
var cli CLI
ctx := kong.Parse(&cli,
kong.DefaultEnvars("MYAPP"),
kong.Bind(cmd.NewVersion("myapp", version, commit, buildSource, date)),
)
_ = ctx.Run()
}
Then run:
$ myapp version name=myapp, version=dev, commit=none, buildDate=unknown, buildSource=unknown
func NewVersion ¶
NewVersion creates a new Version instance with the given version details.