105 lines
3.2 KiB
Go
105 lines
3.2 KiB
Go
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" && mode != "explain" {
|
|
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, pointer string
|
|
registerConfigSelectionFlags(fs, &path, &overlay)
|
|
registerConfigurationOverrides(fs)
|
|
if mode == "explain" {
|
|
fs.StringVar(&pointer, "path", "", "configuration path as a JSON Pointer")
|
|
}
|
|
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
|
|
}
|
|
var explanationPath configkit.Path
|
|
if mode == "explain" {
|
|
if !flagWasSet(fs, "path") {
|
|
fmt.Fprintln(stderr, "config parse error: --path is required")
|
|
return ExitRuntimeError
|
|
}
|
|
var err error
|
|
explanationPath, err = configkit.ParsePath(pointer)
|
|
if err != nil {
|
|
fmt.Fprintln(stderr, "config parse error: --path must be a JSON Pointer")
|
|
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)
|
|
case "explain":
|
|
err = result.WriteExplanation(stdout, explanationPath)
|
|
}
|
|
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")
|
|
}
|