Skip to content

Commit d7e139e

Browse files
authored
fix #15 (#120)
1 parent fd40a96 commit d7e139e

File tree

6 files changed

+190
-13
lines changed

6 files changed

+190
-13
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ vendor/
77
tests/test_all
88
tests/test_nested_cmd
99
tests/test_help
10+
tests/test_argument

confutils.nim

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -182,20 +182,15 @@ func hasOpts(cmd: CmdInfo): bool =
182182
return false
183183

184184
func hasArgs(cmd: CmdInfo): bool =
185-
cmd.opts.len > 0 and cmd.opts[^1].kind == Arg
186-
187-
func firstArgIdx(cmd: CmdInfo): int =
188-
# This will work correctly only if the command has arguments.
189-
result = cmd.opts.len - 1
190-
while result > 0:
191-
if cmd.opts[result - 1].kind != Arg:
192-
return
193-
dec result
185+
for opt in cmd.opts:
186+
if opt.kind == Arg:
187+
return true
188+
false
194189

195190
iterator args(cmd: CmdInfo): OptInfo =
196-
if cmd.hasArgs:
197-
for i in cmd.firstArgIdx ..< cmd.opts.len:
198-
yield cmd.opts[i]
191+
for opt in cmd.opts:
192+
if opt.kind == Arg:
193+
yield opt
199194

200195
func getSubCmdDiscriminator(cmd: CmdInfo): OptInfo =
201196
for i in countdown(cmd.opts.len - 1, 0):
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Usage:
2+
3+
test_argument command
4+
5+
Available sub-commands:
6+
7+
test_argument argAfterOpt [OPTIONS]... <arg-after-opt-arg1>
8+
9+
<arg-after-opt-arg1> arg1 desc.
10+
11+
The following options are available:
12+
13+
--arg-after-opt-opt1 opt1 desc [=opt1 default].
14+
15+
test_argument argBeforeOpt [OPTIONS]... <arg-before-opt-arg2>
16+
17+
<arg-before-opt-arg2> arg2 desc.
18+
19+
The following options are available:
20+
21+
--arg-before-opt-opt2 opt2 desc [=opt2 default].
22+
23+
test_argument argAroundOpt [OPTIONS]... <arg-around-opt-arg4> <arg-around-opt-arg5>
24+
25+
<arg-around-opt-arg4> arg4 desc.
26+
<arg-around-opt-arg5> arg5 desc.
27+
28+
The following options are available:
29+
30+
--arg-around-opt-opt3 opt3 desc [=opt3 default].

tests/help/test_argument.nim

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import ../../confutils
2+
3+
type
4+
Lvl1Cmd* = enum
5+
noCommand
6+
argAfterOpt
7+
argBeforeOpt
8+
argAroundOpt
9+
10+
TestConf* = object
11+
case cmd* {.
12+
command
13+
defaultValue: Lvl1Cmd.noCommand }: Lvl1Cmd
14+
of Lvl1Cmd.noCommand:
15+
discard
16+
of Lvl1Cmd.argAfterOpt:
17+
opt1* {.
18+
defaultValue: "opt1 default"
19+
desc: "opt1 desc"
20+
name: "arg-after-opt-opt1" }: string
21+
arg1* {.
22+
argument
23+
desc: "arg1 desc"
24+
name: "arg-after-opt-arg1" }: string
25+
of Lvl1Cmd.argBeforeOpt:
26+
arg2* {.
27+
argument
28+
desc: "arg2 desc"
29+
name: "arg-before-opt-arg2" }: string
30+
opt2* {.
31+
defaultValue: "opt2 default"
32+
desc: "opt2 desc"
33+
name: "arg-before-opt-opt2" }: string
34+
of Lvl1Cmd.argAroundOpt:
35+
arg4* {.
36+
argument
37+
desc: "arg4 desc"
38+
name: "arg-around-opt-arg4" }: string
39+
opt3* {.
40+
defaultValue: "opt3 default"
41+
desc: "opt3 desc"
42+
name: "arg-around-opt-opt3" }: string
43+
arg5* {.
44+
argument
45+
desc: "arg5 desc"
46+
name: "arg-around-opt-arg5" }: string
47+
48+
when isMainModule:
49+
let c = TestConf.load(termWidth = int.high)

