1 package org.broadinstitute.hellbender.testutils;
2 
3 import htsjdk.samtools.util.Locatable;
4 import org.apache.commons.lang3.StringUtils;
5 import org.broadinstitute.hellbender.cmdline.StandardArgumentDefinitions;
6 import org.broadinstitute.hellbender.cmdline.argumentcollections.IntervalArgumentCollection;
7 import org.broadinstitute.hellbender.utils.IntervalUtils;
8 import org.broadinstitute.hellbender.utils.Utils;
9 
10 import java.io.File;
11 import java.nio.file.Path;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.List;
15 
16 /**
17  * Builder for command line argument lists with lots of convenience methods for adding standard GATK arguments such as
18  * input, output, variants, reference, and intervals.
19  *
20  * Use this only in test code.
21  */
22 public final class ArgumentsBuilder {
23     private final List<String> args= new ArrayList<>();
24 
ArgumentsBuilder()25     public ArgumentsBuilder(){}
26 
ArgumentsBuilder(Object[] args)27     public ArgumentsBuilder(Object[] args){
28         for (Object arg: args){
29             if (arg instanceof String){
30                 addRaw((String) arg);
31             } else {
32                 addRaw(arg);
33             }
34         }
35     }
36 
37     /**
38      * Add a string to the arguments list
39      * Strings are processed specially, they are reformatted to match the new unix style arguments
40      *
41      * NOTE: In general this method should be avoided in favor of other methods that handle adding dashes.
42      * @param arg A string representing one or more arguments
43      * @return the ArgumentsBuilder
44      */
addRaw(String arg)45     public ArgumentsBuilder addRaw(String arg){
46         List<String> chunks = Arrays.asList(StringUtils.split(arg.trim()));
47         for (String chunk : chunks){
48             args.add(chunk);
49         }
50         return this;
51     }
52 
53     /**
54      * Add any object's string representation to the arguments list
55      */
addRaw(Object arg)56     public ArgumentsBuilder addRaw(Object arg) {
57         args.add(arg.toString());
58         return this;
59     }
60 
61     // ARGUMENT/VALUE METHODS
62 
63     /**
64      * add an argument with a given value to this builder.
65      *
66      * This is the fundamental add method that others invoke.  It adds dashes to the argument name.
67      */
add(final String argumentName, final String argumentValue)68     public ArgumentsBuilder add(final String argumentName, final String argumentValue) {
69         Utils.nonNull(argumentValue);
70         Utils.nonNull(argumentName);
71         addRaw("--" + argumentName);
72         addRaw(argumentValue);
73         return this;
74     }
75 
add(final String argumentName, final File file)76     public ArgumentsBuilder add(final String argumentName, final File file){
77         Utils.nonNull(file);
78         return add(argumentName, file.getAbsolutePath());
79     }
80 
add(final String argumentName, final Path path)81     public ArgumentsBuilder add(final String argumentName, final Path path){
82         Utils.nonNull(path);
83         return add(argumentName, path.toString());
84     }
85 
add(final String argumentName, final boolean yes)86     public ArgumentsBuilder add(final String argumentName, final boolean yes){
87         return add(argumentName, String.valueOf(yes));
88     }
89 
add(final String argumentName, final Number value)90     public ArgumentsBuilder add(final String argumentName, final Number value){
91         Utils.nonNull(value);
92         return add(argumentName, value.toString());
93     }
94 
add(final String argumentName, final Enum<?> enummerationValue)95     public ArgumentsBuilder add(final String argumentName, final Enum<?> enummerationValue){
96         Utils.nonNull(enummerationValue);
97         return add(argumentName, enummerationValue.name());
98     }
99 
100     // CONVENIENCE METHODS WITH BUILT-IN STANDARD ARGUMENTS
101 
102     // INPUT
103 
addInput(final File input)104     public ArgumentsBuilder addInput(final File input) {
105         return add(StandardArgumentDefinitions.INPUT_LONG_NAME, input);
106     }
107 
addInput(final String input)108     public ArgumentsBuilder addInput(final String input) {
109         return add(StandardArgumentDefinitions.INPUT_LONG_NAME, input);
110     }
111 
addInput(final Path input)112     public ArgumentsBuilder addInput(final Path input) {
113         return add(StandardArgumentDefinitions.INPUT_LONG_NAME, input);
114     }
115 
116     // OUTPUT
117 
addOutput(final File output)118     public ArgumentsBuilder addOutput(final File output) {
119         return add(StandardArgumentDefinitions.OUTPUT_LONG_NAME, output);
120     }
121 
addOutput(final String output)122     public ArgumentsBuilder addOutput(final String output) {
123         return add(StandardArgumentDefinitions.OUTPUT_LONG_NAME, output);
124     }
125 
addOutput(final Path output)126     public ArgumentsBuilder addOutput(final Path output) {
127         return add(StandardArgumentDefinitions.OUTPUT_LONG_NAME, output.toString());
128     }
129 
130     // REFERENCE
131 
addReference(final File reference)132     public ArgumentsBuilder addReference(final File reference){
133         return add(StandardArgumentDefinitions.REFERENCE_LONG_NAME, reference);
134     }
135 
addReference(final String reference)136     public ArgumentsBuilder addReference(final String reference){
137         return add(StandardArgumentDefinitions.REFERENCE_LONG_NAME, reference);
138     }
139 
addReference(final Path reference)140     public ArgumentsBuilder addReference(final Path reference){
141         return add(StandardArgumentDefinitions.REFERENCE_LONG_NAME, reference.toString());
142     }
143 
144     // VCF
145 
addVCF(final File vcf)146     public ArgumentsBuilder addVCF(final File vcf) {
147         return add(StandardArgumentDefinitions.VARIANT_LONG_NAME, vcf);
148     }
149 
addVCF(final String vcf)150     public ArgumentsBuilder addVCF(final String vcf) {
151         return add(StandardArgumentDefinitions.VARIANT_LONG_NAME, vcf);
152     }
153 
addVCF(final Path vcf)154     public ArgumentsBuilder addVCF(final Path vcf) {
155         return add(StandardArgumentDefinitions.VARIANT_LONG_NAME, vcf);
156     }
157 
158     //FLAG
159 
addFlag(final String argumentName)160     public ArgumentsBuilder addFlag(final String argumentName) {
161         Utils.nonNull(argumentName);
162         return addRaw("--" + argumentName);
163     }
164 
165     // INTERVALS
166 
addInterval(final String interval)167     public ArgumentsBuilder addInterval(final String interval){
168         Utils.nonNull(interval);
169         return add(StandardArgumentDefinitions.INTERVALS_LONG_NAME, interval);
170     }
171 
addInterval(final Locatable interval)172     public ArgumentsBuilder addInterval(final Locatable interval){
173         Utils.nonNull(interval);
174         return add(StandardArgumentDefinitions.INTERVALS_LONG_NAME, IntervalUtils.locatableToString(interval));
175     }
176 
addIntervals(final File interval)177     public ArgumentsBuilder addIntervals(final File interval){
178         Utils.nonNull(interval);
179         return add(StandardArgumentDefinitions.INTERVALS_LONG_NAME, interval);
180     }
181 
addMask(final File mask)182     public ArgumentsBuilder addMask(final File mask){
183         return add(IntervalArgumentCollection.EXCLUDE_INTERVALS_LONG_NAME, mask);
184     }
185 
186     /**
187      * @return the arguments as List
188      */
getArgsList()189     public List<String> getArgsList(){
190         return args;
191     }
192 
193     /**
194      * @return the arguments as String[]
195      */
getArgsArray()196     public String[] getArgsArray(){
197         return args.toArray(new String[this.args.size()]);
198     }
199 
200 
201     /**
202      * @return the arguments as a single String
203      */
getString()204     public String getString() {
205         return String.join(" ", args);
206     }
207 
208     @Override
toString()209     public String toString(){
210         return getString();
211     }
212 }
213