From b441b46d85ee669a8c9b666a05ce931dd56c8044 Mon Sep 17 00:00:00 2001 From: nhas Date: Sun, 10 Nov 2024 14:47:49 +1300 Subject: [PATCH] Add loading config file from flag in cli, and print help from cli if required --- README.md | 4 +++- entry.go | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8b39e09..eb3cc79 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,9 @@ Confy offers a variety of options for configuring your application's settings. | `Defaults(...)` | Loads configurations in the order: config file -> environment variables -> CLI flags. This sets a non-strict parsing mode for unknown fields in the config file. | | `FromConfigFile(...)` | Load configuration from a file. Supports `YAML`, `JSON`, and `TOML`. | | `FromConfigBytes(...)` | Load configuration from raw bytes, ideal for embedding configuration in code. | -| `FromEnvs(...)` | Load configuration from environment variables. Use the delimiter to denote nested fields. | +| `FromConfigURL(...)` | Load configuration from URL. Supports `YAML`, `JSON`, and `TOML`, use extension or content type to specify type when using auto keyword| +| `FromConfigFileFlagPath(...)` | Load configuration from file with filepath specified as cli flag | +| `WithStrictParsing(...)` | Parse config files in a strict way, do not allow unknown fields | | `FromCli(...)` | Load configuration from CLI flags. Set a delimiter for nested struct parsing. | | `WithLogLevel(...)` | Set logging level to control output verbosity. Useful for debugging. | | `WithCliTransform(...)` | Takes a function to run against the generated CLI flag name, allows you to modify the flag name | diff --git a/entry.go b/entry.go index e9e933d..c404e3a 100644 --- a/entry.go +++ b/entry.go @@ -12,6 +12,7 @@ import ( "os" "path/filepath" "reflect" + "slices" "strings" "time" ) @@ -155,6 +156,9 @@ func Config[T any](suppliedOptions ...OptionFunc) (result T, warnings []error, e logger.Warn("parser issued warning", "parser", p, "err", err.Error()) warnings = append(warnings, err) + } else if errors.Is(err, flag.ErrHelp) && slices.Contains(o.order, cli) && p != cli { + err = orderLoadOpts[cli].apply(&result) + return result, nil, err } else { logger.Error("parser issued error", "parser", p, "err", err.Error()) return result, nil, err @@ -356,12 +360,23 @@ func FromConfigURL(urlOpt string, configType ConfigType) OptionFunc { // FromConfigFileFlagPath tells confy to load file from path as specified by cli flag // cliFlagName: string cli option that defines config filepath // configType: ConfigType, what type the config file is expected to be, use `Auto` if you dont care and just want it to choose for you. Supports yaml, toml and json -func FromConfigFileFlagPath(cliFlagName string, configType ConfigType) OptionFunc { +func FromConfigFileFlagPath(cliFlagName, defaultPath, description string, configType ConfigType) OptionFunc { return func(c *options) error { - FromConfigFile("", configType) + commandLine := flag.NewFlagSet(os.Args[0], flag.ContinueOnError) - return nil + configPath := commandLine.String(cliFlagName, defaultPath, description) + if err := commandLine.Parse(os.Args[1:]); err != nil { + if err == flag.ErrHelp { + commandLine.PrintDefaults() + return flag.ErrHelp + } + + // We will get a lot of random "flag not defined" errors,as our flags are defined much later (if at all) in the Cli component + configPath = &defaultPath + } + + return FromConfigFile(*configPath, configType)(c) } }