Fix improper detection of command-line arguments with missing values.
This commit is contained in:
parent
7054c5342f
commit
2ac490dbdf
|
|
@ -174,7 +174,8 @@ public class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
|
||||||
|
|
||||||
static DefinitionMatcher VerifiableDefinitionMatcher = new DefinitionMatcher() {
|
static DefinitionMatcher VerifiableDefinitionMatcher = new DefinitionMatcher() {
|
||||||
public boolean matches( ArgumentDefinition definition, Object key ) {
|
public boolean matches( ArgumentDefinition definition, Object key ) {
|
||||||
return definition.validation != null;
|
// We can perform some sort of validation for anything that isn't a flag.
|
||||||
|
return !definition.isFlag;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ public class ArgumentMatch implements Iterable<ArgumentMatch> {
|
||||||
public final String label;
|
public final String label;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps indicies of command line arguments to values paired with that argument.
|
* Maps indices of command line arguments to values paired with that argument.
|
||||||
*/
|
*/
|
||||||
public final SortedMap<Integer,List<String>> indices = new TreeMap<Integer,List<String>>();
|
public final SortedMap<Integer,List<String>> indices = new TreeMap<Integer,List<String>>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,11 @@ import java.util.*;
|
||||||
* A parser for Sting command-line arguments.
|
* A parser for Sting command-line arguments.
|
||||||
*/
|
*/
|
||||||
public class ParsingEngine {
|
public class ParsingEngine {
|
||||||
|
/**
|
||||||
|
* The loaded argument sources along with their back definitions.
|
||||||
|
*/
|
||||||
|
private Map<ArgumentDefinition,ArgumentSource> argumentSourcesByDefinition = new HashMap<ArgumentDefinition,ArgumentSource>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of defined arguments against which command lines are matched.
|
* A list of defined arguments against which command lines are matched.
|
||||||
* Package protected for testing access.
|
* Package protected for testing access.
|
||||||
|
|
@ -107,8 +112,13 @@ public class ParsingEngine {
|
||||||
*/
|
*/
|
||||||
public void addArgumentSource( String sourceName, Class sourceClass ) {
|
public void addArgumentSource( String sourceName, Class sourceClass ) {
|
||||||
List<ArgumentDefinition> argumentsFromSource = new ArrayList<ArgumentDefinition>();
|
List<ArgumentDefinition> argumentsFromSource = new ArrayList<ArgumentDefinition>();
|
||||||
for( ArgumentSource argumentSource: extractArgumentSources(sourceClass) )
|
for( ArgumentSource argumentSource: extractArgumentSources(sourceClass) ) {
|
||||||
argumentsFromSource.addAll( argumentSource.createArgumentDefinitions() );
|
List<ArgumentDefinition> argumentDefinitions = argumentSource.createArgumentDefinitions();
|
||||||
|
for(ArgumentDefinition argumentDefinition: argumentDefinitions) {
|
||||||
|
argumentSourcesByDefinition.put(argumentDefinition,argumentSource);
|
||||||
|
argumentsFromSource.add( argumentDefinition );
|
||||||
|
}
|
||||||
|
}
|
||||||
argumentDefinitions.add( new ArgumentDefinitionGroup(sourceName, argumentsFromSource) );
|
argumentDefinitions.add( new ArgumentDefinitionGroup(sourceName, argumentsFromSource) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,16 +209,25 @@ public class ParsingEngine {
|
||||||
throw new InvalidArgumentException( invalidArguments );
|
throw new InvalidArgumentException( invalidArguments );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find invalid argument values (arguments that fail the regexp test.
|
// Find invalid argument values -- invalid arguments are either completely missing or fail the specified 'validation' regular expression.
|
||||||
if( !skipValidationOf.contains(ValidationType.InvalidArgumentValue) ) {
|
if( !skipValidationOf.contains(ValidationType.InvalidArgumentValue) ) {
|
||||||
Collection<ArgumentDefinition> verifiableArguments =
|
Collection<ArgumentDefinition> verifiableArguments =
|
||||||
argumentDefinitions.findArgumentDefinitions( null, ArgumentDefinitions.VerifiableDefinitionMatcher );
|
argumentDefinitions.findArgumentDefinitions( null, ArgumentDefinitions.VerifiableDefinitionMatcher );
|
||||||
Collection<Pair<ArgumentDefinition,String>> invalidValues = new ArrayList<Pair<ArgumentDefinition,String>>();
|
Collection<Pair<ArgumentDefinition,String>> invalidValues = new ArrayList<Pair<ArgumentDefinition,String>>();
|
||||||
for( ArgumentDefinition verifiableArgument: verifiableArguments ) {
|
for( ArgumentDefinition verifiableArgument: verifiableArguments ) {
|
||||||
ArgumentMatches verifiableMatches = argumentMatches.findMatches( verifiableArgument );
|
ArgumentMatches verifiableMatches = argumentMatches.findMatches( verifiableArgument );
|
||||||
|
// Check to see whether an argument value was specified. Argument values must be provided
|
||||||
|
// when the argument name is specified and the argument is not a flag type.
|
||||||
|
for(ArgumentMatch verifiableMatch: verifiableMatches) {
|
||||||
|
ArgumentSource argumentSource = argumentSourcesByDefinition.get(verifiableArgument);
|
||||||
|
if(verifiableMatch.values().size() == 0 && !verifiableArgument.isFlag && argumentSource.createsTypeDefault())
|
||||||
|
invalidValues.add(new Pair<ArgumentDefinition,String>(verifiableArgument,null));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the field contents meet the validation criteria specified by the regular expression.
|
||||||
for( ArgumentMatch verifiableMatch: verifiableMatches ) {
|
for( ArgumentMatch verifiableMatch: verifiableMatches ) {
|
||||||
for( String value: verifiableMatch.values() ) {
|
for( String value: verifiableMatch.values() ) {
|
||||||
if( !value.matches(verifiableArgument.validation) )
|
if( verifiableArgument.validation != null && !value.matches(verifiableArgument.validation) )
|
||||||
invalidValues.add( new Pair<ArgumentDefinition,String>(verifiableArgument, value) );
|
invalidValues.add( new Pair<ArgumentDefinition,String>(verifiableArgument, value) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -515,10 +534,14 @@ class InvalidArgumentValueException extends ArgumentException {
|
||||||
private static String formatArguments( Collection<Pair<ArgumentDefinition,String>> invalidArgumentValues ) {
|
private static String formatArguments( Collection<Pair<ArgumentDefinition,String>> invalidArgumentValues ) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for( Pair<ArgumentDefinition,String> invalidValue: invalidArgumentValues ) {
|
for( Pair<ArgumentDefinition,String> invalidValue: invalidArgumentValues ) {
|
||||||
sb.append( String.format("%nArgument '--%s' has value of incorrect format: %s (should match %s)",
|
if(invalidValue.getSecond() == null)
|
||||||
invalidValue.first.fullName,
|
sb.append( String.format("%nArgument '--%s' requires a value but none was provided",
|
||||||
invalidValue.second,
|
invalidValue.first.fullName) );
|
||||||
invalidValue.first.validation) );
|
else
|
||||||
|
sb.append( String.format("%nArgument '--%s' has value of incorrect format: %s (should match %s)",
|
||||||
|
invalidValue.first.fullName,
|
||||||
|
invalidValue.second,
|
||||||
|
invalidValue.first.validation) );
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue