diff --git a/cliutils.nim b/cliutils.nim index c9fd840..479241e 100644 --- a/cliutils.nim +++ b/cliutils.nim @@ -27,7 +27,7 @@ proc stripAnsi*(str: string): string = let STRIP_ANSI_REGEX = re"\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]" return str.replace(STRIP_ANSI_REGEX, "") -proc queryParamsToCliArgs*(queryParams: Table[string, string]): seq[string] = +proc doParseQueryParams[T](queryParams: T): seq[string] = result = @[] for k,v in queryParams: @@ -38,13 +38,8 @@ proc queryParamsToCliArgs*(queryParams: Table[string, string]): seq[string] = result.add("--" & k) if v != "true": result.add(v) # support things like ?verbose=true -> cmd --verbose +proc queryParamsToCliArgs*(queryParams: Table[string, string]): seq[string] = + doParseQueryParams(queryParams) + proc queryParamsToCliArgs*(queryParams: StringTableRef): seq[string] = - result = @[] - - for k,v in queryParams: - # support ?arg1=val1&arg2=val2 -> cmd val1 val2 - if k.startsWith("arg"): result.add(v) - - else : - result.add("--" & k) - if v != "true": result.add(v) # support things like ?verbose=true -> cmd --verbose + doParseQueryParams(queryParams) diff --git a/cliutils.nimble b/cliutils.nimble index 6d09488..42b31a3 100644 --- a/cliutils.nimble +++ b/cliutils.nimble @@ -1,6 +1,6 @@ # Package -version = "0.8.1" +version = "0.8.2" author = "Jonathan Bernard" description = "Helper functions for writing command line interfaces." license = "MIT" diff --git a/cliutils/config.nim b/cliutils/config.nim index e133c01..4e631cf 100644 --- a/cliutils/config.nim +++ b/cliutils/config.nim @@ -6,11 +6,14 @@ type docopt*: Table[string, Value] json*: JsonNode -func keyNames(key: string): tuple[arg, env, json: string] = - result = ( - "--" & key, - key.replace('-', '_').toUpper, - key.replace(re"(-\w)", proc (m: RegexMatch): string = ($m)[1..1].toUpper)) +func keyNames(key: string): tuple[arg, env, json: string] {.raises: [KeyError].} = + try: + result = ( + "--" & key, + key.replace('-', '_').toUpper, + key.replace(re"(-\w)", proc (m: RegexMatch): string = ($m)[1..1].toUpper)) + except CatchableError: + raise newException(KeyError, "invalid config key: '" & key & "'") template walkFieldDefs*(t: NimNode, body: untyped) = let tTypeImpl = t.getTypeImpl @@ -51,7 +54,8 @@ proc initCombinedConfig*( proc findConfigFile*(name: string, otherLocations: seq[string] = @[]): string = let cfgLocations = @[ $getEnv(name.strip(chars = {'.'}).toUpper()), - $getEnv("HOME") / name ] & otherLocations + $getEnv("HOME") / name, + "." / name ] & otherLocations result = cfgLocations.foldl(if fileExists(b): b else: a, "") if result == "" or not fileExists(result): @@ -74,21 +78,33 @@ proc getVal*(cfg: CombinedConfig, key: string): string = of JArray: return $node else: raise newException(ValueError, "cannot find a configuration value for \"" & key & "\"") -proc getVal*(cfg: CombinedConfig, key, default: string): string = +proc getVal*(cfg: CombinedConfig, key, default: string): string {.raises: [].} = try: return getVal(cfg, key) - except: return default + except CatchableError: return default + +proc getJson*( + cfg: CombinedConfig, + key: string + ): JsonNode {.raises: [KeyError, ValueError, IOError, OSError]} = -proc getJson*(cfg: CombinedConfig, key: string): JsonNode = let (argKey, envKey, jsonKey) = keyNames(key) - if cfg.docopt.contains(argKey) and cfg.docopt[argKey]: return parseJson($cfg.docopt[argKey]) - elif existsEnv(envKey): return parseJson(getEnv(envKey)) - elif cfg.json.hasKey(jsonKey): return cfg.json[jsonKey] - else: raise newException(ValueError, "cannot find a configuration value for \"" & key & "\"") + try: + if cfg.docopt.contains(argKey) and cfg.docopt[argKey]: return parseJson($cfg.docopt[argKey]) + elif existsEnv(envKey): return parseJson(getEnv(envKey)) + elif cfg.json.hasKey(jsonKey): return cfg.json[jsonKey] + else: raise newException(ValueError, "cannot find a configuration value for \"" & key & "\"") + except Exception: + raise newException(ValueError, "cannot parse value as JSON:" & getCurrentExceptionMsg()) + +proc getJson*( + cfg: CombinedConfig, + key: string, + default: JsonNode + ) : JsonNode {.raises: []} = -proc getJson*(cfg: CombinedConfig, key: string, default: JsonNode): JsonNode = try: return getJson(cfg, key) - except: return default + except CatchableError: return default proc hasKey*(cfg: CombinedConfig, key: string): bool = let (argKey, envKey, jsonKey) = keyNames(key)