Skip to content

Commit 8e15ed3

Browse files
committed
(PUP-11693) Global OptionParser ignores partially matched invalid params
This commit modifies how partial matches are handled when parsing global command line options. Before, Puppet would accept and do nothing with options global options that use '-' instead of '_'. For example, it would accept '--show-diff' and do nothing when the correct name is '--show_diff'. With this change, while handling any global options given in the command line options, if the command line option does not match existing global options, it will convert '-' to '_' and vice versa. Then, check if that matches a valid global option. Additionally, if the command line option needs to convert '-' to '_' or vice versa, Puppet will also warn to let the user know a partial match was detected and that this behavior will be deprecated in Puppet 9.
1 parent 9b3514e commit 8e15ed3

File tree

2 files changed

+84
-2
lines changed

2 files changed

+84
-2
lines changed

lib/puppet/util/command_line/trollop.rb

+14-2
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,21 @@ def parse cmdline = ARGV
335335
when /^-([^-])$/
336336
@short[::Regexp.last_match(1)]
337337
when /^--no-([^-]\S*)$/
338-
@long["[no-]#{::Regexp.last_match(1)}"]
338+
possible_match = @long["[no-]#{::Regexp.last_match(1)}"]
339+
if !possible_match
340+
Puppet.warning("Partial argument match detected. Partial argument matching will be deprecated in Puppet 9.")
341+
@long["[no-]#{::Regexp.last_match(1).tr('-', '_')}"] || @long["[no-]#{::Regexp.last_match(1).tr('_', '-')}"]
342+
else
343+
possible_match
344+
end
339345
when /^--([^-]\S*)$/
340-
@long[::Regexp.last_match(1)] || @long["[no-]#{::Regexp.last_match(1)}"]
346+
possible_match = @long[::Regexp.last_match(1)] || @long["[no-]#{::Regexp.last_match(1)}"]
347+
if !possible_match
348+
Puppet.warning("Partial argument match detected. Partial argument matching will be deprecated in Puppet 9.")
349+
@long[::Regexp.last_match(1).tr('-', '_')] || @long[::Regexp.last_match(1).tr('_', '-')] || @long["[no-]#{::Regexp.last_match(1).tr('-', '_')}"] || @long["[no-]#{::Regexp.last_match(1).tr('_', '-')}"]
350+
else
351+
possible_match
352+
end
341353
else
342354
raise CommandlineError, _("invalid argument syntax: '%{arg}'") % { arg: arg }
343355
end

spec/unit/util/command_line_utils/puppet_option_parser_spec.rb

+70
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@
1313
)
1414
end
1515

16+
it "parses a 'long' option with a value and converts '-' to '_' & warns" do
17+
parses(
18+
:option => ["--an_gry", "Angry", :REQUIRED],
19+
:from_arguments => ["--an-gry", "foo"],
20+
:expects => "foo"
21+
)
22+
expect(@logs).to have_matching_log(/Partial argument match detected. Partial argument matching will be deprecated in Puppet 9./)
23+
end
24+
25+
it "parses a 'long' option with a value and converts '_' to '-' & warns" do
26+
parses(
27+
:option => ["--an-gry", "Angry", :REQUIRED],
28+
:from_arguments => ["--an_gry", "foo"],
29+
:expects => "foo"
30+
)
31+
expect(@logs).to have_matching_log(/Partial argument match detected. Partial argument matching will be deprecated in Puppet 9./)
32+
end
33+
1634
it "parses a 'short' option with a value" do
1735
parses(
1836
:option => ["--angry", "-a", "Angry", :REQUIRED],
@@ -39,6 +57,24 @@
3957
)
4058
end
4159

60+
it "converts '_' to '-' with a 'long' option & warns" do
61+
parses(
62+
:option => ["--an-gry", "Angry", :NONE],
63+
:from_arguments => ["--an_gry"],
64+
:expects => true
65+
)
66+
expect(@logs).to have_matching_log(/Partial argument match detected. Partial argument matching will be deprecated in Puppet 9./)
67+
end
68+
69+
it "converts '-' to '_' with a 'long' option & warns" do
70+
parses(
71+
:option => ["--an_gry", "Angry", :NONE],
72+
:from_arguments => ["--an-gry"],
73+
:expects => true
74+
)
75+
expect(@logs).to have_matching_log(/Partial argument match detected. Partial argument matching will be deprecated in Puppet 9./)
76+
end
77+
4278
it "parses a 'short' option" do
4379
parses(
4480
:option => ["--angry", "-a", "Angry", :NONE],
@@ -55,6 +91,40 @@
5591
)
5692
end
5793

94+
it "resolves '-' to '_' with '--no-blah' syntax" do
95+
parses(
96+
:option => ["--[no-]an_gry", "Angry", :NONE],
97+
:from_arguments => ["--no-an-gry"],
98+
:expects => false
99+
)
100+
end
101+
102+
it "resolves '_' to '-' with '--no-blah' syntax" do
103+
parses(
104+
:option => ["--[no-]an-gry", "Angry", :NONE],
105+
:from_arguments => ["--no-an_gry"],
106+
:expects => false
107+
)
108+
end
109+
110+
it "resolves '-' to '_' & warns when option is defined with '--no-blah syntax' but argument is given in '--option' syntax" do
111+
parses(
112+
:option => ["--[no-]rag-e", "Rage", :NONE],
113+
:from_arguments => ["--rag_e"],
114+
:expects => true
115+
)
116+
expect(@logs).to have_matching_log(/Partial argument match detected. Partial argument matching will be deprecated in Puppet 9./)
117+
end
118+
119+
it "resolves '_' to '-' & warns when option is defined with '--no-blah syntax' but argument is given in '--option' syntax" do
120+
parses(
121+
:option => ["--[no-]rag_e", "Rage", :NONE],
122+
:from_arguments => ["--rag-e"],
123+
:expects => true
124+
)
125+
expect(@logs).to have_matching_log(/Partial argument match detected. Partial argument matching will be deprecated in Puppet 9./)
126+
end
127+
58128
it "overrides a previous argument with a later one" do
59129
parses(
60130
:option => ["--[no-]rage", "Rage", :NONE],

0 commit comments

Comments
 (0)