Merge pull request #189 from samvv/master
Added converters for URIs, URLs and Paths
diff --git a/build-with-maven b/build-with-maven
index 176ca1a..0e2de5a 100755
--- a/build-with-maven
+++ b/build-with-maven
@@ -2,11 +2,12 @@
#v=6.5.2beta
-export TESTNG=`echo ../testng/target/testng-6.9beta.jar`
+export TESTNG=`echo ../testng/target/testng-6.8.13.jar`
-run="java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml"
+run="java -classpath \"target/classes;target/test-classes;${TESTNG};$CLASSPATH\" org.testng.TestNG src/test/resources/testng.xml"
echo "Launching tests: ${run}"
-java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml
+$run
+#java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml
echo "To deploy to the snapshot repository: mvn deploy"
echo "To deploy to the release directory: mvn -DskipTests=true release:clean release:prepare release:perform"
diff --git a/doc/index.html b/doc/index.html
index a92a969..da0368b 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -30,6 +30,19 @@
<td align="center">
<h1>JCommander</h1>
<h2>Because life is too short to parse command line parameters</h2>
+<h3>
+ <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
+ <input type="hidden" name="cmd" value="_donations">
+ <input type="hidden" name="business" value="[email protected]">
+ <input type="hidden" name="lc" value="US">
+ <input type="hidden" name="item_name" value="Cedric Beust">
+ <input type="hidden" name="no_note" value="0">
+ <input type="hidden" name="currency_code" value="USD">
+ <input type="hidden" name="bn" value="PP-DonationsBF:btn_donate_LG.gif:NonHostedGuest">
+ <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
+ <img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
+ </form>
+</h3>
</td>
</tr>
<tr>
@@ -39,7 +52,7 @@
</tr>
<tr>
<td align="right">
- Last updated: October 25th, 2012
+ Last updated: January 14th, 2015
</td>
</tr>
<tr><td align="right"><a href="mailto:[email protected]">Cédric Beust</a></td></tr>
@@ -795,9 +808,28 @@
}
</pre>
+<h2><a class="section" name="Groovy">JCommander in Groovy</a></h2>
+
+Here is a quick example of how to use JCommander in Groovy (courtesy of Paul King):
+
+
+<pre class="brush: java">
+import com.beust.jcommander.*
+
+class Args {
+ @Parameter(names = ["-f", "--file"], description = "File to load. Can be specified multiple times.")
+ List<String> file
+}
+
+new Args().with {
+ new JCommander(it, args)
+ file.each { println "file: ${new File(it).name}" }
+}
+</pre>
+
<h2><a class="section" name="More_examples">More examples</a></h2>
-TestNG uses JCommander to parse its command line, here is <a href="http://github.com/cbeust/testng/blob/master/src/main/java/org/testng/CommandLineArgs.java">its definition file</a>.
+TestNG uses JCommander to parse its own command line, here is <a href="http://github.com/cbeust/testng/blob/master/src/main/java/org/testng/CommandLineArgs.java">its definition file</a>.
<h2><a class="section" name="Mailing_list">Mailing list</a></h2>
diff --git a/pom.xml b/pom.xml
index 2d5ff92..cc70277 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
<artifactId>jcommander</artifactId>
<packaging>jar</packaging>
<name>JCommander</name>
- <version>1.36-SNAPSHOT</version>
+ <version>1.48-SNAPSHOT</version>
<description>A Java framework to parse command line options with annotations.</description>
<url>http://beust.com/jcommander</url>
<licenses>
@@ -40,6 +40,14 @@
<url>[email protected]:cbeust/jcommander.git</url>
</scm>
+ <distributionManagement>
+ <repository>
+ <id>sonatype-nexus-staging</id>
+ <name>Nexus Staging Repository</name>
+ <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+ </repository>
+ </distributionManagement>
+
<developers>
<developer>
<name>Cedric Beust</name>
@@ -155,6 +163,39 @@
</configuration>
</plugin>
</plugins>
+ <pluginManagement>
+ <plugins>
+ <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>
+ maven-bundle-plugin
+ </artifactId>
+ <versionRange>
+ [2.1.0,)
+ </versionRange>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <ignore />
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
</build>
<dependencies>
diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
index 3884976..98f112e 100644
--- a/src/main/java/com/beust/jcommander/JCommander.java
+++ b/src/main/java/com/beust/jcommander/JCommander.java
@@ -154,6 +154,7 @@
private List<String> m_unknownArgs = Lists.newArrayList();
private boolean m_acceptUnknownOptions = false;
+ private boolean m_allowParameterOverwriting = false;
private static Console m_console;
@@ -485,8 +486,10 @@
// Read through file one line at time. Print line # and line
while ((line = bufRead.readLine()) != null) {
- // Allow empty lines in these at files
- if (line.length() > 0) result.add(line);
+ // Allow empty lines and # comments in these at files
+ if (line.length() > 0 && ! line.trim().startsWith("#")) {
+ result.add(line);
+ }
}
bufRead.close();
@@ -677,6 +680,7 @@
// object)
boolean commandParsed = false;
int i = 0;
+ boolean isDashDash = false; // once we encounter --, everything goes into the main parameter
while (i < args.length && ! commandParsed) {
String arg = args[i];
String a = trim(arg);
@@ -685,7 +689,7 @@
JCommander jc = findCommandByAlias(arg);
int increment = 1;
- if (! "--".equals(a) && isOption(args, a) && jc == null) {
+ if (! isDashDash && ! "--".equals(a) && isOption(args, a) && jc == null) {
//
// Option
//
@@ -745,6 +749,7 @@
//
if (! Strings.isStringEmpty(arg)) {
if ("--".equals(arg)) {
+ isDashDash = true;
a = trim(args[++i]);
}
if (m_commands.isEmpty()) {
@@ -1119,13 +1124,17 @@
// The magic value 3 is the number of spaces between the name of the option
// and its description
for (Map.Entry<ProgramName, JCommander> commands : m_commands.entrySet()) {
- ProgramName progName = commands.getKey();
- String dispName = progName.getDisplayName();
- out.append(indent).append(" " + dispName); // + s(spaceCount) + getCommandDescription(progName.name) + "\n");
+ Object arg = commands.getValue().getObjects().get(0);
+ Parameters p = arg.getClass().getAnnotation(Parameters.class);
+ if (!p.hidden()) {
+ ProgramName progName = commands.getKey();
+ String dispName = progName.getDisplayName();
+ out.append(indent).append(" " + dispName); // + s(spaceCount) + getCommandDescription(progName.name) + "\n");
- // Options for this command
- usage(progName.getName(), out, " ");
- out.append("\n");
+ // Options for this command
+ usage(progName.getName(), out, " ");
+ out.append("\n");
+ }
}
}
}
@@ -1259,11 +1268,16 @@
if (converterClass != null && converterClass.isEnum()) {
try {
result = Enum.valueOf((Class<? extends Enum>) converterClass, value);
- } catch ( IllegalArgumentException e ) {
- result = Enum.valueOf((Class<? extends Enum>) converterClass, value.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ try {
+ result = Enum.valueOf((Class<? extends Enum>) converterClass, value.toUpperCase());
+ } catch (IllegalArgumentException ex) {
+ throw new ParameterException("Invalid value for " + optionName + " parameter. Allowed values:" +
+ EnumSet.allOf((Class<? extends Enum>) converterClass));
+ }
} catch (Exception e) {
throw new ParameterException("Invalid value for " + optionName + " parameter. Allowed values:" +
- EnumSet.allOf((Class<? extends Enum>) converterClass));
+ EnumSet.allOf((Class<? extends Enum>) converterClass));
}
} else {
converter = instantiateConverter(optionName, converterClass);
@@ -1364,6 +1378,7 @@
JCommander jc = new JCommander(object);
jc.setProgramName(name, aliases);
jc.setDefaultProvider(m_defaultProvider);
+ jc.setAcceptUnknownOptions(m_acceptUnknownOptions);
ProgramName progName = jc.m_programName;
m_commands.put(progName, jc);
@@ -1565,7 +1580,13 @@
public List<String> getUnknownOptions() {
return m_unknownArgs;
}
+ public void setAllowParameterOverwriting(boolean b) {
+ m_allowParameterOverwriting = b;
+ }
+ public boolean isParameterOverwritingAllowed() {
+ return m_allowParameterOverwriting;
+ }
// public void setCaseSensitiveCommands(boolean b) {
// m_caseSensitiveCommands = b;
// }
diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java
index 974eeaa..d8cf87d 100644
--- a/src/main/java/com/beust/jcommander/Parameter.java
+++ b/src/main/java/com/beust/jcommander/Parameter.java
@@ -119,4 +119,12 @@
* required parameters are no longer checked for their presence.
*/
boolean help() default false;
+
+ /**
+ * If true, this parameter can be overwritten through a file or another appearance of the parameter
+ * @return
+ */
+ boolean forceNonOverwritable() default false;
+
+
}
diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java
index 33574a9..2ef2d5f 100644
--- a/src/main/java/com/beust/jcommander/ParameterDescription.java
+++ b/src/main/java/com/beust/jcommander/ParameterDescription.java
@@ -186,7 +186,6 @@
String[] names = m_wrappedParameter.names();
for (int i = 0; i < names.length; i++) {
if (i > 0) sb.append(", ");
- if (names.length == 1 && names[i].startsWith("--")) sb.append(" ");
sb.append(names[i]);
}
return sb.toString();
@@ -231,7 +230,7 @@
p("Adding " + (isDefault ? "default " : "") + "value:" + value
+ " to parameter:" + m_parameterized.getName());
String name = m_wrappedParameter.names()[0];
- if (m_assigned && ! isMultiOption()) {
+ if (m_assigned && ! isMultiOption() && !m_jCommander.isParameterOverwritingAllowed() || isNonOverwritableForced()) {
throw new ParameterException("Can only specify option " + name + " once.");
}
@@ -358,4 +357,8 @@
public boolean isHelp() {
return m_wrappedParameter.isHelp();
}
+
+ public boolean isNonOverwritableForced() {
+ return m_wrappedParameter.isNonOverwritableForced();
+ }
}
diff --git a/src/main/java/com/beust/jcommander/Parameters.java b/src/main/java/com/beust/jcommander/Parameters.java
index 9834ea0..f2e8c76 100644
--- a/src/main/java/com/beust/jcommander/Parameters.java
+++ b/src/main/java/com/beust/jcommander/Parameters.java
@@ -67,4 +67,9 @@
* An array of allowed command names.
*/
String[] commandNames() default {};
+
+ /**
+ * If true, this command won't appear in the usage().
+ */
+ boolean hidden() default false;
}
diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java
index 52cafc4..f4e7d56 100644
--- a/src/main/java/com/beust/jcommander/WrappedParameter.java
+++ b/src/main/java/com/beust/jcommander/WrappedParameter.java
@@ -109,4 +109,7 @@
return m_parameter != null && m_parameter.help();
}
+ public boolean isNonOverwritableForced() {
+ return m_parameter != null && m_parameter.forceNonOverwritable();
+ }
}
diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
index 342b858..ad2c5e8 100644
--- a/src/test/java/com/beust/jcommander/JCommanderTest.java
+++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
@@ -1056,7 +1056,7 @@
@Test(enabled = false)
public static void main(String[] args) throws Exception {
-// new JCommanderTest().a();
+ new JCommanderTest().enumArgsFail();
// class A {
// @Parameter(names = "-short", required = true)
// List<String> parameters;
diff --git a/src/test/java/com/beust/jcommander/command/CommandHidden.java b/src/test/java/com/beust/jcommander/command/CommandHidden.java
new file mode 100644
index 0000000..a3fc4fa
--- /dev/null
+++ b/src/test/java/com/beust/jcommander/command/CommandHidden.java
@@ -0,0 +1,17 @@
+package com.beust.jcommander.command;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+
+import java.util.List;
+
+@Parameters(commandNames = "add", commandDescription = "Hidden command to add file contents to the index", hidden = true)
+public class CommandHidden {
+
+ @Parameter(description = "Patterns of files to be added")
+ public List<String> patterns;
+
+ @Parameter(names = "-i")
+ public Boolean interactive = false;
+
+}
diff --git a/src/test/java/com/beust/jcommander/command/CommandTest.java b/src/test/java/com/beust/jcommander/command/CommandTest.java
index 97e0007..cf921bd 100644
--- a/src/test/java/com/beust/jcommander/command/CommandTest.java
+++ b/src/test/java/com/beust/jcommander/command/CommandTest.java
@@ -87,6 +87,28 @@
Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java"));
}
+ @Test
+ public void hiddenCommandTest() {
+ CommandMain cm = new CommandMain();
+ JCommander jc = new JCommander(cm);
+ CommandAdd add = new CommandAdd();
+ jc.addCommand("add", add);
+ CommandHidden hidden = new CommandHidden();
+ jc.addCommand("hidden", hidden);
+ jc.parse("hidden", "-i", "A.java");
+
+ Assert.assertEquals(jc.getParsedCommand(), "hidden");
+ Assert.assertEquals(hidden.interactive.booleanValue(), true);
+ Assert.assertEquals(hidden.patterns, Arrays.asList("A.java"));
+
+ jc.setProgramName("TestCommander");
+ StringBuilder out = new StringBuilder();
+ jc.usage(out);
+
+ Assert.assertTrue(out.toString().contains("add Add file contents to the index"));
+ Assert.assertFalse(out.toString().contains("hidden Hidden command to add file contents to the index"));
+ }
+
public static void main(String[] args) {
new CommandTest().shouldComplainIfNoAnnotations();
}