You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2024/02/27 02:04:38 UTC

(commons-cli) branch master updated: fix for CLI-325 (#237)

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-cli.git


The following commit(s) were added to refs/heads/master by this push:
     new 2dac643  fix for CLI-325 (#237)
2dac643 is described below

commit 2dac643fff43efcb7c42afca526e8af3938a60ba
Author: Claude Warren <cl...@aiven.io>
AuthorDate: Tue Feb 27 03:04:33 2024 +0100

    fix for CLI-325 (#237)
---
 .../java/org/apache/commons/cli/CommandLine.java   | 43 ++++++++++---------
 .../org/apache/commons/cli/bug/BugCLI325Test.java  | 50 ++++++++++++++++++++++
 2 files changed, 73 insertions(+), 20 deletions(-)

diff --git a/src/main/java/org/apache/commons/cli/CommandLine.java b/src/main/java/org/apache/commons/cli/CommandLine.java
index b2f3a3d..3df5f77 100644
--- a/src/main/java/org/apache/commons/cli/CommandLine.java
+++ b/src/main/java/org/apache/commons/cli/CommandLine.java
@@ -170,11 +170,30 @@ public class CommandLine implements Serializable {
         }
     }
 
+    /**
+     * Parses a list of values as properties.  All odd numbered values are property keys
+     * and even numbered values are property values.  If there are an odd number of values
+     * the last value is assumed to be a boolean with a value of "true".
+     * @param props the properties to update.
+     * @param values the list of values to parse.
+     * @since 1.7.0
+     */
+    private void processPropertiesFromValues(final Properties props, final List<String> values) {
+        for (int i = 0; i < values.size(); i += 2) {
+            if (i + 1 < values.size()) {
+                props.put(values.get(i), values.get(i + 1));
+            } else {
+                props.put(values.get(i), "true");
+            }
+        }
+    }
+
     /**
      * Gets the map of values associated to the option. This is convenient for options specifying Java properties like
      * <code>-Dparam1=value1
-     * -Dparam2=value2</code>. The first argument of the option is the key, and the 2nd argument is the value. If the option
-     * has only one argument ({@code -Dfoo}) it is considered as a boolean flag and the value is {@code "true"}.
+     * -Dparam2=value2</code>. All odd numbered values are property keys
+     * and even numbered values are property values.  If there are an odd number of values
+     * the last value is assumed to be a boolean flag and the value is "true".
      *
      * @param option name of the option.
      * @return The Properties mapped by the option, never {@code null} even if the option doesn't exists.
@@ -182,17 +201,9 @@ public class CommandLine implements Serializable {
      */
     public Properties getOptionProperties(final Option option) {
         final Properties props = new Properties();
-
         for (final Option processedOption : options) {
             if (processedOption.equals(option)) {
-                final List<String> values = processedOption.getValuesList();
-                if (values.size() >= 2) {
-                    // use the first 2 arguments as the key/value pair
-                    props.put(values.get(0), values.get(1));
-                } else if (values.size() == 1) {
-                    // no explicit value, handle it as a boolean
-                    props.put(values.get(0), "true");
-                }
+                processPropertiesFromValues(props, processedOption.getValuesList());
             }
         }
 
@@ -211,17 +222,9 @@ public class CommandLine implements Serializable {
      */
     public Properties getOptionProperties(final String opt) {
         final Properties props = new Properties();
-
         for (final Option option : options) {
             if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt())) {
-                final List<String> values = option.getValuesList();
-                if (values.size() >= 2) {
-                    // use the first 2 arguments as the key/value pair
-                    props.put(values.get(0), values.get(1));
-                } else if (values.size() == 1) {
-                    // no explicit value, handle it as a boolean
-                    props.put(values.get(0), "true");
-                }
+                processPropertiesFromValues(props, option.getValuesList());
             }
         }
 
diff --git a/src/test/java/org/apache/commons/cli/bug/BugCLI325Test.java b/src/test/java/org/apache/commons/cli/bug/BugCLI325Test.java
new file mode 100644
index 0000000..e459873
--- /dev/null
+++ b/src/test/java/org/apache/commons/cli/bug/BugCLI325Test.java
@@ -0,0 +1,50 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+package org.apache.commons.cli.bug;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Properties;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.junit.Test;
+
+public class BugCLI325Test {
+
+    @Test
+    public void Cli325() throws ParseException {
+
+        final Option option = Option.builder("x")
+        .hasArgs()
+        .valueSeparator()
+        .desc("Multiple arg option with value separator.")
+        .build();
+
+        String[] args = {"-x", "A=a", "B=b"};
+
+        CommandLine cmdLine = DefaultParser.builder().build().parse(new Options().addOption(option), args);
+        Properties props = cmdLine.getOptionProperties(option);
+        assertEquals(2, props.size());
+        assertEquals("a", props.get("A"));
+        assertEquals("b", props.get("B"));
+    }
+}