diff --git a/cliutils.nimble b/cliutils.nimble index 11bde46..d1c6146 100644 --- a/cliutils.nimble +++ b/cliutils.nimble @@ -1,6 +1,6 @@ # Package -version = "0.12.0" +version = "0.12.1" author = "Jonathan Bernard" description = "Helper functions for writing command line interfaces." license = "MIT" diff --git a/cliutils/config.nim b/cliutils/config.nim index 9f0da2b..8a77d6d 100644 --- a/cliutils/config.nim +++ b/cliutils/config.nim @@ -1,4 +1,4 @@ -import std/[json, os, sequtils, strtabs, strutils] +import std/[json, options, os, sequtils, strtabs, strutils] import docopt, identcasing, regex type @@ -100,6 +100,17 @@ proc findConfigFile*(name: string, otherLocations: seq[string] = @[]): string = raise newException(ValueError, "could not find configuration file") +proc jsonConfigNodeToString(node: JsonNode): string = + case node.kind + of JString: node.getStr + of JInt: $node.getInt + of JFloat: $node.getFloat + of JBool: $node.getBool + of JNull: "" + of JObject: $node + of JArray: $node + + proc getValueAndProvenance*( cfg: CombinedConfig, key: string): tuple[value: string, provenance: ValueProvenance] @@ -111,17 +122,7 @@ proc getValueAndProvenance*( elif existsEnv(envKey): return (getEnv(envKey), ValueProvenance.environment) elif cfg.json.hasKey(jsonKey): - let node = cfg.json[jsonKey] - let value = - case node.kind - of JString: node.getStr - of JInt: $node.getInt - of JFloat: $node.getFloat - of JBool: $node.getBool - of JNull: "" - of JObject: $node - of JArray: $node - return (value, ValueProvenance.json) + return (jsonConfigNodeToString(cfg.json[jsonKey]), ValueProvenance.json) else: raise newException(ValueError, "cannot find a configuration value for \"" & key & "\"") @@ -146,6 +147,21 @@ proc getVal*(cfg: CombinedConfig, key, default: string): string {.raises: [].} = proc `[]`*(cfg: CombinedConfig, key: string): string = getVal(cfg, key) +proc getValueFromSource*( + cfg: CombinedConfig, + source: ValueProvenance, + key: string): Option[string] = + + result = none[string]() + let (argKey, envKey, jsonKey) = keyNames(key) + if source == ValueProvenance.arguments and cfg.docopt.contains(argKey): + result = some($cfg.docopt[argKey]) + elif source == ValueProvenance.environment and existsEnv(envKey): + result = some(getEnv(envKey)) + elif source == ValueProvenance.json and cfg.json.hasKey(jsonKey): + result = some(jsonConfigNodeToString(cfg.json[jsonKey])) + + proc getJsonValueAndProvenance*( cfg: CombinedConfig, key: string): tuple[value: JsonNode, provenance: ValueProvenance] @@ -191,6 +207,21 @@ proc getJson*( except CatchableError: return default +proc getJsonFromSource*( + cfg: CombinedConfig, + source: ValueProvenance, + key: string): Option[JsonNode] = + + result = none[JsonNode]() + let (argKey, envKey, jsonKey) = keyNames(key) + if source == ValueProvenance.arguments and cfg.docopt.contains(argKey): + result = some(parseJson($cfg.docopt[argKey])) + elif source == ValueProvenance.environment and existsEnv(envKey): + result = some(parseJson(getEnv(envKey))) + elif source == ValueProvenance.json and cfg.json.hasKey(jsonKey): + result = some(cfg.json[jsonKey]) + + proc hasKey*(cfg: CombinedConfig, key: string): bool = let (argKey, envKey, jsonKey) = keyNames(key)