mirror of
https://github.com/daylinmorgan/hwylterm.git
synced 2025-02-23 09:45:50 -06:00
args -> positionals
This commit is contained in:
parent
4c63636c24
commit
c40a0a2038
12 changed files with 132 additions and 112 deletions
|
@ -389,8 +389,9 @@ when isMainModule:
|
||||||
hwylCli:
|
hwylCli:
|
||||||
name "bbansi"
|
name "bbansi"
|
||||||
settings ShowHelp
|
settings ShowHelp
|
||||||
|
positionals:
|
||||||
|
args seq[string]
|
||||||
help:
|
help:
|
||||||
usage "[bold]bbansi[/] [[[green]args...[/]] [[[faint]-h|-V[/]]"
|
|
||||||
description """
|
description """
|
||||||
bbansi "[[yellow] yellow text!"
|
bbansi "[[yellow] yellow text!"
|
||||||
-> [yellow] yellow text![/]
|
-> [yellow] yellow text![/]
|
||||||
|
|
|
@ -132,7 +132,6 @@ when isMainModule:
|
||||||
name "hwylchoose"
|
name "hwylchoose"
|
||||||
settings ShowHelp
|
settings ShowHelp
|
||||||
help:
|
help:
|
||||||
usage "[bold]hwylchoose[/] [[[green]args...[/]] [[[faint]-h[/]]"
|
|
||||||
description """
|
description """
|
||||||
hwylchoose a b c d
|
hwylchoose a b c d
|
||||||
hwylchoose a,b,c,d -s ,
|
hwylchoose a,b,c,d -s ,
|
||||||
|
@ -140,6 +139,8 @@ when isMainModule:
|
||||||
hwylchoose --demo
|
hwylchoose --demo
|
||||||
"""
|
"""
|
||||||
hidden demo
|
hidden demo
|
||||||
|
positionals:
|
||||||
|
args seq[string]
|
||||||
flags:
|
flags:
|
||||||
demo "show demo"
|
demo "show demo"
|
||||||
separator:
|
separator:
|
||||||
|
|
|
@ -231,6 +231,7 @@ type
|
||||||
inherit*: Inherit
|
inherit*: Inherit
|
||||||
root*: bool
|
root*: bool
|
||||||
|
|
||||||
|
func hasSubcommands(c: CliCfg): bool = c.subcommands.len > 0
|
||||||
|
|
||||||
func err(c: CliCfg, msg: string) =
|
func err(c: CliCfg, msg: string) =
|
||||||
## quit with error while generating cli
|
## quit with error while generating cli
|
||||||
|
@ -396,6 +397,7 @@ func parseCliSetting(s: string): CliSetting =
|
||||||
try: parseEnum[CliSetting](s)
|
try: parseEnum[CliSetting](s)
|
||||||
except: error "unknown cli setting: " & s
|
except: error "unknown cli setting: " & s
|
||||||
|
|
||||||
|
|
||||||
func parseCliSettings(cfg: var CliCfg, node: NimNode) =
|
func parseCliSettings(cfg: var CliCfg, node: NimNode) =
|
||||||
case node.kind
|
case node.kind
|
||||||
of nnkCommand:
|
of nnkCommand:
|
||||||
|
@ -732,7 +734,7 @@ func parseCliBody(body: NimNode, name = "", root = false): CliCfg =
|
||||||
result.postSub = node[1]
|
result.postSub = node[1]
|
||||||
of "defaultFlagType":
|
of "defaultFlagType":
|
||||||
result.defaultFlagType = node[1]
|
result.defaultFlagType = node[1]
|
||||||
of "args":
|
of "positionals":
|
||||||
parseCliArgs result, node[1]
|
parseCliArgs result, node[1]
|
||||||
else:
|
else:
|
||||||
error "unknown hwylCli setting: " & name
|
error "unknown hwylCli setting: " & name
|
||||||
|
@ -964,6 +966,7 @@ func isBool(f: CliFlag): bool =
|
||||||
func isCount(f: CliFlag): bool =
|
func isCount(f: CliFlag): bool =
|
||||||
f.typeNode == ident"Count"
|
f.typeNode == ident"Count"
|
||||||
|
|
||||||
|
|
||||||
func getNoVals(cfg: CliCfg): tuple[long: NimNode, short: NimNode] =
|
func getNoVals(cfg: CliCfg): tuple[long: NimNode, short: NimNode] =
|
||||||
let flagFlags = cfg.flags.filterIt(it.isBool or it.isCount)
|
let flagFlags = cfg.flags.filterIt(it.isBool or it.isCount)
|
||||||
let long =
|
let long =
|
||||||
|
@ -976,6 +979,7 @@ func getNoVals(cfg: CliCfg): tuple[long: NimNode, short: NimNode] =
|
||||||
)
|
)
|
||||||
result = (nnkPrefix.newTree(ident"@",long), short)
|
result = (nnkPrefix.newTree(ident"@",long), short)
|
||||||
|
|
||||||
|
|
||||||
func setVars(cfg: CliCfg): NimNode =
|
func setVars(cfg: CliCfg): NimNode =
|
||||||
## generate all positinal variables and flags not covered in global module
|
## generate all positinal variables and flags not covered in global module
|
||||||
result = nnkVarSection.newTree()
|
result = nnkVarSection.newTree()
|
||||||
|
@ -990,6 +994,8 @@ func setVars(cfg: CliCfg): NimNode =
|
||||||
result.add cfg.args.mapIt(
|
result.add cfg.args.mapIt(
|
||||||
nnkIdentDefs.newTree(it.ident, it.typeNode, newEmptyNode())
|
nnkIdentDefs.newTree(it.ident, it.typeNode, newEmptyNode())
|
||||||
)
|
)
|
||||||
|
if hasSubcommands cfg:
|
||||||
|
result.add nnkIdentDefs.newTree(ident"subcmd", ident"string", newEmptyNode())
|
||||||
|
|
||||||
func literalFlags(f: CliFlag): NimNode =
|
func literalFlags(f: CliFlag): NimNode =
|
||||||
var flags: seq[string]
|
var flags: seq[string]
|
||||||
|
@ -1007,7 +1013,7 @@ type
|
||||||
func getMultiArgKind(cfg: CliCfg): MultiArgKind =
|
func getMultiArgKind(cfg: CliCfg): MultiArgKind =
|
||||||
if cfg.args.len == 1:
|
if cfg.args.len == 1:
|
||||||
if cfg.args[0].isSeq:
|
if cfg.args[0].isSeq:
|
||||||
return First
|
return Last
|
||||||
else:
|
else:
|
||||||
return NoMulti
|
return NoMulti
|
||||||
if cfg.args[0].isSeq:
|
if cfg.args[0].isSeq:
|
||||||
|
@ -1055,38 +1061,21 @@ func genPosArgHandler(cfg: CliCfg, body: NimNode) =
|
||||||
## generate code to handle positional arguments
|
## generate code to handle positional arguments
|
||||||
let numArgs = cfg.args.len
|
let numArgs = cfg.args.len
|
||||||
let maKind = cfg.getMultiArgKind()
|
let maKind = cfg.getMultiArgKind()
|
||||||
if ExactArgs in cfg.settings:
|
|
||||||
case maKind:
|
|
||||||
of NoMulti:
|
|
||||||
body.add quote do:
|
|
||||||
if result.len != `numArgs`:
|
|
||||||
hwylCliError("missing positional args, got: " & $result.len & ", expected: " & $`numArgs`)
|
|
||||||
else:
|
|
||||||
body.add quote do:
|
|
||||||
if result.len < `numArgs`:
|
|
||||||
hwylCliError("missing positional args, got: " & $result.len & ", expected: " & $`numArgs`)
|
|
||||||
elif maKind == First:
|
|
||||||
body.add quote do:
|
|
||||||
if result.len < `numArgs`:
|
|
||||||
hwylCliError("missing positional args, got: " & $result.len & ", expected at least: " & $`numArgs`)
|
|
||||||
elif maKind == Last:
|
|
||||||
body.add quote do:
|
|
||||||
if result.len < (`numArgs` - 1):
|
|
||||||
hwylCliError("missing positional args, got: " & $result.len & ", expected at least: " & $(`numArgs` - 1))
|
|
||||||
|
|
||||||
case maKind:
|
case maKind:
|
||||||
# BUG: this may create index defects,
|
of NoMulti:
|
||||||
# if not coupled with ExactArgs or result length checks
|
body.add quote do:
|
||||||
of Last:
|
if result.len > `numArgs`:
|
||||||
for i, namedArg in cfg.args[0..^2].mapIt(it.ident):
|
hwylCliError("unexepected positional args, got: " & $result.len & ", expected: " & $`numArgs`)
|
||||||
|
elif result.len < `numArgs`:
|
||||||
|
hwylCliError("missing positional args, got: " & $result.len & ", expected: " & $`numArgs`)
|
||||||
|
for i, namedArg in cfg.args.mapIt(it.name.ident):
|
||||||
body.add quote do:
|
body.add quote do:
|
||||||
parseArgs(result[`i`], `namedArg`)
|
parseArgs(result[`i`], `namedArg`)
|
||||||
|
|
||||||
let lastArg = cfg.args[^1].ident
|
|
||||||
body.add quote do:
|
|
||||||
parseArgs(result[(`numArgs`-1).. ^1],`lastArg`)
|
|
||||||
|
|
||||||
of First:
|
of First:
|
||||||
|
body.add quote do:
|
||||||
|
if result.len < `numArgs`:
|
||||||
|
hwylCliError("missing positional args, got: " & $result.len & ", expected at least: " & $`numArgs`)
|
||||||
for i, namedArg in cfg.args[1..^1].reversed().mapIt(it.ident):
|
for i, namedArg in cfg.args[1..^1].reversed().mapIt(it.ident):
|
||||||
body.add quote do:
|
body.add quote do:
|
||||||
parseArgs(result[^(1+`i`)], `namedArg`)
|
parseArgs(result[^(1+`i`)], `namedArg`)
|
||||||
|
@ -1095,33 +1084,26 @@ func genPosArgHandler(cfg: CliCfg, body: NimNode) =
|
||||||
body.add quote do:
|
body.add quote do:
|
||||||
parseArgs(result[0..^(`numArgs`)], `firstArg`)
|
parseArgs(result[0..^(`numArgs`)], `firstArg`)
|
||||||
|
|
||||||
|
of Last:
|
||||||
of NoMulti:
|
body.add quote do:
|
||||||
for i, namedArg in cfg.args.mapIt(it.name.ident):
|
if result.len < (`numArgs` - 1):
|
||||||
|
hwylCliError("missing positional args, got: " & $result.len & ", expected at least: " & $(`numArgs` - 1))
|
||||||
|
for i, namedArg in cfg.args[0..^2].mapIt(it.ident):
|
||||||
body.add quote do:
|
body.add quote do:
|
||||||
parseArgs(result[`i`], `namedArg`)
|
parseArgs(result[`i`], `namedArg`)
|
||||||
|
|
||||||
if ExactArgs in cfg.settings:
|
let lastArg = cfg.args[^1].ident
|
||||||
if maKind == NoMulti:
|
|
||||||
body.add quote do:
|
|
||||||
result = result[(`numArgs`)..^1]
|
|
||||||
if result.len > 0:
|
|
||||||
hwylCliError("unexpected positional arguments: " & $result)
|
|
||||||
# # here if result.len > 1 then it should error?
|
|
||||||
# # really if we pass ExactArgs the parse function should return nothing...
|
|
||||||
|
|
||||||
# first and last already absorbed the remaining args
|
|
||||||
# so ExactArgs is a NOOP use a compile Hint?
|
|
||||||
|
|
||||||
if maKind in [First, Last]:
|
|
||||||
if ExactArgs in cfg.settings:
|
|
||||||
hint "Exact args is a No-op when one of the positional args is seq[T]"
|
|
||||||
body.add quote do:
|
body.add quote do:
|
||||||
result = @[]
|
if result.len > `numArgs` - 1:
|
||||||
|
parseArgs(result[(`numArgs`-1).. ^1],`lastArg`)
|
||||||
|
|
||||||
|
body.add quote do:
|
||||||
|
result = @[]
|
||||||
|
|
||||||
func addPostParseHook(cfg: CliCfg, body: NimNode) =
|
func addPostParseHook(cfg: CliCfg, body: NimNode) =
|
||||||
## generate block to set defaults and check for required flags
|
## generate block to set defaults and check for required flags
|
||||||
let flagSet = ident"flagSet"
|
let flagSet = ident"flagSet"
|
||||||
|
let subcmd = ident"subcmd"
|
||||||
var required, default: seq[CliFlag]
|
var required, default: seq[CliFlag]
|
||||||
|
|
||||||
for f in cfg.flags:
|
for f in cfg.flags:
|
||||||
|
@ -1146,24 +1128,34 @@ func addPostParseHook(cfg: CliCfg, body: NimNode) =
|
||||||
if `name` notin `flagSet`:
|
if `name` notin `flagSet`:
|
||||||
`target` = `default`
|
`target` = `default`
|
||||||
|
|
||||||
if cfg.args.len > 0:
|
|
||||||
genPosArgHandler cfg, body
|
|
||||||
|
|
||||||
|
if hasSubcommands cfg:
|
||||||
|
body.add quote do:
|
||||||
|
if result.len == 0:
|
||||||
|
hwylCliError("expected subcommand")
|
||||||
|
`subcmd` = result[0]
|
||||||
|
result = result[1..^1]
|
||||||
|
|
||||||
|
|
||||||
|
elif cfg.args.len == 0:
|
||||||
|
body.add quote do:
|
||||||
|
if result.len > 0:
|
||||||
|
hwylCliError("got unexpected positionals args: [b]" & result.join(" "))
|
||||||
|
|
||||||
|
elif cfg.args.len > 0:
|
||||||
|
genPosArgHandler cfg, body
|
||||||
|
|
||||||
func hwylCliImpl(cfg: CliCfg): NimNode
|
func hwylCliImpl(cfg: CliCfg): NimNode
|
||||||
|
|
||||||
func genSubcommandHandler(cfg: CliCfg): NimNode =
|
func genSubcommandHandler(cfg: CliCfg): NimNode =
|
||||||
let args = ident"args"
|
let subcmd = ident"subcmd"
|
||||||
result = nnkStmtList.newTree()
|
result = nnkStmtList.newTree()
|
||||||
result.add quote do:
|
|
||||||
if `args`.len == 0:
|
|
||||||
hwylCliError("expected subcommand")
|
|
||||||
|
|
||||||
var subCommandCase = nnkCaseStmt.newTree()
|
var subCommandCase = nnkCaseStmt.newTree()
|
||||||
if NoNormalize notin cfg.settings:
|
if NoNormalize notin cfg.settings:
|
||||||
subCommandCase.add(quote do: optionNormalize(`args`[0]))
|
subCommandCase.add(quote do: optionNormalize(`subcmd`))
|
||||||
else:
|
else:
|
||||||
subCommandCase.add(quote do: `args`[0])
|
subCommandCase.add(quote do: `subcmd`)
|
||||||
|
|
||||||
for sub in cfg.subcommands:
|
for sub in cfg.subcommands:
|
||||||
var branch = nnkOfBranch.newTree()
|
var branch = nnkOfBranch.newTree()
|
||||||
|
@ -1175,7 +1167,7 @@ func genSubcommandHandler(cfg: CliCfg): NimNode =
|
||||||
|
|
||||||
subcommandCase.add nnkElse.newTree(
|
subcommandCase.add nnkElse.newTree(
|
||||||
quote do:
|
quote do:
|
||||||
hwylCliError("unknown subcommand: [b]" & `args`[0])
|
hwylCliError("unknown subcommand: [b]" & `subcmd`)
|
||||||
)
|
)
|
||||||
|
|
||||||
result.add subCommandCase
|
result.add subCommandCase
|
||||||
|
@ -1199,14 +1191,14 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
name = cfg.name.replace(" ", "")
|
name = cfg.name.replace(" ", "")
|
||||||
printHelpName = ident("print" & name & "Help")
|
printHelpName = ident("print" & name & "Help")
|
||||||
parserProcName = ident("parse" & name)
|
parserProcName = ident("parse" & name)
|
||||||
args = ident"args"
|
posArgs = ident"posArgs"
|
||||||
optParser = ident("p")
|
optParser = ident("p")
|
||||||
cmdLine = ident"cmdLine"
|
cmdLine = ident"cmdLine"
|
||||||
flagSet = ident"flagSet"
|
flagSet = ident"flagSet"
|
||||||
nArgs = ident"nargs"
|
nArgs = ident"nargs"
|
||||||
(longNoVal, shortNoVal) = cfg.getNoVals()
|
(longNoVal, shortNoVal) = cfg.getNoVals()
|
||||||
printHelpProc = generateCliHelpProc(cfg, printHelpName)
|
printHelpProc = generateCliHelpProc(cfg, printHelpName)
|
||||||
flagVars = setVars(cfg)
|
varBlock= setVars(cfg)
|
||||||
|
|
||||||
var
|
var
|
||||||
parserBody = nnkStmtList.newTree()
|
parserBody = nnkStmtList.newTree()
|
||||||
|
@ -1259,6 +1251,7 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if ShowHelp in cfg.settings:
|
if ShowHelp in cfg.settings:
|
||||||
parserBody.add quote do:
|
parserBody.add quote do:
|
||||||
if commandLineParams().len == 0:
|
if commandLineParams().len == 0:
|
||||||
|
@ -1278,7 +1271,7 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
runBody.add cfg.post
|
runBody.add cfg.post
|
||||||
|
|
||||||
# args and subcommands need to be mutually exclusive -> implement using a CommandKind?
|
# args and subcommands need to be mutually exclusive -> implement using a CommandKind?
|
||||||
if cfg.subcommands.len > 0:
|
if hasSubcommands cfg:
|
||||||
runBody.add genSubcommandHandler(cfg)
|
runBody.add genSubcommandHandler(cfg)
|
||||||
|
|
||||||
result = newTree(nnkStmtList)
|
result = newTree(nnkStmtList)
|
||||||
|
@ -1286,12 +1279,12 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
result.add quote do:
|
result.add quote do:
|
||||||
# block:
|
# block:
|
||||||
`printHelpProc`
|
`printHelpProc`
|
||||||
`flagVars`
|
`varBlock`
|
||||||
proc `parserProcName`(`cmdLine`: openArray[string] = commandLineParams()): seq[string] =
|
proc `parserProcName`(`cmdLine`: openArray[string] = commandLineParams()): seq[string] =
|
||||||
`parserBody`
|
`parserBody`
|
||||||
|
|
||||||
proc `runProcName`(`cmdLine`: openArray[string] = commandLineParams()) =
|
proc `runProcName`(`cmdLine`: openArray[string] = commandLineParams()) =
|
||||||
let `args` {.used.} = `parserProcName`(`cmdLine`)
|
let `posArgs` {.used.} = `parserProcName`(`cmdLine`)
|
||||||
`runBody`
|
`runBody`
|
||||||
|
|
||||||
if cfg.root:
|
if cfg.root:
|
||||||
|
@ -1300,7 +1293,7 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
`runProcName`()
|
`runProcName`()
|
||||||
else:
|
else:
|
||||||
result.add quote do:
|
result.add quote do:
|
||||||
`runProcName`(`args`[1..^1])
|
`runProcName`(`posArgs`)
|
||||||
|
|
||||||
macro hwylCli*(body: untyped) =
|
macro hwylCli*(body: untyped) =
|
||||||
## generate a CLI styled by `hwylterm` and parsed by `parseopt3`
|
## generate a CLI styled by `hwylterm` and parsed by `parseopt3`
|
||||||
|
|
|
@ -5,8 +5,6 @@ type
|
||||||
Color = enum
|
Color = enum
|
||||||
red, blue, green
|
red, blue, green
|
||||||
|
|
||||||
# TODO: color should be a required flag by default?
|
|
||||||
|
|
||||||
hwylCli:
|
hwylCli:
|
||||||
name "enumFlag"
|
name "enumFlag"
|
||||||
flags:
|
flags:
|
||||||
|
@ -14,4 +12,3 @@ hwylCli:
|
||||||
T Color
|
T Color
|
||||||
run:
|
run:
|
||||||
echo fmt"{color=}"
|
echo fmt"{color=}"
|
||||||
assert args.len == 0
|
|
||||||
|
|
9
tests/cli/clis/posBasic.nim
Normal file
9
tests/cli/clis/posBasic.nim
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import std/[strformat]
|
||||||
|
import hwylterm, hwylterm/hwylcli
|
||||||
|
|
||||||
|
hwylCli:
|
||||||
|
name "posLast"
|
||||||
|
positionals:
|
||||||
|
args seq[string]
|
||||||
|
run:
|
||||||
|
echo fmt"{args=}"
|
|
@ -3,10 +3,9 @@ import hwylterm, hwylterm/hwylcli
|
||||||
|
|
||||||
hwylCli:
|
hwylCli:
|
||||||
name "positionals"
|
name "positionals"
|
||||||
args:
|
positionals:
|
||||||
first seq[string]
|
first seq[string]
|
||||||
second string
|
second string
|
||||||
third string
|
third string
|
||||||
run:
|
run:
|
||||||
echo fmt"{first=}, {second=}, {third=}"
|
echo fmt"{first=}, {second=}, {third=}"
|
||||||
echo fmt"{args=}"
|
|
||||||
|
|
|
@ -3,10 +3,9 @@ import hwylterm, hwylterm/hwylcli
|
||||||
|
|
||||||
hwylCli:
|
hwylCli:
|
||||||
name "posLast"
|
name "posLast"
|
||||||
args:
|
positionals:
|
||||||
first string
|
first string
|
||||||
second string
|
second string
|
||||||
third seq[string]
|
third seq[string]
|
||||||
run:
|
run:
|
||||||
echo fmt"{first=}, {second=}, {third=}"
|
echo fmt"{first=}, {second=}, {third=}"
|
||||||
assert args.len == 0
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
import std/[strformat]
|
|
||||||
import hwylterm, hwylterm/hwylcli
|
|
||||||
|
|
||||||
hwylCli:
|
|
||||||
name "posLast"
|
|
||||||
settings: ExactArgs
|
|
||||||
args:
|
|
||||||
first string
|
|
||||||
second string
|
|
||||||
third seq[string]
|
|
||||||
run:
|
|
||||||
echo fmt"{first=}, {second=}, {third=}"
|
|
||||||
assert args.len == 0
|
|
|
@ -3,11 +3,9 @@ import hwylterm, hwylterm/hwylcli
|
||||||
|
|
||||||
hwylCli:
|
hwylCli:
|
||||||
name "positionals"
|
name "positionals"
|
||||||
settings: ExactArgs
|
positionals:
|
||||||
args:
|
|
||||||
first int
|
first int
|
||||||
second string
|
second string
|
||||||
third string
|
third string
|
||||||
run:
|
run:
|
||||||
echo fmt"{first=}, {second=}, {third=}"
|
echo fmt"{first=}, {second=}, {third=}"
|
||||||
assert args.len == 0
|
|
||||||
|
|
22
tests/cli/clis/subcommands.nim
Normal file
22
tests/cli/clis/subcommands.nim
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import std/[strformat]
|
||||||
|
import hwylterm, hwylterm/hwylcli
|
||||||
|
|
||||||
|
hwylCli:
|
||||||
|
name "subcommands"
|
||||||
|
subcommands:
|
||||||
|
[a]
|
||||||
|
... "a subcommand with positionals"
|
||||||
|
positionals:
|
||||||
|
input string
|
||||||
|
outputs seq[string]
|
||||||
|
run:
|
||||||
|
echo fmt"{input=} {outputs=}"
|
||||||
|
[b]
|
||||||
|
... "a subcommand with flags"
|
||||||
|
flags:
|
||||||
|
input:
|
||||||
|
T string
|
||||||
|
outputs:
|
||||||
|
T seq[string]
|
||||||
|
run:
|
||||||
|
echo fmt"{input=} {outputs=}"
|
|
@ -23,16 +23,22 @@ proc preCompileWorkingModule(module: string) =
|
||||||
echo "cmd: ", cmd
|
echo "cmd: ", cmd
|
||||||
quit "failed to precompile test module"
|
quit "failed to precompile test module"
|
||||||
|
|
||||||
|
proc preCompileTestModules*() =
|
||||||
|
for srcModule in walkDirRec(pathToSrc / "clis"):
|
||||||
|
if srcModule.endsWith(".nim"):
|
||||||
|
let (_, moduleName, _) = srcModule.splitFile
|
||||||
|
preCompileWorkingModule(moduleName)
|
||||||
|
|
||||||
template okWithArgs*(module: string, args = "", output = "") =
|
template okWithArgs*(module: string, args = "", output = "") =
|
||||||
preCompileWorkingModule(module)
|
preCompileWorkingModule(module)
|
||||||
test module:
|
test (module & "|" & args):
|
||||||
let (actualOutput, code) = runTestCli(module, args)
|
let (actualOutput, code) = runTestCli(module, args)
|
||||||
check code == 0
|
check code == 0
|
||||||
check output == actualOutput
|
check output == actualOutput
|
||||||
|
|
||||||
template failWithArgs*(module: string, args = "", output = "") =
|
template failWithArgs*(module: string, args = "", output = "") =
|
||||||
preCompileWorkingModule(module)
|
preCompileWorkingModule(module)
|
||||||
test module:
|
test (module & "|" & args):
|
||||||
let (actualOutput, code) = runTestCli(module, args)
|
let (actualOutput, code) = runTestCli(module, args)
|
||||||
check code == 1
|
check code == 1
|
||||||
check output == actualOutput
|
check output == actualOutput
|
||||||
|
|
|
@ -2,31 +2,39 @@ import std/[unittest]
|
||||||
import ./lib
|
import ./lib
|
||||||
|
|
||||||
suite "hwylcli":
|
suite "hwylcli":
|
||||||
test "positionals":
|
setup:
|
||||||
okWithArgs(
|
preCompileTestModules()
|
||||||
"posFirst",
|
|
||||||
"a b c d e",
|
|
||||||
"""
|
|
||||||
first=@["a", "b", "c"], second=d, third=e
|
|
||||||
args=@[]"""
|
|
||||||
)
|
|
||||||
failWithArgs(
|
|
||||||
"posFirst",
|
|
||||||
"a b",
|
|
||||||
"error missing positional args, got: 2, expected at least: 3",
|
|
||||||
)
|
|
||||||
okWithArgs("posLast", "a b", """first=a, second=b, third=@[]""")
|
|
||||||
okWithArgs("posLastExact", "a b c d e", """first=a, second=b, third=@["c", "d", "e"]""")
|
|
||||||
okWithArgs("posNoMulti", "5 b c", """first=5, second=b, third=c""")
|
|
||||||
failWithArgs("posNoMulti", "5 b c d", """error missing positional args, got: 4, expected: 3""")
|
|
||||||
test "special flag types":
|
|
||||||
okWithArgs("enumFlag","--color red", "color=red")
|
|
||||||
failWithArgs("enumFlag","--color black", "error failed to parse value for color as enum: black expected one of: red,blue,green")
|
|
||||||
|
|
||||||
test "help":
|
okWithArgs(
|
||||||
okWithArgs("posFirst", "--help",
|
"posBasic",
|
||||||
|
"a b c d e",
|
||||||
|
"""args=@["a", "b", "c", "d", "e"]"""
|
||||||
|
)
|
||||||
|
okWithArgs(
|
||||||
|
"posFirst",
|
||||||
|
"a b c d e",
|
||||||
|
"""first=@["a", "b", "c"], second=d, third=e"""
|
||||||
|
)
|
||||||
|
failWithArgs(
|
||||||
|
"posFirst",
|
||||||
|
"a b",
|
||||||
|
"error missing positional args, got: 2, expected at least: 3",
|
||||||
|
)
|
||||||
|
okWithArgs("posLast", "a b", """first=a, second=b, third=@[]""")
|
||||||
|
okWithArgs("posNoMulti", "5 b c", """first=5, second=b, third=c""")
|
||||||
|
failWithArgs("posNoMulti", "5 b c d", """error unexepected positional args, got: 4, expected: 3""")
|
||||||
|
|
||||||
|
okWithArgs("enumFlag","--color red", "color=red")
|
||||||
|
failWithArgs("enumFlag","--color black", "error failed to parse value for color as enum: black expected one of: red,blue,green")
|
||||||
|
|
||||||
|
okWithArgs("subcommands", "a b c","""input=b outputs=@["c"]""")
|
||||||
|
failWithArgs("subcommands", "b b c","""error got unexpected positionals args: b c""")
|
||||||
|
okWithArgs("subcommands","b --input in --outputs out1 --outputs out2", """input=in outputs=@["out1", "out2"]""")
|
||||||
|
|
||||||
|
okWithArgs("posFirst", "--help",
|
||||||
"""usage:
|
"""usage:
|
||||||
positionals first... second third [flags]
|
positionals first... second third [flags]
|
||||||
|
|
||||||
flags:
|
flags:
|
||||||
-h --help show this help""")
|
-h --help show this help""")
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue