Skip to content

Commit 2dac643

Browse files
authored
fix for CLI-325 (#237)
1 parent a175b2d commit 2dac643

2 files changed

Lines changed: 73 additions & 20 deletions

File tree

src/main/java/org/apache/commons/cli/CommandLine.java

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -170,29 +170,40 @@ public Object getOptionObject(final String opt) {
170170
}
171171
}
172172

173+
/**
174+
* Parses a list of values as properties. All odd numbered values are property keys
175+
* and even numbered values are property values. If there are an odd number of values
176+
* the last value is assumed to be a boolean with a value of "true".
177+
* @param props the properties to update.
178+
* @param values the list of values to parse.
179+
* @since 1.7.0
180+
*/
181+
private void processPropertiesFromValues(final Properties props, final List<String> values) {
182+
for (int i = 0; i < values.size(); i += 2) {
183+
if (i + 1 < values.size()) {
184+
props.put(values.get(i), values.get(i + 1));
185+
} else {
186+
props.put(values.get(i), "true");
187+
}
188+
}
189+
}
190+
173191
/**
174192
* Gets the map of values associated to the option. This is convenient for options specifying Java properties like
175193
* <code>-Dparam1=value1
176-
* -Dparam2=value2</code>. The first argument of the option is the key, and the 2nd argument is the value. If the option
177-
* has only one argument ({@code -Dfoo}) it is considered as a boolean flag and the value is {@code "true"}.
194+
* -Dparam2=value2</code>. All odd numbered values are property keys
195+
* and even numbered values are property values. If there are an odd number of values
196+
* the last value is assumed to be a boolean flag and the value is "true".
178197
*
179198
* @param option name of the option.
180199
* @return The Properties mapped by the option, never {@code null} even if the option doesn't exists.
181200
* @since 1.5.0
182201
*/
183202
public Properties getOptionProperties(final Option option) {
184203
final Properties props = new Properties();
185-
186204
for (final Option processedOption : options) {
187205
if (processedOption.equals(option)) {
188-
final List<String> values = processedOption.getValuesList();
189-
if (values.size() >= 2) {
190-
// use the first 2 arguments as the key/value pair
191-
props.put(values.get(0), values.get(1));
192-
} else if (values.size() == 1) {
193-
// no explicit value, handle it as a boolean
194-
props.put(values.get(0), "true");
195-
}
206+
processPropertiesFromValues(props, processedOption.getValuesList());
196207
}
197208
}
198209

@@ -211,17 +222,9 @@ public Properties getOptionProperties(final Option option) {
211222
*/
212223
public Properties getOptionProperties(final String opt) {
213224
final Properties props = new Properties();
214-
215225
for (final Option option : options) {
216226
if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt())) {
217-
final List<String> values = option.getValuesList();
218-
if (values.size() >= 2) {
219-
// use the first 2 arguments as the key/value pair
220-
props.put(values.get(0), values.get(1));
221-
} else if (values.size() == 1) {
222-
// no explicit value, handle it as a boolean
223-
props.put(values.get(0), "true");
224-
}
227+
processPropertiesFromValues(props, option.getValuesList());
225228
}
226229
}
227230

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package org.apache.commons.cli.bug;
19+
20+
import static org.junit.Assert.assertEquals;
21+
22+
import java.util.Properties;
23+
24+
import org.apache.commons.cli.CommandLine;
25+
import org.apache.commons.cli.DefaultParser;
26+
import org.apache.commons.cli.Option;
27+
import org.apache.commons.cli.Options;
28+
import org.apache.commons.cli.ParseException;
29+
import org.junit.Test;
30+
31+
public class BugCLI325Test {
32+
33+
@Test
34+
public void Cli325() throws ParseException {
35+
36+
final Option option = Option.builder("x")
37+
.hasArgs()
38+
.valueSeparator()
39+
.desc("Multiple arg option with value separator.")
40+
.build();
41+
42+
String[] args = {"-x", "A=a", "B=b"};
43+
44+
CommandLine cmdLine = DefaultParser.builder().build().parse(new Options().addOption(option), args);
45+
Properties props = cmdLine.getOptionProperties(option);
46+
assertEquals(2, props.size());
47+
assertEquals("a", props.get("A"));
48+
assertEquals("b", props.get("B"));
49+
}
50+
}

0 commit comments

Comments
 (0)