Add the ability to query for config values from specific sources.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.12.0"
|
version = "0.12.1"
|
||||||
author = "Jonathan Bernard"
|
author = "Jonathan Bernard"
|
||||||
description = "Helper functions for writing command line interfaces."
|
description = "Helper functions for writing command line interfaces."
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import std/[json, os, sequtils, strtabs, strutils]
|
import std/[json, options, os, sequtils, strtabs, strutils]
|
||||||
import docopt, identcasing, regex
|
import docopt, identcasing, regex
|
||||||
|
|
||||||
type
|
type
|
||||||
@@ -100,6 +100,17 @@ proc findConfigFile*(name: string, otherLocations: seq[string] = @[]): string =
|
|||||||
raise newException(ValueError, "could not find configuration file")
|
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*(
|
proc getValueAndProvenance*(
|
||||||
cfg: CombinedConfig,
|
cfg: CombinedConfig,
|
||||||
key: string): tuple[value: string, provenance: ValueProvenance]
|
key: string): tuple[value: string, provenance: ValueProvenance]
|
||||||
@@ -111,17 +122,7 @@ proc getValueAndProvenance*(
|
|||||||
elif existsEnv(envKey):
|
elif existsEnv(envKey):
|
||||||
return (getEnv(envKey), ValueProvenance.environment)
|
return (getEnv(envKey), ValueProvenance.environment)
|
||||||
elif cfg.json.hasKey(jsonKey):
|
elif cfg.json.hasKey(jsonKey):
|
||||||
let node = cfg.json[jsonKey]
|
return (jsonConfigNodeToString(cfg.json[jsonKey]), ValueProvenance.json)
|
||||||
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)
|
|
||||||
else: raise newException(ValueError, "cannot find a configuration value for \"" & key & "\"")
|
else: raise newException(ValueError, "cannot find a configuration value for \"" & key & "\"")
|
||||||
|
|
||||||
|
|
||||||
@@ -146,6 +147,22 @@ proc getVal*(cfg: CombinedConfig, key, default: string): string {.raises: [].} =
|
|||||||
proc `[]`*(cfg: CombinedConfig, key: string): string = getVal(cfg, key)
|
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) and cfg.docopt[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*(
|
proc getJsonValueAndProvenance*(
|
||||||
cfg: CombinedConfig,
|
cfg: CombinedConfig,
|
||||||
key: string): tuple[value: JsonNode, provenance: ValueProvenance]
|
key: string): tuple[value: JsonNode, provenance: ValueProvenance]
|
||||||
@@ -191,6 +208,22 @@ proc getJson*(
|
|||||||
except CatchableError: return default
|
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) and cfg.docopt[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 =
|
proc hasKey*(cfg: CombinedConfig, key: string): bool =
|
||||||
let (argKey, envKey, jsonKey) = keyNames(key)
|
let (argKey, envKey, jsonKey) = keyNames(key)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user