From 9ef8499183dfe2450a35be88e048d797512a58ab Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 19 Mar 2020 14:06:37 +0800 Subject: [PATCH] flag: unify apis --- cmd/tools/gen_vc.v | 18 +++---- cmd/tools/modules/vgit/vgit.v | 10 ++-- cmd/tools/oldv.v | 4 +- cmd/tools/performance_compare.v | 4 +- cmd/tools/vbin2v.v | 6 +-- cmd/tools/vnames.v | 2 +- vlib/flag/flag.v | 48 ++--------------- vlib/flag/flag_test.v | 94 ++++++++++++++++----------------- 8 files changed, 73 insertions(+), 113 deletions(-) diff --git a/cmd/tools/gen_vc.v b/cmd/tools/gen_vc.v index b89d8c973f..7d83cd84aa 100644 --- a/cmd/tools/gen_vc.v +++ b/cmd/tools/gen_vc.v @@ -117,7 +117,7 @@ fn main() { fp.description(app_description) fp.skip_executable() - show_help:=fp.bool('help', false, 'Show this help screen\n') + show_help:=fp.bool('help', 0, false, 'Show this help screen\n') flag_options := parse_flags(mut fp) if( show_help ){ println( fp.usage() ) exit(0) } @@ -181,14 +181,14 @@ pub fn (ws &WebhookServer) reset() { // parse flags to FlagOptions struct fn parse_flags(fp mut flag.FlagParser) FlagOptions { return FlagOptions{ - serve : fp.bool('serve', false, 'run in webhook server mode') - work_dir : fp.string('work-dir', work_dir, 'gen_vc working directory') - purge : fp.bool('purge', false, 'force purge the local repositories') - port : fp.int('port', server_port, 'port for web server to listen on') - log_to : fp.string('log-to', log_to, 'log to is \'file\' or \'terminal\'') - log_file : fp.string('log-file', log_file, 'log file to use when log-to is \'file\'') - dry_run : fp.bool('dry-run', dry_run, 'when specified dont push anything to remote repo') - force : fp.bool('force', false, 'force update even if already up to date') + serve : fp.bool('serve', 0, false, 'run in webhook server mode') + work_dir : fp.string('work-dir', 0, work_dir, 'gen_vc working directory') + purge : fp.bool('purge', 0, false, 'force purge the local repositories') + port : fp.int('port', 0, server_port, 'port for web server to listen on') + log_to : fp.string('log-to', 0, log_to, 'log to is \'file\' or \'terminal\'') + log_file : fp.string('log-file', 0, log_file, 'log file to use when log-to is \'file\'') + dry_run : fp.bool('dry-run', 0, dry_run, 'when specified dont push anything to remote repo') + force : fp.bool('force', 0, false, 'force update even if already up to date') } } diff --git a/cmd/tools/modules/vgit/vgit.v b/cmd/tools/modules/vgit/vgit.v index 33a37136ac..73bfa321dd 100644 --- a/cmd/tools/modules/vgit/vgit.v +++ b/cmd/tools/modules/vgit/vgit.v @@ -137,16 +137,16 @@ pub fn (vgit_context mut VGitContext) compile_oldv_if_needed() { pub fn add_common_tool_options(context mut T, fp mut flag.FlagParser) []string { tdir := os.temp_dir() - context.workdir = os.realpath(fp.string_('workdir', `w`, tdir, 'A writable base folder. Default: $tdir')) - context.v_repo_url = fp.string('vrepo', vgit.remote_v_repo_url, 'The url of the V repository. You can clone it locally too. See also --vcrepo below.') - context.vc_repo_url = fp.string('vcrepo', vgit.remote_vc_repo_url, 'The url of the vc repository. You can clone it + context.workdir = os.realpath(fp.string('workdir', `w`, tdir, 'A writable base folder. Default: $tdir')) + context.v_repo_url = fp.string('vrepo', 0, vgit.remote_v_repo_url, 'The url of the V repository. You can clone it locally too. See also --vcrepo below.') + context.vc_repo_url = fp.string('vcrepo', 0, vgit.remote_vc_repo_url, 'The url of the vc repository. You can clone it ${flag.SPACE}beforehand, and then just give the local folder ${flag.SPACE}path here. That will eliminate the network ops ${flag.SPACE}done by this tool, which is useful, if you want ${flag.SPACE}to script it/run it in a restrictive vps/docker. ') - context.show_help = fp.bool_('help', `h`, false, 'Show this help screen.') - context.verbose = fp.bool_('verbose', `v`, false, 'Be more verbose.') + context.show_help = fp.bool('help', `h`, false, 'Show this help screen.') + context.verbose = fp.bool('verbose', `v`, false, 'Be more verbose.') if (context.show_help) { println(fp.usage()) diff --git a/cmd/tools/oldv.v b/cmd/tools/oldv.v index 94e150f4de..24beca3fd5 100644 --- a/cmd/tools/oldv.v +++ b/cmd/tools/oldv.v @@ -76,8 +76,8 @@ fn main() { fp.skip_executable() fp.limit_free_args(1, 1) - 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.\n') + context.cleanup = fp.bool('clean', 0, true, 'Clean before running (slower).') + context.cmd_to_run = fp.string('command', `c`, '', 'Command to run in the old V repo.\n') commits := vgit.add_common_tool_options(mut context, mut fp) if commits.len > 0 { diff --git a/cmd/tools/performance_compare.v b/cmd/tools/performance_compare.v index 0462e21c8f..6357a12ff3 100644 --- a/cmd/tools/performance_compare.v +++ b/cmd/tools/performance_compare.v @@ -187,8 +187,8 @@ fn main() { fp.skip_executable() fp.limit_free_args(1, 2) - context.vflags = fp.string('vflags', '', 'Additional options to pass to the v commands, for example "-cc tcc"') - context.hyperfineopts = fp.string('hyperfine_options', '', + context.vflags = fp.string('vflags', 0, '', 'Additional options to pass to the v commands, for example "-cc tcc"') + context.hyperfineopts = fp.string('hyperfine_options', 0, '', 'Additional options passed to hyperfine. ${flag.SPACE}For example on linux, you may want to pass: ${flag.SPACE}--hyperfine_options "--prepare \'sync; echo 3 | sudo tee /proc/sys/vm/drop_caches\'" diff --git a/cmd/tools/vbin2v.v b/cmd/tools/vbin2v.v index ce186befd8..38f9db5b85 100644 --- a/cmd/tools/vbin2v.v +++ b/cmd/tools/vbin2v.v @@ -69,9 +69,9 @@ fn main() { fp.version(tool_version) fp.description(tool_description) fp.arguments_description('FILE [FILE]...') - context.show_help = fp.bool_('help', `h`, false, 'Show this help screen.') - context.module_name = fp.string_('module', `m`, 'binary', 'Name of the generated module.\n') - context.prefix = fp.string_('prefix', `p`, '', 'A prefix put before each resource name.\n') + context.show_help = fp.bool('help', `h`, false, 'Show this help screen.') + context.module_name = fp.string('module', `m`, 'binary', 'Name of the generated module.\n') + context.prefix = fp.string('prefix', `p`, '', 'A prefix put before each resource name.\n') if (context.show_help) { println(fp.usage()) exit(0) diff --git a/cmd/tools/vnames.v b/cmd/tools/vnames.v index a66849f033..a476e86640 100644 --- a/cmd/tools/vnames.v +++ b/cmd/tools/vnames.v @@ -64,7 +64,7 @@ fn main(){ fp.arguments_description('FILE.v/FOLDER [FILE.v/FOLDER]...') fp.limit_free_args_to_at_least(1) fp.skip_executable() - show_help:=fp.bool_('help', `h`, false, 'Show this help screen\n') + show_help:=fp.bool('help', `h`, false, 'Show this help screen\n') if( show_help ){ println( fp.usage() ) exit(0) diff --git a/vlib/flag/flag.v b/vlib/flag/flag.v index a781adc4f4..cd9f3e5c61 100644 --- a/vlib/flag/flag.v +++ b/vlib/flag/flag.v @@ -245,23 +245,13 @@ pub fn (fs mut FlagParser) bool_opt(name string, abbr byte, usage string) ?bool // the default value is returned // version with abbr //TODO error handling for invalid string to bool conversion -pub fn (fs mut FlagParser) bool_(name string, abbr byte, bdefault bool, usage string) bool { +pub fn (fs mut FlagParser) bool(name string, abbr byte, bdefault bool, usage string) bool { value := fs.bool_opt(name, abbr, usage) or { return bdefault } return value } -// defining and parsing a bool flag -// if defined -// the value is returned (true/false) -// else -// the default value is returned -//TODO error handling for invalid string to bool conversion -pub fn (fs mut FlagParser) bool(name string, v bool, usage string) bool { - return fs.bool_(name, 0, v, usage) -} - // int_multi returns all instances of values associated with the flags provided // In the case that none were found, it returns an empty array. pub fn (fs mut FlagParser) int_multi(name string, abbr byte, usage string) []int { @@ -292,23 +282,13 @@ pub fn (fs mut FlagParser) int_opt(name string, abbr byte, usage string) ?int { // the default value is returned // version with abbr //TODO error handling for invalid string to int conversion -pub fn (fs mut FlagParser) int_(name string, abbr byte, idefault int, usage string) int { +pub fn (fs mut FlagParser) int(name string, abbr byte, idefault int, usage string) int { value := fs.int_opt(name, abbr, usage) or { return idefault } return value } -// defining and parsing an int flag -// if defined -// the value is returned (int) -// else -// the default value is returned -//TODO error handling for invalid string to int conversion -pub fn (fs mut FlagParser) int(name string, i int, usage string) int { - return fs.int_(name, 0, i, usage) -} - // float_multi returns all instances of values associated with the flags provided // In the case that none were found, it returns an empty array. pub fn (fs mut FlagParser) float_multi(name string, abbr byte, usage string) []f32 { @@ -339,23 +319,13 @@ pub fn (fs mut FlagParser) float_opt(name string, abbr byte, usage string) ?f32 // the default value is returned // version with abbr //TODO error handling for invalid string to float conversion -pub fn (fs mut FlagParser) float_(name string, abbr byte, fdefault f32, usage string) f32 { +pub fn (fs mut FlagParser) float(name string, abbr byte, fdefault f32, usage string) f32 { value := fs.float_opt(name, abbr, usage) or { return fdefault } return value } -// defining and parsing a float flag -// if defined -// the value is returned (float) -// else -// the default value is returned -//TODO error handling for invalid string to float conversion -pub fn (fs mut FlagParser) float(name string, f f32, usage string) f32 { - return fs.float_(name, 0, f, usage) -} - // string_multi returns all instances of values associated with the flags provided // In the case that none were found, it returns an empty array. pub fn (fs mut FlagParser) string_multi(name string, abbr byte, usage string) []string { @@ -380,22 +350,13 @@ pub fn (fs mut FlagParser) string_opt(name string, abbr byte, usage string) ?str // else // the default value is returned // version with abbr -pub fn (fs mut FlagParser) string_(name string, abbr byte, sdefault string, usage string) string { +pub fn (fs mut FlagParser) string(name string, abbr byte, sdefault string, usage string) string { value := fs.string_opt(name, abbr, usage) or { return sdefault } return value } -// defining and parsing a string flag -// if defined -// the value is returned (string) -// else -// the default value is returned -pub fn (fs mut FlagParser) string(name string, sdefault string, usage string) string { - return fs.string_(name, 0, sdefault, usage) -} - pub fn (fs mut FlagParser) limit_free_args_to_at_least(n int) { if n > MAX_ARGS_NUMBER { panic('flag.limit_free_args_to_at_least expect n to be smaller than $MAX_ARGS_NUMBER') @@ -522,4 +483,3 @@ pub fn (fs FlagParser) finalize() ?[]string { } return fs.args } - diff --git a/vlib/flag/flag_test.v b/vlib/flag/flag_test.v index 6c20198934..5851434779 100644 --- a/vlib/flag/flag_test.v +++ b/vlib/flag/flag_test.v @@ -3,10 +3,10 @@ import flag fn test_if_flag_not_given_return_default_values() { mut fp := flag.new_flag_parser([]) - assert false == fp.bool('a_bool', false, '') - && 42 == fp.int('an_int', 42, '') - && 1.0 == fp.float('a_float', 1.0, '') - && 'stuff' == fp.string('a_string', 'stuff', '') + assert false == fp.bool('a_bool', 0, false, '') + && 42 == fp.int('an_int', 0, 42, '') + && 1.0 == fp.float('a_float', 0, 1.0, '') + && 'stuff' == fp.string('a_string', 0, 'stuff', '') } @@ -24,7 +24,7 @@ fn test_could_define_application_name_and_version() { fn test_bool_flags_do_not_need_an_value() { mut fp := flag.new_flag_parser(['--a_bool']) - assert true == fp.bool('a_bool', false, '') + assert true == fp.bool('a_bool', 0, false, '') } fn test_flags_could_be_defined_with_eq() { @@ -35,11 +35,11 @@ fn test_flags_could_be_defined_with_eq() { '--a_string=stuff', '--a_bool=true']) - assert 42 == fp.int('an_int', 666, '') - && true == fp.bool('a_bool', false, '') - && true == fp.bool('bool_without', false, '') - && 2.0 == fp.float('a_float', 1.0, '') - && 'stuff' == fp.string('a_string', 'not_stuff', '') + assert 42 == fp.int('an_int', 0, 666, '') + && true == fp.bool('a_bool', 0, false, '') + && true == fp.bool('bool_without', 0, false, '') + && 2.0 == fp.float('a_float', 0, 1.0, '') + && 'stuff' == fp.string('a_string', 0, 'not_stuff', '') } fn test_values_could_be_defined_without_eq() { @@ -50,11 +50,11 @@ fn test_values_could_be_defined_without_eq() { '--a_string', 'stuff', '--a_bool', 'true']) - assert 42 == fp.int('an_int', 666, '') - && true == fp.bool('a_bool', false, '') - && true == fp.bool('bool_without', false, '') - && 2.0 == fp.float('a_float', 1.0, '') - && 'stuff' == fp.string('a_string', 'not_stuff', '') + assert 42 == fp.int('an_int', 0, 666, '') + && true == fp.bool('a_bool', 0, false, '') + && true == fp.bool('bool_without', 0, false, '') + && 2.0 == fp.float('a_float', 0, 1.0, '') + && 'stuff' == fp.string('a_string', 0, 'not_stuff', '') } fn test_values_could_be_defined_mixed() { @@ -65,11 +65,11 @@ fn test_values_could_be_defined_mixed() { '--a_string', 'stuff', '--a_bool=true']) - assert 42 == fp.int('an_int', 666, '') - && true == fp.bool('a_bool', false, '') - && true == fp.bool('bool_without', false, '') - && 2.0 == fp.float('a_float', 1.0, '') - && 'stuff' == fp.string('a_string', 'not_stuff', '') + assert 42 == fp.int('an_int', 0, 666, '') + && true == fp.bool('a_bool', 0, false, '') + && true == fp.bool('bool_without', 0, false, '') + && 2.0 == fp.float('a_float', 0, 1.0, '') + && 'stuff' == fp.string('a_string', 0, 'not_stuff', '') } fn test_beaware_for_argument_names_with_same_prefix() { @@ -78,8 +78,8 @@ fn test_beaware_for_argument_names_with_same_prefix() { '--shorter=7' ]) - assert 5 == fp.int('short', 666, '') - && 7 == fp.int('shorter', 666, '') + assert 5 == fp.int('short', 0, 666, '') + && 7 == fp.int('shorter', 0, 666, '') } fn test_beaware_for_argument_names_with_same_prefix_inverse() { @@ -88,8 +88,8 @@ fn test_beaware_for_argument_names_with_same_prefix_inverse() { '--short', '5', ]) - assert 5 == fp.int('short', 666, '') - && 7 == fp.int('shorter', 666, '') + assert 5 == fp.int('short', 0, 666, '') + && 7 == fp.int('shorter', 0, 666, '') } fn test_allow_to_skip_executable_path() { @@ -108,14 +108,14 @@ fn test_none_flag_arguments_are_allowed() { mut fp := flag.new_flag_parser([ 'file1', '--an_int=2', 'file2', 'file3', '--bool_without', 'file4', '--outfile', 'outfile']) - assert 2 == fp.int('an_int', 666, '') - && 'outfile' == fp.string('outfile', 'bad', '') - && true == fp.bool('bool_without', false, '') + assert 2 == fp.int('an_int', 0, 666, '') + && 'outfile' == fp.string('outfile', 0, 'bad', '') + && true == fp.bool('bool_without', 0, false, '') } fn test_finalize_returns_none_flag_arguments_ordered() { mut fp := flag.new_flag_parser(['d', 'b', 'x', 'a', '--outfile', 'outfile']) - fp.string('outfile', 'bad', '') + fp.string('outfile', 0, 'bad', '') finalized := fp.finalize() or { assert false @@ -133,7 +133,7 @@ fn test_finalize_returns_none_flag_arguments_ordered() { fn test_finalize_returns_error_for_unknown_flags() { mut fp := flag.new_flag_parser(['--known', '--unknown']) - fp.bool('known', false, '') + fp.bool('known', 0, false, '') finalized := fp.finalize() or { assert err == 'Unknown argument \'unknown\'' @@ -149,11 +149,11 @@ fn test_allow_to_build_usage_message() { fp.version('v0.0.0') fp.description('some short information about this tool') - fp.int('an_int', 666, 'some int to define') - fp.bool('a_bool', false, 'some bool to define') - fp.bool('bool_without_but_really_big', false, 'this should appear on the next line') - fp.float('a_float', 1.0, 'some float as well') - fp.string('a_string', 'not_stuff', 'your credit card number') + fp.int('an_int', 0, 666, 'some int to define') + fp.bool('a_bool', 0, false, 'some bool to define') + fp.bool('bool_without_but_really_big', 0, false, 'this should appear on the next line') + fp.float('a_float', 0, 1.0, 'some float as well') + fp.string('a_string', 0, 'not_stuff', 'your credit card number') usage := fp.usage() mut all_strings_found := true @@ -180,7 +180,7 @@ fn test_if_no_description_given_usage_message_does_not_contain_descpription() { fp.application('flag_tool') fp.version('v0.0.0') - fp.bool('a_bool', false, '') + fp.bool('a_bool', 0, false, '') assert !fp.usage().contains('Description:') } @@ -236,10 +236,10 @@ fn test_could_expect_no_free_args() { fn test_allow_abreviations() { mut fp := flag.new_flag_parser(['-v', '-o', 'some_file', '-i', '42', '-f', '2.0']) - v := fp.bool_('version', `v`, false, '') - o := fp.string_('output', `o`, 'empty', '') - i := fp.int_('count', `i`, 0, '') - f := fp.float_('value', `f`, 0.0, '') + v := fp.bool('version', `v`, false, '') + o := fp.string('output', `o`, 'empty', '') + i := fp.int('count', `i`, 0, '') + f := fp.float('value', `f`, 0.0, '') assert v && o == 'some_file' && i == 42 && f == 2.0 @@ -256,8 +256,8 @@ fn test_allow_kebab_options() { mut fp := flag.new_flag_parser(['--my-long-flag', 'true', '--my-long-option', long_option_value ]) - my_flag := fp.bool('my-long-flag', false, 'flag with long-kebab-name') - my_option := fp.string('my-long-option', default_value, 'string with long-kebab-name') + my_flag := fp.bool('my-long-flag', 0, false, 'flag with long-kebab-name') + my_option := fp.string('my-long-option', 0, default_value, 'string with long-kebab-name') assert my_flag == true assert my_option == long_option_value @@ -324,9 +324,9 @@ fn test_multiple_arguments() { fn test_long_options_that_start_with_the_same_letter_as_another_short_option() { mut fp := flag.new_flag_parser([ '--vabc', '/abc', - ]) - verbose := fp.bool_('verbose', `v`, false, 'Be more verbose.') - vabc := fp.string_('vabc', `x`, 'default', 'Another option that *may* conflict with v, but *should not*') + ]) + verbose := fp.bool('verbose', `v`, false, 'Be more verbose.') + vabc := fp.string('vabc', `x`, 'default', 'Another option that *may* conflict with v, but *should not*') assert verbose == false assert vabc == '/abc' } @@ -335,9 +335,9 @@ fn test_long_options_that_start_with_the_same_letter_as_another_short_option_bot mut fp := flag.new_flag_parser([ '-v', '--vabc', '/abc', - ]) - verbose := fp.bool_('verbose', `v`, false, 'Be more verbose.') - vabc := fp.string_('vabc', `x`, 'default', 'Another option that *may* conflict with v, but *should not*') + ]) + verbose := fp.bool('verbose', `v`, false, 'Be more verbose.') + vabc := fp.string('vabc', `x`, 'default', 'Another option that *may* conflict with v, but *should not*') assert verbose == true assert vabc == '/abc' }