flag: fix displaying of both abbreviated and long options
Add tests for the usage screenpull/3280/head
parent
d07953b0f0
commit
d2f2ac523f
15
tools/oldv.v
15
tools/oldv.v
|
@ -109,18 +109,19 @@ fn main(){
|
||||||
scripting.used_tools_must_exist(['git','cc'])
|
scripting.used_tools_must_exist(['git','cc'])
|
||||||
mut context := Context{}
|
mut context := Context{}
|
||||||
mut fp := flag.new_flag_parser(os.args)
|
mut fp := flag.new_flag_parser(os.args)
|
||||||
fp.application(os.filename(os.executable()))
|
fp.application(filepath.filename(os.executable()))
|
||||||
fp.version( tool_version )
|
fp.version( tool_version )
|
||||||
fp.description( tool_description )
|
fp.description( tool_description )
|
||||||
fp.arguments_description('VCOMMIT')
|
fp.arguments_description('VCOMMIT')
|
||||||
fp.skip_executable()
|
fp.skip_executable()
|
||||||
|
|
||||||
show_help:=fp.bool('help', false, 'Show this help screen\n')
|
show_help:=fp.bool_('help', `h`, false, 'Show this help screen.')
|
||||||
context.cmd_to_run = fp.string('command', '', 'Command to run in the old V repo.\n')
|
context.verbose = fp.bool_('verbose', `v`, false, 'Be more verbose.\n')
|
||||||
context.cleanup = fp.bool('clean', true, 'Clean before running (slower).\n')
|
|
||||||
context.verbose = fp.bool('verbose', false, 'Be more verbose.\n')
|
|
||||||
|
|
||||||
context.workdir = os.realpath( fp.string('work-dir', os.tmpdir(), 'A writable folder, where the comparison will be done.\n') )
|
context.cleanup = fp.bool('clean', true, 'Clean before running (slower).')
|
||||||
|
context.cmd_to_run = fp.string_('command', `c`, '', 'Command to run in the old V repo.')
|
||||||
|
|
||||||
|
context.workdir = os.realpath( fp.string_('work-dir', `w`, os.tmpdir(), 'A writable folder, where the comparison will be done.\n') )
|
||||||
|
|
||||||
context.repo_url_v = fp.string('v-repo', remote_repo_url_v, 'The url of the V repository. You can clone it locally too.\n')
|
context.repo_url_v = fp.string('v-repo', remote_repo_url_v, 'The url of the V repository. You can clone it locally too.\n')
|
||||||
|
|
||||||
|
@ -129,7 +130,7 @@ fn main(){
|
||||||
flag.SPACE+'beforehand, and then just give the local folder \n'+
|
flag.SPACE+'beforehand, and then just give the local folder \n'+
|
||||||
flag.SPACE+'path here. That will eliminate the network ops \n'+
|
flag.SPACE+'path here. That will eliminate the network ops \n'+
|
||||||
flag.SPACE+'done by this tool, which is useful, if you want \n'+
|
flag.SPACE+'done by this tool, which is useful, if you want \n'+
|
||||||
flag.SPACE+'to script it/run it in a restrictive vps/docker.\n')
|
flag.SPACE+'to script it/run it in a restrictive vps/docker.')
|
||||||
|
|
||||||
if( show_help ){
|
if( show_help ){
|
||||||
println( fp.usage() )
|
println( fp.usage() )
|
||||||
|
|
|
@ -8,7 +8,6 @@ module main
|
||||||
// / code, instead of in embedded C ...
|
// / code, instead of in embedded C ...
|
||||||
// /////////////////////////////////////////////////////////////////////
|
// /////////////////////////////////////////////////////////////////////
|
||||||
import (
|
import (
|
||||||
term
|
|
||||||
filepath
|
filepath
|
||||||
benchmark
|
benchmark
|
||||||
)
|
)
|
||||||
|
|
147
vlib/flag/flag.v
147
vlib/flag/flag.v
|
@ -83,18 +83,18 @@ pub fn new_flag_parser(args []string) &FlagParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
// change the application name to be used in 'usage' output
|
// change the application name to be used in 'usage' output
|
||||||
pub fn (fs mut FlagParser) application(n string) {
|
pub fn (fs mut FlagParser) application(name string) {
|
||||||
fs.application_name = n
|
fs.application_name = name
|
||||||
}
|
}
|
||||||
|
|
||||||
// change the application version to be used in 'usage' output
|
// change the application version to be used in 'usage' output
|
||||||
pub fn (fs mut FlagParser) version(n string) {
|
pub fn (fs mut FlagParser) version(vers string) {
|
||||||
fs.application_version = n
|
fs.application_version = vers
|
||||||
}
|
}
|
||||||
|
|
||||||
// change the application version to be used in 'usage' output
|
// change the application version to be used in 'usage' output
|
||||||
pub fn (fs mut FlagParser) description(n string) {
|
pub fn (fs mut FlagParser) description(desc string) {
|
||||||
fs.application_description = n
|
fs.application_description = desc
|
||||||
}
|
}
|
||||||
|
|
||||||
// in most cases you do not need the first argv for flag parsing
|
// in most cases you do not need the first argv for flag parsing
|
||||||
|
@ -103,12 +103,12 @@ pub fn (fs mut FlagParser) skip_executable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// private helper to register a flag
|
// private helper to register a flag
|
||||||
fn (fs mut FlagParser) add_flag(n string, a byte, u, vd string) {
|
fn (fs mut FlagParser) add_flag(name string, abbr byte, usage string, desc string) {
|
||||||
fs.flags << Flag{
|
fs.flags << Flag{
|
||||||
name: n,
|
name: name,
|
||||||
abbr: a,
|
abbr: abbr,
|
||||||
usage: u,
|
usage: usage,
|
||||||
val_desc: vd
|
val_desc: desc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,10 +204,10 @@ fn (fs mut FlagParser) parse_bool_value(longhand string, shorthand byte) ?string
|
||||||
|
|
||||||
// bool_opt returns an optional that returns the value associated with the flag.
|
// bool_opt returns an optional that returns the value associated with the flag.
|
||||||
// In the situation that the flag was not provided, it returns null.
|
// In the situation that the flag was not provided, it returns null.
|
||||||
pub fn (fs mut FlagParser) bool_opt(n string, a byte, u string) ?bool {
|
pub fn (fs mut FlagParser) bool_opt(name string, abbr byte, usage string) ?bool {
|
||||||
fs.add_flag(n, a, u, '<bool>')
|
fs.add_flag(name, abbr, usage, '<bool>')
|
||||||
parsed := fs.parse_bool_value(n, a) or {
|
parsed := fs.parse_bool_value(name, abbr) or {
|
||||||
return error("parameter '$n' not provided")
|
return error("parameter '$name' not provided")
|
||||||
}
|
}
|
||||||
return parsed == 'true'
|
return parsed == 'true'
|
||||||
}
|
}
|
||||||
|
@ -217,11 +217,11 @@ pub fn (fs mut FlagParser) bool_opt(n string, a byte, u string) ?bool {
|
||||||
// the value is returned (true/false)
|
// the value is returned (true/false)
|
||||||
// else
|
// else
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
// version with abbreviation
|
// version with abbr
|
||||||
//TODO error handling for invalid string to bool conversion
|
//TODO error handling for invalid string to bool conversion
|
||||||
pub fn (fs mut FlagParser) bool_(n string, a byte, v bool, u string) bool {
|
pub fn (fs mut FlagParser) bool_(name string, abbr byte, bdefault bool, usage string) bool {
|
||||||
value := fs.bool_opt(n, a, u) or {
|
value := fs.bool_opt(name, abbr, usage) or {
|
||||||
return v
|
return bdefault
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
@ -232,15 +232,15 @@ pub fn (fs mut FlagParser) bool_(n string, a byte, v bool, u string) bool {
|
||||||
// else
|
// else
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
//TODO error handling for invalid string to bool conversion
|
//TODO error handling for invalid string to bool conversion
|
||||||
pub fn (fs mut FlagParser) bool(n string, v bool, u string) bool {
|
pub fn (fs mut FlagParser) bool(name string, v bool, usage string) bool {
|
||||||
return fs.bool_(n, `\0`, v, u)
|
return fs.bool_(name, 0, v, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// int_multi returns all instances of values associated with the flags provided
|
// int_multi returns all instances of values associated with the flags provided
|
||||||
// In the case that none were found, it returns an empty array.
|
// In the case that none were found, it returns an empty array.
|
||||||
pub fn (fs mut FlagParser) int_multi(n string, a byte, u string) []int {
|
pub fn (fs mut FlagParser) int_multi(name string, abbr byte, usage string) []int {
|
||||||
fs.add_flag(n, a, u, '<multiple ints>')
|
fs.add_flag(name, abbr, usage, '<multiple ints>')
|
||||||
parsed := fs.parse_value(n, a)
|
parsed := fs.parse_value(name, abbr)
|
||||||
mut value := []int
|
mut value := []int
|
||||||
for val in parsed {
|
for val in parsed {
|
||||||
value << val.int()
|
value << val.int()
|
||||||
|
@ -250,11 +250,11 @@ pub fn (fs mut FlagParser) int_multi(n string, a byte, u string) []int {
|
||||||
|
|
||||||
// int_opt returns an optional that returns the value associated with the flag.
|
// int_opt returns an optional that returns the value associated with the flag.
|
||||||
// In the situation that the flag was not provided, it returns null.
|
// In the situation that the flag was not provided, it returns null.
|
||||||
pub fn (fs mut FlagParser) int_opt(n string, a byte, u string) ?int {
|
pub fn (fs mut FlagParser) int_opt(name string, abbr byte, usage string) ?int {
|
||||||
fs.add_flag(n, a, u, '<int>')
|
fs.add_flag(name, abbr, usage, '<int>')
|
||||||
parsed := fs.parse_value(n, a)
|
parsed := fs.parse_value(name, abbr)
|
||||||
if parsed.len == 0 {
|
if parsed.len == 0 {
|
||||||
return error("parameter '$n' not provided")
|
return error("parameter '$name' not provided")
|
||||||
}
|
}
|
||||||
return parsed[0].int()
|
return parsed[0].int()
|
||||||
}
|
}
|
||||||
|
@ -264,11 +264,11 @@ pub fn (fs mut FlagParser) int_opt(n string, a byte, u string) ?int {
|
||||||
// the value is returned (int)
|
// the value is returned (int)
|
||||||
// else
|
// else
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
// version with abbreviation
|
// version with abbr
|
||||||
//TODO error handling for invalid string to int conversion
|
//TODO error handling for invalid string to int conversion
|
||||||
pub fn (fs mut FlagParser) int_(n string, a byte, i int, u string) int {
|
pub fn (fs mut FlagParser) int_(name string, abbr byte, idefault int, usage string) int {
|
||||||
value := fs.int_opt(n, a, u) or {
|
value := fs.int_opt(name, abbr, usage) or {
|
||||||
return i
|
return idefault
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
@ -279,15 +279,15 @@ pub fn (fs mut FlagParser) int_(n string, a byte, i int, u string) int {
|
||||||
// else
|
// else
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
//TODO error handling for invalid string to int conversion
|
//TODO error handling for invalid string to int conversion
|
||||||
pub fn (fs mut FlagParser) int(n string, i int, u string) int {
|
pub fn (fs mut FlagParser) int(name string, i int, usage string) int {
|
||||||
return fs.int_(n, `\0`, i, u)
|
return fs.int_(name, 0, i, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// float_multi returns all instances of values associated with the flags provided
|
// float_multi returns all instances of values associated with the flags provided
|
||||||
// In the case that none were found, it returns an empty array.
|
// In the case that none were found, it returns an empty array.
|
||||||
pub fn (fs mut FlagParser) float_multi(n string, a byte, u string) []f32 {
|
pub fn (fs mut FlagParser) float_multi(name string, abbr byte, usage string) []f32 {
|
||||||
fs.add_flag(n, a, u, '<multiple floats>')
|
fs.add_flag(name, abbr, usage, '<multiple floats>')
|
||||||
parsed := fs.parse_value(n, a)
|
parsed := fs.parse_value(name, abbr)
|
||||||
mut value := []f32
|
mut value := []f32
|
||||||
for val in parsed {
|
for val in parsed {
|
||||||
value << val.f32()
|
value << val.f32()
|
||||||
|
@ -297,11 +297,11 @@ pub fn (fs mut FlagParser) float_multi(n string, a byte, u string) []f32 {
|
||||||
|
|
||||||
// float_opt returns an optional that returns the value associated with the flag.
|
// float_opt returns an optional that returns the value associated with the flag.
|
||||||
// In the situation that the flag was not provided, it returns null.
|
// In the situation that the flag was not provided, it returns null.
|
||||||
pub fn (fs mut FlagParser) float_opt(n string, a byte, u string) ?f32 {
|
pub fn (fs mut FlagParser) float_opt(name string, abbr byte, usage string) ?f32 {
|
||||||
fs.add_flag(n, a, u, '<float>')
|
fs.add_flag(name, abbr, usage, '<float>')
|
||||||
parsed := fs.parse_value(n, a)
|
parsed := fs.parse_value(name, abbr)
|
||||||
if parsed.len == 0 {
|
if parsed.len == 0 {
|
||||||
return error("parameter '$n' not provided")
|
return error("parameter '$name' not provided")
|
||||||
}
|
}
|
||||||
return parsed[0].f32()
|
return parsed[0].f32()
|
||||||
}
|
}
|
||||||
|
@ -311,11 +311,11 @@ pub fn (fs mut FlagParser) float_opt(n string, a byte, u string) ?f32 {
|
||||||
// the value is returned (float)
|
// the value is returned (float)
|
||||||
// else
|
// else
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
// version with abbreviation
|
// version with abbr
|
||||||
//TODO error handling for invalid string to float conversion
|
//TODO error handling for invalid string to float conversion
|
||||||
pub fn (fs mut FlagParser) float_(n string, a byte, f f32, u string) f32 {
|
pub fn (fs mut FlagParser) float_(name string, abbr byte, fdefault f32, usage string) f32 {
|
||||||
value := fs.float_opt(n, a, u) or {
|
value := fs.float_opt(name, abbr, usage) or {
|
||||||
return f
|
return fdefault
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
@ -326,24 +326,24 @@ pub fn (fs mut FlagParser) float_(n string, a byte, f f32, u string) f32 {
|
||||||
// else
|
// else
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
//TODO error handling for invalid string to float conversion
|
//TODO error handling for invalid string to float conversion
|
||||||
pub fn (fs mut FlagParser) float(n string, f f32, u string) f32 {
|
pub fn (fs mut FlagParser) float(name string, f f32, usage string) f32 {
|
||||||
return fs.float_(n, `\0`, f, u)
|
return fs.float_(name, 0, f, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// string_multi returns all instances of values associated with the flags provided
|
// string_multi returns all instances of values associated with the flags provided
|
||||||
// In the case that none were found, it returns an empty array.
|
// In the case that none were found, it returns an empty array.
|
||||||
pub fn (fs mut FlagParser) string_multi(n string, a byte, u string) []string {
|
pub fn (fs mut FlagParser) string_multi(name string, abbr byte, usage string) []string {
|
||||||
fs.add_flag(n, a, u, '<multiple floats>')
|
fs.add_flag(name, abbr, usage, '<multiple floats>')
|
||||||
return fs.parse_value(n, a)
|
return fs.parse_value(name, abbr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// string_opt returns an optional that returns the value associated with the flag.
|
// string_opt returns an optional that returns the value associated with the flag.
|
||||||
// In the situation that the flag was not provided, it returns null.
|
// In the situation that the flag was not provided, it returns null.
|
||||||
pub fn (fs mut FlagParser) string_opt(n string, a byte, u string) ?string {
|
pub fn (fs mut FlagParser) string_opt(name string, abbr byte, usage string) ?string {
|
||||||
fs.add_flag(n, a, u, '<string>')
|
fs.add_flag(name, abbr, usage, '<string>')
|
||||||
parsed := fs.parse_value(n, a)
|
parsed := fs.parse_value(name, abbr)
|
||||||
if parsed.len == 0 {
|
if parsed.len == 0 {
|
||||||
return error("parameter '$n' not provided")
|
return error("parameter '$name' not provided")
|
||||||
}
|
}
|
||||||
return parsed[0]
|
return parsed[0]
|
||||||
}
|
}
|
||||||
|
@ -353,10 +353,10 @@ pub fn (fs mut FlagParser) string_opt(n string, a byte, u string) ?string {
|
||||||
// the value is returned (string)
|
// the value is returned (string)
|
||||||
// else
|
// else
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
// version with abbreviation
|
// version with abbr
|
||||||
pub fn (fs mut FlagParser) string_(n string, a byte, v, u string) string {
|
pub fn (fs mut FlagParser) string_(name string, abbr byte, sdefault string, usage string) string {
|
||||||
value := fs.string_opt(n, a, u) or {
|
value := fs.string_opt(name, abbr, usage) or {
|
||||||
return v
|
return sdefault
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
@ -366,8 +366,8 @@ pub fn (fs mut FlagParser) string_(n string, a byte, v, u string) string {
|
||||||
// the value is returned (string)
|
// the value is returned (string)
|
||||||
// else
|
// else
|
||||||
// the default value is returned
|
// the default value is returned
|
||||||
pub fn (fs mut FlagParser) string(n, v, u string) string {
|
pub fn (fs mut FlagParser) string(name string, sdefault string, usage string) string {
|
||||||
return fs.string_(n, `\0`, v, u)
|
return fs.string_(name, 0, sdefault, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (fs mut FlagParser) limit_free_args_to_at_least(n int) {
|
pub fn (fs mut FlagParser) limit_free_args_to_at_least(n int) {
|
||||||
|
@ -448,23 +448,24 @@ pub fn (fs FlagParser) usage() string {
|
||||||
if fs.flags.len > 0 {
|
if fs.flags.len > 0 {
|
||||||
use += 'Options:\n'
|
use += 'Options:\n'
|
||||||
for f in fs.flags {
|
for f in fs.flags {
|
||||||
longstr := if f.val_desc.contains('bool') {
|
mut onames:=[]string
|
||||||
', --$f.name'
|
if f.abbr != 0 {
|
||||||
} else {
|
onames << '-${f.abbr.str()}'
|
||||||
', --$f.name $f.val_desc'
|
|
||||||
}
|
}
|
||||||
flag_desc := if f.name.len == 0 {
|
if f.name != '' {
|
||||||
', $f.val_desc'
|
if !f.val_desc.contains('<bool>') {
|
||||||
} else {
|
onames << '--${f.name} $f.val_desc'
|
||||||
longstr
|
}else{
|
||||||
|
onames << '--${f.name}'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
space := if flag_desc.len > SPACE.len-2 {
|
option_names := ' ' + onames.join(', ')
|
||||||
'\n$SPACE'
|
space := if option_names.len > SPACE.len-2 {
|
||||||
|
'\n${SPACE}'
|
||||||
} else {
|
} else {
|
||||||
SPACE[flag_desc.len..]
|
SPACE[option_names.len..]
|
||||||
}
|
}
|
||||||
abbr_desc := if f.abbr == `\0` { '' } else { ' -${tos(f.abbr, 1)}' }
|
use += '${option_names}${space}${f.usage}\n'
|
||||||
use += '${abbr_desc}${flag_desc}${space}${f.usage}\n'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,6 +245,9 @@ fn test_allow_abreviations() {
|
||||||
|
|
||||||
u := fp.usage()
|
u := fp.usage()
|
||||||
assert u.contains(' -v') && u.contains(' -o') && u.contains(' -i') && u.contains(' -f')
|
assert u.contains(' -v') && u.contains(' -o') && u.contains(' -i') && u.contains(' -f')
|
||||||
|
assert u.contains(' -o, --output <string>')
|
||||||
|
assert u.contains(' -i, --count <int>')
|
||||||
|
assert u.contains(' -f, --value <float>')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_allow_kebab_options() {
|
fn test_allow_kebab_options() {
|
||||||
|
|
Loading…
Reference in New Issue