Documentation
¶
Overview ¶
Package zapp provides a small lifecycle wrapper for command-line apps.
A Program creates a typed app instance, runs it, and returns a process exit code. App handles signal cancellation, panic recovery, and deterministic cleanup of named io.Closer resources.
Typical usage keeps main.go small:
type Zarlcode struct {
// config, stores, services, TUI handles, etc.
}
type CLI struct{}
func (CLI) Name() string { return "zarlcode" }
func (CLI) Create(ctx context.Context, app *zapp.App[*Zarlcode]) (*Zarlcode, error) {
z := &Zarlcode{}
// app.AddCloser("state-db", db)
return z, nil
}
func (CLI) Run(ctx context.Context, app *zapp.App[*Zarlcode], z *Zarlcode) int {
return zapp.ExitOK
}
func main() {
app := zapp.New[*Zarlcode](CLI{})
os.Exit(app.Run(context.Background()))
}
Index ¶
- Constants
- Variables
- func WithCleanupFailureExitCode[T any](code int) options.Option[App[T]]
- func WithCreateFailureExitCode[T any](code int) options.Option[App[T]]
- func WithPanicExitCode[T any](code int) options.Option[App[T]]
- func WithPanicHandler[T any](handler PanicHandler) options.Option[App[T]]
- func WithShutdownTimeout[T any](timeout time.Duration) options.Option[App[T]]
- func WithSignals[T any](signals ...os.Signal) options.Option[App[T]]
- type App
- type CloseFunc
- type ContextCloseFunc
- type ContextCloser
- type PanicHandler
- type Program
Examples ¶
Constants ¶
const ( // ExitOK is the default successful process exit code. ExitOK = 0 // ExitFailure is the default process exit code for expected failures. ExitFailure = 1 // ExitPanic is the default process exit code for recovered panics. ExitPanic = 2 )
Variables ¶
var ( ErrNilProgram = errors.New("zapp: nil program") ErrEmptyName = errors.New("zapp: empty resource name") ErrNilCloser = errors.New("zapp: nil closer") ErrDuplicateName = errors.New("zapp: duplicate resource name") ErrClosed = errors.New("zapp: app is closing or closed") )
Registration and lifecycle errors. All are programmer errors surfaced at wire-up time except ErrClosed, which callers can race against legitimately during shutdown.
Functions ¶
func WithCleanupFailureExitCode ¶
WithCleanupFailureExitCode configures the exit code returned when cleanup fails after an otherwise successful run.
func WithCreateFailureExitCode ¶
WithCreateFailureExitCode configures the exit code returned when Create fails.
func WithPanicExitCode ¶
WithPanicExitCode configures the exit code returned when Run recovers a panic.
func WithPanicHandler ¶
func WithPanicHandler[T any](handler PanicHandler) options.Option[App[T]]
WithPanicHandler configures a callback for panics recovered by Run.
func WithShutdownTimeout ¶
WithShutdownTimeout configures the maximum time allowed for cleanup.
Types ¶
type App ¶
type App[T any] struct { // contains filtered or unexported fields }
App wraps a Program with signal handling, panic recovery, and deterministic resource cleanup.
Example ¶
package main
import (
"context"
"fmt"
"github.com/zarldev/zarlmono/zkit/zapp"
)
type exampleProgram struct{}
func (exampleProgram) Name() string { return "example" }
func (exampleProgram) Create(_ context.Context, app *zapp.App[string]) (string, error) {
_ = app.AddCloser("cleanup", zapp.CloseFunc(func() error {
fmt.Println("cleanup")
return nil
}))
return "ready", nil
}
func (exampleProgram) Run(_ context.Context, _ *zapp.App[string], value string) int {
fmt.Println(value)
return zapp.ExitOK
}
func main() {
code := zapp.New[string](exampleProgram{}).Run(context.Background())
fmt.Println(code)
}
Output: ready cleanup 0
func New ¶
New creates an App for program using sensible defaults.
Example ¶
package main
import (
"context"
"fmt"
"github.com/zarldev/zarlmono/zkit/zapp"
)
type exampleZarlcode struct{}
type exampleCLI struct{}
func (exampleCLI) Name() string { return "zarlcode" }
func (exampleCLI) Create(context.Context, *zapp.App[*exampleZarlcode]) (*exampleZarlcode, error) {
return &exampleZarlcode{}, nil
}
func (exampleCLI) Run(context.Context, *zapp.App[*exampleZarlcode], *exampleZarlcode) int {
return zapp.ExitOK
}
func main() {
app := zapp.New(exampleCLI{})
fmt.Println(app.Name())
}
Output: zarlcode
func (*App[T]) AddContextCloser ¶ added in v0.16.0
func (a *App[T]) AddContextCloser(name string, closer ContextCloser) error
AddContextCloser registers a named context-aware resource for cleanup.
type CloseFunc ¶
type CloseFunc func() error
CloseFunc adapts a cleanup function to io.Closer so callers can register function-shaped cleanup with App.AddCloser without defining local adapter types.
type ContextCloseFunc ¶ added in v0.16.0
ContextCloseFunc adapts a context-aware cleanup function to ContextCloser.
type ContextCloser ¶ added in v0.16.0
ContextCloser releases a resource while honoring the caller's shutdown deadline. Long-running cleanup should implement this contract rather than hiding its own timeout inside an io.Closer.
type PanicHandler ¶
PanicHandler observes a panic recovered by App.Run.
type Program ¶
type Program[T any] interface { Name() string Create(context.Context, *App[T]) (T, error) Run(context.Context, *App[T], T) int }
Program defines the lifecycle for a command-line application.
Create builds the typed application instance and may register resources with AddCloser. Run executes the application and returns the desired process exit code. Name identifies the program in errors and metadata.