cli: add flag/cmd sorting + get_all_found (#5615)
parent
6cbc0e84f0
commit
703b060d09
|
@ -15,6 +15,9 @@ pub mut:
|
||||||
disable_version bool
|
disable_version bool
|
||||||
disable_flags bool
|
disable_flags bool
|
||||||
|
|
||||||
|
sort_flags bool = true
|
||||||
|
sort_commands bool = true
|
||||||
|
|
||||||
parent &Command = nil()
|
parent &Command = nil()
|
||||||
commands []Command
|
commands []Command
|
||||||
flags []Flag
|
flags []Flag
|
||||||
|
@ -49,6 +52,13 @@ pub fn (mut cmd Command) parse(args []string) {
|
||||||
}
|
}
|
||||||
cmd.add_default_commands()
|
cmd.add_default_commands()
|
||||||
|
|
||||||
|
if cmd.sort_flags {
|
||||||
|
cmd.flags.sort()
|
||||||
|
}
|
||||||
|
if cmd.sort_commands {
|
||||||
|
cmd.commands.sort()
|
||||||
|
}
|
||||||
|
|
||||||
cmd.args = args[1..]
|
cmd.args = args[1..]
|
||||||
for i in 0..cmd.commands.len {
|
for i in 0..cmd.commands.len {
|
||||||
cmd.commands[i].parent = cmd
|
cmd.commands[i].parent = cmd
|
||||||
|
@ -88,6 +98,7 @@ fn (mut cmd Command) parse_flags() {
|
||||||
mut flag := &cmd.flags[i]
|
mut flag := &cmd.flags[i]
|
||||||
if flag.matches(cmd.args) {
|
if flag.matches(cmd.args) {
|
||||||
found = true
|
found = true
|
||||||
|
flag.found = true
|
||||||
cmd.args = flag.parse(cmd.args) or {
|
cmd.args = flag.parse(cmd.args) or {
|
||||||
println('failed to parse flag ${cmd.args[0]}: ${err}')
|
println('failed to parse flag ${cmd.args[0]}: ${err}')
|
||||||
exit(1)
|
exit(1)
|
||||||
|
@ -127,8 +138,7 @@ fn (mut cmd Command) parse_commands() {
|
||||||
if int(cmd.execute) == 0 {
|
if int(cmd.execute) == 0 {
|
||||||
if !cmd.disable_help {
|
if !cmd.disable_help {
|
||||||
help_cmd := cmd.commands.get('help') or { return } // ignore error and handle command normally
|
help_cmd := cmd.commands.get('help') or { return } // ignore error and handle command normally
|
||||||
execute := help_cmd.execute
|
help_cmd.execute(help_cmd)
|
||||||
execute(help_cmd)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cmd.check_required_flags()
|
cmd.check_required_flags()
|
||||||
|
@ -153,8 +163,7 @@ fn (mut cmd Command) check_help_flag() {
|
||||||
help_flag := cmd.flags.get_bool('help') or { return } // ignore error and handle command normally
|
help_flag := cmd.flags.get_bool('help') or { return } // ignore error and handle command normally
|
||||||
if help_flag {
|
if help_flag {
|
||||||
help_cmd := cmd.commands.get('help') or { return } // ignore error and handle command normally
|
help_cmd := cmd.commands.get('help') or { return } // ignore error and handle command normally
|
||||||
execute := help_cmd.execute
|
help_cmd.execute(help_cmd)
|
||||||
execute(help_cmd)
|
|
||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,8 +177,7 @@ fn (mut cmd Command) check_version_flag() {
|
||||||
version_flag := cmd.flags.get_bool('version') or { return } // ignore error and handle command normally
|
version_flag := cmd.flags.get_bool('version') or { return } // ignore error and handle command normally
|
||||||
if version_flag {
|
if version_flag {
|
||||||
version_cmd := cmd.commands.get('version') or { return } // ignore error and handle command normally
|
version_cmd := cmd.commands.get('version') or { return } // ignore error and handle command normally
|
||||||
execute := version_cmd.execute
|
version_cmd.execute(version_cmd)
|
||||||
execute(version_cmd)
|
|
||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,6 +193,15 @@ fn (mut cmd Command) check_required_flags() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (cmds []Command) get(name string) ?Command {
|
||||||
|
for cmd in cmds {
|
||||||
|
if cmd.name == name {
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error('command \'${name}\' not found.')
|
||||||
|
}
|
||||||
|
|
||||||
fn (cmds []Command) contains(name string) bool {
|
fn (cmds []Command) contains(name string) bool {
|
||||||
for cmd in cmds {
|
for cmd in cmds {
|
||||||
if cmd.name == name {
|
if cmd.name == name {
|
||||||
|
@ -194,11 +211,8 @@ fn (cmds []Command) contains(name string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (cmds []Command) get(name string) ?Command {
|
fn (mut cmds []Command) sort() {
|
||||||
for cmd in cmds {
|
cmds.sort_with_compare(fn(a &Command, b &Command) int {
|
||||||
if cmd.name == name {
|
return compare_strings(&a.name, &b.name)
|
||||||
return cmd
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
return error('command \'${name}\' not found.')
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,24 @@ pub mut:
|
||||||
description string
|
description string
|
||||||
global bool
|
global bool
|
||||||
required bool
|
required bool
|
||||||
|
|
||||||
value string
|
value string
|
||||||
|
|
||||||
|
mut:
|
||||||
|
found bool
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (flags []Flag) get_all_found() []Flag {
|
||||||
|
return flags.filter(it.found)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (flag Flag) get_bool() ?bool {
|
||||||
|
if flag.flag != .bool { return error('invalid flag type') }
|
||||||
|
return flag.value == 'true'
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (flags []Flag) get_bool(name string) ?bool {
|
pub fn (flags []Flag) get_bool(name string) ?bool {
|
||||||
flag := flags.get(name) or { return error(err) }
|
flag := flags.get(name) or { return error(err) }
|
||||||
if flag.flag != .bool { return error('invalid flag type') }
|
return flag.get_bool()
|
||||||
return flag.value == 'true'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (flags []Flag) get_bool_or(name string, or_value bool) bool {
|
pub fn (flags []Flag) get_bool_or(name string, or_value bool) bool {
|
||||||
|
@ -30,34 +40,46 @@ pub fn (flags []Flag) get_bool_or(name string, or_value bool) bool {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (flags []Flag) get_int(name string) ?int {
|
pub fn (flag Flag) get_int() ?int {
|
||||||
flag := flags.get(name) or { return error(err) }
|
|
||||||
if flag.flag != .int { return error('invalid flag type') }
|
if flag.flag != .int { return error('invalid flag type') }
|
||||||
return flag.value.int()
|
return flag.value.int()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (flags []Flag) get_int(name string) ?int {
|
||||||
|
flag := flags.get(name) or { return error(err) }
|
||||||
|
return flag.get_int()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (flags []Flag) get_int_or(name string, or_value int) int {
|
pub fn (flags []Flag) get_int_or(name string, or_value int) int {
|
||||||
value := flags.get_int(name) or { return or_value }
|
value := flags.get_int(name) or { return or_value }
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (flags []Flag) get_float(name string) ?f32 {
|
pub fn (flag Flag) get_float() ?f64 {
|
||||||
flag := flags.get(name) or { return error(err) }
|
|
||||||
if flag.flag != .float { return error('invalid flag type') }
|
if flag.flag != .float { return error('invalid flag type') }
|
||||||
return flag.value.f32()
|
return flag.value.f64()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (flags []Flag) get_float_or(name string, or_value f32) f32 {
|
pub fn (flags []Flag) get_float(name string) ?f64 {
|
||||||
|
flag := flags.get(name) or { return error(err) }
|
||||||
|
return flag.get_float()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (flags []Flag) get_float_or(name string, or_value f64) f64 {
|
||||||
value := flags.get_float(name) or { return or_value }
|
value := flags.get_float(name) or { return or_value }
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (flags []Flag) get_string(name string) ?string {
|
pub fn (flag Flag) get_string() ?string {
|
||||||
flag := flags.get(name) or { return error(err) }
|
|
||||||
if flag.flag != .string { return error('invalid flag type') }
|
if flag.flag != .string { return error('invalid flag type') }
|
||||||
return flag.value
|
return flag.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (flags []Flag) get_string(name string) ?string {
|
||||||
|
flag := flags.get(name) or { return error(err) }
|
||||||
|
return flag.get_string()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (flags []Flag) get_string_or(name string, or_value string) string {
|
pub fn (flags []Flag) get_string_or(name string, or_value string) string {
|
||||||
value := flags.get_string(name) or { return or_value }
|
value := flags.get_string(name) or { return or_value }
|
||||||
return value
|
return value
|
||||||
|
@ -81,8 +103,10 @@ fn (mut flag Flag) parse(args []string) ?[]string {
|
||||||
// check if first arg matches flag
|
// check if first arg matches flag
|
||||||
fn (mut flag Flag) matches(args []string) bool {
|
fn (mut flag Flag) matches(args []string) bool {
|
||||||
return
|
return
|
||||||
(flag.name != '' && args[0].starts_with('--${flag.name}')) ||
|
(flag.name != '' && args[0] == '--${flag.name}') ||
|
||||||
(flag.abbrev != '' && args[0].starts_with('-${flag.abbrev}'))
|
(flag.name != '' && args[0].starts_with('--${flag.name}=')) ||
|
||||||
|
(flag.abbrev != '' && args[0] == '-${flag.abbrev}') ||
|
||||||
|
(flag.abbrev != '' && args[0].starts_with('-${flag.abbrev}='))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut flag Flag) parse_raw(args []string) ?[]string {
|
fn (mut flag Flag) parse_raw(args []string) ?[]string {
|
||||||
|
@ -127,3 +151,9 @@ fn (flags []Flag) contains(name string) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut flags []Flag) sort() {
|
||||||
|
flags.sort_with_compare(fn(a &Flag, b &Flag) int {
|
||||||
|
return compare_strings(&a.name, &b.name)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -18,15 +18,27 @@ fn test_if_bool_flag_parses() {
|
||||||
flag: .bool,
|
flag: .bool,
|
||||||
name: 'flag',
|
name: 'flag',
|
||||||
}
|
}
|
||||||
|
mut value := false
|
||||||
|
|
||||||
flag.parse(['--flag']) or { panic(err) }
|
flag.parse(['--flag']) or { panic(err) }
|
||||||
assert flag.value == 'true'
|
value = flag.get_bool() or { panic(err) }
|
||||||
|
assert value == true
|
||||||
|
|
||||||
flag.parse(['--flag', 'true']) or { panic(err) }
|
flag.parse(['--flag', 'true']) or { panic(err) }
|
||||||
assert flag.value == 'true'
|
value = flag.get_bool() or { panic(err) }
|
||||||
|
assert value == true
|
||||||
|
|
||||||
flag.parse(['--flag=true']) or { panic(err) }
|
flag.parse(['--flag=true']) or { panic(err) }
|
||||||
assert flag.value == 'true'
|
value = flag.get_bool() or { panic(err) }
|
||||||
|
assert value == true
|
||||||
|
|
||||||
|
flag.parse(['--flag', 'false']) or { panic(err) }
|
||||||
|
value = flag.get_bool() or { panic(err) }
|
||||||
|
assert value == false
|
||||||
|
|
||||||
|
flag.parse(['--flag=false']) or { panic(err) }
|
||||||
|
value = flag.get_bool() or { panic(err) }
|
||||||
|
assert value == false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_if_int_flag_parses() {
|
fn test_if_int_flag_parses() {
|
||||||
|
@ -34,12 +46,15 @@ fn test_if_int_flag_parses() {
|
||||||
flag: .int,
|
flag: .int,
|
||||||
name: 'flag',
|
name: 'flag',
|
||||||
}
|
}
|
||||||
|
mut value := 0
|
||||||
|
|
||||||
flag.parse(['--flag', '42']) or { panic(err) }
|
flag.parse(['--flag', '42']) or { panic(err) }
|
||||||
assert flag.value.int() == 42
|
value = flag.get_int() or { panic(err) }
|
||||||
|
assert value == 42
|
||||||
|
|
||||||
flag.parse(['--flag=42']) or { panic(err) }
|
flag.parse(['--flag=42']) or { panic(err) }
|
||||||
assert flag.value.int() == 42
|
value = flag.get_int() or { panic(err) }
|
||||||
|
assert value == 42
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_if_float_flag_parses() {
|
fn test_if_float_flag_parses() {
|
||||||
|
@ -47,10 +62,14 @@ fn test_if_float_flag_parses() {
|
||||||
flag: .float,
|
flag: .float,
|
||||||
name: 'flag',
|
name: 'flag',
|
||||||
}
|
}
|
||||||
|
mut value := f64(0)
|
||||||
|
|
||||||
flag.parse(['--flag', '3.14159']) or { panic(err) }
|
flag.parse(['--flag', '3.14159']) or { panic(err) }
|
||||||
assert flag.value.f64() == 3.14159
|
value = flag.get_float() or { panic(err) }
|
||||||
|
assert value == 3.14159
|
||||||
|
|
||||||
flag.parse(['--flag=3.14159']) or { panic(err) }
|
flag.parse(['--flag=3.14159']) or { panic(err) }
|
||||||
assert flag.value.f64() == 3.14159
|
assert flag.value.f64() == 3.14159
|
||||||
|
value = flag.get_float() or { panic(err) }
|
||||||
|
assert value == 3.14159
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue