Improved detection of missing argument values
In particular, it was possible to specify arguments for Files or Compound types without values Added a special "none" value for annotations, since a bare "-A" is no longer allowed Delivers PT 71792842 and 59360374
This commit is contained in:
parent
03e7ee6e9c
commit
593663d9b6
|
|
@ -212,7 +212,7 @@ public class UnifiedGenotyper extends LocusWalker<List<VariantCallContext>, Unif
|
|||
* If specified, all available annotations in the group will be applied. See the VariantAnnotator -list argument to view available groups.
|
||||
* Keep in mind that RODRequiringAnnotations are not intended to be used as a group, because they require specific ROD inputs.
|
||||
*/
|
||||
@Argument(fullName="group", shortName="G", doc="One or more classes/groups of annotations to apply to variant calls", required=false)
|
||||
@Argument(fullName="group", shortName="G", doc="One or more classes/groups of annotations to apply to variant calls. The single value 'none' removes the default group", required=false)
|
||||
protected String[] annotationClassesToUse = { "Standard" };
|
||||
|
||||
// the calculation arguments
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ public class HaplotypeCaller extends ActiveRegionWalker<List<VariantContext>, In
|
|||
* Which annotations to add to the output VCF file. See the VariantAnnotator -list argument to view available annotations.
|
||||
*/
|
||||
@Advanced
|
||||
@Argument(fullName="annotation", shortName="A", doc="One or more specific annotations to apply to variant calls", required=false)
|
||||
@Argument(fullName="annotation", shortName="A", doc="One or more specific annotations to apply to variant calls. The single value 'none' removes the default annotations", required=false)
|
||||
protected List<String> annotationsToUse = new ArrayList<>(Arrays.asList(new String[]{"ClippingRankSumTest", "DepthPerSampleHC"}));
|
||||
|
||||
/**
|
||||
|
|
@ -334,7 +334,7 @@ public class HaplotypeCaller extends ActiveRegionWalker<List<VariantContext>, In
|
|||
/**
|
||||
* Which groups of annotations to add to the output VCF file. See the VariantAnnotator -list argument to view available groups.
|
||||
*/
|
||||
@Argument(fullName="group", shortName="G", doc="One or more classes/groups of annotations to apply to variant calls", required=false)
|
||||
@Argument(fullName="group", shortName="G", doc="One or more classes/groups of annotations to apply to variant calls. The single value 'none' removes the default group", required=false)
|
||||
protected String[] annotationClassesToUse = { "Standard" };
|
||||
|
||||
@ArgumentCollection
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ public class GenotypeGVCFs extends RodWalker<VariantContext, VariantContextWrite
|
|||
* Which annotations to recompute for the combined output VCF file.
|
||||
*/
|
||||
@Advanced
|
||||
@Argument(fullName="annotation", shortName="A", doc="One or more specific annotations to recompute", required=false)
|
||||
@Argument(fullName="annotation", shortName="A", doc="One or more specific annotations to recompute. The single value 'none' removes the default annotations", required=false)
|
||||
protected List<String> annotationsToUse = new ArrayList<>(Arrays.asList(new String[]{"InbreedingCoeff", "FisherStrand", "QualByDepth", "ChromosomeCounts", "GenotypeSummaries"}));
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public class HaplotypeCallerParallelIntegrationTest extends WalkerTest {
|
|||
WalkerTestSpec spec = new WalkerTestSpec(
|
||||
"-T HaplotypeCaller --pcr_indel_model NONE -R " + b37KGReference + " --no_cmdline_in_header -I "
|
||||
+ privateTestDir + "PCRFree.2x250.Illumina.20_10_11.bam -o %s " +
|
||||
" -L 20:10,000,000-10,100,000 -G none -A -contamination 0.0 -nct " + nct, 1,
|
||||
" -L 20:10,000,000-10,100,000 -G none -A none -contamination 0.0 -nct " + nct, 1,
|
||||
Arrays.asList(md5));
|
||||
executeTest("HC test parallel HC with NCT with nct " + nct, spec);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public class NanoSchedulerIntegrationTest extends WalkerTest {
|
|||
WalkerTestSpec spec = new WalkerTestSpec(
|
||||
buildCommandLine(
|
||||
"-T UnifiedGenotyper -R " + b37KGReference,
|
||||
"--no_cmdline_in_header -G",
|
||||
"--no_cmdline_in_header -G none",
|
||||
//"--dbsnp " + b37dbSNP132,
|
||||
"-I " + privateTestDir + "NA12878.HiSeq.b37.chr20.10_11mb.bam",
|
||||
"-L 20:10,000,000-10,100,000",
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ import org.broadinstitute.gatk.utils.exceptions.UserException;
|
|||
import java.util.*;
|
||||
|
||||
public class AnnotationInterfaceManager {
|
||||
private static final String NULL_ANNOTATION_NAME = "none";
|
||||
private static final String NULL_ANNOTATION_GROUP_NAME = "none";
|
||||
|
||||
private static PluginManager<InfoFieldAnnotation> infoFieldAnnotationPluginManager = new PluginManager<InfoFieldAnnotation>(InfoFieldAnnotation.class);
|
||||
private static PluginManager<GenotypeAnnotation> genotypeAnnotationPluginManager = new PluginManager<GenotypeAnnotation>(GenotypeAnnotation.class);
|
||||
private static PluginManager<AnnotationType> annotationTypePluginManager = new PluginManager<AnnotationType>(AnnotationType.class);
|
||||
|
|
@ -53,7 +56,7 @@ public class AnnotationInterfaceManager {
|
|||
for ( Class c : annotationTypePluginManager.getInterfaces() )
|
||||
classMap.put(c.getSimpleName(), c);
|
||||
|
||||
if ( annotationGroupsToUse.size() != 1 || !"none".equals(annotationGroupsToUse.get(0)) ) {
|
||||
if ( annotationGroupsToUse.size() != 1 || !NULL_ANNOTATION_GROUP_NAME.equals(annotationGroupsToUse.get(0)) ) {
|
||||
for ( String group : annotationGroupsToUse ) {
|
||||
Class interfaceClass = classMap.get(group);
|
||||
if ( interfaceClass == null )
|
||||
|
|
@ -64,15 +67,17 @@ public class AnnotationInterfaceManager {
|
|||
}
|
||||
|
||||
// validate the specific classes provided
|
||||
for ( String annotation : annotationsToUse ) {
|
||||
Class annotationClass = classMap.get(annotation);
|
||||
if ( annotationClass == null )
|
||||
annotationClass = classMap.get(annotation + "Annotation");
|
||||
if ( annotationClass == null ) {
|
||||
if (DeprecatedToolChecks.isDeprecatedAnnotation(annotation) ) {
|
||||
throw new UserException.DeprecatedAnnotation(annotation, DeprecatedToolChecks.getAnnotationDeprecationInfo(annotation));
|
||||
} else {
|
||||
throw new UserException.BadArgumentValue("annotation", "Annotation " + annotation + " was not found; please check that you have specified the annotation name correctly");
|
||||
if ( annotationsToUse.size() != 1 || !NULL_ANNOTATION_NAME.equals(annotationsToUse.get(0)) ) {
|
||||
for (String annotation : annotationsToUse) {
|
||||
Class annotationClass = classMap.get(annotation);
|
||||
if (annotationClass == null)
|
||||
annotationClass = classMap.get(annotation + "Annotation");
|
||||
if (annotationClass == null) {
|
||||
if (DeprecatedToolChecks.isDeprecatedAnnotation(annotation)) {
|
||||
throw new UserException.DeprecatedAnnotation(annotation, DeprecatedToolChecks.getAnnotationDeprecationInfo(annotation));
|
||||
} else {
|
||||
throw new UserException.BadArgumentValue("annotation", "Annotation " + annotation + " was not found; please check that you have specified the annotation name correctly");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -105,7 +110,7 @@ public class AnnotationInterfaceManager {
|
|||
}
|
||||
});
|
||||
|
||||
if ( annotationGroupsToUse.size() != 1 || !"none".equals(annotationGroupsToUse.get(0)) ) {
|
||||
if ( annotationGroupsToUse.size() != 1 || !NULL_ANNOTATION_GROUP_NAME.equals(annotationGroupsToUse.get(0)) ) {
|
||||
for ( String group : annotationGroupsToUse ) {
|
||||
Class interfaceClass = classMap.get(group);
|
||||
if ( interfaceClass == null )
|
||||
|
|
@ -116,12 +121,14 @@ public class AnnotationInterfaceManager {
|
|||
}
|
||||
|
||||
// get the specific classes provided
|
||||
for ( String annotation : annotationsToUse ) {
|
||||
Class annotationClass = classMap.get(annotation);
|
||||
if ( annotationClass == null )
|
||||
annotationClass = classMap.get(annotation + "Annotation");
|
||||
if ( annotationClass != null )
|
||||
classes.add(annotationClass);
|
||||
if ( annotationsToUse.size() != 1 || !NULL_ANNOTATION_NAME.equals(annotationsToUse.get(0)) ) {
|
||||
for (String annotation : annotationsToUse) {
|
||||
Class annotationClass = classMap.get(annotation);
|
||||
if (annotationClass == null)
|
||||
annotationClass = classMap.get(annotation + "Annotation");
|
||||
if (annotationClass != null)
|
||||
classes.add(annotationClass);
|
||||
}
|
||||
}
|
||||
|
||||
// note that technically an annotation can work on both the INFO and FORMAT fields
|
||||
|
|
|
|||
|
|
@ -174,8 +174,9 @@ public class ArgumentDefinitions implements Iterable<ArgumentDefinition> {
|
|||
|
||||
static DefinitionMatcher VerifiableDefinitionMatcher = new DefinitionMatcher() {
|
||||
public boolean matches( ArgumentDefinition definition, Object key ) {
|
||||
// We can perform some sort of validation for anything that isn't a flag.
|
||||
return !definition.isFlag;
|
||||
// We can perform some sort of validation for anything that isn't a flag or enum.
|
||||
// Because enums can have a default value, it might be valid to specify an enum argument with no value
|
||||
return !definition.isFlag && !definition.argumentType.isEnum();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ public class ArgumentMatch implements Iterable<ArgumentMatch> {
|
|||
* @return True if there's another token waiting in the wings. False otherwise.
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
return nextToken != null;
|
||||
return nextSite != null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -195,7 +195,7 @@ public class ArgumentMatch implements Iterable<ArgumentMatch> {
|
|||
* @return The next ArgumentMatch in the series. Should never be null.
|
||||
*/
|
||||
public ArgumentMatch next() {
|
||||
if( nextSite == null || nextToken == null )
|
||||
if( nextSite == null )
|
||||
throw new IllegalStateException( "No more ArgumentMatches are available" );
|
||||
|
||||
ArgumentMatch match = new ArgumentMatch( label, definition, nextSite, nextToken, tags );
|
||||
|
|
@ -221,10 +221,8 @@ public class ArgumentMatch implements Iterable<ArgumentMatch> {
|
|||
nextSite = siteIterator.next();
|
||||
if( sites.get(nextSite) != null ) {
|
||||
tokenIterator = sites.get(nextSite).iterator();
|
||||
if( tokenIterator.hasNext() ) {
|
||||
nextToken = tokenIterator.next();
|
||||
break;
|
||||
}
|
||||
nextToken = tokenIterator.hasNext() ? tokenIterator.next() : null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -280,6 +278,8 @@ public class ArgumentMatch implements Iterable<ArgumentMatch> {
|
|||
for ( final List<ArgumentMatchValue> siteValue : sites.values() ) {
|
||||
if ( siteValue != null )
|
||||
values.addAll(siteValue);
|
||||
else
|
||||
values.add(null);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -736,8 +736,10 @@ class SimpleArgumentTypeDescriptor extends ArgumentTypeDescriptor {
|
|||
} else if (type.equals(File.class)) {
|
||||
result = value == null ? null : value.asFile();
|
||||
} else {
|
||||
if (value == null)
|
||||
throw new MissingArgumentValueException(createDefaultArgumentDefinition(source));
|
||||
Constructor ctor = type.getConstructor(String.class);
|
||||
result = ctor.newInstance(value == null ? null : value.asString());
|
||||
result = ctor.newInstance(value.asString());
|
||||
}
|
||||
} catch (UserException e) {
|
||||
throw e;
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ public class ParsingEngine {
|
|||
// 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())
|
||||
if(verifiableMatch.values().size() == 0 && !verifiableArgument.isFlag && !argumentSource.createsTypeDefault())
|
||||
invalidValues.add(new Pair<ArgumentDefinition,String>(verifiableArgument,null));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Test suite for the parsing engine.
|
||||
*/
|
||||
|
|
@ -135,7 +137,7 @@ public class ParsingEngineUnitTest extends BaseTest {
|
|||
Assert.assertEquals(argProvider.foo, 5, "Argument is not correctly initialized");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions=MissingArgumentValueException.class)
|
||||
@Test(expectedExceptions=InvalidArgumentValueException.class)
|
||||
public void primitiveArgumentNoValueTest() {
|
||||
final String[] commandLine = new String[] {"--foo"};
|
||||
|
||||
|
|
@ -948,6 +950,7 @@ public class ParsingEngineUnitTest extends BaseTest {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class NumericRangeArgProvider {
|
||||
@Argument(fullName = "intWithHardMinAndMax", minValue = 5, maxValue = 10)
|
||||
public int intWithHardMinAndMax;
|
||||
|
|
@ -1089,4 +1092,50 @@ public class ParsingEngineUnitTest extends BaseTest {
|
|||
NumericRangeArgProvider argProvider = new NumericRangeArgProvider();
|
||||
parsingEngine.loadArgumentsIntoObject(argProvider);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class VariedTypeArgProvider {
|
||||
@Argument(fullName = "intVal", required=false)
|
||||
private int anInt;
|
||||
|
||||
@Argument(fullName = "stringVal", required=false)
|
||||
private String aString;
|
||||
|
||||
@Argument(fullName = "enumVal", required=false)
|
||||
private TestEnum anEnum;
|
||||
|
||||
@Argument(fullName = "fileVal", required=false)
|
||||
private File aFile;
|
||||
|
||||
@Argument(fullName = "stringSet", required=false)
|
||||
private Set<String> someStrings;
|
||||
|
||||
@Argument(fullName = "intervalVal", required=false)
|
||||
private IntervalBinding<Feature> anInterval;
|
||||
}
|
||||
|
||||
@DataProvider(name = "MissingArgumentValueDataProvider")
|
||||
public Object[][] missingArgumentDataProvider() {
|
||||
return new Object[][]{
|
||||
{ new String[]{"--intVal"} },
|
||||
{ new String[]{"--stringVal"} },
|
||||
{ new String[]{"--enumVal"} },
|
||||
{ new String[]{"--fileVal"} },
|
||||
{ new String[]{"--stringSet"} },
|
||||
{ new String[]{"--stringSet", "aha", "--stringSet"} },
|
||||
{ new String[]{"--intervalVal"} }
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "MissingArgumentValueDataProvider",
|
||||
expectedExceptions = {InvalidArgumentValueException.class, MissingArgumentValueException.class})
|
||||
public void testMissingArguments( final String[] commandLine ) {
|
||||
parsingEngine.addArgumentSource( VariedTypeArgProvider.class );
|
||||
parsingEngine.parse( commandLine );
|
||||
parsingEngine.validate();
|
||||
|
||||
VariedTypeArgProvider argProvider = new VariedTypeArgProvider();
|
||||
parsingEngine.loadArgumentsIntoObject(argProvider);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue