flag: add overridable --help and --version by default

pull/10730/head
Delyan Angelov 2021-07-09 22:08:01 +03:00
parent eb96ad11d9
commit 477d442f18
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
8 changed files with 92 additions and 1 deletions

View File

@ -0,0 +1,35 @@
import os
const source = 'vlib/flag/testdata/simplest_flag_program.v'
const simple_flag_app_executable = os.real_path(os.join_path(os.cache_dir(), 'simple_flag_app.exe'))
fn testsuite_begin() {
os.chdir(@VMODROOT)
os.rm(simple_flag_app_executable) or {}
res := os.execute('${@VEXE} -o $simple_flag_app_executable $source')
assert res.exit_code == 0
assert os.execute(simple_flag_app_executable).exit_code == 0
}
fn testsuite_end() {
os.rm(simple_flag_app_executable) or {}
assert true
}
fn check_program(opts string, extension string) {
result := source.replace('.v', extension)
res := os.execute('$simple_flag_app_executable $opts')
lines := os.read_lines(result) or { panic(err) }
assert res.exit_code == 0
assert res.output.split_into_lines() == lines
}
fn test_default_builtin_flag_options() {
check_program('', '.out')
check_program(' -- --help', '.dashdash.help.out')
check_program(' -- --version', '.dashdash.version.out')
check_program(' -h', '.help.out')
check_program(' --help', '.help.out')
check_program(' --version', '.version.out')
}

View File

@ -62,6 +62,8 @@ pub:
idx_dashdash int // the index of a `--`, -1 if there is not any idx_dashdash int // the index of a `--`, -1 if there is not any
all_after_dashdash []string // all options after `--` are ignored, and will be passed to the application unmodified all_after_dashdash []string // all options after `--` are ignored, and will be passed to the application unmodified
pub mut: pub mut:
default_help_label string = 'display this help and exit'
default_version_label string = 'output version information and exit'
args []string // the current list of processed args args []string // the current list of processed args
max_free_args int max_free_args int
flags []Flag // registered flags flags []Flag // registered flags
@ -507,12 +509,41 @@ pub fn (fs FlagParser) usage() string {
return use.join('\n').replace('- ,', ' ') return use.join('\n').replace('- ,', ' ')
} }
fn (mut fs FlagParser) find_existing_flag(fname string) ?Flag {
for f in fs.flags {
if f.name == fname {
return f
}
}
return error('no such flag')
}
fn (mut fs FlagParser) handle_builtin_options() {
mut show_version := false
mut show_help := false
fs.find_existing_flag('help') or {
show_help = fs.bool('help', `h`, false, fs.default_help_label)
}
fs.find_existing_flag('version') or {
show_version = fs.bool('version', 0, false, fs.default_version_label)
}
if show_help {
println(fs.usage())
exit(0)
}
if show_version {
println('$fs.application_name $fs.application_version')
exit(0)
}
}
// finalize - return all remaining arguments (non options). // finalize - return all remaining arguments (non options).
// Call .finalize() after all arguments are defined. // Call .finalize() after all arguments are defined.
// The remaining arguments are returned in the same order they are // The remaining arguments are returned in the same order they are
// defined on the command line. If additional flags are found, i.e. // defined on the command line. If additional flags are found, i.e.
// (things starting with '--' or '-'), it returns an error. // (things starting with '--' or '-'), it returns an error.
pub fn (fs FlagParser) finalize() ?[]string { pub fn (mut fs FlagParser) finalize() ?[]string {
fs.handle_builtin_options()
mut remaining := fs.args.clone() mut remaining := fs.args.clone()
if !fs.allow_unknown_args { if !fs.allow_unknown_args {
for a in remaining { for a in remaining {

View File

@ -0,0 +1 @@
[vlib/flag/testdata/simplest_flag_program.v:13] rest_of_args: ['--help']

View File

@ -0,0 +1 @@
[vlib/flag/testdata/simplest_flag_program.v:13] rest_of_args: ['--version']

View File

@ -0,0 +1,7 @@
abc 0.0.1
-----------------------------------------------
Usage: abc [options] [ARGS]
Options:
-h, --help display this help and exit
--version output version information and exit

View File

@ -0,0 +1 @@
[vlib/flag/testdata/simplest_flag_program.v:13] rest_of_args: []

View File

@ -0,0 +1,14 @@
import os
import flag
fn main() {
mut fp := flag.new_flag_parser(os.args)
fp.application('abc')
fp.version('0.0.1')
fp.skip_executable()
rest_of_args := fp.finalize() or {
eprintln(err)
exit(1)
}
dump(rest_of_args)
}

View File

@ -0,0 +1 @@
abc 0.0.1