package cli import ( "encoding/json" "flag" "fmt" "io" configkit "gitea.maximumdirect.net/eric/ConfigKit" appconfig "gitea.maximumdirect.net/eric/scriptorium/internal/config" ) type configurationSource struct { ID string `json:"id"` Label string `json:"label"` Layer configkit.Layer `json:"layer"` Path string `json:"path,omitempty"` } func configCommand(args []string, stdout, stderr io.Writer) int { if len(args) == 0 { fmt.Fprintln(stderr, "config parse error: configuration mode is required") return ExitRuntimeError } mode := args[0] if mode != "validate" && mode != "show" && mode != "sources" { fmt.Fprintln(stderr, "config parse error: unknown configuration mode") return ExitRuntimeError } fs := flag.NewFlagSet("config "+mode, flag.ContinueOnError) fs.SetOutput(io.Discard) var path, overlay string registerConfigSelectionFlags(fs, &path, &overlay) registerConfigurationOverrides(fs) if err := fs.Parse(args[1:]); err != nil { writeApplicationError(stderr, "config parse", err) return ExitRuntimeError } if fs.NArg() != 0 { fmt.Fprintln(stderr, "config parse error: positional arguments are not accepted") return ExitRuntimeError } result, err := appconfig.Load(appconfig.LoadOptions{ Path: path, Explicit: flagWasSet(fs, "config"), Overlay: overlay, Overrides: applicationOverrides(fs), }) if err != nil { writeApplicationError(stderr, "config", err) return ExitRuntimeError } if err := writeApplicationWarnings(stderr, result.Diagnostics()); err != nil { return ExitRuntimeError } switch mode { case "validate": return ExitOK case "show": err = result.WriteEffective(stdout) case "sources": sources := make([]configurationSource, 0, len(result.Sources())) for _, source := range result.Sources() { sources = append(sources, configurationSource{ ID: source.ID, Label: source.Label, Layer: source.Layer, Path: source.Path, }) } err = json.NewEncoder(stdout).Encode(sources) } if err != nil { fmt.Fprintf(stderr, "config output error: %v\n", err) return ExitRuntimeError } return ExitOK } func registerConfigurationOverrides(fs *flag.FlagSet) { fs.String("prompt-dir", "", "prompt-definition directory override") fs.String("profile-dir", "", "profile directory override") fs.String("schema-dir", "", "schema directory override") fs.String("addr", "", "HTTP listen address override") fs.String("artifact-root", "", "HTTP artifact root override") fs.Int64("max-request-bytes", 0, "HTTP request byte limit override") fs.Int64("max-artifact-bytes", 0, "HTTP artifact byte limit override") fs.Int64("max-response-bytes", 0, "HTTP response byte limit override") }