diff --git a/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLineArgsParser.java b/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLineArgsParser.java index bcf8d07160..08b0143983 100644 --- a/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLineArgsParser.java +++ b/spring-core/src/main/java/org/springframework/core/env/SimpleCommandLineArgsParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,13 @@ package org.springframework.core.env; * without spaces by an equals sign ("="). The value may optionally be * an empty string. * + *
This parser supports the POSIX "end of options" delimiter, meaning that + * any {@code "--"} (empty option name) in the command signals that all remaining + * arguments will non-optional. For example, here {@code "--opt=ignored"} is considered + * as a non-optional argument. + *
+ * --foo=bar -- --opt=ignored+ * *
* --foo
@@ -53,6 +60,7 @@ package org.springframework.core.env;
*
* @author Chris Beams
* @author Sam Brannen
+ * @author Brian Clozel
* @since 3.1
*/
class SimpleCommandLineArgsParser {
@@ -65,23 +73,26 @@ class SimpleCommandLineArgsParser {
*/
public CommandLineArgs parse(String... args) {
CommandLineArgs commandLineArgs = new CommandLineArgs();
+ boolean endOfOptions = false;
for (String arg : args) {
- if (arg.startsWith("--")) {
+ if (!endOfOptions && arg.startsWith("--")) {
String optionText = arg.substring(2);
- String optionName;
- String optionValue = null;
int indexOfEqualsSign = optionText.indexOf('=');
if (indexOfEqualsSign > -1) {
- optionName = optionText.substring(0, indexOfEqualsSign);
- optionValue = optionText.substring(indexOfEqualsSign + 1);
+ String optionName = optionText.substring(0, indexOfEqualsSign);
+ String optionValue = optionText.substring(indexOfEqualsSign + 1);
+ if (optionName.isEmpty()) {
+ throw new IllegalArgumentException("Invalid argument syntax: " + arg);
+ }
+ commandLineArgs.addOptionArg(optionName, optionValue);
+ }
+ else if (!optionText.isEmpty()){
+ commandLineArgs.addOptionArg(optionText, null);
}
else {
- optionName = optionText;
+ // '--' End of options delimiter, all remaining args must be non-optional
+ endOfOptions = true;
}
- if (optionName.isEmpty()) {
- throw new IllegalArgumentException("Invalid argument syntax: " + arg);
- }
- commandLineArgs.addOptionArg(optionName, optionValue);
}
else {
commandLineArgs.addNonOptionArg(arg);
diff --git a/spring-core/src/test/java/org/springframework/core/env/SimpleCommandLineArgsParserTests.java b/spring-core/src/test/java/org/springframework/core/env/SimpleCommandLineArgsParserTests.java
index c5bbb89f8e..180dfa8fbc 100644
--- a/spring-core/src/test/java/org/springframework/core/env/SimpleCommandLineArgsParserTests.java
+++ b/spring-core/src/test/java/org/springframework/core/env/SimpleCommandLineArgsParserTests.java
@@ -30,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
*
* @author Chris Beams
* @author Sam Brannen
+ * @author Brian Clozel
*/
class SimpleCommandLineArgsParserTests {
@@ -66,11 +67,6 @@ class SimpleCommandLineArgsParserTests {
assertThat(args.getOptionValues("o3")).isNull();
}
- @Test
- void withEmptyOptionText() {
- assertThatIllegalArgumentException().isThrownBy(() -> parser.parse("--"));
- }
-
@Test
void withEmptyOptionName() {
assertThatIllegalArgumentException().isThrownBy(() -> parser.parse("--=v1"));
@@ -112,4 +108,13 @@ class SimpleCommandLineArgsParserTests {
args.getNonOptionArgs().add("foo"));
}
+ @Test
+ void supportsEndOfOptionsDelimiter() {
+ CommandLineArgs args = parser.parse("--o1=v1", "--", "--o2=v2");
+ assertThat(args.containsOption("o1")).isTrue();
+ assertThat(args.containsOption("o2")).isFalse();
+ assertThat(args.getOptionValues("o1")).containsExactly("v1");
+ assertThat(args.getNonOptionArgs()).contains("--o2=v2");
+ }
+
}