tests/test_argument.nim

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# confutils
2+
# Copyright (c) 2018-2025 Status Research & Development GmbH
3+
# Licensed under either of
4+
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
5+
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
6+
# at your option.
7+
# This file may not be copied, modified, or distributed except according to
8+
# those terms.
9+
10+
import unittest2, ../confutils, ./help/test_argument
11+
12+
suite "test argument":
13+
test "no command":
14+
let conf = TestConf.load(cmdLine = @[])
15+
check:
16+
conf.cmd == Lvl1Cmd.noCommand
17+
18+
test "pass arg first to argAfterOpt":
19+
let conf = TestConf.load(cmdLine = @[
20+
"argAfterOpt",
21+
"foo",
22+
"--arg-after-opt-opt1=bar"
23+
])
24+
check:
25+
conf.cmd == Lvl1Cmd.argAfterOpt
26+
conf.arg1 == "foo"
27+
conf.opt1 == "bar"
28+
29+
test "pass arg last to argAfterOpt":
30+
let conf = TestConf.load(cmdLine = @[
31+
"argAfterOpt",
32+
"--arg-after-opt-opt1=bar",
33+
"foo"
34+
])
35+
check:
36+
conf.cmd == Lvl1Cmd.argAfterOpt
37+
conf.arg1 == "foo"
38+
conf.opt1 == "bar"
39+
40+
test "pass arg first to argBeforeOpt":
41+
let conf = TestConf.load(cmdLine = @[
42+
"argBeforeOpt",
43+
"foo",
44+
"--arg-before-opt-opt2=bar"
45+
])
46+
check:
47+
conf.cmd == Lvl1Cmd.argBeforeOpt
48+
conf.arg2 == "foo"
49+
conf.opt2 == "bar"
50+
51+
test "pass arg last to argBeforeOpt":
52+
let conf = TestConf.load(cmdLine = @[
53+
"argBeforeOpt",
54+
"--arg-before-opt-opt2=bar",
55+
"foo"
56+
])
57+
check:
58+
conf.cmd == Lvl1Cmd.argBeforeOpt
59+
conf.arg2 == "foo"
60+
conf.opt2 == "bar"
61+
62+
test "pass arg first to argAroundOpt":
63+
let conf = TestConf.load(cmdLine = @[
64+
"argAroundOpt",
65+
"foo",
66+
"bar",
67+
"--arg-around-opt-opt3=baz"
68+
])
69+
check:
70+
conf.cmd == Lvl1Cmd.argAroundOpt
71+
conf.arg4 == "foo"
72+
conf.arg5 == "bar"
73+
conf.opt3 == "baz"
74+
75+
test "pass arg last to argAroundOpt":
76+
let conf = TestConf.load(cmdLine = @[
77+
"argAroundOpt",
78+
"--arg-around-opt-opt3=baz",
79+
"foo",
80+
"bar"
81+
])
82+
check:
83+
conf.cmd == Lvl1Cmd.argAroundOpt
84+
conf.arg4 == "foo"
85+
conf.arg5 == "bar"
86+
conf.opt3 == "baz"
87+
88+
test "pass arg mix to argAroundOpt":
89+
let conf = TestConf.load(cmdLine = @[
90+
"argAroundOpt",
91+
"foo",
92+
"--arg-around-opt-opt3=baz",
93+
"bar"
94+
])
95+
check:
96+
conf.cmd == Lvl1Cmd.argAroundOpt
97+
conf.arg4 == "foo"
98+
conf.arg5 == "bar"
99+
conf.opt3 == "baz"

tests/test_help.nim

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ suite "test --help":
5959

6060
test "test test_nested_cmd lvl1Cmd1":
6161
cmdTest("test_nested_cmd", "lvl1Cmd1")
62-
62+
6363
test "test test_nested_cmd lvl1Cmd1 lvl2Cmd2":
6464
cmdTest("test_nested_cmd", "lvl1Cmd1 lvl2Cmd2")
65+
66+
test "test test_argument":
67+
cmdTest("test_argument", "")

0 commit comments

Comments
 (0)