From 8184a4e287e87fe28064dbc4d0fe91f3e2b65af1 Mon Sep 17 00:00:00 2001 From: Rob Donnelly Date: Sun, 5 Nov 2023 21:32:26 -0800 Subject: [PATCH 1/4] refactor: move plus option help into PlusOption class --- lib/jobrnr/plus_option_parser.rb | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/jobrnr/plus_option_parser.rb b/lib/jobrnr/plus_option_parser.rb index 7643239..147a6a8 100644 --- a/lib/jobrnr/plus_option_parser.rb +++ b/lib/jobrnr/plus_option_parser.rb @@ -40,6 +40,13 @@ def value=(value) end def parse_value(value); end + + def format_help + [ + " +#{name}=", + " #{description} Default: #{default}" + ].join("\n") + end end # An option that accepts true/false values @@ -58,6 +65,13 @@ def parse_value(value) "type for the '+#{name}' option" end end + + def format_help + [ + " +#{name}[=]", + " #{description} Default: #{default}" + ].join("\n") + end end # An option that accepts string values @@ -236,7 +250,7 @@ def help(option_definitions, doc_params = {}) lines << [ "OPTIONS", - option_definitions.values.map { |option_definition| help_format_option(option_definition) }, + option_definitions.values.map(&:format_help), " +help\n Show this help and exit." ] @@ -249,17 +263,6 @@ def help(option_definitions, doc_params = {}) lines.join("\n\n") end - def help_format_option(option_definition) - [ - " +#{help_format_name(option_definition)}", - " #{option_definition.description} Default: #{option_definition.default}" - ].join("\n") - end - - def help_format_name(option_definition) - option_definition.name + (option_definition.is_a?(BooleanOption) ? "[=]" : "=") - end - def specs_to_defs(options_spec) options_spec .map { |id, spec| [id, spec_to_def(id, spec)] } From 5f1ab7a73bbd11fa7ac2f947736579a17c21251d Mon Sep 17 00:00:00 2001 From: Rob Donnelly Date: Sun, 5 Nov 2023 21:33:51 -0800 Subject: [PATCH 2/4] refactor: rename :noarg to :implicit_true --- lib/jobrnr/plus_option_parser.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/jobrnr/plus_option_parser.rb b/lib/jobrnr/plus_option_parser.rb index 147a6a8..660e83c 100644 --- a/lib/jobrnr/plus_option_parser.rb +++ b/lib/jobrnr/plus_option_parser.rb @@ -53,7 +53,7 @@ def format_help class BooleanOption < PlusOption def parse_value(value) case value - when :noarg + when :implicit_true true when /^(true|t|yes|y|1)$/ # rubocop: disable Lint/DuplicateBranch true @@ -77,7 +77,7 @@ def format_help # An option that accepts string values class StringOption < PlusOption def parse_value(value) - if value == :noarg + if value == :implicit_true raise Jobrnr::ArgumentError, "No argument given for '+#{name}' option" end @@ -89,7 +89,7 @@ def parse_value(value) # An option that accepts Integer values class IntegerOption < PlusOption def parse_value(value) - if value == :noarg + if value == :implicit_true raise Jobrnr::ArgumentError, "No argument given for '+#{name}' option" end @@ -292,7 +292,7 @@ def plus_options_to_hash(plus_options) if (md = plus_option.match(/^\+(.*?)=(.*)/)) plus_options_hash[s_to_sym(md.captures.first)] = md.captures.last elsif (md = plus_option.match(/^\+((\w|-)+)$/)) - plus_options_hash[s_to_sym(md.captures.first)] = :noarg + plus_options_hash[s_to_sym(md.captures.first)] = :implicit_true end end end From f59081ab5af0e5bf86a49a946cde926ac50de696 Mon Sep 17 00:00:00 2001 From: Rob Donnelly Date: Sun, 5 Nov 2023 21:37:36 -0800 Subject: [PATCH 3/4] feat: Add GNU style negation for bool plus option Closes #30 --- lib/jobrnr/plus_option_parser.rb | 16 +++++++++++++++- test/plus_option_parser_test.rb | 26 ++++++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/lib/jobrnr/plus_option_parser.rb b/lib/jobrnr/plus_option_parser.rb index 660e83c..c7a6056 100644 --- a/lib/jobrnr/plus_option_parser.rb +++ b/lib/jobrnr/plus_option_parser.rb @@ -55,6 +55,8 @@ def parse_value(value) case value when :implicit_true true + when :implicit_false + false when /^(true|t|yes|y|1)$/ # rubocop: disable Lint/DuplicateBranch true when /^(false|f|no|n|0)$/ @@ -68,7 +70,7 @@ def parse_value(value) def format_help [ - " +#{name}[=]", + " +[no-]#{name}", " #{description} Default: #{default}" ].join("\n") end @@ -82,6 +84,11 @@ def parse_value(value) "No argument given for '+#{name}' option" end + if value == :implicit_false + raise Jobrnr::ArgumentError, + "Unrecognized option '+no-#{name}'" + end + value end end @@ -94,6 +101,11 @@ def parse_value(value) "No argument given for '+#{name}' option" end + if value == :implicit_false + raise Jobrnr::ArgumentError, + "Unrecognized option '+no-#{name}'" + end + begin Integer(value) rescue StandardError @@ -291,6 +303,8 @@ def plus_options_to_hash(plus_options) plus_options.each_with_object({}) do |plus_option, plus_options_hash| if (md = plus_option.match(/^\+(.*?)=(.*)/)) plus_options_hash[s_to_sym(md.captures.first)] = md.captures.last + elsif (md = plus_option.match(/^\+no-((\w|-)+)$/)) + plus_options_hash[s_to_sym(md.captures.first)] = :implicit_false elsif (md = plus_option.match(/^\+((\w|-)+)$/)) plus_options_hash[s_to_sym(md.captures.first)] = :implicit_true end diff --git a/test/plus_option_parser_test.rb b/test/plus_option_parser_test.rb index 1a172d0..2628380 100644 --- a/test/plus_option_parser_test.rb +++ b/test/plus_option_parser_test.rb @@ -122,6 +122,20 @@ assert_equal(exp, act) end + it "accepts gnu negation" do + exp = { + default_true: false, + default_inferred: false, + integer: 1, + string: "hello world", + } + act = @obj.parse( + @specs, + %w[+no-default-true], + ) + assert_equal(exp, act) + end + describe "+help" do it "general" do e = assert_raises(Jobrnr::HelpException) { @obj.parse(@specs, %w[+help]) } @@ -129,10 +143,10 @@ assert_equal(Jobrnr::Util.strip_heredoc(<<-EOF).strip, e.message) OPTIONS - +default-true[=] + +[no-]default-true An option with a default true value. Default: true - +default-inferred[=] + +[no-]default-inferred An option with an inferred default value. Default: false +integer= @@ -180,10 +194,10 @@ OPTIONS - +default-true[=] + +[no-]default-true An option with a default true value. Default: true - +default-inferred[=] + +[no-]default-inferred An option with an inferred default value. Default: false +integer= @@ -212,10 +226,10 @@ OPTIONS - +default-true[=] + +[no-]default-true An option with a default true value. Default: true - +default-inferred[=] + +[no-]default-inferred An option with an inferred default value. Default: false +integer= From 195d8ba07f53fd921a9b668580eb3f653accfcc7 Mon Sep 17 00:00:00 2001 From: Rob Donnelly Date: Sun, 5 Nov 2023 21:41:52 -0800 Subject: [PATCH 4/4] chore: update CHANGELOG for #30 --- CHANGELOG.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index f807b8d..6db487d 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -167,6 +167,8 @@ Fourth Ctrl-C sends SIGKILL to active jobs. * Added `--dry-run` option +* Added GNU style negation for boolean plus options (e.g. `+no-flag` is the same as `+flag=false`) + === Fixed * Fixed typo of `--verbose` option