17850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com/*
27850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Copyright (C) 2009 The Android Open Source Project
37850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com *
47850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Licensed under the Apache License, Version 2.0 (the "License");
57850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * you may not use this file except in compliance with the License.
67850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * You may obtain a copy of the License at
77850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com *
87850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com *      http://www.apache.org/licenses/LICENSE-2.0
97850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com *
107850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Unless required by applicable law or agreed to in writing, software
117850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * distributed under the License is distributed on an "AS IS" BASIS,
127850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * See the License for the specific language governing permissions and
147850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * limitations under the License.
157850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com */
167850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
177850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.compackage vogar;
187850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
197029503206e4c89fe167c3389c1062d89cf35c52Paul Duffinimport com.google.common.annotations.VisibleForTesting;
207029503206e4c89fe167c3389c1062d89cf35c52Paul Duffinimport com.google.common.collect.ImmutableList;
21d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.comimport com.google.common.collect.Lists;
22fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerally
237850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.io.File;
247850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.io.IOException;
257850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.ArrayList;
267850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.List;
277850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.comimport java.util.Set;
28fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerallyimport java.util.LinkedHashSet;
29fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerally
307029503206e4c89fe167c3389c1062d89cf35c52Paul Duffinimport vogar.android.AdbTarget;
31969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.comimport vogar.android.AndroidSdk;
327029503206e4c89fe167c3389c1062d89cf35c52Paul Duffinimport vogar.android.DeviceFileCache;
337029503206e4c89fe167c3389c1062d89cf35c52Paul Duffinimport vogar.android.DeviceFilesystem;
347029503206e4c89fe167c3389c1062d89cf35c52Paul Duffinimport vogar.commands.Mkdir;
357029503206e4c89fe167c3389c1062d89cf35c52Paul Duffinimport vogar.commands.Rm;
36c7b173425beec5784c669388345eb3b7b96fc341enh@google.comimport vogar.util.Strings;
377850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
387850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com/**
397850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com * Command line interface for running benchmarks and tests on dalvik.
407850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com */
417850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.compublic final class Vogar {
42f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    static final int LARGE_TIMEOUT_MULTIPLIER = 10;
433b3cf36f62d25eb950f0bf95071a82b83e730a58jessewilson@google.com    public static final int NUM_PROCESSORS = Runtime.getRuntime().availableProcessors();
448c03f5a6370cf6521384a268e12808e163ae4339jessewilson@google.com
45d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    private final List<File> actionFiles = new ArrayList<File>();
46d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    private final List<String> actionClassesAndPackages = new ArrayList<String>();
47f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    final List<String> targetArgs = new ArrayList<String>();
48fc358e65b59087a1fe4e17ff64e23eaf2922b72ejsharpe@google.com    private final OptionParser optionParser = new OptionParser(this);
4925d56e71aa66d20d4326eee3696f4ce060201708bdc@google.com    private File configFile = Vogar.dotFile(".vogarconfig");
50c7b173425beec5784c669388345eb3b7b96fc341enh@google.com    private String[] configArgs;
51fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerally    public final static Console console = new Console.StreamingConsole();
5225d56e71aa66d20d4326eee3696f4ce060201708bdc@google.com
537029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private boolean useJack;
547029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin
55969d5622a380e2f2f9ebdfbf7a22cbb3e031125bjessewilson@google.com    public static File dotFile (String name) {
5625d56e71aa66d20d4326eee3696f4ce060201708bdc@google.com        return new File(System.getProperty("user.home", "."), name);
5725d56e71aa66d20d4326eee3696f4ce060201708bdc@google.com    }
5825d56e71aa66d20d4326eee3696f4ce060201708bdc@google.com
59d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--expectations" })
60f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    Set<File> expectationFiles = new LinkedHashSet<File>();
61d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    {
629f9a3ba8e244912c50140ba15ec583a8098dca41enh@google.com        expectationFiles.addAll(AndroidSdk.defaultExpectations());
63d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    }
647850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
65d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--mode" })
66c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com    ModeId modeId = ModeId.DEVICE;
67c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com
6806f9cc5c1a455157ff325c64d89acd1aade05f34Nicolas Geoffray    @Option(names = { "--variant" })
69c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com    Variant variant = Variant.X32;
707850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
710eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com    @Option(names = { "--ssh" })
727029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private String sshHost;
730eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com
74d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--timeout" })
757029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    int timeoutSeconds = 60; // default is one minute;
767850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
77126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com    @Option(names = { "--first-monitor-port" })
78f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    int firstMonitorPort = -1;
79126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com
80d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--clean-before" })
81f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    boolean cleanBefore = true;
827850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
83d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--clean-after" })
84f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    boolean cleanAfter = true;
857850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
86d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--clean" })
87d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    private boolean clean = true;
887850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
89d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--xml-reports-directory" })
90f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    File xmlReportsDirectory;
917850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
92d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--indent" })
937029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private String indent = "  ";
947850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
95d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--verbose" })
967029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private boolean verbose;
977850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
98d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--stream" })
99f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    boolean stream = true;
1007850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
101d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--color" })
1027029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private boolean color = true;
1037850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
10450bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com    @Option(names = { "--pass-color" })
1057029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private int passColor = 32; // green
10650bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com
1075ad56966d0c66ab4b733fe97c4b862f5f85711e8Nicolas Geoffray    @Option(names = { "--skip-color" })
1087029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private int skipColor = 33; // yellow
10950bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com
11050bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com    @Option(names = { "--fail-color" })
1117029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private int failColor = 31; // red
11250bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com
1135ad56966d0c66ab4b733fe97c4b862f5f85711e8Nicolas Geoffray    @Option(names = { "--warn-color" })
1147029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private int warnColor = 35; // purple
1155ad56966d0c66ab4b733fe97c4b862f5f85711e8Nicolas Geoffray
1160942355a74d759fb2e50a002b6b0b93430f07d72bdc@google.com    @Option(names = { "--ansi" })
1177029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private boolean ansi = !"dumb".equals(System.getenv("TERM"));
1180942355a74d759fb2e50a002b6b0b93430f07d72bdc@google.com
119d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--debug" })
120f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    Integer debugPort;
121d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
122328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally    @Option(names = { "--debug-app" })
123328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally    boolean debugApp;
124328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally
1253d6e772fe3a0d392af6f6ca008c556ba7c253503bdc@google.com    @Option(names = { "--device-dir" })
1267029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private File deviceDir;
127d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
128d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--vm-arg" })
129f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    List<String> vmArgs = new ArrayList<String>();
130d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
131f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com    @Option(names = { "--vm-command" })
132f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com    String vmCommand;
133f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com
134f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com    @Option(names = { "--dalvik-cache" })
135f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com    String dalvikCache = "dalvik-cache";
136f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com
137d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--java-home" })
138f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    File javaHome;
139d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
140d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--javac-arg" })
141f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    List<String> javacArgs = new ArrayList<String>();
142d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
14382131e6aba37e8b6f8ebbadbbe57fb5a78b4f743jessewilson@google.com    @Option(names = { "--use-bootclasspath" })
144f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    boolean useBootClasspath = false;
145d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
146d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--build-classpath" })
147f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    List<File> buildClasspath = new ArrayList<File>();
148d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
149d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--classpath", "-cp" })
150f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    List<File> classpath = new ArrayList<File>();
151d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
1525379730d1295c75e2b7b1c6d193e74ba5f54cf17enh@google.com    @Option(names = { "--resource-classpath" })
1535379730d1295c75e2b7b1c6d193e74ba5f54cf17enh@google.com    List<File> resourceClasspath = new ArrayList<File>();
1545379730d1295c75e2b7b1c6d193e74ba5f54cf17enh@google.com
155d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    @Option(names = { "--sourcepath" })
156f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    List<File> sourcepath = new ArrayList<File>();
157dd2774574cb456b48b8ec2aafbf0e6583f4faa41enh@google.com    {
158dd2774574cb456b48b8ec2aafbf0e6583f4faa41enh@google.com        sourcepath.addAll(AndroidSdk.defaultSourcePath());
159dd2774574cb456b48b8ec2aafbf0e6583f4faa41enh@google.com    }
160d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
161d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com    @Option(names = { "--jar-search-dir" })
162f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    List<File> jarSearchDirs = Lists.newArrayList();
163d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com
164d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com    @Option(names = { "--vogar-dir" })
165f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    File vogarDir = Vogar.dotFile(".vogar");
1664cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com
167d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com    @Option(names = { "--record-results" })
168f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    boolean recordResults = false;
169d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com
170d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com    @Option(names = { "--results-dir" })
171f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    File resultsDir = null;
172d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com
1733dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com    @Option(names = { "--suggest-classpaths" })
174f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    boolean suggestClasspaths = false;
1753dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com
1760ebefc061203658ed8b7f5df31a65d2cf6ea89b2jsharpe@google.com    @Option(names = { "--invoke-with" })
177f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    String invokeWith = null;
1785bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com
179e5dfbecbaa8568c2885a4cb859c8afa8b6a08d5bjsharpe@google.com    @Option(names = { "--benchmark" })
180f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    boolean benchmark = false;
181e5dfbecbaa8568c2885a4cb859c8afa8b6a08d5bjsharpe@google.com
18234688e44757e5f31838dee7d52106531791fcb43jessewilson@google.com    @Option(names = { "--open-bugs-command" })
183f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    String openBugsCommand;
18434688e44757e5f31838dee7d52106531791fcb43jessewilson@google.com
1851bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com    @Option(names = { "--profile" })
186f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    boolean profile = false;
1871bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com
18834b70bff9faaac07abcffa193b05cfb52d6d9908bdc@google.com    @Option(names = { "--profile-binary" })
189f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    boolean profileBinary = false;
19034b70bff9faaac07abcffa193b05cfb52d6d9908bdc@google.com
1911bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com    @Option(names = { "--profile-file" })
192f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    File profileFile;
1931bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com
1941bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com    @Option(names = { "--profile-depth" })
195f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    int profileDepth = 4;
1961bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com
1971bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com    @Option(names = { "--profile-interval" })
198f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    int profileInterval = 10;
1991bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com
2001bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com    @Option(names = { "--profile-thread-group" })
201f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    boolean profileThreadGroup = false;
2021bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com
203cef780b87ae30112756d40ea3c639a1660fd7c29Nicolas Geoffray    @Option(names = { "--test-only" })
204cef780b87ae30112756d40ea3c639a1660fd7c29Nicolas Geoffray    boolean testOnly = false;
205cef780b87ae30112756d40ea3c639a1660fd7c29Nicolas Geoffray
206fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerally    @Option(names = { "--toolchain" })
2073cdb4296d00bf9294b6d4705e5a7b6742d7e6148Neil Fuller    private String toolchain = "jack";
208fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerally
209207781e883c6e94f65be2bf1c8e653a5928b937cNeil Fuller    @Option(names = { "--language" })
2103cdb4296d00bf9294b6d4705e5a7b6742d7e6148Neil Fuller    Language language = Language.JN;
211207781e883c6e94f65be2bf1c8e653a5928b937cNeil Fuller
212f76a1e929a3ad46e7612a9307efffffc47222cc4Rayhaan Jaufeerally    @Option(names = { "--check-jni" })
213f76a1e929a3ad46e7612a9307efffffc47222cc4Rayhaan Jaufeerally    boolean checkJni = true;
214f76a1e929a3ad46e7612a9307efffffc47222cc4Rayhaan Jaufeerally
2157029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    @VisibleForTesting public Vogar() {}
216d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
217d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    private void printUsage() {
218fc358e65b59087a1fe4e17ff64e23eaf2922b72ejsharpe@google.com        // have to reset fields so that "Default is: FOO" lines are accurate
219fc358e65b59087a1fe4e17ff64e23eaf2922b72ejsharpe@google.com        optionParser.reset();
220fc358e65b59087a1fe4e17ff64e23eaf2922b72ejsharpe@google.com
221d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("Usage: Vogar [options]... <actions>... [-- target args]...");
222d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
223d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  <actions>: .java files, directories, or class names.");
224d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      These should be JUnit tests, jtreg tests, Caliper benchmarks");
225d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      or executable Java classes.");
226d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
22772c9585a2c7535a2a847b8c316d28d875582dc09jsharpe@google.com        System.out.println("      When passing in a JUnit test class, it may have \"#method_name\"");
22872c9585a2c7535a2a847b8c316d28d875582dc09jsharpe@google.com        System.out.println("      appended to it, to specify a single test method.");
22972c9585a2c7535a2a847b8c316d28d875582dc09jsharpe@google.com        System.out.println();
230d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  [args]: arguments passed to the target process. This is only useful when");
231d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      the target process is a Caliper benchmark or main method.");
232d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
233d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("GENERAL OPTIONS");
234d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
2356373ab628b4a93a375b8cfde633229816ba101afRayhaan Jaufeerally        System.out.println("  --mode <activity|device|host|jvm>: specify which environment to run in.");
236d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      activity: runs in an Android application on a device or emulator");
237c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        System.out.println("      device: runs in an ART runtime on a device or emulator");
238c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        System.out.println("      host: runs in an ART runtime on the local desktop built with any lunch combo.");
23979e4231584a3b24b44f42224475d41fcbe957af4jessewilson@google.com        System.out.println("      jvm: runs in a Java VM on the local desktop");
240c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        System.out.println("      Default is: " + modeId);
241c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        System.out.println();
242c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        System.out.println("  --variant <x32>: specify which architecture variant to execute with.");
243c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        System.out.println("      x32: 32-bit");
244c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        System.out.println("      Default is: " + variant);
245d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
2463cdb4296d00bf9294b6d4705e5a7b6742d7e6148Neil Fuller        System.out.println("  --toolchain <jdk|jack>: Which toolchain to use.");
2473cdb4296d00bf9294b6d4705e5a7b6742d7e6148Neil Fuller        System.out.println("      Default is: " + toolchain);
2483cdb4296d00bf9294b6d4705e5a7b6742d7e6148Neil Fuller        System.out.println();
2493cdb4296d00bf9294b6d4705e5a7b6742d7e6148Neil Fuller        System.out.println("  --language <J1_7|JN>: Which language level to use.");
2503cdb4296d00bf9294b6d4705e5a7b6742d7e6148Neil Fuller        System.out.println("      Default is: " + language);
2513cdb4296d00bf9294b6d4705e5a7b6742d7e6148Neil Fuller        System.out.println();
2520eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        System.out.println("  --ssh <host:port>: target a remote machine via SSH.");
2530eb0936e90bf11463c8ee937ca996d7bd654a098jessewilson@google.com        System.out.println();
254d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --clean: synonym for --clean-before and --clean-after (default).");
255d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      Disable with --no-clean if you want no files removed.");
256d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
257d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --stream: stream output as it is emitted.");
258d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
259e5dfbecbaa8568c2885a4cb859c8afa8b6a08d5bjsharpe@google.com        System.out.println("  --benchmark: for use with dalvikvm, this dexes all files together,");
260e5dfbecbaa8568c2885a4cb859c8afa8b6a08d5bjsharpe@google.com        System.out.println("      and is mandatory for running Caliper benchmarks, and a good idea");
261e5dfbecbaa8568c2885a4cb859c8afa8b6a08d5bjsharpe@google.com        System.out.println("      other performance sensitive code.");
262e5dfbecbaa8568c2885a4cb859c8afa8b6a08d5bjsharpe@google.com        System.out.println();
26334b70bff9faaac07abcffa193b05cfb52d6d9908bdc@google.com        System.out.println("  --profile: run with a profiler to produce an hprof file.");
26434b70bff9faaac07abcffa193b05cfb52d6d9908bdc@google.com        System.out.println();
26534b70bff9faaac07abcffa193b05cfb52d6d9908bdc@google.com        System.out.println("  --profile-binary: produce a binary hprof file instead of the default ASCII.");
2661bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println();
2671bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println("  --profile-file <filename>: filename for hprof profile data.");
26834b70bff9faaac07abcffa193b05cfb52d6d9908bdc@google.com        System.out.println("      Default is java.hprof.txt in ASCII mode and java.hprof in binary mode.");
2691bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println();
2701bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println("  --profile-depth <count>: number of frames in profile stack traces.");
2711bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println("      Default is: " + profileDepth);
2721bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println();
2731bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println("  --profile-interval <milliseconds>: interval between profile samples.");
2741bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println("      Default is: " + profileInterval);
2751bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println();
2761bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println("  --profile-thread-group: profile thread group instead of single thread in dalvikvms");
2771bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println("      Note --mode jvm only supports full VM profiling.");
2781bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println("      Default is: " + profileThreadGroup);
2791bdeb9dd8f1ab3f308c285729af007ae8970425bbdc@google.com        System.out.println();
2805b644afaebd7afc43f75010b7c32f02129638a49bdc@google.com        System.out.println("  --invoke-with: provide a command to invoke the VM with. Examples:");
2815b644afaebd7afc43f75010b7c32f02129638a49bdc@google.com        System.out.println("      --mode host --invoke-with \"valgrind --leak-check=full\"");
282fe3edd898b04ad1647a8fe4914a70245c01dc03abdc@google.com        System.out.println("      --mode device --invoke-with \"strace -f -o/sdcard/strace.txt\"");
2835bbc674fa121ae7898bfa6987e7a39c5ba4299e2enh@google.com        System.out.println();
284d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --timeout <seconds>: maximum execution time of each action before the");
285d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      runner aborts it. Specifying zero seconds or using --debug will");
2868c03f5a6370cf6521384a268e12808e163ae4339jessewilson@google.com        System.out.println("      disable the execution timeout. Tests tagged with 'large' will time");
2878c03f5a6370cf6521384a268e12808e163ae4339jessewilson@google.com        System.out.println("      out in " + LARGE_TIMEOUT_MULTIPLIER + "x this timeout.");
288d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      Default is: " + timeoutSeconds);
289d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
290d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --xml-reports-directory <path>: directory to emit JUnit-style");
291d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      XML test results.");
292d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
293d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --classpath <jar file>: add the .jar to both build and execute classpaths.");
294d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
295ba0670d6c4481a866ae558d4e31f8004c709dd77jessewilson@google.com        System.out.println("  --use-bootclasspath: use the classpath as search path for bootstrap classes.");
296d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
297d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --build-classpath <element>: add the directory or .jar to the build");
298d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      classpath. Such classes are available as build dependencies, but");
299d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      not at runtime.");
300d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
301d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --sourcepath <directory>: add the directory to the build sourcepath.");
302d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
303d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("  --vogar-dir <directory>: directory in which to find Vogar");
304f7cb247687b72084b71a434a25d8b3c320071a96jessewilson@google.com        System.out.println("      configuration information, caches, saved and results");
3056a52e048641707c987c6a00691ba8c9f891ccf00jsharpe@google.com        System.out.println("      unless they've been put explicitly elsewhere.");
306d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("      Default is: " + vogarDir);
3074cb68042e7513b3f9444a17d91eb0d92480a74b4jsharpe@google.com        System.out.println();
308d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("  --record-results: record test results for future comparison.");
309d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println();
310d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("  --results-dir <directory>: read and write (if --record-results used)");
311d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("      results from and to this directory.");
312d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println();
313cef780b87ae30112756d40ea3c639a1660fd7c29Nicolas Geoffray        System.out.println("  --test-only: only run JUnit tests.");
314cef780b87ae30112756d40ea3c639a1660fd7c29Nicolas Geoffray        System.out.println("      Default is: " + testOnly);
315cef780b87ae30112756d40ea3c639a1660fd7c29Nicolas Geoffray        System.out.println();
316d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --verbose: turn on persistent verbose output.");
317d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
318f76a1e929a3ad46e7612a9307efffffc47222cc4Rayhaan Jaufeerally        System.out.println("  --check-jni: enable CheckJNI mode.");
319f76a1e929a3ad46e7612a9307efffffc47222cc4Rayhaan Jaufeerally        System.out.println("      See http://developer.android.com/training/articles/perf-jni.html.");
320f76a1e929a3ad46e7612a9307efffffc47222cc4Rayhaan Jaufeerally        System.out.println("      Default is: " + checkJni + ", but disabled for --benchmark.");
321f76a1e929a3ad46e7612a9307efffffc47222cc4Rayhaan Jaufeerally        System.out.println();
322d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("TARGET OPTIONS");
323d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
324d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --debug <port>: enable Java debugging on the specified port.");
325d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      This port must be free both on the device and on the local");
326d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      system. Disables the timeout specified by --timeout-seconds.");
327d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
328328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally        System.out.println("  --debug-app: enable debugging while running in an activity.");
329328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally        System.out.println("      This will require the use of DDMS to connect to the activity");
330328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally        System.out.println("      on the device, and expose the debugger on an appropriate port.");
331328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally        System.out.println();
3323d6e772fe3a0d392af6f6ca008c556ba7c253503bdc@google.com        System.out.println("  --device-dir <directory>: use the specified directory for");
333d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      on-device temporary files and code.");
334d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
335d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --vm-arg <argument>: include the specified argument when spawning a");
336d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      virtual machine. Examples: -Xint:fast, -ea, -Xmx16M");
337d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
338f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com        System.out.println("  --vm-command <argument>: override default vm executable name.");
339c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        System.out.println("      Default is 'java' for the JVM and a version of dalvikvm for the host and target.");
340f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com        System.out.println();
341d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --java-home <java_home>: execute the actions on the local workstation");
342d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      using the specified java home directory. This does not impact");
343d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      which javac gets used. When unset, java is used from the PATH.");
344d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
345d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("EXOTIC OPTIONS");
346d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
3473dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com        System.out.println("  --suggest-classpaths: build an index of jar files under the");
348d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("      directories given by --jar-search-dir arguments. If Vogar then ");
349d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("      fails due to missing classes or packages, it will use the index to");
350d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("      diagnose the problem and suggest a fix.");
3513dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com        System.out.println();
3523dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com        System.out.println("      Currently only looks for jars called exactly \"classes.jar\".");
3533dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com        System.out.println();
354d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("  --jar-search-dir <directory>: a directory that should be searched for");
355d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("      jar files to add to the class file index for use with");
356d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("      --suggest-classpaths.");
357d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println();
358d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --clean-before: remove working directories before building and");
359d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      running (default). Disable with --no-clean-before if you are");
360d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      using interactively with your own temporary input files.");
361d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
362d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --clean-after: remove temporary files after running (default).");
363d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      Disable with --no-clean-after and use with --verbose if");
364d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      you'd like to manually re-run commands afterwards.");
365d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
366d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --color: format output in technicolor.");
367d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
36850bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com        System.out.println("  --pass-color: ANSI color code to use for passes.");
36950bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com        System.out.println("      Default: 32 (green)");
37050bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com        System.out.println();
3715ad56966d0c66ab4b733fe97c4b862f5f85711e8Nicolas Geoffray        System.out.println("  --skip-color: ANSI color code to use for skips.");
37250bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com        System.out.println("      Default: 33 (yellow)");
37350bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com        System.out.println();
3745ad56966d0c66ab4b733fe97c4b862f5f85711e8Nicolas Geoffray        System.out.println("  --warn-color: ANSI color code to use for warnings.");
3755ad56966d0c66ab4b733fe97c4b862f5f85711e8Nicolas Geoffray        System.out.println("      Default: 35 (purple)");
3765ad56966d0c66ab4b733fe97c4b862f5f85711e8Nicolas Geoffray        System.out.println();
37750bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com        System.out.println("  --fail-color: ANSI color code to use for failures.");
37850bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com        System.out.println("      Default: 31 (red)");
37950bd7c43bee5854a7a824265ec224c58c67c698bjsharpe@google.com        System.out.println();
380dc0120df8603b26adfd4ddfbeac422ff99a002b5jessewilson@google.com        System.out.println("  --ansi: use ANSI escape sequences to remove intermediate output.");
3810942355a74d759fb2e50a002b6b0b93430f07d72bdc@google.com        System.out.println();
382d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --expectations <file>: include the specified file when looking for");
383d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      action expectations. The file should include qualified action names");
384d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      and the corresponding expected output.");
385d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      Default is: " + expectationFiles);
386d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
3873dafbce3b8d025f465ebf0a4c6d018c7dc31654ejsharpe@google.com        System.out.println("  --indent: amount to indent action result output. Can be set to ''");
388d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      (aka empty string) to simplify output parsing.");
389d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      Default is: '" + indent + "'");
390d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
391d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("  --javac-arg <argument>: include the specified argument when invoking");
392d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println("      javac. Examples: --javac-arg -Xmaxerrs --javac-arg 1");
393d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        System.out.println();
394f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com        System.out.println("  --dalvik-cache <argument>: override default dalvik-cache location.");
395f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com        System.out.println("      Default is: " + dalvikCache);
396f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com        System.out.println();
397126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com        System.out.println("  --first-monitor-port <port>: the port on the host (and possibly target)");
398126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com        System.out.println("      used to traffic control messages between vogar and forked processes.");
399126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com        System.out.println("      Use this to avoid port conflicts when running multiple vogar instances");
400126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com        System.out.println("      concurrently. Vogar will use up to N ports starting with this one,");
401126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com        System.out.println("      where N is the number of processors on the host (" + NUM_PROCESSORS + "). ");
402126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com        System.out.println();
40334688e44757e5f31838dee7d52106531791fcb43jessewilson@google.com        System.out.println("  --open-bugs-command <command>: a command that will take bug IDs as parameters");
40434688e44757e5f31838dee7d52106531791fcb43jessewilson@google.com        System.out.println("      and return those bugs that are still open. For example, if bugs 123 and");
40534688e44757e5f31838dee7d52106531791fcb43jessewilson@google.com        System.out.println("      789 are both open, the command should echo those values:");
40634688e44757e5f31838dee7d52106531791fcb43jessewilson@google.com        System.out.println("         $ ~/bin/bug-command 123 456 789");
40734688e44757e5f31838dee7d52106531791fcb43jessewilson@google.com        System.out.println("         123");
40834688e44757e5f31838dee7d52106531791fcb43jessewilson@google.com        System.out.println("         789");
40934688e44757e5f31838dee7d52106531791fcb43jessewilson@google.com        System.out.println();
410d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("CONFIG FILE");
411d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println();
412d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("  User-defined default arguments can be specified in ~/.vogarconfig. See");
413d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println("  .vogarconfig.example for an example.");
414d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        System.out.println();
415d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    }
416d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
4177029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    @VisibleForTesting
4187029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    public boolean parseArgs(String[] args) {
419d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        // extract arguments from config file
4207029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        configArgs = OptionParser.readFile(configFile);
421d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com
422d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        // config file args are added first so that in a conflict, the currently supplied
423d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com        // arguments win.
424c7b173425beec5784c669388345eb3b7b96fc341enh@google.com        List<String> actionsAndTargetArgs = optionParser.parse(configArgs);
4258918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com        if (!actionsAndTargetArgs.isEmpty()) {
4268918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com            throw new RuntimeException(
4278918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com                    "actions or targets given in .vogarconfig: " + actionsAndTargetArgs);
4288918b5cafd482363a48e0bc9ae0114028cda7e79jsharpe@google.com        }
429d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com
430d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        try {
431d806c4c900e08bf04e07b5c564f2f61d8c490731jsharpe@google.com            actionsAndTargetArgs.addAll(optionParser.parse(args));
432d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        } catch (RuntimeException e) {
433d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            System.out.println(e.getMessage());
434d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            return false;
435d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        }
436d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
437d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        //
438d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        // Semantic error validation
439d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        //
440d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
441d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        if (javaHome != null && !new File(javaHome, "/bin/java").exists()) {
442d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            System.out.println("Invalid java home: " + javaHome);
443d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            return false;
444d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        }
4457850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
446d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        // check vm option consistency
447c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        if (!modeId.acceptsVmArgs() && !vmArgs.isEmpty()) {
448c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            System.out.println("VM args " + vmArgs + " should not be specified for mode " + modeId);
449c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            return false;
450c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        }
451c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com
452c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        // Check variant / mode compatibility.
453c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        if (!modeId.supportsVariant(variant)) {
454c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            System.out.println("Variant " + variant + " not supported for mode " + modeId);
455d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            return false;
456d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        }
457d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
458d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        if (xmlReportsDirectory != null && !xmlReportsDirectory.isDirectory()) {
459d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            System.out.println("Invalid XML reports directory: " + xmlReportsDirectory);
460d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            return false;
461d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        }
462d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
463d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        if (!clean) {
464d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            cleanBefore = false;
465d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            cleanAfter = false;
466d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        }
4677850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
468d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        //
469d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        // Post-processing arguments
470d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        //
471d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
472f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com        if (vmCommand == null) {
473c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            vmCommand = modeId.defaultVmCommand(variant);
474f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com        }
475f1622c3bd3278fefaab9fa78aca445908362a74abdc@google.com
4768627ce00fa3feb5d0ade63eb1a5ec41bbfad4282enh@google.com        // disable timeout when benchmarking or debugging
4778627ce00fa3feb5d0ade63eb1a5ec41bbfad4282enh@google.com        if (benchmark || debugPort != null) {
478d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            timeoutSeconds = 0;
479d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        }
480d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
481126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com        if (firstMonitorPort == -1) {
482c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            firstMonitorPort = modeId.isLocal() ? 8788 : 8787;
483126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com        }
484126b86dba3853c165e2d2f46e3cdffd7b2bb2f5bjessewilson@google.com
48534b70bff9faaac07abcffa193b05cfb52d6d9908bdc@google.com        if (profileFile == null) {
48634b70bff9faaac07abcffa193b05cfb52d6d9908bdc@google.com            profileFile = new File(profileBinary ? "java.hprof" : "java.hprof.txt");
48734b70bff9faaac07abcffa193b05cfb52d6d9908bdc@google.com        }
48834b70bff9faaac07abcffa193b05cfb52d6d9908bdc@google.com
489d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        // separate the actions and the target args
490d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        int index = 0;
491d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        for (; index < actionsAndTargetArgs.size(); index++) {
492d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            String arg = actionsAndTargetArgs.get(index);
493d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            if (arg.equals("--")) {
494d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com                index++;
495d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com                break;
4967850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com            }
4977850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
498d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            File file = new File(arg);
499d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            if (file.exists()) {
500d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com                if (arg.endsWith(".java") || file.isDirectory()) {
501995a215ce56a98ed522888b0fdc286cd612c0218jessewilson@google.com                    actionFiles.add(file.getAbsoluteFile());
502d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com                } else {
503d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com                    System.out.println("Expected a .jar file, .java file, directory, "
504d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com                            + "package name or classname, but was: " + arg);
505d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com                    return false;
506d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com                }
507d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            } else {
508d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com                actionClassesAndPackages.add(arg);
5097850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com            }
510d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        }
511d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com
512d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        targetArgs.addAll(actionsAndTargetArgs.subList(index, actionsAndTargetArgs.size()));
5137850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
514d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        if (actionFiles.isEmpty() && actionClassesAndPackages.isEmpty()) {
515d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            System.out.println("No actions provided.");
516d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            return false;
5177850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com        }
5187850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
519c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com        if (!modeId.acceptsVmArgs() && !targetArgs.isEmpty()) {
520c620846e4044b3b3a8abfc42ddba4adca4e545d9nfuller@google.com            System.out.println("Target args " + targetArgs + " should not be specified for mode " + modeId);
521d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            return false;
522d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        }
5237850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
524328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally        // Check that jack is setup correctly & check compatibility
525fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerally        if (toolchain.toLowerCase().equals("jack")) {
5267029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin            useJack = true;
527fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerally        } else if (!toolchain.toLowerCase().equals("jdk")) {
528fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerally            System.out.println("The options for toolchain are either jack or jdk.");
529fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerally            return false;
530fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerally        }
531fca99ba6a930cd7a36b1807c0201f49a80cadcf6Rayhaan Jaufeerally
532328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally        if (modeId == ModeId.ACTIVITY && debugPort != null) {
533328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally            System.out.println("Activity debugging requires the use of --debug-app and DDMS.");
534328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally            return false;
535328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally        }
536328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally
537328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally        if (debugApp && modeId != ModeId.ACTIVITY) {
538328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally            System.out.println("--debug-app can only be used in combination with --mode activity.");
539328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally            return false;
540328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally        }
541328ef3e5167b8f08057aecf67fd4a0b353d9358cRayhaan Jaufeerally
542d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        return true;
543d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com    }
5447850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
5457029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    /**
5467029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin     * The type of the target.
5477029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin     */
5487029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    private enum TargetType {
5497029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        ADB(AdbTarget.defaultDeviceDir()),
5507029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        LOCAL(LocalTarget.defaultDeviceDir()),
5517029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        SSH(SshTarget.defaultDeviceDir());
5527029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin
5537029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        /**
5547029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin         * The default device dir.
5557029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin         */
5567029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        private final File defaultDeviceDir;
5577029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin
5587029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        TargetType(File defaultDeviceDir) {
5597029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin            this.defaultDeviceDir = defaultDeviceDir;
5607029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        }
5617029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin
5627029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        public File defaultDeviceDir() {
5637029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin            return defaultDeviceDir;
5647029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        }
5657029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin    }
5667029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin
567f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    private boolean run() throws IOException {
5687029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        // Create a new Console for use by Run.
5697029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        Console console = this.stream
5707029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                ? new Console.StreamingConsole()
5717029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                : new Console.MultiplexingConsole();
5727029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        console.setUseColor(color, passColor, skipColor, failColor, warnColor);
5737029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        console.setAnsi(ansi);
5747029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        console.setIndent(indent);
5757029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        console.setVerbose(verbose);
5767029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin
5777029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        Mkdir mkdir = new Mkdir(console);
5787029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        Rm rm = new Rm(console);
5797029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin
5807029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        // Select the target type, this is needed in order to calculate the runnerDir, which is in
5817029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        // turn needed for creating the AdbTarget below.
5827029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        TargetType targetType;
5837029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        if (sshHost != null) {
5847029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin            targetType = TargetType.SSH;
5857029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        } else if (modeId.isLocal()) {
5867029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin            targetType = TargetType.LOCAL;
5877029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        } else {
5887029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin            targetType = TargetType.ADB;
5897029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        }
5907029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin
5917029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        File runnerDir = deviceDir != null
5927029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                ? new File(deviceDir, "run")
5937029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                : new File(targetType.defaultDeviceDir(), "run");
5947029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin
5957029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        // Create the target.
5967029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        Target target;
5977029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        switch (targetType) {
5987029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin            case ADB:
5997029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                DeviceFilesystem deviceFilesystem =
6007029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                        new DeviceFilesystem(console, ImmutableList.of("adb", "shell"));
6017029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                DeviceFileCache deviceFileCache =
6027029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                        new DeviceFileCache(console, runnerDir, deviceFilesystem);
6037029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                target = new AdbTarget(console, deviceFilesystem, deviceFileCache);
6047029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                break;
6057029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin            case SSH:
6067029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                target = new SshTarget(console, sshHost);
6077029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                break;
6087029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin            case LOCAL:
6097029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                target = new LocalTarget(console, mkdir, rm);
6107029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                break;
6117029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin            default:
6127029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin                throw new IllegalStateException("Unknown target type: " + targetType);
6137029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        }
6147029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin
6157029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        AndroidSdk androidSdk = null;
6167029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        if (modeId.requiresAndroidSdk()) {
6177029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin            androidSdk = AndroidSdk.createAndroidSdk(console, mkdir, modeId, useJack);
6187029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        }
6197029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin
6207029503206e4c89fe167c3389c1062d89cf35c52Paul Duffin        Run run = new Run(this, useJack, console, mkdir, androidSdk, rm, target, runnerDir);
621c7b173425beec5784c669388345eb3b7b96fc341enh@google.com        if (configArgs.length > 0) {
622c7b173425beec5784c669388345eb3b7b96fc341enh@google.com            run.console.verbose("loaded arguments from .vogarconfig: " +
6232f7dda9ade5ebaba54984c09f30d13226a295c86Nicolas Geoffray                                Strings.join(" ", (Object)configArgs));
624c7b173425beec5784c669388345eb3b7b96fc341enh@google.com        }
625f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com        return run.driver.buildAndRun(actionFiles, actionClassesAndPackages);
6267850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com    }
6277850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com
628f83be5e4273263df2bb9ef609946b911695b3996jessewilson@google.com    public static void main(String[] args) throws IOException {
6297850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com        Vogar vogar = new Vogar();
630d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com        if (!vogar.parseArgs(args)) {
631d0944e3ecda89a97ac35537e280b2776b53c25ecjessewilson@google.com            vogar.printUsage();
63206f9cc5c1a455157ff325c64d89acd1aade05f34Nicolas Geoffray            System.exit(1);
6337850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com        }
63475a72cc4c645e7e038f381c936d3f521ac6c30adbdc@google.com        boolean allSuccess = vogar.run();
63575a72cc4c645e7e038f381c936d3f521ac6c30adbdc@google.com        System.exit(allSuccess ? 0 : 1);
6367850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com    }
6377850f3f3da0099b76f09ed64d23e0a43ba4a5c76jessewilson@google.com}
638