diff --git a/src/main/java/org/springframework/shell/commands/DateCommands.java b/src/main/java/org/springframework/shell/commands/DateCommands.java index 10d76849..568ff2e4 100644 --- a/src/main/java/org/springframework/shell/commands/DateCommands.java +++ b/src/main/java/org/springframework/shell/commands/DateCommands.java @@ -25,15 +25,14 @@ import org.springframework.stereotype.Component; /** * Commands related to the dates - * + * */ @Component -public class DateCommands implements CommandMarker { - +public class DateCommands implements CommandMarker { + @CliCommand(value = { "date" }, help = "Displays the local date and time") public String date() { - return DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL,Locale.US) - .format(new Date()); + return DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.US).format(new Date()); } } diff --git a/src/main/java/org/springframework/shell/core/Tokenizer.java b/src/main/java/org/springframework/shell/core/Tokenizer.java index 5cabe74a..fe38ba41 100644 --- a/src/main/java/org/springframework/shell/core/Tokenizer.java +++ b/src/main/java/org/springframework/shell/core/Tokenizer.java @@ -113,7 +113,7 @@ public class Tokenizer { eatKeyEqualsValue(); } else { - String value = eatValue(); + String value = eatValue(true); store("", value); } @@ -128,8 +128,9 @@ public class Tokenizer { /** * Eat a value that may be enclosed in some delimiters. + * @param emptyKey if true, we're currently reading the value for the empty key */ - private String eatValue() { + private String eatValue(boolean emptyKey) { StringBuilder sb = new StringBuilder(); char endDelimiter = ' '; if (buffer[pos] == '"') { @@ -148,6 +149,20 @@ public class Tokenizer { sb.append(buffer[pos]); pos++; } + // If we're grabbing the key-less value, allow additional chunks, as long as + // 1) we don't hit '--' + // 2) we were not using a quote delimited value + if (emptyKey && endDelimiter == ' ') { + while (!lookAhead('-', '-') && pos < buffer.length) { + sb.append(buffer[pos++]); + } + // Trim to the right + while (Character.isWhitespace(sb.charAt(sb.length() - 1))) { + sb.setLength(sb.length() - 1); + } + return sb.toString(); + } + // When here, we either ran out of input, or encountered our delim, or both // Fail, unless we allow an unfinished quoted string to be reported if (endDelimiter == '"' && // we're using quotes @@ -226,7 +241,7 @@ public class Tokenizer { value = ""; } else { - value = eatValue(); + value = eatValue(false); } // Don't store the ""="" that would result from having a pending " --" at the end if (key.equals("") && value.equals("")) { diff --git a/src/test/java/org/springframework/shell/core/TokenizerTests.java b/src/test/java/org/springframework/shell/core/TokenizerTests.java index 3c0bb7fc..1a4c227c 100644 --- a/src/test/java/org/springframework/shell/core/TokenizerTests.java +++ b/src/test/java/org/springframework/shell/core/TokenizerTests.java @@ -18,7 +18,10 @@ package org.springframework.shell.core; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonMap; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.util.HashMap; @@ -80,9 +83,22 @@ public class TokenizerTests { tokenize("--foo bar --foo buzz"); } + @Test + public void testAllowTwoOptionsSameEmptyKeyIfNextToEachOther() { + Map result = tokenize("bar buzz"); + assertThat(result.keySet(), hasSize(1)); + assertThat(result.get(""), equalTo("bar buzz")); + + result = tokenize("--foo wizz bar buzz --woot cool"); + assertThat(result.keySet(), hasSize(3)); + assertThat(result.get(""), equalTo("bar buzz")); + assertThat(result.get("foo"), equalTo("wizz")); + assertThat(result.get("woot"), equalTo("cool")); + } + @Test(expected = IllegalArgumentException.class) - public void testTwoOptionsSameEmptyKey() { - tokenize("bar buzz"); + public void testDisallowTwoOptionsSameEmptyKeyIfNotNextToEachOther() { + tokenize("bar --foo wizz buzz"); } @Test