auto import from //branches/cupcake/...@125939
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="tests"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/SdkUiLib"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
@@ -0,0 +1,580 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.sdkmanager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* Parses the command-line and stores flags needed or requested.
|
||||
* <p/>
|
||||
* This is a base class. To be useful you want to:
|
||||
* <ul>
|
||||
* <li>override it.
|
||||
* <li>pass an action array to the constructor.
|
||||
* <li>define flags for your actions.
|
||||
* </ul>
|
||||
* <p/>
|
||||
* To use, call {@link #parseArgs(String[])} and then call {@link #getValue(String, String)}.
|
||||
*/
|
||||
public class CommandLineProcessor {
|
||||
|
||||
/** Internal action name for all global flags. */
|
||||
public final static String GLOBAL_FLAG = "global";
|
||||
/** Internal action name for internally hidden flags.
|
||||
* This is currently used to store the requested action name. */
|
||||
public final static String INTERNAL_FLAG = "internal";
|
||||
|
||||
/** The global help flag. */
|
||||
public static final String KEY_HELP = "help";
|
||||
/** The global verbose flag. */
|
||||
public static final String KEY_VERBOSE = "verbose";
|
||||
/** The internal action flag. */
|
||||
public static final String KEY_ACTION = "action";
|
||||
|
||||
/** List of available actions.
|
||||
* <p/>
|
||||
* Each entry must be a 2-string array with first the action name and then
|
||||
* a description.
|
||||
*/
|
||||
private final String[][] mActions;
|
||||
/** The hash of all defined arguments.
|
||||
* <p/>
|
||||
* The key is a string "action/longName".
|
||||
*/
|
||||
private final HashMap<String, Arg> mArguments = new HashMap<String, Arg>();
|
||||
|
||||
public CommandLineProcessor(String[][] actions) {
|
||||
mActions = actions;
|
||||
|
||||
define(MODE.STRING, false, INTERNAL_FLAG, null, KEY_ACTION, "Selected Action", null);
|
||||
|
||||
define(MODE.BOOLEAN, false, GLOBAL_FLAG, "v", KEY_VERBOSE, "Verbose mode", false);
|
||||
define(MODE.BOOLEAN, false, GLOBAL_FLAG, "h", KEY_HELP, "This help", false);
|
||||
}
|
||||
|
||||
//------------------
|
||||
// Helpers to get flags values
|
||||
|
||||
/** Helper that returns true if --verbose was requested. */
|
||||
public boolean isVerbose() {
|
||||
return ((Boolean) getValue(GLOBAL_FLAG, KEY_VERBOSE)).booleanValue();
|
||||
}
|
||||
|
||||
/** Helper that returns true if --help was requested. */
|
||||
public boolean isHelpRequested() {
|
||||
return ((Boolean) getValue(GLOBAL_FLAG, KEY_HELP)).booleanValue();
|
||||
}
|
||||
|
||||
/** Helper that returns the requested action name. */
|
||||
public String getActionRequested() {
|
||||
return (String) getValue(INTERNAL_FLAG, KEY_ACTION);
|
||||
}
|
||||
|
||||
//------------------
|
||||
|
||||
/**
|
||||
* Raw access to parsed parameter values.
|
||||
* @param action The action name, including {@link #GLOBAL_FLAG} and {@link #INTERNAL_FLAG}
|
||||
* @param longFlagName The long flag name for the given action.
|
||||
* @return The current value object stored in the parameter, which depends on the argument mode.
|
||||
*/
|
||||
public Object getValue(String action, String longFlagName) {
|
||||
String key = action + "/" + longFlagName;
|
||||
Arg arg = mArguments.get(key);
|
||||
return arg.getCurrentValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal setter for raw parameter value.
|
||||
* @param action The action name, including {@link #GLOBAL_FLAG} and {@link #INTERNAL_FLAG}
|
||||
* @param longFlagName The long flag name for the given action.
|
||||
* @param value The new current value object stored in the parameter, which depends on the
|
||||
* argument mode.
|
||||
*/
|
||||
protected void setValue(String action, String longFlagName, Object value) {
|
||||
String key = action + "/" + longFlagName;
|
||||
Arg arg = mArguments.get(key);
|
||||
arg.setCurrentValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the command-line arguments.
|
||||
* <p/>
|
||||
* This method will exit and not return if a parsing error arise.
|
||||
*
|
||||
* @param args The arguments typically received by a main method.
|
||||
*/
|
||||
public void parseArgs(String[] args) {
|
||||
String needsHelp = null;
|
||||
String action = null;
|
||||
|
||||
int n = args.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
Arg arg = null;
|
||||
String a = args[i];
|
||||
if (a.startsWith("--")) {
|
||||
arg = findLongArg(action, a.substring(2));
|
||||
} else if (a.startsWith("-")) {
|
||||
arg = findShortArg(action, a.substring(1));
|
||||
}
|
||||
|
||||
// Not a keyword and we don't have an action yet, this should be an action
|
||||
if (arg == null && action == null) {
|
||||
|
||||
if (a.startsWith("-")) {
|
||||
// Got a keyword but not valid for global flags
|
||||
needsHelp = String.format(
|
||||
"Flag '%1$s' is not a valid global flag. Did you mean to specify it after the action name?",
|
||||
a, action);
|
||||
break;
|
||||
}
|
||||
|
||||
for (String[] actionDesc : mActions) {
|
||||
if (actionDesc[0].equals(a)) {
|
||||
action = a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (action == null) {
|
||||
needsHelp = String.format(
|
||||
"Expected action name after global parameters but found %1$s instead.",
|
||||
a);
|
||||
break;
|
||||
}
|
||||
} else if (arg == null && action != null) {
|
||||
// Got a keyword but not valid for the current action
|
||||
needsHelp = String.format(
|
||||
"Flag '%1$s' is not valid for action '%2$s'.",
|
||||
a, action);
|
||||
break;
|
||||
|
||||
} else if (arg != null) {
|
||||
// Process keyword
|
||||
String error = null;
|
||||
if (arg.getMode().needsExtra()) {
|
||||
if (++i >= n) {
|
||||
needsHelp = String.format("Missing argument for flag %1$s.", a);
|
||||
break;
|
||||
}
|
||||
|
||||
error = arg.getMode().process(arg, args[i]);
|
||||
} else {
|
||||
error = arg.getMode().process(arg, null);
|
||||
|
||||
// If we just toggled help, we want to exit now without printing any error.
|
||||
// We do this test here only when a Boolean flag is toggled since booleans
|
||||
// are the only flags that don't take parameters and help is a boolean.
|
||||
if (isHelpRequested()) {
|
||||
printHelpAndExit(null);
|
||||
// The call above should terminate however in unit tests we override
|
||||
// it so we still need to return here.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (error != null) {
|
||||
needsHelp = String.format("Invalid usage for flag %1$s: %2$s.", a, error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needsHelp == null) {
|
||||
if (action == null) {
|
||||
needsHelp = "Missing action name.";
|
||||
} else {
|
||||
// Validate that all mandatory arguments are non-null for this action
|
||||
for (Entry<String, Arg> entry : mArguments.entrySet()) {
|
||||
Arg arg = entry.getValue();
|
||||
if (arg.getAction().equals(action)) {
|
||||
if (arg.isMandatory() && arg.getCurrentValue() == null) {
|
||||
needsHelp = String.format("The parameter --%1$s must be defined for action '%2$s'",
|
||||
arg.getLongArg(),
|
||||
action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setValue(INTERNAL_FLAG, KEY_ACTION, action);
|
||||
}
|
||||
}
|
||||
|
||||
if (needsHelp != null) {
|
||||
printHelpAndExitForAction(action, needsHelp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an {@link Arg} given an action name and a long flag name.
|
||||
* @return The {@link Arg} found or null.
|
||||
*/
|
||||
protected Arg findLongArg(String action, String longName) {
|
||||
if (action == null) {
|
||||
action = GLOBAL_FLAG;
|
||||
}
|
||||
String key = action + "/" + longName;
|
||||
return mArguments.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an {@link Arg} given an action name and a short flag name.
|
||||
* @return The {@link Arg} found or null.
|
||||
*/
|
||||
protected Arg findShortArg(String action, String shortName) {
|
||||
if (action == null) {
|
||||
action = GLOBAL_FLAG;
|
||||
}
|
||||
|
||||
for (Entry<String, Arg> entry : mArguments.entrySet()) {
|
||||
Arg arg = entry.getValue();
|
||||
if (arg.getAction().equals(action)) {
|
||||
if (shortName.equals(arg.getShortArg())) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the help/usage and exits.
|
||||
*
|
||||
* @param errorFormat Optional error message to print prior to usage using String.format
|
||||
* @param args Arguments for String.format
|
||||
*/
|
||||
public void printHelpAndExit(String errorFormat, Object... args) {
|
||||
printHelpAndExitForAction(null /*actionFilter*/, errorFormat, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the help/usage and exits.
|
||||
*
|
||||
* @param actionFilter If null, displays help for all actions. If not null, display help only
|
||||
* for that specific action. In all cases also display general usage and action list.
|
||||
* @param errorFormat Optional error message to print prior to usage using String.format
|
||||
* @param args Arguments for String.format
|
||||
*/
|
||||
public void printHelpAndExitForAction(String actionFilter, String errorFormat, Object... args) {
|
||||
if (errorFormat != null) {
|
||||
stderr(errorFormat, args);
|
||||
}
|
||||
|
||||
/*
|
||||
* usage should fit in 80 columns
|
||||
* 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
*/
|
||||
stdout("\n" +
|
||||
"Usage:\n" +
|
||||
" android [global options] action [action options]\n" +
|
||||
"\n" +
|
||||
"Global options:");
|
||||
listOptions(GLOBAL_FLAG);
|
||||
|
||||
stdout("\nValid actions:");
|
||||
for (String[] action : mActions) {
|
||||
String filler = "";
|
||||
int len = action[0].length();
|
||||
if (len < 10) {
|
||||
filler = " ".substring(len);
|
||||
}
|
||||
|
||||
stdout("- %1$s:%2$s %3$s", action[0], filler, action[1]);
|
||||
}
|
||||
|
||||
for (String[] action : mActions) {
|
||||
if (actionFilter == null || actionFilter.equals(action[0])) {
|
||||
stdout("\nAction \"%1$s\":", action[0]);
|
||||
stdout(" %1$s", action[1]);
|
||||
stdout("Options:");
|
||||
listOptions(action[0]);
|
||||
}
|
||||
}
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal helper to print all the option flags for a given action name.
|
||||
*/
|
||||
protected void listOptions(String action) {
|
||||
int numOptions = 0;
|
||||
for (Entry<String, Arg> entry : mArguments.entrySet()) {
|
||||
Arg arg = entry.getValue();
|
||||
if (arg.getAction().equals(action)) {
|
||||
|
||||
String value = null;
|
||||
if (arg.getDefaultValue() instanceof String[]) {
|
||||
value = "";
|
||||
for (String v : (String[]) arg.getDefaultValue()) {
|
||||
if (value.length() > 0) {
|
||||
value += "|";
|
||||
}
|
||||
value += v;
|
||||
}
|
||||
} else if (arg.getDefaultValue() != null) {
|
||||
value = arg.getDefaultValue().toString();
|
||||
}
|
||||
|
||||
stdout(" -%1$s %2$-10s %3$s%4$s",
|
||||
arg.getShortArg(),
|
||||
"--" + arg.getLongArg(),
|
||||
arg.getDescription(),
|
||||
value == null ? "" : " (" + value + ")");
|
||||
numOptions++;
|
||||
}
|
||||
}
|
||||
|
||||
if (numOptions == 0) {
|
||||
stdout(" No options");
|
||||
}
|
||||
}
|
||||
|
||||
//----
|
||||
|
||||
/**
|
||||
* The mode of an argument specifies the type of variable it represents,
|
||||
* whether an extra parameter is required after the flag and how to parse it.
|
||||
*/
|
||||
static enum MODE {
|
||||
/** Argument value is a Boolean. Default value is a Boolean. */
|
||||
BOOLEAN {
|
||||
@Override
|
||||
public boolean needsExtra() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public String process(Arg arg, String extra) {
|
||||
// Toggle the current value
|
||||
arg.setCurrentValue(! ((Boolean) arg.getCurrentValue()).booleanValue());
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/** Argument value is an Integer. Default value is an Integer. */
|
||||
INTEGER {
|
||||
@Override
|
||||
public boolean needsExtra() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String process(Arg arg, String extra) {
|
||||
try {
|
||||
arg.setCurrentValue(Integer.parseInt(extra));
|
||||
return null;
|
||||
} catch (NumberFormatException e) {
|
||||
return String.format("Failed to parse '%1$s' as an integer: %2%s",
|
||||
extra, e.getMessage());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/** Argument value is a String. Default value is a String[]. */
|
||||
ENUM {
|
||||
@Override
|
||||
public boolean needsExtra() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String process(Arg arg, String extra) {
|
||||
StringBuilder desc = new StringBuilder();
|
||||
String[] values = (String[]) arg.getDefaultValue();
|
||||
for (String value : values) {
|
||||
if (value.equals(extra)) {
|
||||
arg.setCurrentValue(extra);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (desc.length() != 0) {
|
||||
desc.append(", ");
|
||||
}
|
||||
desc.append(value);
|
||||
}
|
||||
|
||||
return String.format("'%1$s' is not one of %2$s", extra, desc.toString());
|
||||
}
|
||||
},
|
||||
|
||||
/** Argument value is a String. Default value is a null. */
|
||||
STRING {
|
||||
@Override
|
||||
public boolean needsExtra() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String process(Arg arg, String extra) {
|
||||
arg.setCurrentValue(extra);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if this mode requires an extra parameter.
|
||||
*/
|
||||
public abstract boolean needsExtra();
|
||||
|
||||
/**
|
||||
* Processes the flag for this argument.
|
||||
*
|
||||
* @param arg The argument being processed.
|
||||
* @param extra The extra parameter. Null if {@link #needsExtra()} returned false.
|
||||
* @return An error string or null if there's no error.
|
||||
*/
|
||||
public abstract String process(Arg arg, String extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument accepted by the command-line, also called "a flag".
|
||||
* Arguments must have a short version (one letter), a long version name and a description.
|
||||
* They can have a default value, or it can be null.
|
||||
* Depending on the {@link MODE}, the default value can be a Boolean, an Integer, a String
|
||||
* or a String array (in which case the first item is the current by default.)
|
||||
*/
|
||||
static class Arg {
|
||||
private final String mAction;
|
||||
private final String mShortName;
|
||||
private final String mLongName;
|
||||
private final String mDescription;
|
||||
private final Object mDefaultValue;
|
||||
private Object mCurrentValue;
|
||||
private final MODE mMode;
|
||||
private final boolean mMandatory;
|
||||
|
||||
/**
|
||||
* Creates a new argument flag description.
|
||||
*
|
||||
* @param mode The {@link MODE} for the argument.
|
||||
* @param mandatory True if this argument is mandatory for this action.
|
||||
* @param action The action name. Can be #GLOBAL_FLAG or #INTERNAL_FLAG.
|
||||
* @param shortName The one-letter short argument name. Cannot be empty nor null.
|
||||
* @param longName The long argument name. Cannot be empty nor null.
|
||||
* @param description The description. Cannot be null.
|
||||
* @param defaultValue The default value (or values), which depends on the selected {@link MODE}.
|
||||
*/
|
||||
public Arg(MODE mode,
|
||||
boolean mandatory,
|
||||
String action,
|
||||
String shortName,
|
||||
String longName,
|
||||
String description,
|
||||
Object defaultValue) {
|
||||
mMode = mode;
|
||||
mMandatory = mandatory;
|
||||
mAction = action;
|
||||
mShortName = shortName;
|
||||
mLongName = longName;
|
||||
mDescription = description;
|
||||
mDefaultValue = defaultValue;
|
||||
if (defaultValue instanceof String[]) {
|
||||
mCurrentValue = ((String[])defaultValue)[0];
|
||||
} else {
|
||||
mCurrentValue = mDefaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMandatory() {
|
||||
return mMandatory;
|
||||
}
|
||||
|
||||
public String getShortArg() {
|
||||
return mShortName;
|
||||
}
|
||||
|
||||
public String getLongArg() {
|
||||
return mLongName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return mAction;
|
||||
}
|
||||
|
||||
public Object getDefaultValue() {
|
||||
return mDefaultValue;
|
||||
}
|
||||
|
||||
public Object getCurrentValue() {
|
||||
return mCurrentValue;
|
||||
}
|
||||
|
||||
public void setCurrentValue(Object currentValue) {
|
||||
mCurrentValue = currentValue;
|
||||
}
|
||||
|
||||
public MODE getMode() {
|
||||
return mMode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal helper to define a new argument for a give action.
|
||||
*
|
||||
* @param mode The {@link MODE} for the argument.
|
||||
* @param action The action name. Can be #GLOBAL_FLAG or #INTERNAL_FLAG.
|
||||
* @param shortName The one-letter short argument name. Cannot be empty nor null.
|
||||
* @param longName The long argument name. Cannot be empty nor null.
|
||||
* @param description The description. Cannot be null.
|
||||
* @param defaultValue The default value (or values), which depends on the selected {@link MODE}.
|
||||
*/
|
||||
protected void define(MODE mode,
|
||||
boolean mandatory,
|
||||
String action,
|
||||
String shortName, String longName,
|
||||
String description, Object defaultValue) {
|
||||
assert(mandatory || mode == MODE.BOOLEAN); // a boolean mode cannot be mandatory
|
||||
|
||||
String key = action + "/" + longName;
|
||||
mArguments.put(key, new Arg(mode, mandatory,
|
||||
action, shortName, longName, description, defaultValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exits in case of error.
|
||||
* This is protected so that it can be overridden in unit tests.
|
||||
*/
|
||||
protected void exit() {
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a line to stdout.
|
||||
* This is protected so that it can be overridden in unit tests.
|
||||
*
|
||||
* @param format The string to be formatted. Cannot be null.
|
||||
* @param args Format arguments.
|
||||
*/
|
||||
protected void stdout(String format, Object...args) {
|
||||
System.out.println(String.format(format, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a line to stderr.
|
||||
* This is protected so that it can be overridden in unit tests.
|
||||
*
|
||||
* @param format The string to be formatted. Cannot be null.
|
||||
* @param args Format arguments.
|
||||
*/
|
||||
protected void stderr(String format, Object...args) {
|
||||
System.err.println(String.format(format, args));
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ import com.android.sdklib.ISdkLog;
|
||||
import com.android.sdklib.SdkConstants;
|
||||
import com.android.sdklib.SdkManager;
|
||||
import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
|
||||
import com.android.sdklib.project.ProjectCreator;
|
||||
import com.android.sdklib.project.ProjectCreator.OutputLevel;
|
||||
import com.android.sdklib.vm.HardwareProperties;
|
||||
import com.android.sdklib.vm.VmManager;
|
||||
import com.android.sdklib.vm.HardwareProperties.HardwareProperty;
|
||||
@@ -35,31 +37,20 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Main class for the 'android' application
|
||||
*
|
||||
* Main class for the 'android' application.
|
||||
*/
|
||||
class Main {
|
||||
|
||||
private final static String TOOLSDIR = "com.android.sdkmanager.toolsdir";
|
||||
|
||||
private final static String ARG_LIST_TARGET = "target";
|
||||
private final static String ARG_LIST_VM = "vm";
|
||||
|
||||
private final static String[] BOOLEAN_YES_REPLIES = new String[] { "yes", "y" };
|
||||
private final static String[] BOOLEAN_NO_REPLIES = new String[] { "no", "n" };
|
||||
|
||||
private String mSdkFolder;
|
||||
private ISdkLog mSdkLog;
|
||||
private SdkManager mSdkManager;
|
||||
private VmManager mVmManager;
|
||||
|
||||
/* --list parameters */
|
||||
private String mListObject;
|
||||
|
||||
/* --create parameters */
|
||||
private boolean mCreateVm;
|
||||
private int mCreateTargetId;
|
||||
private IAndroidTarget mCreateTarget;
|
||||
private String mCreateName;
|
||||
private SdkCommandLine mSdkCommandLine;
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Main().run(args);
|
||||
@@ -71,7 +62,7 @@ class Main {
|
||||
*/
|
||||
private void run(String[] args) {
|
||||
init();
|
||||
parseArgs(args);
|
||||
mSdkCommandLine.parseArgs(args);
|
||||
parseSdk();
|
||||
doAction();
|
||||
}
|
||||
@@ -81,70 +72,41 @@ class Main {
|
||||
* doing basic parsing of the SDK.
|
||||
*/
|
||||
private void init() {
|
||||
mSdkCommandLine = new SdkCommandLine();
|
||||
|
||||
/* We get passed a property for the tools dir */
|
||||
String toolsDirProp = System.getProperty(TOOLSDIR);
|
||||
if (toolsDirProp == null) {
|
||||
// for debugging, it's easier to override using the process environment
|
||||
toolsDirProp = System.getenv(TOOLSDIR);
|
||||
}
|
||||
if (toolsDirProp == null) {
|
||||
printHelpAndExit("ERROR: The tools directory property is not set, please make sure you are executing android or android.bat");
|
||||
}
|
||||
|
||||
// got back a level for the SDK folder
|
||||
File tools = new File(toolsDirProp);
|
||||
mSdkFolder = tools.getParent();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses command-line arguments, or prints help/usage and exits if error.
|
||||
* @param args arguments passed to the program
|
||||
*/
|
||||
private void parseArgs(String[] args) {
|
||||
final int numArgs = args.length;
|
||||
|
||||
try {
|
||||
int argPos = 0;
|
||||
for (; argPos < numArgs; argPos++) {
|
||||
final String arg = args[argPos];
|
||||
if (arg.equals("-l") || arg.equals("--list")) {
|
||||
mListObject = args[++argPos];
|
||||
} else if (arg.equals("-c") || arg.equals("--create")) {
|
||||
mCreateVm = true;
|
||||
parseCreateArgs(args, ++argPos);
|
||||
if (toolsDirProp != null) {
|
||||
// got back a level for the SDK folder
|
||||
File tools;
|
||||
if (toolsDirProp.length() > 0) {
|
||||
tools = new File(toolsDirProp);
|
||||
mSdkFolder = tools.getParent();
|
||||
} else {
|
||||
try {
|
||||
tools = new File(".").getCanonicalFile();
|
||||
mSdkFolder = tools.getParent();
|
||||
} catch (IOException e) {
|
||||
// Will print an error below since mSdkFolder is not defined
|
||||
}
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
/* Any OOB triggers help */
|
||||
printHelpAndExit("ERROR: Not enough arguments.");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseCreateArgs(String[] args, int argPos) {
|
||||
final int numArgs = args.length;
|
||||
|
||||
try {
|
||||
for (; argPos < numArgs; argPos++) {
|
||||
final String arg = args[argPos];
|
||||
if (arg.equals("-t") || arg.equals("--target")) {
|
||||
String targetId = args[++argPos];
|
||||
try {
|
||||
// get the target id
|
||||
mCreateTargetId = Integer.parseInt(targetId);
|
||||
} catch (NumberFormatException e) {
|
||||
printHelpAndExit("ERROR: Target Id is not a number");
|
||||
}
|
||||
} else if (arg.equals("-n") || arg.equals("--name")) {
|
||||
mCreateName = args[++argPos];
|
||||
} else {
|
||||
printHelpAndExit("ERROR: '%s' unknown argument for --create mode",
|
||||
args[argPos]);
|
||||
}
|
||||
if (mSdkFolder == null) {
|
||||
String os = System.getProperty("os.name");
|
||||
String cmd = "android";
|
||||
if (os.startsWith("Windows")) {
|
||||
cmd += ".bat";
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
/* Any OOB triggers help */
|
||||
printHelpAndExit("ERROR: Not enough arguments for --create");
|
||||
|
||||
mSdkCommandLine.printHelpAndExit(
|
||||
"ERROR: The tools directory property is not set, please make sure you are executing %1$s",
|
||||
cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,10 +114,15 @@ class Main {
|
||||
* Does the basic SDK parsing required for all actions
|
||||
*/
|
||||
private void parseSdk() {
|
||||
mSdkManager = SdkManager.createManager(mSdkFolder, new ISdkLog() {
|
||||
public void error(String errorFormat, Object... args) {
|
||||
System.err.printf("Error: " + errorFormat, args);
|
||||
System.err.println("");
|
||||
mSdkLog = new ISdkLog() {
|
||||
public void error(Throwable t, String errorFormat, Object... args) {
|
||||
if (errorFormat != null) {
|
||||
System.err.printf("Error: " + errorFormat, args);
|
||||
System.err.println("");
|
||||
}
|
||||
if (t != null) {
|
||||
System.err.print("Error: " + t.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void warning(String warningFormat, Object... args) {
|
||||
@@ -165,10 +132,15 @@ class Main {
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
public void printf(String msgFormat, Object... args) {
|
||||
System.out.printf(msgFormat, args);
|
||||
}
|
||||
};
|
||||
mSdkManager = SdkManager.createManager(mSdkFolder, mSdkLog);
|
||||
|
||||
if (mSdkManager == null) {
|
||||
printHelpAndExit("ERROR: Unable to parse SDK content.");
|
||||
mSdkCommandLine.printHelpAndExit("ERROR: Unable to parse SDK content.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,19 +148,37 @@ class Main {
|
||||
* Actually do an action...
|
||||
*/
|
||||
private void doAction() {
|
||||
if (mListObject != null) {
|
||||
String action = mSdkCommandLine.getActionRequested();
|
||||
|
||||
if (SdkCommandLine.ACTION_LIST.equals(action)) {
|
||||
// list action.
|
||||
if (ARG_LIST_TARGET.equals(mListObject)) {
|
||||
if (SdkCommandLine.ARG_TARGET.equals(mSdkCommandLine.getListFilter())) {
|
||||
displayTargetList();
|
||||
} else if (ARG_LIST_VM.equals(mListObject)) {
|
||||
} else if (SdkCommandLine.ARG_VM.equals(mSdkCommandLine.getListFilter())) {
|
||||
displayVmList();
|
||||
} else {
|
||||
printHelpAndExit("'%s' is not a valid --list option", mListObject);
|
||||
displayTargetList();
|
||||
displayVmList();
|
||||
}
|
||||
} else if (mCreateVm) {
|
||||
} else if (SdkCommandLine.ACTION_NEW_VM.equals(action)) {
|
||||
createVm();
|
||||
} else if (SdkCommandLine.ACTION_NEW_PROJECT.equals(action)) {
|
||||
// get the target and try to resolve it.
|
||||
int targetId = mSdkCommandLine.getNewProjectTargetId();
|
||||
IAndroidTarget[] targets = mSdkManager.getTargets();
|
||||
if (targetId < 1 || targetId > targets.length) {
|
||||
mSdkCommandLine.printHelpAndExit("ERROR: Wrong target id.");
|
||||
}
|
||||
IAndroidTarget target = targets[targetId - 1];
|
||||
|
||||
ProjectCreator creator = new ProjectCreator(mSdkFolder,
|
||||
OutputLevel.NORMAL, mSdkLog);
|
||||
|
||||
creator.createProject(mSdkCommandLine.getNewProjectLocation(),
|
||||
mSdkCommandLine.getNewProjectName(), mSdkCommandLine.getNewProjectPackage(),
|
||||
mSdkCommandLine.getNewProjectActivity(), target, true);
|
||||
} else {
|
||||
printHelpAndExit(null);
|
||||
mSdkCommandLine.printHelpAndExit(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +264,7 @@ class Main {
|
||||
index++;
|
||||
}
|
||||
} catch (AndroidLocationException e) {
|
||||
printHelpAndExit(e.getMessage());
|
||||
mSdkCommandLine.printHelpAndExit(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,11 +273,14 @@ class Main {
|
||||
*/
|
||||
private void createVm() {
|
||||
// find a matching target
|
||||
if (mCreateTargetId >= 1 && mCreateTargetId <= mSdkManager.getTargets().length) {
|
||||
mCreateTarget = mSdkManager.getTargets()[mCreateTargetId-1]; // target it is 1-based
|
||||
int targetId = mSdkCommandLine.getNewVmTargetId();
|
||||
IAndroidTarget target = null;
|
||||
|
||||
if (targetId >= 1 && targetId <= mSdkManager.getTargets().length) {
|
||||
target = mSdkManager.getTargets()[targetId-1]; // target it is 1-based
|
||||
} else {
|
||||
printHelpAndExit(
|
||||
"ERROR: Target Id is not a valid Id. Check android --list target for the list of targets.");
|
||||
mSdkCommandLine.printHelpAndExit(
|
||||
"ERROR: Target Id is not a valid Id. Check 'android list target' for the list of targets.");
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -295,19 +288,24 @@ class Main {
|
||||
String vmRoot = AndroidLocation.getFolder() + AndroidLocation.FOLDER_VMS;
|
||||
|
||||
Map<String, String> hardwareConfig = null;
|
||||
if (mCreateTarget.isPlatform()) {
|
||||
if (target.isPlatform()) {
|
||||
try {
|
||||
hardwareConfig = promptForHardware(mCreateTarget);
|
||||
hardwareConfig = promptForHardware(target);
|
||||
} catch (IOException e) {
|
||||
printHelpAndExit(e.getMessage());
|
||||
mSdkCommandLine.printHelpAndExit(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
VmManager.createVm(vmRoot, mCreateName, mCreateTarget, null /*skinName*/,
|
||||
null /*sdcardPath*/, 0 /*sdcardSize*/, hardwareConfig,
|
||||
VmManager.createVm(vmRoot,
|
||||
mSdkCommandLine.getNewVmName(),
|
||||
target,
|
||||
null /*skinName*/,
|
||||
null /*sdcardPath*/,
|
||||
0 /*sdcardSize*/,
|
||||
hardwareConfig,
|
||||
null /* sdklog */);
|
||||
} catch (AndroidLocationException e) {
|
||||
printHelpAndExit(e.getMessage());
|
||||
mSdkCommandLine.printHelpAndExit(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +323,7 @@ class Main {
|
||||
System.out.print(String.format("Do you which to create a custom hardware profile [%s]",
|
||||
defaultAnswer));
|
||||
|
||||
result = readLine(readLineBuffer);
|
||||
result = readLine(readLineBuffer).trim();
|
||||
// handle default:
|
||||
if (result.length() == 0) {
|
||||
result = defaultAnswer;
|
||||
@@ -391,8 +389,7 @@ class Main {
|
||||
break;
|
||||
case INTEGER:
|
||||
try {
|
||||
@SuppressWarnings("unused")
|
||||
int value = Integer.parseInt(result);
|
||||
Integer.parseInt(result);
|
||||
map.put(property.getName(), result);
|
||||
i++; // valid reply, move to next property
|
||||
} catch (NumberFormatException e) {
|
||||
@@ -414,9 +411,8 @@ class Main {
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the line from the input stream.
|
||||
* Reads the line from the input stream.
|
||||
* @param buffer
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private String readLine(byte[] buffer) throws IOException {
|
||||
@@ -434,7 +430,12 @@ class Main {
|
||||
return new String(buffer, 0, count) + secondHalf;
|
||||
}
|
||||
|
||||
return new String(buffer, 0, count - 1); // -1 to not include the carriage return
|
||||
// ignore end whitespace
|
||||
while (count > 0 && (buffer[count-1] == '\r' || buffer[count-1] == '\n')) {
|
||||
count--;
|
||||
}
|
||||
|
||||
return new String(buffer, 0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -442,6 +443,7 @@ class Main {
|
||||
* @throws IOException If the value is not a boolean string.
|
||||
*/
|
||||
private boolean getBooleanReply(String reply) throws IOException {
|
||||
|
||||
for (String valid : BOOLEAN_YES_REPLIES) {
|
||||
if (valid.equalsIgnoreCase(reply)) {
|
||||
return true;
|
||||
@@ -456,32 +458,4 @@ class Main {
|
||||
|
||||
throw new IOException(String.format("%s is not a valid reply", reply));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the help/usage and exits.
|
||||
* @param errorFormat Optional error message to print prior to usage using String.format
|
||||
* @param args Arguments for String.format
|
||||
*/
|
||||
private void printHelpAndExit(String errorFormat, Object... args) {
|
||||
if (errorFormat != null) {
|
||||
System.err.println(String.format(errorFormat, args));
|
||||
}
|
||||
|
||||
/*
|
||||
* usage should fit in 80 columns
|
||||
* 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
*/
|
||||
final String usage = "\n" +
|
||||
"Usage:\n" +
|
||||
" android --list [target|vm]\n" +
|
||||
" android --create --target <target id> --name <name>\n" +
|
||||
"\n" +
|
||||
"Options:\n" +
|
||||
" -l [target|vm], --list [target|vm]\n" +
|
||||
" Outputs the available targets or Virtual Machines and their Ids.\n" +
|
||||
"\n";
|
||||
|
||||
System.out.println(usage);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.sdkmanager;
|
||||
|
||||
import com.android.sdklib.SdkManager;
|
||||
|
||||
|
||||
/**
|
||||
* Specific command-line flags for the {@link SdkManager}.
|
||||
*/
|
||||
public class SdkCommandLine extends CommandLineProcessor {
|
||||
|
||||
public static final String ARG_ALIAS = "alias";
|
||||
public static final String ARG_ACTIVITY = "activity";
|
||||
public static final String ARG_VM = "vm";
|
||||
public static final String ARG_TARGET = "target";
|
||||
public static final String ARG_ALL = "all";
|
||||
|
||||
public static final String KEY_IN = "in";
|
||||
public static final String KEY_ACTIVITY = ARG_ACTIVITY;
|
||||
public static final String KEY_PACKAGE = "package";
|
||||
public static final String KEY_MODE = "mode";
|
||||
public static final String KEY_TARGET_ID = ARG_TARGET;
|
||||
public static final String KEY_NAME = "name";
|
||||
public static final String KEY_OUT = "out";
|
||||
public static final String KEY_FILTER = "filter";
|
||||
|
||||
public final static String ACTION_LIST = "list";
|
||||
public final static String ACTION_NEW_VM = ARG_VM;
|
||||
public final static String ACTION_NEW_PROJECT = "project";
|
||||
public final static String ACTION_UPDATE_PROJECT = "update";
|
||||
|
||||
private final static String[][] ACTIONS = {
|
||||
{ ACTION_LIST,
|
||||
"Lists existing targets or VMs." },
|
||||
{ ACTION_NEW_VM,
|
||||
"Creates a new VM." },
|
||||
{ ACTION_NEW_PROJECT,
|
||||
"Creates a new project using a template." },
|
||||
{ ACTION_UPDATE_PROJECT,
|
||||
"Updates a new project from existing source (must have an AndroidManifest.xml)." },
|
||||
};
|
||||
|
||||
public SdkCommandLine() {
|
||||
super(ACTIONS);
|
||||
|
||||
define(MODE.ENUM, false, ACTION_LIST, "f", KEY_FILTER,
|
||||
"List filter", new String[] { ARG_ALL, ARG_TARGET, ARG_VM });
|
||||
|
||||
define(MODE.STRING, false, ACTION_NEW_VM, "o", KEY_OUT,
|
||||
"Location path of new VM", null);
|
||||
define(MODE.STRING, true, ACTION_NEW_VM, "n", KEY_NAME,
|
||||
"Name of the new VM", null);
|
||||
define(MODE.INTEGER, true, ACTION_NEW_VM, "t", KEY_TARGET_ID,
|
||||
"Target id of the new VM", null);
|
||||
|
||||
define(MODE.ENUM, true, ACTION_NEW_PROJECT, "m", KEY_MODE,
|
||||
"Project mode", new String[] { ARG_ACTIVITY, ARG_ALIAS });
|
||||
define(MODE.STRING, false, ACTION_NEW_PROJECT, "o", KEY_OUT,
|
||||
"Location path of new project", null);
|
||||
define(MODE.STRING, true, ACTION_NEW_PROJECT, "n", KEY_NAME,
|
||||
"Name of the new project", null);
|
||||
define(MODE.INTEGER, true, ACTION_NEW_PROJECT, "t", KEY_TARGET_ID,
|
||||
"Target id of the new project", null);
|
||||
define(MODE.STRING, true, ACTION_NEW_PROJECT, "p", KEY_PACKAGE,
|
||||
"Package name", null);
|
||||
define(MODE.STRING, true, ACTION_NEW_PROJECT, "a", KEY_ACTIVITY,
|
||||
"Activity name", null);
|
||||
|
||||
define(MODE.STRING, false, ACTION_UPDATE_PROJECT, "i", KEY_IN,
|
||||
"Directory location of the project", null);
|
||||
define(MODE.STRING, true, ACTION_UPDATE_PROJECT, "t", KEY_TARGET_ID,
|
||||
"Target id to set for the project", null);
|
||||
}
|
||||
|
||||
// -- some helpers for list action flags
|
||||
|
||||
/** Helper to retrieve the --filter for the list action. */
|
||||
public String getListFilter() {
|
||||
return ((String) getValue(ACTION_LIST, KEY_FILTER));
|
||||
}
|
||||
|
||||
// -- some helpers for vm action flags
|
||||
|
||||
/** Helper to retrieve the --out location for the new vm action. */
|
||||
public String getNewVmLocation() {
|
||||
return ((String) getValue(ACTION_NEW_VM, KEY_OUT));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --target id for the new vm action. */
|
||||
public int getNewVmTargetId() {
|
||||
return ((Integer) getValue(ACTION_NEW_VM, KEY_TARGET_ID)).intValue();
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --name for the new vm action. */
|
||||
public String getNewVmName() {
|
||||
return ((String) getValue(ACTION_NEW_VM, KEY_NAME));
|
||||
}
|
||||
|
||||
// -- some helpers for project action flags
|
||||
|
||||
/** Helper to retrieve the --out location for the new project action. */
|
||||
public String getNewProjectLocation() {
|
||||
return ((String) getValue(ACTION_NEW_PROJECT, KEY_OUT));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --target id for the new project action. */
|
||||
public int getNewProjectTargetId() {
|
||||
return ((Integer) getValue(ACTION_NEW_PROJECT, KEY_TARGET_ID)).intValue();
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --name for the new project action. */
|
||||
public String getNewProjectName() {
|
||||
return ((String) getValue(ACTION_NEW_PROJECT, KEY_NAME));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --package for the new project action. */
|
||||
public String getNewProjectPackage() {
|
||||
return ((String) getValue(ACTION_NEW_PROJECT, KEY_PACKAGE));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --activity for the new project action. */
|
||||
public String getNewProjectActivity() {
|
||||
return ((String) getValue(ACTION_NEW_PROJECT, KEY_ACTIVITY));
|
||||
}
|
||||
|
||||
// -- some helpers for update action flags
|
||||
|
||||
/** Helper to retrieve the --out location for the update project action. */
|
||||
public String getUpdateProjectLocation() {
|
||||
return ((String) getValue(ACTION_UPDATE_PROJECT, KEY_OUT));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --target id for the update project action. */
|
||||
public int getUpdateProjectTargetId() {
|
||||
return ((Integer) getValue(ACTION_UPDATE_PROJECT, KEY_TARGET_ID)).intValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.sdkmanager;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
||||
public class CommandLineProcessorTest extends TestCase {
|
||||
|
||||
/**
|
||||
* A mock version of the {@link CommandLineProcessor} class that does not
|
||||
* exits and captures its stdout/stderr output.
|
||||
*/
|
||||
public static class MockCommandLineProcessor extends CommandLineProcessor {
|
||||
private boolean mExitCalled;
|
||||
private boolean mHelpCalled;
|
||||
private String mStdOut = "";
|
||||
private String mStdErr = "";
|
||||
|
||||
public MockCommandLineProcessor() {
|
||||
super(new String[][] {
|
||||
{ "action1", "Some action" },
|
||||
{ "action2", "Another action" },
|
||||
});
|
||||
define(MODE.STRING, false /*mandatory*/,
|
||||
"action1", "1", "first", "non-mandatory flag", null);
|
||||
define(MODE.STRING, true /*mandatory*/,
|
||||
"action1", "2", "second", "mandatory flag", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printHelpAndExitForAction(String actionFilter,
|
||||
String errorFormat, Object... args) {
|
||||
mHelpCalled = true;
|
||||
super.printHelpAndExitForAction(actionFilter, errorFormat, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void exit() {
|
||||
mExitCalled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stdout(String format, Object... args) {
|
||||
String s = String.format(format, args);
|
||||
mStdOut += s + "\n";
|
||||
// don't call super to avoid printing stuff
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stderr(String format, Object... args) {
|
||||
String s = String.format(format, args);
|
||||
mStdErr += s + "\n";
|
||||
// don't call super to avoid printing stuff
|
||||
}
|
||||
|
||||
public boolean wasHelpCalled() {
|
||||
return mHelpCalled;
|
||||
}
|
||||
|
||||
public boolean wasExitCalled() {
|
||||
return mExitCalled;
|
||||
}
|
||||
|
||||
public String getStdOut() {
|
||||
return mStdOut;
|
||||
}
|
||||
|
||||
public String getStdErr() {
|
||||
return mStdErr;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public final void testPrintHelpAndExit() {
|
||||
MockCommandLineProcessor c = new MockCommandLineProcessor();
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertFalse(c.wasHelpCalled());
|
||||
assertTrue(c.getStdOut().equals(""));
|
||||
assertTrue(c.getStdErr().equals(""));
|
||||
c.printHelpAndExit(null);
|
||||
assertTrue(c.getStdOut().indexOf("-v") != -1);
|
||||
assertTrue(c.getStdOut().indexOf("--verbose") != -1);
|
||||
assertTrue(c.getStdErr().equals(""));
|
||||
assertTrue(c.wasExitCalled());
|
||||
|
||||
c = new MockCommandLineProcessor();
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertTrue(c.getStdOut().equals(""));
|
||||
assertTrue(c.getStdErr().indexOf("Missing parameter") == -1);
|
||||
|
||||
c.printHelpAndExit("Missing %s", "parameter");
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertFalse(c.getStdOut().equals(""));
|
||||
assertTrue(c.getStdErr().indexOf("Missing parameter") != -1);
|
||||
}
|
||||
|
||||
public final void testVerbose() {
|
||||
MockCommandLineProcessor c = new MockCommandLineProcessor();
|
||||
|
||||
assertFalse(c.isVerbose());
|
||||
c.parseArgs(new String[] { "-v" });
|
||||
assertTrue(c.isVerbose());
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertTrue(c.wasHelpCalled());
|
||||
assertTrue(c.getStdErr().indexOf("Missing action name.") != -1);
|
||||
|
||||
c = new MockCommandLineProcessor();
|
||||
c.parseArgs(new String[] { "--verbose" });
|
||||
assertTrue(c.isVerbose());
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertTrue(c.wasHelpCalled());
|
||||
assertTrue(c.getStdErr().indexOf("Missing action name.") != -1);
|
||||
}
|
||||
|
||||
public final void testHelp() {
|
||||
MockCommandLineProcessor c = new MockCommandLineProcessor();
|
||||
|
||||
c.parseArgs(new String[] { "-h" });
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertTrue(c.wasHelpCalled());
|
||||
assertTrue(c.getStdErr().indexOf("Missing action name.") == -1);
|
||||
|
||||
c = new MockCommandLineProcessor();
|
||||
c.parseArgs(new String[] { "--help" });
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertTrue(c.wasHelpCalled());
|
||||
assertTrue(c.getStdErr().indexOf("Missing action name.") == -1);
|
||||
}
|
||||
|
||||
public final void testMandatory() {
|
||||
MockCommandLineProcessor c = new MockCommandLineProcessor();
|
||||
|
||||
c.parseArgs(new String[] { "action1", "-1", "value1", "-2", "value2" });
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertFalse(c.wasHelpCalled());
|
||||
assertEquals("", c.getStdErr());
|
||||
assertEquals("value1", c.getValue("action1", "first"));
|
||||
assertEquals("value2", c.getValue("action1", "second"));
|
||||
|
||||
c = new MockCommandLineProcessor();
|
||||
c.parseArgs(new String[] { "action1", "-2", "value2" });
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertFalse(c.wasHelpCalled());
|
||||
assertEquals("", c.getStdErr());
|
||||
assertEquals(null, c.getValue("action1", "first"));
|
||||
assertEquals("value2", c.getValue("action1", "second"));
|
||||
|
||||
c = new MockCommandLineProcessor();
|
||||
c.parseArgs(new String[] { "action1" });
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertTrue(c.wasHelpCalled());
|
||||
assertTrue(c.getStdErr().indexOf("must be defined") != -1);
|
||||
assertEquals(null, c.getValue("action1", "first"));
|
||||
assertEquals(null, c.getValue("action1", "second"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.sdkmanager;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SdkCommandLineTest extends TestCase {
|
||||
|
||||
/**
|
||||
* A mock version of the {@link SdkCommandLine} class that does not
|
||||
* exits and discards its stdout/stderr output.
|
||||
*/
|
||||
public static class MockSdkCommandLine extends SdkCommandLine {
|
||||
private boolean mExitCalled;
|
||||
private boolean mHelpCalled;
|
||||
|
||||
public MockSdkCommandLine() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printHelpAndExitForAction(String actionFilter,
|
||||
String errorFormat, Object... args) {
|
||||
mHelpCalled = true;
|
||||
super.printHelpAndExitForAction(actionFilter, errorFormat, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void exit() {
|
||||
mExitCalled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stdout(String format, Object... args) {
|
||||
// discard
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stderr(String format, Object... args) {
|
||||
// discard
|
||||
}
|
||||
|
||||
public boolean wasExitCalled() {
|
||||
return mExitCalled;
|
||||
}
|
||||
|
||||
public boolean wasHelpCalled() {
|
||||
return mHelpCalled;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/** Test list with long name and verbose */
|
||||
public final void testList_Long_Verbose() {
|
||||
MockSdkCommandLine c = new MockSdkCommandLine();
|
||||
assertEquals("all", c.getListFilter());
|
||||
c.parseArgs(new String[] { "-v", "list", "--filter", "vm" });
|
||||
assertFalse(c.wasHelpCalled());
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertEquals("vm", c.getListFilter());
|
||||
assertTrue(c.isVerbose());
|
||||
}
|
||||
|
||||
/** Test list with short name and no verbose */
|
||||
public final void testList_Short() {
|
||||
MockSdkCommandLine c = new MockSdkCommandLine();
|
||||
assertEquals("all", c.getListFilter());
|
||||
c.parseArgs(new String[] { "list", "-f", "vm" });
|
||||
assertFalse(c.wasHelpCalled());
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertEquals("vm", c.getListFilter());
|
||||
}
|
||||
|
||||
/** Test list with long name and missing parameter */
|
||||
public final void testList_Long_MissingParam() {
|
||||
MockSdkCommandLine c = new MockSdkCommandLine();
|
||||
assertEquals("all", c.getListFilter());
|
||||
c.parseArgs(new String[] { "list", "--filter" });
|
||||
assertTrue(c.wasHelpCalled());
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertEquals("all", c.getListFilter());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user