summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukáš Petrovický <lukas@petrovicky.net>2017-03-09 10:36:32 +0100
committerLukáš Petrovický <lpetrovi@redhat.com>2017-03-09 10:36:32 +0100
commit45aec91a6acf18aba7c03d213bfd85fddab5527e (patch)
treeac461be6b86c5c6bc8bced88129ac8512d446fc4
parentfab3cb966234895881a2134fdc4c394f0382d792 (diff)
downloadjcommander-45aec91a6acf18aba7c03d213bfd85fddab5527e.tar.gz
Never prompt for password if it was passed as an argument (fixes #195)
Took the liberty of also fixing one pre-existing test related to passwords that was marked as disabled until now.
-rw-r--r--src/main/java/com/beust/jcommander/JCommander.java77
-rw-r--r--src/test/java/com/beust/jcommander/JCommanderTest.java108
2 files changed, 143 insertions, 42 deletions
diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java
index ac28cca..7d05d10 100644
--- a/src/main/java/com/beust/jcommander/JCommander.java
+++ b/src/main/java/com/beust/jcommander/JCommander.java
@@ -18,20 +18,42 @@
package com.beust.jcommander;
-import com.beust.jcommander.FuzzyMap.IKey;
-import com.beust.jcommander.converters.*;
-import com.beust.jcommander.internal.*;
-
import java.io.BufferedReader;
import java.io.IOException;
-import java.lang.reflect.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.CopyOnWriteArrayList;
+import com.beust.jcommander.FuzzyMap.IKey;
+import com.beust.jcommander.converters.DefaultListConverter;
+import com.beust.jcommander.converters.EnumConverter;
+import com.beust.jcommander.converters.IParameterSplitter;
+import com.beust.jcommander.converters.NoConverter;
+import com.beust.jcommander.converters.StringConverter;
+import com.beust.jcommander.internal.Console;
+import com.beust.jcommander.internal.DefaultConsole;
+import com.beust.jcommander.internal.DefaultConverterFactory;
+import com.beust.jcommander.internal.JDK6Console;
+import com.beust.jcommander.internal.Lists;
+import com.beust.jcommander.internal.Maps;
+import com.beust.jcommander.internal.Nullable;
+
/**
* The main class for JCommander. It's responsible for parsing the object that contains
* all the annotated fields, parse the command line and assign the fields with the correct
@@ -642,12 +664,7 @@ public class JCommander {
if (pd != null) {
if (pd.getParameter().password()) {
- //
- // Password option, use the Console to retrieve the password
- //
- char[] password = readPassword(pd.getDescription(), pd.getParameter().echoInput());
- pd.addValue(new String(password));
- requiredFields.remove(pd.getParameterized());
+ increment = processPassword(args, i, pd, validate);
} else {
if (pd.getParameter().variableArity()) {
//
@@ -760,6 +777,34 @@ public class JCommander {
private final IVariableArity DEFAULT_VARIABLE_ARITY = new DefaultVariableArity();
+ private final int determineArity(String[] args, int index, ParameterDescription pd, IVariableArity va) {
+ List<String> currentArgs = Lists.newArrayList();
+ for (int j = index + 1; j < args.length; j++) {
+ currentArgs.add(args[j]);
+ }
+ return va.processVariableArity(pd.getParameter().names()[0],
+ currentArgs.toArray(new String[0]));
+ }
+
+ /**
+ * @return the number of options that were processed.
+ */
+ private int processPassword(String[] args, int index, ParameterDescription pd, boolean validate) {
+ final int passwordArity = determineArity(args, index, pd, DEFAULT_VARIABLE_ARITY);
+ if (passwordArity == 0) {
+ // password option with password not specified, use the Console to retrieve the password
+ char[] password = readPassword(pd.getDescription(), pd.getParameter().echoInput());
+ pd.addValue(new String(password));
+ requiredFields.remove(pd.getParameterized());
+ return 1;
+ } else if (passwordArity == 1) {
+ // password option with password specified
+ return processFixedArity(args, index, pd, validate, List.class, 1);
+ } else {
+ throw new ParameterException("Password parameter must have at most 1 argument.");
+ }
+ }
+
/**
* @return the number of options that were processed.
*/
@@ -772,13 +817,7 @@ public class JCommander {
va = (IVariableArity) arg;
}
- List<String> currentArgs = Lists.newArrayList();
- for (int j = index + 1; j < args.length; j++) {
- currentArgs.add(args[j]);
- }
- int arity = va.processVariableArity(pd.getParameter().names()[0],
- currentArgs.toArray(new String[0]));
-
+ int arity = determineArity(args, index, pd, va);
int result = processFixedArity(args, index, pd, validate, List.class, arity);
return result;
}
diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java
index 4c3feab..c1befe1 100644
--- a/src/test/java/com/beust/jcommander/JCommanderTest.java
+++ b/src/test/java/com/beust/jcommander/JCommanderTest.java
@@ -18,8 +18,64 @@
package com.beust.jcommander;
-import com.beust.jcommander.args.*;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.TreeSet;
+
+import com.beust.jcommander.args.AlternateNamesForListArgs;
+import com.beust.jcommander.args.Args1;
+import com.beust.jcommander.args.Args1Setter;
+import com.beust.jcommander.args.Args2;
+import com.beust.jcommander.args.ArgsArityString;
+import com.beust.jcommander.args.ArgsBooleanArity;
+import com.beust.jcommander.args.ArgsBooleanArity0;
+import com.beust.jcommander.args.ArgsConverter;
+import com.beust.jcommander.args.ArgsEnum;
import com.beust.jcommander.args.ArgsEnum.ChoiceType;
+import com.beust.jcommander.args.ArgsEquals;
+import com.beust.jcommander.args.ArgsHelp;
+import com.beust.jcommander.args.ArgsI18N1;
+import com.beust.jcommander.args.ArgsI18N2;
+import com.beust.jcommander.args.ArgsI18N2New;
+import com.beust.jcommander.args.ArgsInherited;
+import com.beust.jcommander.args.ArgsList;
+import com.beust.jcommander.args.ArgsLongCommandDescription;
+import com.beust.jcommander.args.ArgsLongDescription;
+import com.beust.jcommander.args.ArgsLongMainParameterDescription;
+import com.beust.jcommander.args.ArgsMainParameter1;
+import com.beust.jcommander.args.ArgsMaster;
+import com.beust.jcommander.args.ArgsMultipleUnparsed;
+import com.beust.jcommander.args.ArgsOutOfMemory;
+import com.beust.jcommander.args.ArgsPrivate;
+import com.beust.jcommander.args.ArgsRequired;
+import com.beust.jcommander.args.ArgsSlave;
+import com.beust.jcommander.args.ArgsSlaveBogus;
+import com.beust.jcommander.args.ArgsValidate1;
+import com.beust.jcommander.args.ArgsWithSet;
+import com.beust.jcommander.args.Arity1;
+import com.beust.jcommander.args.HiddenArgs;
+import com.beust.jcommander.args.SeparatorColon;
+import com.beust.jcommander.args.SeparatorEqual;
+import com.beust.jcommander.args.SeparatorMixed;
+import com.beust.jcommander.args.SlashSeparator;
+import com.beust.jcommander.args.VariableArity;
import com.beust.jcommander.command.CommandAdd;
import com.beust.jcommander.command.CommandCommit;
import com.beust.jcommander.command.CommandMain;
@@ -29,14 +85,6 @@ import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-import java.io.*;
-import java.math.BigDecimal;
-import java.nio.charset.Charset;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.ResourceBundle;
-
@Test
public class JCommanderTest {
@@ -818,21 +866,35 @@ public class JCommanderTest {
jc.parse("--configure");
}
- // Tests:
- // required unparsed parameter
- @Test(enabled = false,
- description = "For some reason, this test still asks the password on stdin")
- public void askedRequiredPassword() {
- class A {
- @Parameter(names = {"--password", "-p"}, description = "Private key password",
- password = true, required = true)
- public String password;
+ public static class PasswordTestingArgs {
+ @Parameter(names = {"--password", "-p"}, description = "Private key password",
+ password = true, required = true)
+ public String password;
- @Parameter(names = {"--port", "-o"}, description = "Port to bind server to",
- required = true)
- public int port;
- }
- A a = new A();
+ @Parameter(names = {"--port", "-o"}, description = "Port to bind server to",
+ required = true)
+ public int port;
+ }
+
+ @Test
+ public void passwordNotRequiredToAsk() {
+ PasswordTestingArgs a = new PasswordTestingArgs();
+ final String expectedPassword = "somepassword";
+ final int expectedPort = 7;
+ new JCommander(a, "--password", expectedPassword, "--port", String.valueOf(7));
+ Assert.assertEquals(a.port, expectedPort);
+ Assert.assertEquals(a.password, expectedPassword);
+ }
+
+ @Test(expectedExceptions = ParameterException.class)
+ public void passwordWithExcessiveArity() {
+ PasswordTestingArgs a = new PasswordTestingArgs();
+ new JCommander(a, "--password", "somepassword", "someotherarg", "--port", String.valueOf(7));
+ }
+
+ @Test
+ public void passwordRequiredAsked() {
+ PasswordTestingArgs a = new PasswordTestingArgs();
InputStream stdin = System.in;
try {
System.setIn(new ByteArrayInputStream("password".getBytes()));