mirror of
https://github.com/daylinmorgan/hwylterm.git
synced 2024-11-16 06:28:32 -06:00
modify flag inheritance to support individual flags
This commit is contained in:
parent
ad57eee373
commit
2a5dce888d
2 changed files with 68 additions and 34 deletions
|
@ -146,6 +146,12 @@ type
|
||||||
short*: char
|
short*: char
|
||||||
long*: string
|
long*: string
|
||||||
help*: NimNode
|
help*: NimNode
|
||||||
|
group*: string
|
||||||
|
|
||||||
|
Inherit = object
|
||||||
|
settings: set[CliSetting]
|
||||||
|
flags: seq[string]
|
||||||
|
groups: seq[string]
|
||||||
|
|
||||||
CliCfg = object
|
CliCfg = object
|
||||||
stopWords*: seq[string]
|
stopWords*: seq[string]
|
||||||
|
@ -160,9 +166,9 @@ type
|
||||||
version*, usage*: NimNode
|
version*, usage*: NimNode
|
||||||
flags*: seq[CliFlag]
|
flags*: seq[CliFlag]
|
||||||
builtinFlags*: seq[BuiltinFlag]
|
builtinFlags*: seq[BuiltinFlag]
|
||||||
flagGroups: Table[string, seq[CliFlag]]
|
flagDefs*: seq[CliFlag]
|
||||||
required*: seq[string]
|
required*: seq[string]
|
||||||
inheritFlags*: seq[string]
|
inherit*: Inherit
|
||||||
root*: bool
|
root*: bool
|
||||||
|
|
||||||
# some debug procs I use to wrap my ahead aroung the magic of *macro*
|
# some debug procs I use to wrap my ahead aroung the magic of *macro*
|
||||||
|
@ -252,24 +258,35 @@ func parseCliFlags(cfg: var CliCfg, node: NimNode) =
|
||||||
var group: string
|
var group: string
|
||||||
expectKind node, nnkStmtList
|
expectKind node, nnkStmtList
|
||||||
for n in node:
|
for n in node:
|
||||||
|
<<< n
|
||||||
var flag: CliFlag
|
var flag: CliFlag
|
||||||
case n.kind
|
case n.kind
|
||||||
of nnkCall, nnkCommand:
|
of nnkCall, nnkCommand:
|
||||||
flag = parseCliFlag(n)
|
flag = parseCliFlag(n)
|
||||||
if group == "":
|
flag.group = group
|
||||||
cfg.flags.add flag
|
cfg.flagDefs.add flag
|
||||||
else:
|
|
||||||
if group notin cfg.flagGroups: cfg.flagGroups[group] = @[flag]
|
|
||||||
else: cfg.flagGroups[group].add flag
|
|
||||||
of nnkBracket:
|
of nnkBracket:
|
||||||
group = n[0].strVal
|
group = n[0].strVal
|
||||||
continue
|
continue
|
||||||
of nnkPrefix:
|
of nnkPrefix:
|
||||||
if n[0].kind != nnkIdent and n[0].strVal != "^":
|
if
|
||||||
error "unexpected node in flags: " & $n.kind
|
n[0].kind != nnkIdent or
|
||||||
expectKind n[1], nnkBracket
|
n[0].strVal != "^" or
|
||||||
cfg.inheritFlags.add n[1][0].strVal
|
n.len != 2 or
|
||||||
else: bad(n, "flag")
|
n[1].kind notin [nnkBracket, nnkIdent, nnkStrLit]:
|
||||||
|
error "unexpected node in flags: " & $n.kind
|
||||||
|
|
||||||
|
case n[1].kind
|
||||||
|
of nnkBracket:
|
||||||
|
cfg.inherit.groups.add n[1][0].strVal
|
||||||
|
# cfg.inheritFlags.add n[1][0].strVal
|
||||||
|
of nnkIdent, nnkStrLit:
|
||||||
|
cfg.inherit.flags.add n[1].strval
|
||||||
|
else: bad(n, "flag")
|
||||||
|
|
||||||
|
else: bad(n, "flag")
|
||||||
|
|
||||||
|
cfg.flags = cfg.flagDefs.filterIt(it.group in ["", "global"])
|
||||||
|
|
||||||
func parseCliSetting(s: string): CliSetting =
|
func parseCliSetting(s: string): CliSetting =
|
||||||
try: parseEnum[CliSetting](s)
|
try: parseEnum[CliSetting](s)
|
||||||
|
@ -332,25 +349,41 @@ func sliceStmts(node: NimNode): seq[
|
||||||
start = i + 1
|
start = i + 1
|
||||||
|
|
||||||
|
|
||||||
func addInheritedFlags(child: var CliCfg, parent: CliCfg, self = false) =
|
func inheritFrom(child: var CliCfg, parent: CliCfg) =
|
||||||
let names = child.flags.mapIt(it.name)
|
## inherit settings from parent command
|
||||||
var groups: seq[string]
|
var
|
||||||
if not self:
|
pflags: Table[string, CliFlag]
|
||||||
groups.add child.inheritFlags
|
pgroups: Table[string, seq[CliFlag]]
|
||||||
|
flags: seq[string]
|
||||||
|
groups: seq[string]
|
||||||
|
|
||||||
# autoinherit the "global" flags
|
flags &= child.inherit.flags
|
||||||
if "global" in parent.flagGroups:
|
groups &= child.inherit.groups
|
||||||
|
|
||||||
|
for f in parent.flagDefs:
|
||||||
|
pflags[f.name] = f
|
||||||
|
if f.group in pgroups:
|
||||||
|
pgroups[f.group].add f
|
||||||
|
else:
|
||||||
|
pgroups[f.group] = @[f]
|
||||||
|
|
||||||
|
if "global" in pgroups:
|
||||||
groups.add "global"
|
groups.add "global"
|
||||||
|
|
||||||
|
for f in flags:
|
||||||
|
if f notin pflags:
|
||||||
|
error "expected parent command to define flag: " & f
|
||||||
|
else:
|
||||||
|
child.flags.add pflags[f]
|
||||||
|
|
||||||
for g in groups:
|
for g in groups:
|
||||||
if g notin parent.flagGroups:
|
if g notin pgroups:
|
||||||
debugEcho parent.flagGroups.keys().toSeq()
|
error "expected parent command to define flag group " & g
|
||||||
error "expected flag group: " & g & " to exist in parent command"
|
else:
|
||||||
for f in parent.flagGroups[g]:
|
child.flags &= pgroups[g]
|
||||||
if f.name in names:
|
|
||||||
error "global flag " & f.name & " conflicts with command flag"
|
|
||||||
child.flags.add f
|
|
||||||
|
|
||||||
func parseCliSubcommands(cfg: var CliCfg, node: NimNode) =
|
func parseCliSubcommands(cfg: var CliCfg, node: NimNode) =
|
||||||
expectKind node[1], nnkStmtList
|
expectKind node[1], nnkStmtList
|
||||||
for (name, s) in sliceStmts(node[1]):
|
for (name, s) in sliceStmts(node[1]):
|
||||||
|
@ -359,7 +392,7 @@ func parseCliSubcommands(cfg: var CliCfg, node: NimNode) =
|
||||||
nnkStmtList.newTree(node[1][s]), cfg.name & " " & name
|
nnkStmtList.newTree(node[1][s]), cfg.name & " " & name
|
||||||
)
|
)
|
||||||
subCfg.subName = name
|
subCfg.subName = name
|
||||||
subCfg.addInheritedFlags(cfg)
|
subCfg.inheritFrom(cfg)
|
||||||
cfg.subcommands.add subCfg
|
cfg.subcommands.add subCfg
|
||||||
|
|
||||||
func parseHiddenFlags(cfg: var CliCfg, node: NimNode) =
|
func parseHiddenFlags(cfg: var CliCfg, node: NimNode) =
|
||||||
|
@ -454,8 +487,6 @@ func parseCliBody(body: NimNode, name = "", root = false): CliCfg =
|
||||||
sub.pre = result.preSub
|
sub.pre = result.preSub
|
||||||
sub.post = result.postSub
|
sub.post = result.postSub
|
||||||
|
|
||||||
result.addInheritedFlags(result, self = true)
|
|
||||||
|
|
||||||
if result.name == "":
|
if result.name == "":
|
||||||
error "missing required option: name"
|
error "missing required option: name"
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,10 @@ hwylCli:
|
||||||
yes:
|
yes:
|
||||||
T bool
|
T bool
|
||||||
? "set flag to yes"
|
? "set flag to yes"
|
||||||
[config]
|
[shared]
|
||||||
confiG:
|
something:
|
||||||
|
? "some flag only needed in one subcommand"
|
||||||
|
config:
|
||||||
T seq[string]
|
T seq[string]
|
||||||
? "path to config file"
|
? "path to config file"
|
||||||
* @["config.yml"]
|
* @["config.yml"]
|
||||||
|
@ -31,7 +33,7 @@ hwylCli:
|
||||||
the first subcommand
|
the first subcommand
|
||||||
|
|
||||||
this command features both an enum flag and a Count flag
|
this command features both an enum flag and a Count flag
|
||||||
it also inherits the `[[config]` flag group
|
it also inherits the `[[shared]` flag group
|
||||||
"""
|
"""
|
||||||
|
|
||||||
flags:
|
flags:
|
||||||
|
@ -42,7 +44,7 @@ hwylCli:
|
||||||
T Count
|
T Count
|
||||||
? "a count flag"
|
? "a count flag"
|
||||||
- v
|
- v
|
||||||
^[config]
|
^[shared]
|
||||||
run:
|
run:
|
||||||
echo "hello from `example one` command!"
|
echo "hello from `example one` command!"
|
||||||
echo args
|
echo args
|
||||||
|
@ -58,6 +60,7 @@ hwylCli:
|
||||||
and it will automatically be "bb"'ed [bold]this is bold text[/]
|
and it will automatically be "bb"'ed [bold]this is bold text[/]
|
||||||
"""
|
"""
|
||||||
flags:
|
flags:
|
||||||
|
^something
|
||||||
auto:
|
auto:
|
||||||
- a
|
- a
|
||||||
? "some help"
|
? "some help"
|
||||||
|
|
Loading…
Reference in a new issue