Compare commits

..

No commits in common. "2a5dce888d7abf5409a62208d951ac3a4e6babfa" and "94e5b8708819e9a3503bee686b1617912518fccb" have entirely different histories.

3 changed files with 35 additions and 71 deletions

View file

@ -124,8 +124,8 @@ type
val*: int val*: int
type type
# ----
CliSetting* = enum CliSetting* = enum
# Propagate, ## Include parent command settings in subcommand
GenerateOnly, ## Don't attach root `runProc()` node GenerateOnly, ## Don't attach root `runProc()` node
NoHelpFlag, ## Remove the builtin help flag NoHelpFlag, ## Remove the builtin help flag
ShowHelp, ## If cmdline empty show help ShowHelp, ## If cmdline empty show help
@ -146,12 +146,6 @@ 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]
@ -166,9 +160,9 @@ type
version*, usage*: NimNode version*, usage*: NimNode
flags*: seq[CliFlag] flags*: seq[CliFlag]
builtinFlags*: seq[BuiltinFlag] builtinFlags*: seq[BuiltinFlag]
flagDefs*: seq[CliFlag] flagGroups: Table[string, seq[CliFlag]]
required*: seq[string] required*: seq[string]
inherit*: Inherit inheritFlags*: seq[string]
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*
@ -258,36 +252,25 @@ 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)
flag.group = group if group == "":
cfg.flagDefs.add flag cfg.flags.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 if n[0].kind != nnkIdent and n[0].strVal != "^":
n[0].kind != nnkIdent or
n[0].strVal != "^" or
n.len != 2 or
n[1].kind notin [nnkBracket, nnkIdent, nnkStrLit]:
error "unexpected node in flags: " & $n.kind error "unexpected node in flags: " & $n.kind
expectKind n[1], nnkBracket
case n[1].kind cfg.inheritFlags.add n[1][0].strVal
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")
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)
except: error "unknown cli setting: " & s except: error "unknown cli setting: " & s
@ -349,40 +332,24 @@ func sliceStmts(node: NimNode): seq[
start = i + 1 start = i + 1
func inheritFrom(child: var CliCfg, parent: CliCfg) = func addInheritedFlags(child: var CliCfg, parent: CliCfg, self = false) =
## inherit settings from parent command let names = child.flags.mapIt(it.name)
var var groups: seq[string]
pflags: Table[string, CliFlag] if not self:
pgroups: Table[string, seq[CliFlag]] groups.add child.inheritFlags
flags: seq[string]
groups: seq[string]
flags &= child.inherit.flags # autoinherit the "global" flags
groups &= child.inherit.groups if "global" in parent.flagGroups:
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 pgroups: if g notin parent.flagGroups:
error "expected parent command to define flag group " & g debugEcho parent.flagGroups.keys().toSeq()
else: error "expected flag group: " & g & " to exist in parent command"
child.flags &= pgroups[g] for f in parent.flagGroups[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
@ -392,7 +359,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.inheritFrom(cfg) subCfg.addInheritedFlags(cfg)
cfg.subcommands.add subCfg cfg.subcommands.add subCfg
func parseHiddenFlags(cfg: var CliCfg, node: NimNode) = func parseHiddenFlags(cfg: var CliCfg, node: NimNode) =
@ -487,6 +454,8 @@ 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"

View file

@ -16,10 +16,8 @@ hwylCli:
yes: yes:
T bool T bool
? "set flag to yes" ? "set flag to yes"
[shared] [config]
something: confiG:
? "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"]
@ -33,7 +31,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 `[[shared]` flag group it also inherits the `[[config]` flag group
""" """
flags: flags:
@ -44,7 +42,7 @@ hwylCli:
T Count T Count
? "a count flag" ? "a count flag"
- v - v
^[shared] ^[config]
run: run:
echo "hello from `example one` command!" echo "hello from `example one` command!"
echo args echo args
@ -60,7 +58,6 @@ 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"

View file

@ -18,8 +18,6 @@
- [ ] add support for types(metavars)/defaults/required in help output - [ ] add support for types(metavars)/defaults/required in help output
- [ ] add nargs to CliCfg - [ ] add nargs to CliCfg
- [ ] add support for inheriting a single flag from parent (even from a "group")
- [ ] add support to either (lengthen commands) or provide an alias for a subcommand
## features ## features