Files

108 lines
3.4 KiB
Go

package main
import (
"context"
"fmt"
"io"
"os"
"strconv"
commandkit "gitea.maximumdirect.net/eric/CommandKit"
"gitea.maximumdirect.net/eric/CommandKit/integrations/ckconfig"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
)
type appConfiguration struct {
Schema struct {
Version int `yaml:"version"`
} `yaml:"schema"`
Greeting string `yaml:"greeting"`
}
type greetInput struct {
Count commandkit.Supplied[int]
Tags commandkit.Supplied[[]string]
}
func loadAppConfiguration(_ context.Context, selection ckconfig.Selection) (*configkit.Result[appConfiguration], error) {
source := configkit.Mapping("simple application settings", map[string]any{
"schema": map[string]any{"version": 2},
"greeting": "Hello",
})
if selection.Config.Set {
source = configkit.File(selection.Config.Value)
}
options := configkit.Options[appConfiguration]{
Definition: configkit.Definition[appConfiguration]{
Version: &configkit.VersionRule{
Path: configkit.Keys("schema", "version"),
Check: func(version configkit.Version, validation *configkit.Validation) error {
if version.Text == "1" {
validation.Warning(configkit.Keys("schema", "version"), "schema version 1 is supported; upgrade to version 2 before the next example release")
}
return nil
},
},
},
}
if selection.Overlay.Set {
options.Overlay = selection.Overlay.Value
options.Filesystem = &configkit.FilesystemContext{Root: ".", BaseDir: "."}
}
return configkit.Load(source, options)
}
func newApp() (*commandkit.App, error) {
countDefault := 1
tagDefaults := []string{"example"}
greet := commandkit.NewCommand(commandkit.CommandSpec[greetInput]{
Name: "greet",
Summary: "Show flag presence and repeated values.",
Flags: []commandkit.Flag[greetInput]{
commandkit.ValueFlag(commandkit.FlagMeta{Name: "count", Usage: "Greeting count."}, &countDefault, strconv.Atoi, func(input *greetInput, value commandkit.Supplied[int]) {
input.Count = value
}),
commandkit.RepeatFlag(commandkit.FlagMeta{Name: "tag", Usage: "A repeatable label."}, tagDefaults, func(value string) (string, error) { return value, nil }, func(input *greetInput, value commandkit.Supplied[[]string]) {
input.Tags = value
}),
},
Run: func(invocation commandkit.Invocation, input greetInput) commandkit.Outcome {
reporter := invocation.Reporter()
configuration, err := loadAppConfiguration(invocation.Context, ckconfig.Selection{})
if err != nil {
return commandkit.Failure("Could not load application configuration.").WithCause(err)
}
count := fmt.Sprintf("default %d (not supplied)", input.Count.Value)
if input.Count.Set {
count = fmt.Sprintf("explicit %d", input.Count.Value)
}
tags := fmt.Sprintf("default %v (not supplied)", input.Tags.Value)
if input.Tags.Set {
tags = fmt.Sprintf("explicit %v", input.Tags.Value)
}
_ = reporter.RenderOutput(func(writer io.Writer) error {
_, err := fmt.Fprintf(writer, "%s; count=%s; tags=%s\n", configuration.Config.Greeting, count, tags)
return err
})
return commandkit.Success()
},
})
return commandkit.New(
commandkit.Identity{Name: "simple-example", Version: "1.0"},
ckconfig.AppCommand(loadAppConfiguration),
greet,
)
}
func main() {
app, err := newApp()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
outcome := app.Execute(context.Background(), os.Args[1:], commandkit.Streams{Out: os.Stdout, Err: os.Stderr})
if outcome.Status != 0 {
os.Exit(outcome.Status)
}
}