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) } }