auto import from //branches/cupcake/...@130745
This commit is contained in:
@@ -31,52 +31,67 @@ import java.util.Map.Entry;
|
||||
* <li>define flags for your actions.
|
||||
* </ul>
|
||||
* <p/>
|
||||
* To use, call {@link #parseArgs(String[])} and then call {@link #getValue(String, String)}.
|
||||
* To use, call {@link #parseArgs(String[])} and then
|
||||
* call {@link #getValue(String, 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";
|
||||
|
||||
/** Internal verb name for internally hidden flags. */
|
||||
public final static String GLOBAL_FLAG_VERB = "@@internal@@";
|
||||
|
||||
/** String to use when the verb doesn't need any object. */
|
||||
public final static String NO_VERB_OBJECT = "";
|
||||
|
||||
/** The global help flag. */
|
||||
public static final String KEY_HELP = "help";
|
||||
/** The global verbose flag. */
|
||||
public static final String KEY_VERBOSE = "verbose";
|
||||
/** The global silent flag. */
|
||||
public static final String KEY_SILENT = "silent";
|
||||
/** The internal action flag. */
|
||||
public static final String KEY_ACTION = "action";
|
||||
|
||||
/** Verb requested by the user. Null if none specified, which will be an error. */
|
||||
private String mVerbRequested;
|
||||
/** Direct object requested by the user. Can be null. */
|
||||
private String mDirectObjectRequested;
|
||||
|
||||
/** List of available actions.
|
||||
/**
|
||||
* Action definitions.
|
||||
* <p/>
|
||||
* Each entry must be a 2-string array with first the action name and then
|
||||
* a description.
|
||||
* Each entry is a string array with:
|
||||
* <ul>
|
||||
* <li> the verb.
|
||||
* <li> a direct object (use #NO_VERB_OBJECT if there's no object).
|
||||
* <li> a description.
|
||||
* <li> an alternate form for the object (e.g. plural).
|
||||
* </ul>
|
||||
*/
|
||||
private final String[][] mActions;
|
||||
/** The hash of all defined arguments.
|
||||
|
||||
private static final int ACTION_VERB_INDEX = 0;
|
||||
private static final int ACTION_OBJECT_INDEX = 1;
|
||||
private static final int ACTION_DESC_INDEX = 2;
|
||||
private static final int ACTION_ALT_OBJECT_INDEX = 3;
|
||||
|
||||
/**
|
||||
* The map of all defined arguments.
|
||||
* <p/>
|
||||
* The key is a string "action/longName".
|
||||
* The key is a string "verb/directObject/longName".
|
||||
*/
|
||||
private final HashMap<String, Arg> mArguments = new HashMap<String, Arg>();
|
||||
/** Logger */
|
||||
private final ISdkLog mLog;
|
||||
|
||||
public CommandLineProcessor(ISdkLog logger, String[][] actions) {
|
||||
mLog = logger;
|
||||
mActions = actions;
|
||||
|
||||
define(MODE.STRING, false, INTERNAL_FLAG, null, KEY_ACTION,
|
||||
"Selected Action", null);
|
||||
|
||||
define(MODE.BOOLEAN, false, GLOBAL_FLAG, "v", KEY_VERBOSE,
|
||||
define(MODE.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "v", KEY_VERBOSE,
|
||||
"Verbose mode: errors, warnings and informational messages are printed.",
|
||||
false);
|
||||
define(MODE.BOOLEAN, false, GLOBAL_FLAG, "s", KEY_SILENT,
|
||||
define(MODE.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "s", KEY_SILENT,
|
||||
"Silent mode: only errors are printed out.",
|
||||
false);
|
||||
define(MODE.BOOLEAN, false, GLOBAL_FLAG, "h", KEY_HELP,
|
||||
define(MODE.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "h", KEY_HELP,
|
||||
"This help.",
|
||||
false);
|
||||
}
|
||||
@@ -86,47 +101,54 @@ public class CommandLineProcessor {
|
||||
|
||||
/** Helper that returns true if --verbose was requested. */
|
||||
public boolean isVerbose() {
|
||||
return ((Boolean) getValue(GLOBAL_FLAG, KEY_VERBOSE)).booleanValue();
|
||||
return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_VERBOSE)).booleanValue();
|
||||
}
|
||||
|
||||
/** Helper that returns true if --silent was requested. */
|
||||
public boolean isSilent() {
|
||||
return ((Boolean) getValue(GLOBAL_FLAG, KEY_SILENT)).booleanValue();
|
||||
return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_SILENT)).booleanValue();
|
||||
}
|
||||
|
||||
/** Helper that returns true if --help was requested. */
|
||||
public boolean isHelpRequested() {
|
||||
return ((Boolean) getValue(GLOBAL_FLAG, KEY_HELP)).booleanValue();
|
||||
return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_HELP)).booleanValue();
|
||||
}
|
||||
|
||||
/** Returns the verb name from the command-line. Can be null. */
|
||||
public String getVerb() {
|
||||
return mVerbRequested;
|
||||
}
|
||||
|
||||
/** Helper that returns the requested action name. */
|
||||
public String getActionRequested() {
|
||||
return (String) getValue(INTERNAL_FLAG, KEY_ACTION);
|
||||
/** Returns the direct object name from the command-line. Can be null. */
|
||||
public String getDirectObject() {
|
||||
return mDirectObjectRequested;
|
||||
}
|
||||
|
||||
//------------------
|
||||
|
||||
/**
|
||||
* Raw access to parsed parameter values.
|
||||
* @param action The action name, including {@link #GLOBAL_FLAG} and {@link #INTERNAL_FLAG}
|
||||
* @param verb The verb name, including {@link #GLOBAL_FLAG_VERB}.
|
||||
* @param directObject The direct object name, including {@link #NO_VERB_OBJECT}.
|
||||
* @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;
|
||||
public Object getValue(String verb, String directObject, String longFlagName) {
|
||||
String key = verb + "/" + directObject + "/" + 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 verb The verb name, including {@link #GLOBAL_FLAG_VERB}.
|
||||
* @param directObject The direct object name, including {@link #NO_VERB_OBJECT}.
|
||||
* @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;
|
||||
protected void setValue(String verb, String directObject, String longFlagName, Object value) {
|
||||
String key = verb + "/" + directObject + "/" + longFlagName;
|
||||
Arg arg = mArguments.get(key);
|
||||
arg.setCurrentValue(value);
|
||||
}
|
||||
@@ -140,114 +162,172 @@ public class CommandLineProcessor {
|
||||
*/
|
||||
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) {
|
||||
String verb = null;
|
||||
String directObject = 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;
|
||||
}
|
||||
try {
|
||||
int n = args.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
Arg arg = null;
|
||||
String a = args[i];
|
||||
if (a.startsWith("--")) {
|
||||
arg = findLongArg(verb, directObject, a.substring(2));
|
||||
} else if (a.startsWith("-")) {
|
||||
arg = findShortArg(verb, directObject, a.substring(1));
|
||||
}
|
||||
|
||||
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;
|
||||
// No matching argument name found
|
||||
if (arg == null) {
|
||||
// Does it looks like a dashed parameter?
|
||||
if (a.startsWith("-")) {
|
||||
if (verb == null || directObject == null) {
|
||||
// It looks like a dashed parameter and we don't have a a verb/object
|
||||
// set yet, the parameter was just given too early.
|
||||
|
||||
needsHelp = String.format(
|
||||
"Flag '%1$s' is not a valid global flag. Did you mean to specify it after the verb/object name?",
|
||||
a);
|
||||
return;
|
||||
} else {
|
||||
// It looks like a dashed parameter and but it is unknown by this
|
||||
// verb-object combination
|
||||
|
||||
needsHelp = String.format(
|
||||
"Flag '%1$s' is not valid for '%2$s %3$s'.",
|
||||
a, verb, directObject);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
if (verb == null) {
|
||||
// Fill verb first. Find it.
|
||||
for (String[] actionDesc : mActions) {
|
||||
if (actionDesc[ACTION_VERB_INDEX].equals(a)) {
|
||||
verb = a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Error if it was not a valid verb
|
||||
if (verb == null) {
|
||||
needsHelp = String.format(
|
||||
"Expected verb after global parameters but found '%1$s' instead.",
|
||||
a);
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (directObject == null) {
|
||||
// Then fill the direct object. Find it.
|
||||
for (String[] actionDesc : mActions) {
|
||||
if (actionDesc[ACTION_VERB_INDEX].equals(verb)) {
|
||||
if (actionDesc[ACTION_OBJECT_INDEX].equals(a)) {
|
||||
directObject = a;
|
||||
break;
|
||||
} else if (actionDesc.length > ACTION_ALT_OBJECT_INDEX &&
|
||||
actionDesc[ACTION_ALT_OBJECT_INDEX].equals(a)) {
|
||||
// if the alternate form exist and is used, we internally
|
||||
// only memorize the default direct object form.
|
||||
directObject = actionDesc[ACTION_OBJECT_INDEX];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Error if it was not a valid object for that verb
|
||||
if (directObject == null) {
|
||||
needsHelp = String.format(
|
||||
"Expected verb after global parameters but found '%1$s' instead.",
|
||||
a);
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
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
|
||||
String missing = null;
|
||||
boolean plural = false;
|
||||
for (Entry<String, Arg> entry : mArguments.entrySet()) {
|
||||
Arg arg = entry.getValue();
|
||||
if (arg.getAction().equals(action)) {
|
||||
if (arg.isMandatory() && arg.getCurrentValue() == null) {
|
||||
if (missing == null) {
|
||||
missing = "--" + arg.getLongArg();
|
||||
} else {
|
||||
missing += ", --" + arg.getLongArg();
|
||||
plural = true;
|
||||
if (needsHelp == null) {
|
||||
if (verb == null) {
|
||||
needsHelp = "Missing verb name.";
|
||||
} else {
|
||||
if (directObject == null) {
|
||||
// Make sure this verb has an optional direct object
|
||||
for (String[] actionDesc : mActions) {
|
||||
if (actionDesc[ACTION_VERB_INDEX].equals(verb) &&
|
||||
actionDesc[ACTION_OBJECT_INDEX].equals(NO_VERB_OBJECT)) {
|
||||
directObject = NO_VERB_OBJECT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (directObject == null) {
|
||||
needsHelp = String.format("Missing object name for verb '%1$s'.", verb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate that all mandatory arguments are non-null for this action
|
||||
String missing = null;
|
||||
boolean plural = false;
|
||||
for (Entry<String, Arg> entry : mArguments.entrySet()) {
|
||||
Arg arg = entry.getValue();
|
||||
if (arg.getVerb().equals(verb) &&
|
||||
arg.getDirectObject().equals(directObject)) {
|
||||
if (arg.isMandatory() && arg.getCurrentValue() == null) {
|
||||
if (missing == null) {
|
||||
missing = "--" + arg.getLongArg();
|
||||
} else {
|
||||
missing += ", --" + arg.getLongArg();
|
||||
plural = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (missing != null) {
|
||||
needsHelp = String.format(
|
||||
"The %1$s %2$s must be defined for action '%3$s %4$s'",
|
||||
plural ? "parameters" : "parameter",
|
||||
missing,
|
||||
verb,
|
||||
directObject);
|
||||
}
|
||||
|
||||
if (missing != null) {
|
||||
needsHelp = String.format("The %1$s %2$s must be defined for action '%3$s'",
|
||||
plural ? "parameters" : "parameter",
|
||||
missing,
|
||||
action);
|
||||
mVerbRequested = verb;
|
||||
mDirectObjectRequested = directObject;
|
||||
}
|
||||
|
||||
setValue(INTERNAL_FLAG, KEY_ACTION, action);
|
||||
}
|
||||
}
|
||||
|
||||
if (needsHelp != null) {
|
||||
printHelpAndExitForAction(action, needsHelp);
|
||||
} finally {
|
||||
if (needsHelp != null) {
|
||||
printHelpAndExitForAction(verb, directObject, needsHelp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,11 +335,14 @@ public class CommandLineProcessor {
|
||||
* 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;
|
||||
protected Arg findLongArg(String verb, String directObject, String longName) {
|
||||
if (verb == null) {
|
||||
verb = GLOBAL_FLAG_VERB;
|
||||
}
|
||||
String key = action + "/" + longName;
|
||||
if (directObject == null) {
|
||||
directObject = NO_VERB_OBJECT;
|
||||
}
|
||||
String key = verb + "/" + directObject + "/" + longName;
|
||||
return mArguments.get(key);
|
||||
}
|
||||
|
||||
@@ -267,14 +350,17 @@ public class CommandLineProcessor {
|
||||
* 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;
|
||||
protected Arg findShortArg(String verb, String directObject, String shortName) {
|
||||
if (verb == null) {
|
||||
verb = GLOBAL_FLAG_VERB;
|
||||
}
|
||||
if (directObject == null) {
|
||||
directObject = NO_VERB_OBJECT;
|
||||
}
|
||||
|
||||
for (Entry<String, Arg> entry : mArguments.entrySet()) {
|
||||
Arg arg = entry.getValue();
|
||||
if (arg.getAction().equals(action)) {
|
||||
if (arg.getVerb().equals(verb) && arg.getDirectObject().equals(directObject)) {
|
||||
if (shortName.equals(arg.getShortArg())) {
|
||||
return arg;
|
||||
}
|
||||
@@ -291,18 +377,22 @@ public class CommandLineProcessor {
|
||||
* @param args Arguments for String.format
|
||||
*/
|
||||
public void printHelpAndExit(String errorFormat, Object... args) {
|
||||
printHelpAndExitForAction(null /*actionFilter*/, errorFormat, args);
|
||||
printHelpAndExitForAction(null /*verb*/, null /*directObject*/, 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 verb If null, displays help for all verbs. If not null, display help only
|
||||
* for that specific verb. In all cases also displays general usage and action list.
|
||||
* @param directObject If null, displays help for all verb objects.
|
||||
* If not null, displays 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) {
|
||||
public void printHelpAndExitForAction(String verb, String directObject,
|
||||
String errorFormat, Object... args) {
|
||||
if (errorFormat != null) {
|
||||
stderr(errorFormat, args);
|
||||
}
|
||||
@@ -316,25 +406,27 @@ public class CommandLineProcessor {
|
||||
" android [global options] action [action options]\n" +
|
||||
"\n" +
|
||||
"Global options:");
|
||||
listOptions(GLOBAL_FLAG);
|
||||
listOptions(GLOBAL_FLAG_VERB, NO_VERB_OBJECT);
|
||||
|
||||
stdout("\nValid actions:");
|
||||
stdout("\nValid actions are composed of a verb and an optional direct object:");
|
||||
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]);
|
||||
stdout("- %1$6s %2$-7s: %3$s",
|
||||
action[ACTION_VERB_INDEX],
|
||||
action[ACTION_OBJECT_INDEX],
|
||||
action[ACTION_DESC_INDEX]);
|
||||
}
|
||||
|
||||
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]);
|
||||
if (verb == null || verb.equals(action[ACTION_VERB_INDEX])) {
|
||||
if (directObject == null || directObject.equals(action[ACTION_OBJECT_INDEX])) {
|
||||
stdout("\nAction \"%1$s %2$s\":",
|
||||
action[ACTION_VERB_INDEX],
|
||||
action[ACTION_OBJECT_INDEX]);
|
||||
stdout(" %1$s", action[ACTION_DESC_INDEX]);
|
||||
stdout("Options:");
|
||||
listOptions(action[ACTION_VERB_INDEX], action[ACTION_OBJECT_INDEX]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,11 +436,11 @@ public class CommandLineProcessor {
|
||||
/**
|
||||
* Internal helper to print all the option flags for a given action name.
|
||||
*/
|
||||
protected void listOptions(String action) {
|
||||
protected void listOptions(String verb, String directObject) {
|
||||
int numOptions = 0;
|
||||
for (Entry<String, Arg> entry : mArguments.entrySet()) {
|
||||
Arg arg = entry.getValue();
|
||||
if (arg.getAction().equals(action)) {
|
||||
if (arg.getVerb().equals(verb) && arg.getDirectObject().equals(directObject)) {
|
||||
|
||||
String value = "";
|
||||
if (arg.getDefaultValue() instanceof String[]) {
|
||||
@@ -483,21 +575,22 @@ public class CommandLineProcessor {
|
||||
* 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 mVerb;
|
||||
private final String mDirectObject;
|
||||
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;
|
||||
private Object mCurrentValue;
|
||||
|
||||
/**
|
||||
* 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 directObject The action name. Can be #NO_VERB_OBJECT 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.
|
||||
@@ -505,14 +598,16 @@ public class CommandLineProcessor {
|
||||
*/
|
||||
public Arg(MODE mode,
|
||||
boolean mandatory,
|
||||
String action,
|
||||
String verb,
|
||||
String directObject,
|
||||
String shortName,
|
||||
String longName,
|
||||
String description,
|
||||
Object defaultValue) {
|
||||
mMode = mode;
|
||||
mMandatory = mandatory;
|
||||
mAction = action;
|
||||
mVerb = verb;
|
||||
mDirectObject = directObject;
|
||||
mShortName = shortName;
|
||||
mLongName = longName;
|
||||
mDescription = description;
|
||||
@@ -540,8 +635,12 @@ public class CommandLineProcessor {
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return mAction;
|
||||
public String getVerb() {
|
||||
return mVerb;
|
||||
}
|
||||
|
||||
public String getDirectObject() {
|
||||
return mDirectObject;
|
||||
}
|
||||
|
||||
public Object getDefaultValue() {
|
||||
@@ -565,7 +664,8 @@ public class CommandLineProcessor {
|
||||
* 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 verb The verb name. Can be #INTERNAL_VERB.
|
||||
* @param directObject The action name. Can be #NO_VERB_OBJECT 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.
|
||||
@@ -573,14 +673,19 @@ public class CommandLineProcessor {
|
||||
*/
|
||||
protected void define(MODE mode,
|
||||
boolean mandatory,
|
||||
String action,
|
||||
String verb,
|
||||
String directObject,
|
||||
String shortName, String longName,
|
||||
String description, Object defaultValue) {
|
||||
assert(mandatory || mode == MODE.BOOLEAN); // a boolean mode cannot be mandatory
|
||||
|
||||
String key = action + "/" + longName;
|
||||
if (directObject == null) {
|
||||
directObject = NO_VERB_OBJECT;
|
||||
}
|
||||
|
||||
String key = verb + "/" + directObject + "/" + longName;
|
||||
mArguments.put(key, new Arg(mode, mandatory,
|
||||
action, shortName, longName, description, defaultValue));
|
||||
verb, directObject, shortName, longName, description, defaultValue));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,12 +23,12 @@ 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.avd.AvdManager;
|
||||
import com.android.sdklib.avd.HardwareProperties;
|
||||
import com.android.sdklib.avd.AvdManager.AvdInfo;
|
||||
import com.android.sdklib.avd.HardwareProperties.HardwareProperty;
|
||||
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;
|
||||
import com.android.sdklib.vm.VmManager.VmInfo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -56,8 +56,8 @@ class Main {
|
||||
private ISdkLog mSdkLog;
|
||||
/** The SDK manager parses the SDK folder and gives access to the content. */
|
||||
private SdkManager mSdkManager;
|
||||
/** Virtual Machine manager to access the list of VMs or create new ones. */
|
||||
private VmManager mVmManager;
|
||||
/** Virtual Machine manager to access the list of AVDs or create new ones. */
|
||||
private AvdManager mAvdManager;
|
||||
/** Command-line processor with options specific to SdkManager. */
|
||||
private SdkCommandLine mSdkCommandLine;
|
||||
/** The working directory, either null or set to an existing absolute canonical directory. */
|
||||
@@ -183,26 +183,31 @@ class Main {
|
||||
* Actually do an action...
|
||||
*/
|
||||
private void doAction() {
|
||||
String action = mSdkCommandLine.getActionRequested();
|
||||
String verb = mSdkCommandLine.getVerb();
|
||||
String directObject = mSdkCommandLine.getDirectObject();
|
||||
|
||||
if (SdkCommandLine.ACTION_LIST.equals(action)) {
|
||||
if (SdkCommandLine.VERB_LIST.equals(verb)) {
|
||||
// list action.
|
||||
if (SdkCommandLine.ARG_TARGET.equals(mSdkCommandLine.getListFilter())) {
|
||||
if (SdkCommandLine.OBJECT_TARGET.equals(directObject)) {
|
||||
displayTargetList();
|
||||
} else if (SdkCommandLine.ARG_VM.equals(mSdkCommandLine.getListFilter())) {
|
||||
displayVmList();
|
||||
} else if (SdkCommandLine.OBJECT_AVD.equals(directObject)) {
|
||||
displayAvdList();
|
||||
} else {
|
||||
displayTargetList();
|
||||
displayVmList();
|
||||
displayAvdList();
|
||||
}
|
||||
} else if (SdkCommandLine.ACTION_NEW_VM.equals(action)) {
|
||||
createVm();
|
||||
} else if (SdkCommandLine.ACTION_NEW_PROJECT.equals(action)) {
|
||||
|
||||
} else if (SdkCommandLine.VERB_CREATE.equals(verb) &&
|
||||
SdkCommandLine.OBJECT_AVD.equals(directObject)) {
|
||||
createAvd();
|
||||
|
||||
} else if (SdkCommandLine.VERB_CREATE.equals(verb) &&
|
||||
SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
|
||||
// get the target and try to resolve it.
|
||||
int targetId = mSdkCommandLine.getNewProjectTargetId();
|
||||
int targetId = mSdkCommandLine.getCreateProjectTargetId();
|
||||
IAndroidTarget[] targets = mSdkManager.getTargets();
|
||||
if (targetId < 1 || targetId > targets.length) {
|
||||
errorAndExit("Target id is not valid. Use '%s list -f target' to get the target Ids.",
|
||||
errorAndExit("Target id is not valid. Use '%s list targets' to get the target ids.",
|
||||
SdkConstants.androidCmdName());
|
||||
}
|
||||
IAndroidTarget target = targets[targetId - 1];
|
||||
@@ -213,22 +218,24 @@ class Main {
|
||||
OutputLevel.NORMAL,
|
||||
mSdkLog);
|
||||
|
||||
String projectDir = getProjectLocation(mSdkCommandLine.getNewProjectLocation());
|
||||
String projectDir = getProjectLocation(mSdkCommandLine.getCreateProjectLocation());
|
||||
|
||||
creator.createProject(projectDir,
|
||||
mSdkCommandLine.getNewProjectName(),
|
||||
mSdkCommandLine.getNewProjectPackage(),
|
||||
mSdkCommandLine.getNewProjectActivity(),
|
||||
mSdkCommandLine.getCreateProjectName(),
|
||||
mSdkCommandLine.getCreateProjectPackage(),
|
||||
mSdkCommandLine.getCreateProjectActivity(),
|
||||
target,
|
||||
false /* isTestProject*/);
|
||||
} else if (SdkCommandLine.ACTION_UPDATE_PROJECT.equals(action)) {
|
||||
|
||||
} else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
|
||||
SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
|
||||
// get the target and try to resolve it.
|
||||
IAndroidTarget target = null;
|
||||
int targetId = mSdkCommandLine.getUpdateProjectTargetId();
|
||||
if (targetId >= 0) {
|
||||
IAndroidTarget[] targets = mSdkManager.getTargets();
|
||||
if (targetId < 1 || targetId > targets.length) {
|
||||
errorAndExit("Target id is not valid. Use '%s list -f target' to get the target Ids.",
|
||||
errorAndExit("Target id is not valid. Use '%s list targets' to get the target ids.",
|
||||
SdkConstants.androidCmdName());
|
||||
}
|
||||
target = targets[targetId - 1];
|
||||
@@ -340,20 +347,20 @@ class Main {
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the list of available VMs.
|
||||
* Displays the list of available AVDs.
|
||||
*/
|
||||
private void displayVmList() {
|
||||
private void displayAvdList() {
|
||||
try {
|
||||
mVmManager = new VmManager(mSdkManager, null /* sdklog */);
|
||||
mAvdManager = new AvdManager(mSdkManager, null /* sdklog */);
|
||||
|
||||
mSdkLog.printf("Available Android VMs:\n");
|
||||
mSdkLog.printf("Available Android Virtual Devices:\n");
|
||||
|
||||
int index = 1;
|
||||
for (VmInfo info : mVmManager.getVms()) {
|
||||
for (AvdInfo info : mAvdManager.getAvds()) {
|
||||
mSdkLog.printf("[%d] %s\n", index, info.getName());
|
||||
mSdkLog.printf(" Path: %s\n", info.getPath());
|
||||
|
||||
// get the target of the Vm
|
||||
// get the target of the AVD
|
||||
IAndroidTarget target = info.getTarget();
|
||||
if (target.isPlatform()) {
|
||||
mSdkLog.printf(" Target: %s (API level %d)\n", target.getName(),
|
||||
@@ -373,57 +380,85 @@ class Main {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new VM. This is a text based creation with command line prompt.
|
||||
* Creates a new AVD. This is a text based creation with command line prompt.
|
||||
*/
|
||||
private void createVm() {
|
||||
private void createAvd() {
|
||||
// find a matching target
|
||||
int targetId = mSdkCommandLine.getNewVmTargetId();
|
||||
int targetId = mSdkCommandLine.getCreateAvdTargetId();
|
||||
IAndroidTarget target = null;
|
||||
|
||||
if (targetId >= 1 && targetId <= mSdkManager.getTargets().length) {
|
||||
target = mSdkManager.getTargets()[targetId-1]; // target it is 1-based
|
||||
} else {
|
||||
errorAndExit("Target id is not valid. Use '%s list -f target' to get the target Ids.",
|
||||
errorAndExit("Target id is not valid. Use '%s list targets' to get the target ids.",
|
||||
SdkConstants.androidCmdName());
|
||||
}
|
||||
|
||||
try {
|
||||
mVmManager = new VmManager(mSdkManager, mSdkLog);
|
||||
boolean removePrevious = false;
|
||||
mAvdManager = new AvdManager(mSdkManager, mSdkLog);
|
||||
|
||||
String vmName = mSdkCommandLine.getNewVmName();
|
||||
VmInfo info = mVmManager.getVm(vmName);
|
||||
String avdName = mSdkCommandLine.getCreateAvdName();
|
||||
AvdInfo info = mAvdManager.getAvd(avdName);
|
||||
if (info != null) {
|
||||
errorAndExit("VM %s already exists.", vmName);
|
||||
} else {
|
||||
String vmParentFolder = mSdkCommandLine.getNewVmLocation();
|
||||
if (vmParentFolder == null) {
|
||||
vmParentFolder = AndroidLocation.getFolder() + AndroidLocation.FOLDER_VMS;
|
||||
if (mSdkCommandLine.getCreateAvdForce()) {
|
||||
removePrevious = true;
|
||||
mSdkLog.warning(
|
||||
"Android Virtual Device '%s' already exists and will be replaced.",
|
||||
avdName);
|
||||
} else {
|
||||
errorAndExit("Android Virtual Device '%s' already exists.", avdName);
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, String> hardwareConfig = null;
|
||||
if (target.isPlatform()) {
|
||||
try {
|
||||
hardwareConfig = promptForHardware(target);
|
||||
} catch (IOException e) {
|
||||
errorAndExit(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
mVmManager.createVm(vmParentFolder,
|
||||
mSdkCommandLine.getNewVmName(),
|
||||
target,
|
||||
mSdkCommandLine.getNewVmSkin(),
|
||||
mSdkCommandLine.getNewVmSdCard(),
|
||||
hardwareConfig,
|
||||
mSdkLog);
|
||||
}
|
||||
|
||||
String avdParentFolder = mSdkCommandLine.getCreateAvdLocation();
|
||||
if (avdParentFolder == null) {
|
||||
avdParentFolder = AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD;
|
||||
}
|
||||
|
||||
Map<String, String> hardwareConfig = null;
|
||||
if (target.isPlatform()) {
|
||||
try {
|
||||
hardwareConfig = promptForHardware(target);
|
||||
} catch (IOException e) {
|
||||
errorAndExit(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
AvdInfo oldAvdInfo = null;
|
||||
if (removePrevious) {
|
||||
oldAvdInfo = mAvdManager.getAvd(avdName);
|
||||
}
|
||||
|
||||
AvdInfo newAvdInfo = mAvdManager.createAvd(avdParentFolder,
|
||||
avdName,
|
||||
target,
|
||||
mSdkCommandLine.getCreateAvdSkin(),
|
||||
mSdkCommandLine.getCreateAvdSdCard(),
|
||||
hardwareConfig,
|
||||
removePrevious,
|
||||
mSdkLog);
|
||||
|
||||
if (newAvdInfo != null &&
|
||||
oldAvdInfo != null &&
|
||||
!oldAvdInfo.getPath().equals(newAvdInfo.getPath())) {
|
||||
mSdkLog.warning("Removing previous AVD directory at %s", oldAvdInfo.getPath());
|
||||
// Remove the old data directory
|
||||
File dir = new File(oldAvdInfo.getPath());
|
||||
mAvdManager.recursiveDelete(dir);
|
||||
dir.delete();
|
||||
// Remove old avd info from manager
|
||||
mAvdManager.removeAvd(oldAvdInfo);
|
||||
}
|
||||
|
||||
} catch (AndroidLocationException e) {
|
||||
errorAndExit(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompts the user to setup a hardware config for a Platform-based VM.
|
||||
* Prompts the user to setup a hardware config for a Platform-based AVD.
|
||||
* @throws IOException
|
||||
*/
|
||||
private Map<String, String> promptForHardware(IAndroidTarget createTarget) throws IOException {
|
||||
|
||||
@@ -25,152 +25,218 @@ import com.android.sdklib.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_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 static final String KEY_SKIN = "skin";
|
||||
public static final String KEY_SDCARD = "sdcard";
|
||||
public final static String VERB_LIST = "list";
|
||||
public final static String VERB_CREATE = "create";
|
||||
public final static String VERB_RENAME = "rename";
|
||||
public final static String VERB_MOVE = "move";
|
||||
public final static String VERB_DELETE = "delete";
|
||||
public final static String VERB_UPDATE = "update";
|
||||
|
||||
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";
|
||||
|
||||
public static final String OBJECT_AVD = "avd";
|
||||
public static final String OBJECT_AVDS = "avds";
|
||||
public static final String OBJECT_TARGET = "target";
|
||||
public static final String OBJECT_TARGETS = "targets";
|
||||
public static final String OBJECT_PROJECT = "project";
|
||||
|
||||
public static final String ARG_ALIAS = "alias";
|
||||
public static final String ARG_ACTIVITY = "activity";
|
||||
|
||||
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 = OBJECT_TARGET;
|
||||
public static final String KEY_NAME = "name";
|
||||
public static final String KEY_PATH = "path";
|
||||
public static final String KEY_FILTER = "filter";
|
||||
public static final String KEY_SKIN = "skin";
|
||||
public static final String KEY_SDCARD = "sdcard";
|
||||
public static final String KEY_FORCE = "force";
|
||||
|
||||
/**
|
||||
* Action definitions for SdkManager command line.
|
||||
* <p/>
|
||||
* Each entry is a string array with:
|
||||
* <ul>
|
||||
* <li> the verb.
|
||||
* <li> an object (use #NO_VERB_OBJECT if there's no object).
|
||||
* <li> a description.
|
||||
* <li> an alternate form for the object (e.g. plural).
|
||||
* </ul>
|
||||
*/
|
||||
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 project from existing source (must have an AndroidManifest.xml)." },
|
||||
{ VERB_LIST,
|
||||
NO_VERB_OBJECT,
|
||||
"Lists existing targets or virtual devices." },
|
||||
{ VERB_LIST,
|
||||
OBJECT_AVD,
|
||||
"Lists existing Android Virtual Devices.",
|
||||
OBJECT_AVDS },
|
||||
{ VERB_LIST,
|
||||
OBJECT_TARGET,
|
||||
"Lists existing targets.",
|
||||
OBJECT_TARGETS },
|
||||
|
||||
{ VERB_CREATE,
|
||||
OBJECT_AVD,
|
||||
"Creates a new Android Virtual Device." },
|
||||
{ VERB_RENAME,
|
||||
OBJECT_AVD,
|
||||
"Renames a new Android Virtual Device." },
|
||||
{ VERB_MOVE,
|
||||
OBJECT_AVD,
|
||||
"Moves a new Android Virtual Device." },
|
||||
{ VERB_DELETE,
|
||||
OBJECT_AVD,
|
||||
"Deletes a new Android Virtual Device." },
|
||||
|
||||
{ VERB_CREATE,
|
||||
OBJECT_PROJECT,
|
||||
"Creates a new Android Project." },
|
||||
{ VERB_UPDATE,
|
||||
OBJECT_PROJECT,
|
||||
"Updates an Android Project (must have an AndroidManifest.xml)." },
|
||||
};
|
||||
|
||||
public SdkCommandLine(ISdkLog logger) {
|
||||
super(logger, ACTIONS);
|
||||
|
||||
define(MODE.ENUM, false, ACTION_LIST, "f", KEY_FILTER,
|
||||
"List filter", new String[] { ARG_ALL, ARG_TARGET, ARG_VM });
|
||||
define(MODE.STRING, false,
|
||||
VERB_CREATE, OBJECT_AVD,
|
||||
"p", KEY_PATH,
|
||||
"Location path of the parent directory where the new AVD will be created", null);
|
||||
define(MODE.STRING, true,
|
||||
VERB_CREATE, OBJECT_AVD,
|
||||
"n", KEY_NAME,
|
||||
"Name of the new AVD", null);
|
||||
define(MODE.INTEGER, true,
|
||||
VERB_CREATE, OBJECT_AVD,
|
||||
"t", KEY_TARGET_ID,
|
||||
"Target id of the new AVD", null);
|
||||
define(MODE.STRING, true,
|
||||
VERB_CREATE, OBJECT_AVD,
|
||||
"s", KEY_SKIN,
|
||||
"Skin of the new AVD", null);
|
||||
define(MODE.STRING, false,
|
||||
VERB_CREATE, OBJECT_AVD,
|
||||
"c", KEY_SDCARD,
|
||||
"Path to a shared SD card image, or size of a new sdcard for the new AVD", null);
|
||||
define(MODE.BOOLEAN, false,
|
||||
VERB_CREATE, OBJECT_AVD,
|
||||
"f", KEY_FORCE,
|
||||
"Force creation (override an existing AVD)", false);
|
||||
|
||||
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.STRING, true, ACTION_NEW_VM, "s", KEY_SKIN,
|
||||
"Skin of the new VM", null);
|
||||
define(MODE.STRING, false, ACTION_NEW_VM, "c", KEY_SDCARD,
|
||||
"Path to a shared SD card image, or size of a new sdcard for the new VM", null);
|
||||
|
||||
define(MODE.ENUM, true, ACTION_NEW_PROJECT, "m", KEY_MODE,
|
||||
define(MODE.ENUM, true,
|
||||
VERB_CREATE, OBJECT_PROJECT,
|
||||
"m", KEY_MODE,
|
||||
"Project mode", new String[] { ARG_ACTIVITY, ARG_ALIAS });
|
||||
define(MODE.STRING, true, ACTION_NEW_PROJECT, "o", KEY_OUT,
|
||||
define(MODE.STRING, true,
|
||||
VERB_CREATE, OBJECT_PROJECT,
|
||||
"p", KEY_PATH,
|
||||
"Location path of new project", null);
|
||||
define(MODE.INTEGER, true, ACTION_NEW_PROJECT, "t", KEY_TARGET_ID,
|
||||
define(MODE.INTEGER, true,
|
||||
VERB_CREATE, OBJECT_PROJECT,
|
||||
"t", KEY_TARGET_ID,
|
||||
"Target id of the new project", null);
|
||||
define(MODE.STRING, true, ACTION_NEW_PROJECT, "p", KEY_PACKAGE,
|
||||
define(MODE.STRING, true,
|
||||
VERB_CREATE, OBJECT_PROJECT,
|
||||
"k", KEY_PACKAGE,
|
||||
"Package name", null);
|
||||
define(MODE.STRING, true, ACTION_NEW_PROJECT, "a", KEY_ACTIVITY,
|
||||
define(MODE.STRING, true,
|
||||
VERB_CREATE, OBJECT_PROJECT,
|
||||
"a", KEY_ACTIVITY,
|
||||
"Activity name", null);
|
||||
define(MODE.STRING, false, ACTION_NEW_PROJECT, "n", KEY_NAME,
|
||||
define(MODE.STRING, false,
|
||||
VERB_CREATE, OBJECT_PROJECT,
|
||||
"n", KEY_NAME,
|
||||
"Project name", null);
|
||||
|
||||
define(MODE.STRING, true, ACTION_UPDATE_PROJECT, "o", KEY_OUT,
|
||||
define(MODE.STRING, true,
|
||||
VERB_UPDATE, OBJECT_PROJECT,
|
||||
"p", KEY_PATH,
|
||||
"Location path of the project", null);
|
||||
define(MODE.INTEGER, true, ACTION_UPDATE_PROJECT, "t", KEY_TARGET_ID,
|
||||
define(MODE.INTEGER, true,
|
||||
VERB_UPDATE, OBJECT_PROJECT,
|
||||
"t", KEY_TARGET_ID,
|
||||
"Target id to set for the project", -1);
|
||||
define(MODE.STRING, false, ACTION_UPDATE_PROJECT, "n", KEY_NAME,
|
||||
define(MODE.STRING, false,
|
||||
VERB_UPDATE, OBJECT_PROJECT,
|
||||
"n", KEY_NAME,
|
||||
"Project name", null);
|
||||
}
|
||||
|
||||
// -- some helpers for list action flags
|
||||
// -- some helpers for AVD action flags
|
||||
|
||||
/** Helper to retrieve the --filter for the list action. */
|
||||
public String getListFilter() {
|
||||
return ((String) getValue(ACTION_LIST, KEY_FILTER));
|
||||
/** Helper to retrieve the --out location for the new AVD action. */
|
||||
public String getCreateAvdLocation() {
|
||||
return ((String) getValue(VERB_CREATE, OBJECT_AVD, KEY_PATH));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --target id for the new AVD action. */
|
||||
public int getCreateAvdTargetId() {
|
||||
return ((Integer) getValue(VERB_CREATE, OBJECT_AVD, KEY_TARGET_ID)).intValue();
|
||||
}
|
||||
|
||||
// -- 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 --name for the new AVD action. */
|
||||
public String getCreateAvdName() {
|
||||
return ((String) getValue(VERB_CREATE, OBJECT_AVD, KEY_NAME));
|
||||
}
|
||||
|
||||
/** 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 --skin name for the new AVD action. */
|
||||
public String getCreateAvdSkin() {
|
||||
return ((String) getValue(VERB_CREATE, OBJECT_AVD, KEY_SKIN));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --name for the new vm action. */
|
||||
public String getNewVmName() {
|
||||
return ((String) getValue(ACTION_NEW_VM, KEY_NAME));
|
||||
/** Helper to retrieve the --sdcard data for the new AVD action. */
|
||||
public String getCreateAvdSdCard() {
|
||||
return ((String) getValue(VERB_CREATE, OBJECT_AVD, KEY_SDCARD));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --skin name for the new vm action. */
|
||||
public String getNewVmSkin() {
|
||||
return ((String) getValue(ACTION_NEW_VM, KEY_SKIN));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --sdcard data for the new vm action. */
|
||||
public String getNewVmSdCard() {
|
||||
return ((String) getValue(ACTION_NEW_VM, KEY_SDCARD));
|
||||
public boolean getCreateAvdForce() {
|
||||
return ((Boolean) getValue(VERB_CREATE, OBJECT_AVD, KEY_FORCE)).booleanValue();
|
||||
}
|
||||
|
||||
|
||||
// -- 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));
|
||||
public String getCreateProjectLocation() {
|
||||
return ((String) getValue(VERB_CREATE, OBJECT_PROJECT, KEY_PATH));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --target id for the new project action. */
|
||||
public int getNewProjectTargetId() {
|
||||
return ((Integer) getValue(ACTION_NEW_PROJECT, KEY_TARGET_ID)).intValue();
|
||||
public int getCreateProjectTargetId() {
|
||||
return ((Integer) getValue(VERB_CREATE, OBJECT_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));
|
||||
public String getCreateProjectName() {
|
||||
return ((String) getValue(VERB_CREATE, OBJECT_PROJECT, KEY_NAME));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --package for the new project action. */
|
||||
public String getNewProjectPackage() {
|
||||
return ((String) getValue(ACTION_NEW_PROJECT, KEY_PACKAGE));
|
||||
public String getCreateProjectPackage() {
|
||||
return ((String) getValue(VERB_CREATE, OBJECT_PROJECT, KEY_PACKAGE));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --activity for the new project action. */
|
||||
public String getNewProjectActivity() {
|
||||
return ((String) getValue(ACTION_NEW_PROJECT, KEY_ACTIVITY));
|
||||
public String getCreateProjectActivity() {
|
||||
return ((String) getValue(VERB_CREATE, OBJECT_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));
|
||||
return ((String) getValue(VERB_UPDATE, OBJECT_PROJECT, KEY_PATH));
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --target id for the update project action. */
|
||||
public int getUpdateProjectTargetId() {
|
||||
return ((Integer) getValue(ACTION_UPDATE_PROJECT, KEY_TARGET_ID)).intValue();
|
||||
return ((Integer) getValue(VERB_UPDATE, OBJECT_PROJECT, KEY_TARGET_ID)).intValue();
|
||||
}
|
||||
|
||||
/** Helper to retrieve the --name for the update project action. */
|
||||
public String getUpdateProjectName() {
|
||||
return ((String) getValue(ACTION_UPDATE_PROJECT, KEY_NAME));
|
||||
return ((String) getValue(VERB_UPDATE, OBJECT_PROJECT, KEY_NAME));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,20 +38,20 @@ public class CommandLineProcessorTest extends TestCase {
|
||||
public MockCommandLineProcessor(ISdkLog logger) {
|
||||
super(logger,
|
||||
new String[][] {
|
||||
{ "action1", "Some action" },
|
||||
{ "action2", "Another action" },
|
||||
{ "verb1", "action1", "Some action" },
|
||||
{ "verb1", "action2", "Another action" },
|
||||
});
|
||||
define(MODE.STRING, false /*mandatory*/,
|
||||
"action1", "1", "first", "non-mandatory flag", null);
|
||||
"verb1", "action1", "1", "first", "non-mandatory flag", null);
|
||||
define(MODE.STRING, true /*mandatory*/,
|
||||
"action1", "2", "second", "mandatory flag", null);
|
||||
"verb1", "action1", "2", "second", "mandatory flag", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printHelpAndExitForAction(String actionFilter,
|
||||
public void printHelpAndExitForAction(String verb, String directObject,
|
||||
String errorFormat, Object... args) {
|
||||
mHelpCalled = true;
|
||||
super.printHelpAndExitForAction(actionFilter, errorFormat, args);
|
||||
super.printHelpAndExitForAction(verb, directObject, errorFormat, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -132,14 +132,14 @@ public class CommandLineProcessorTest extends TestCase {
|
||||
assertTrue(c.isVerbose());
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertTrue(c.wasHelpCalled());
|
||||
assertTrue(c.getStdErr().indexOf("Missing action name.") != -1);
|
||||
assertTrue(c.getStdErr().indexOf("Missing verb name.") != -1);
|
||||
|
||||
c = new MockCommandLineProcessor(mLog);
|
||||
c.parseArgs(new String[] { "--verbose" });
|
||||
assertTrue(c.isVerbose());
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertTrue(c.wasHelpCalled());
|
||||
assertTrue(c.getStdErr().indexOf("Missing action name.") != -1);
|
||||
assertTrue(c.getStdErr().indexOf("Missing verb name.") != -1);
|
||||
}
|
||||
|
||||
public final void testHelp() {
|
||||
@@ -148,39 +148,39 @@ public class CommandLineProcessorTest extends TestCase {
|
||||
c.parseArgs(new String[] { "-h" });
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertTrue(c.wasHelpCalled());
|
||||
assertTrue(c.getStdErr().indexOf("Missing action name.") == -1);
|
||||
assertTrue(c.getStdErr().indexOf("Missing verb name.") == -1);
|
||||
|
||||
c = new MockCommandLineProcessor(mLog);
|
||||
c.parseArgs(new String[] { "--help" });
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertTrue(c.wasHelpCalled());
|
||||
assertTrue(c.getStdErr().indexOf("Missing action name.") == -1);
|
||||
assertTrue(c.getStdErr().indexOf("Missing verb name.") == -1);
|
||||
}
|
||||
|
||||
public final void testMandatory() {
|
||||
MockCommandLineProcessor c = new MockCommandLineProcessor(mLog);
|
||||
|
||||
c.parseArgs(new String[] { "action1", "-1", "value1", "-2", "value2" });
|
||||
c.parseArgs(new String[] { "verb1", "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"));
|
||||
assertEquals("value1", c.getValue("verb1", "action1", "first"));
|
||||
assertEquals("value2", c.getValue("verb1", "action1", "second"));
|
||||
|
||||
c = new MockCommandLineProcessor(mLog);
|
||||
c.parseArgs(new String[] { "action1", "-2", "value2" });
|
||||
c.parseArgs(new String[] { "verb1", "action1", "-2", "value2" });
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertFalse(c.wasHelpCalled());
|
||||
assertEquals("", c.getStdErr());
|
||||
assertEquals(null, c.getValue("action1", "first"));
|
||||
assertEquals("value2", c.getValue("action1", "second"));
|
||||
assertEquals(null, c.getValue("verb1", "action1", "first"));
|
||||
assertEquals("value2", c.getValue("verb1", "action1", "second"));
|
||||
|
||||
c = new MockCommandLineProcessor(mLog);
|
||||
c.parseArgs(new String[] { "action1" });
|
||||
c.parseArgs(new String[] { "verb1", "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"));
|
||||
assertEquals(null, c.getValue("verb1", "action1", "first"));
|
||||
assertEquals(null, c.getValue("verb1", "action1", "second"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ public class SdkCommandLineTest extends TestCase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printHelpAndExitForAction(String actionFilter,
|
||||
public void printHelpAndExitForAction(String verb, String directObject,
|
||||
String errorFormat, Object... args) {
|
||||
mHelpCalled = true;
|
||||
super.printHelpAndExitForAction(actionFilter, errorFormat, args);
|
||||
super.printHelpAndExitForAction(verb, directObject, errorFormat, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,34 +78,64 @@ public class SdkCommandLineTest extends TestCase {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/** Test list with long name and verbose */
|
||||
public final void testList_Long_Verbose() {
|
||||
/** Test list */
|
||||
public final void testList_Avd_Verbose() {
|
||||
MockSdkCommandLine c = new MockSdkCommandLine(mLog);
|
||||
assertEquals("all", c.getListFilter());
|
||||
c.parseArgs(new String[] { "-v", "list", "--filter", "vm" });
|
||||
c.parseArgs(new String[] { "-v", "list", "avd" });
|
||||
assertFalse(c.wasHelpCalled());
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertEquals("vm", c.getListFilter());
|
||||
assertEquals("list", c.getVerb());
|
||||
assertEquals("avd", c.getDirectObject());
|
||||
assertTrue(c.isVerbose());
|
||||
}
|
||||
|
||||
/** Test list with short name and no verbose */
|
||||
public final void testList_Short() {
|
||||
public final void testList_Target() {
|
||||
MockSdkCommandLine c = new MockSdkCommandLine(mLog);
|
||||
assertEquals("all", c.getListFilter());
|
||||
c.parseArgs(new String[] { "list", "-f", "vm" });
|
||||
c.parseArgs(new String[] { "list", "target" });
|
||||
assertFalse(c.wasHelpCalled());
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertEquals("vm", c.getListFilter());
|
||||
assertEquals("list", c.getVerb());
|
||||
assertEquals("target", c.getDirectObject());
|
||||
assertFalse(c.isVerbose());
|
||||
}
|
||||
|
||||
/** Test list with long name and missing parameter */
|
||||
public final void testList_Long_MissingParam() {
|
||||
|
||||
public final void testList_None() {
|
||||
MockSdkCommandLine c = new MockSdkCommandLine(mLog);
|
||||
assertEquals("all", c.getListFilter());
|
||||
c.parseArgs(new String[] { "list", "--filter" });
|
||||
c.parseArgs(new String[] { "list" });
|
||||
assertFalse(c.wasHelpCalled());
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertEquals("list", c.getVerb());
|
||||
assertEquals("", c.getDirectObject());
|
||||
assertFalse(c.isVerbose());
|
||||
}
|
||||
|
||||
public final void testList_Invalid() {
|
||||
MockSdkCommandLine c = new MockSdkCommandLine(mLog);
|
||||
c.parseArgs(new String[] { "list", "unknown" });
|
||||
assertTrue(c.wasHelpCalled());
|
||||
assertTrue(c.wasExitCalled());
|
||||
assertEquals("all", c.getListFilter());
|
||||
assertEquals(null, c.getVerb());
|
||||
assertEquals(null, c.getDirectObject());
|
||||
assertFalse(c.isVerbose());
|
||||
}
|
||||
|
||||
public final void testList_Plural() {
|
||||
MockSdkCommandLine c = new MockSdkCommandLine(mLog);
|
||||
c.parseArgs(new String[] { "list", "avds" });
|
||||
assertFalse(c.wasHelpCalled());
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertEquals("list", c.getVerb());
|
||||
// we get the non-plural form
|
||||
assertEquals("avd", c.getDirectObject());
|
||||
assertFalse(c.isVerbose());
|
||||
|
||||
c = new MockSdkCommandLine(mLog);
|
||||
c.parseArgs(new String[] { "list", "targets" });
|
||||
assertFalse(c.wasHelpCalled());
|
||||
assertFalse(c.wasExitCalled());
|
||||
assertEquals("list", c.getVerb());
|
||||
// we get the non-plural form
|
||||
assertEquals("target", c.getDirectObject());
|
||||
assertFalse(c.isVerbose());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user