OSDN Git Service

android tool: support --target symbolic target names
authorRaphael <raphael@google.com>
Thu, 10 Sep 2009 22:14:11 +0000 (15:14 -0700)
committerRaphael <raphael@google.com>
Thu, 10 Sep 2009 23:06:32 +0000 (16:06 -0700)
BUG 2056746

Change-Id: I579e58f7c63cf404cd11af394f41ed7f998593ce

tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java

index 50fe5c6..5da5645 100644 (file)
@@ -34,7 +34,7 @@ import java.util.Map.Entry;
  * To use, call {@link #parseArgs(String[])} and then
  * call {@link #getValue(String, String, String)}.
  */
-public class CommandLineProcessor {
+class CommandLineProcessor {
 
     /** Internal verb name for internally hidden flags. */
     public final static String GLOBAL_FLAG_VERB = "@@internal@@";
index 491e61c..6236599 100644 (file)
@@ -50,6 +50,9 @@ class Main {
      *  is actually the tools dir, in which case this is used to get the original CWD. */
     private final static String WORKDIR = "com.android.sdkmanager.workdir";
 
+    /** Value returned by {@link #resolveTargetName(String)} when the target id does not match. */
+    private final static int INVALID_TARGET_ID = 0;
+
     private final static String[] BOOLEAN_YES_REPLIES = new String[] { "yes", "y" };
     private final static String[] BOOLEAN_NO_REPLIES = new String[] { "no", "n" };
 
@@ -260,7 +263,7 @@ class Main {
      */
     private void createProject() {
         // get the target and try to resolve it.
-        int targetId = mSdkCommandLine.getParamTargetId();
+        int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId());
         IAndroidTarget[] targets = mSdkManager.getTargets();
         if (targetId < 1 || targetId > targets.length) {
             errorAndExit("Target id is not valid. Use '%s list targets' to get the target ids.",
@@ -320,7 +323,7 @@ class Main {
     private void updateProject() {
         // get the target and try to resolve it.
         IAndroidTarget target = null;
-        int targetId = mSdkCommandLine.getParamTargetId();
+        int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId());
         if (targetId >= 0) {
             IAndroidTarget[] targets = mSdkManager.getTargets();
             if (targetId < 1 || targetId > targets.length) {
@@ -412,7 +415,7 @@ class Main {
 
         int index = 1;
         for (IAndroidTarget target : mSdkManager.getTargets()) {
-            mSdkLog.printf("id: %d\n", index);
+            mSdkLog.printf("id: %1$d or \"%2$s\"\n", index, target.hashString());
             mSdkLog.printf("     Name: %s\n", target.getName());
             if (target.isPlatform()) {
                 mSdkLog.printf("     Type: Platform\n");
@@ -557,7 +560,7 @@ class Main {
      */
     private void createAvd() {
         // find a matching target
-        int targetId = mSdkCommandLine.getParamTargetId();
+        int targetId = resolveTargetName(mSdkCommandLine.getParamTargetId());
         IAndroidTarget target = null;
 
         if (targetId >= 1 && targetId <= mSdkManager.getTargets().length) {
@@ -587,7 +590,9 @@ class Main {
                             "Android Virtual Device '%s' already exists and will be replaced.",
                             avdName);
                 } else {
-                    errorAndExit("Android Virtual Device '%s' already exists.", avdName);
+                    errorAndExit("Android Virtual Device '%s' already exists.\n" +
+                                 "Use --force if you want to replace it.",
+                                 avdName);
                     return;
                 }
             }
@@ -608,7 +613,7 @@ class Main {
                 skin = null;
             }
 
-            if (skin != null) {
+            if (skin != null && target != null) {
                 boolean valid = false;
                 // Is it a know skin name for this target?
                 for (String s : target.getSkins()) {
@@ -640,7 +645,7 @@ class Main {
             }
 
             Map<String, String> hardwareConfig = null;
-            if (target.isPlatform()) {
+            if (target != null && target.isPlatform()) {
                 try {
                     hardwareConfig = promptForHardware(target, skinHardwareConfig);
                 } catch (IOException e) {
@@ -648,11 +653,13 @@ class Main {
                 }
             }
 
+            @SuppressWarnings("unused") // oldAvdInfo is never read, yet useful for debugging
             AvdInfo oldAvdInfo = null;
             if (removePrevious) {
                 oldAvdInfo = avdManager.getAvd(avdName, false /*validAvdOnly*/);
             }
 
+            @SuppressWarnings("unused") // newAvdInfo is never read, yet useful for debugging
             AvdInfo newAvdInfo = avdManager.createAvd(avdFolder,
                     avdName,
                     target,
@@ -979,4 +986,43 @@ class Main {
         mSdkLog.error(null, format, args);
         System.exit(1);
     }
+
+    /**
+     * Converts a symbolic target name (such as those accepted by --target on the command-line)
+     * to an internal target index id. A valid target name is either a numeric target id (> 0)
+     * or a target hash string.
+     * <p/>
+     * If the given target can't be mapped, {@link #INVALID_TARGET_ID} (0) is returned.
+     * It's up to the caller to output an error.
+     * <p/>
+     * On success, returns a value > 0.
+     */
+    private int resolveTargetName(String targetName) {
+
+        if (targetName == null) {
+            return INVALID_TARGET_ID;
+        }
+
+        targetName = targetName.trim();
+
+        // Case of an integer number
+        if (targetName.matches("[0-9]*")) {
+            try {
+                int n = Integer.parseInt(targetName);
+                return n < 1 ? INVALID_TARGET_ID : n;
+            } catch (NumberFormatException e) {
+                // Ignore. Should not happen.
+            }
+        }
+
+        // Let's try to find a platform or addon name.
+        IAndroidTarget[] targets = mSdkManager.getTargets();
+        for (int i = 0; i < targets.length; i++) {
+            if (targetName.equals(targets[i].hashString())) {
+                return i + 1;
+            }
+        }
+
+        return INVALID_TARGET_ID;
+    }
 }
index c48a386..a23a65c 100644 (file)
@@ -23,7 +23,7 @@ import com.android.sdklib.SdkManager;
 /**
  * Specific command-line flags for the {@link SdkManager}.
  */
-public class SdkCommandLine extends CommandLineProcessor {
+class SdkCommandLine extends CommandLineProcessor {
 
     public final static String VERB_LIST   = "list";
     public final static String VERB_CREATE = "create";
@@ -104,7 +104,7 @@ public class SdkCommandLine extends CommandLineProcessor {
         define(Mode.STRING, true,
                 VERB_CREATE, OBJECT_AVD, "n", KEY_NAME,
                 "Name of the new AVD", null);
-        define(Mode.INTEGER, true,
+        define(Mode.STRING, true,
                 VERB_CREATE, OBJECT_AVD, "t", KEY_TARGET_ID,
                 "Target id of the new AVD", null);
         define(Mode.STRING, false,
@@ -154,7 +154,7 @@ public class SdkCommandLine extends CommandLineProcessor {
                 VERB_CREATE, OBJECT_PROJECT,
                 "p", KEY_PATH,
                 "Location path of new project", null);
-        define(Mode.INTEGER, true,
+        define(Mode.STRING, true,
                 VERB_CREATE, OBJECT_PROJECT, "t", KEY_TARGET_ID,
                 "Target id of the new project", null);
         define(Mode.STRING, true,
@@ -173,7 +173,7 @@ public class SdkCommandLine extends CommandLineProcessor {
                 VERB_UPDATE, OBJECT_PROJECT,
                 "p", KEY_PATH,
                 "Location path of the project", null);
-        define(Mode.INTEGER, true,
+        define(Mode.STRING, true,
                 VERB_UPDATE, OBJECT_PROJECT,
                 "t", KEY_TARGET_ID,
                 "Target id to set for the project", -1);
@@ -196,27 +196,34 @@ public class SdkCommandLine extends CommandLineProcessor {
 
     /** Helper to retrieve the --path value. */
     public String getParamLocationPath() {
-        return ((String) getValue(null, null, KEY_PATH));
+        return (String) getValue(null, null, KEY_PATH);
     }
 
-    /** Helper to retrieve the --target id value. */
-    public int getParamTargetId() {
-        return ((Integer) getValue(null, null, KEY_TARGET_ID)).intValue();
+    /**
+     * Helper to retrieve the --target id value.
+     * The id is a string. It can be one of:
+     * - an integer, in which case it's the index of the target (cf "android list targets")
+     * - a symbolic name such as android-N for platforn API N
+     * - a symbolic add-on name such as written in the avd/*.ini files,
+     *   e.g. "Google Inc.:Google APIs:3"
+     */
+    public String getParamTargetId() {
+        return (String) getValue(null, null, KEY_TARGET_ID);
     }
 
     /** Helper to retrieve the --name value. */
     public String getParamName() {
-        return ((String) getValue(null, null, KEY_NAME));
+        return (String) getValue(null, null, KEY_NAME);
     }
 
     /** Helper to retrieve the --skin value. */
     public String getParamSkin() {
-        return ((String) getValue(null, null, KEY_SKIN));
+        return (String) getValue(null, null, KEY_SKIN);
     }
 
     /** Helper to retrieve the --sdcard value. */
     public String getParamSdCard() {
-        return ((String) getValue(null, null, KEY_SDCARD));
+        return (String) getValue(null, null, KEY_SDCARD);
     }
 
     /** Helper to retrieve the --force flag. */
@@ -228,7 +235,7 @@ public class SdkCommandLine extends CommandLineProcessor {
 
     /** Helper to retrieve the --rename value for a move verb. */
     public String getParamMoveNewName() {
-        return ((String) getValue(VERB_MOVE, null, KEY_RENAME));
+        return (String) getValue(VERB_MOVE, null, KEY_RENAME);
     }
 
 
index b23d1bd..7b47f4a 100644 (file)
@@ -89,6 +89,16 @@ public final class SdkManager {
     private IAndroidTarget[] mTargets;
 
     /**
+     * Create a new {@link SdkManager} instance.
+     * External users should use {@link #createManager(String, ISdkLog)}.
+     *
+     * @param sdkLocation the location of the SDK.
+     */
+    private SdkManager(String sdkLocation) {
+        mSdkLocation = sdkLocation;
+    }
+
+    /**
      * Creates an {@link SdkManager} for a given sdk location.
      * @param sdkLocation the location of the SDK.
      * @param log the ISdkLog object receiving warning/error from the parsing.
@@ -125,12 +135,24 @@ public final class SdkManager {
 
     /**
      * Returns the targets that are available in the SDK.
+     * <p/>
+     * The array can be empty but not null.
      */
     public IAndroidTarget[] getTargets() {
         return mTargets;
     }
 
     /**
+     * Sets the targets that are available in the SDK.
+     * <p/>
+     * The array can be empty but not null.
+     */
+    private void setTargets(IAndroidTarget[] targets) {
+        assert targets != null;
+        mTargets = targets;
+    }
+
+    /**
      * Returns a target from a hash that was generated by {@link IAndroidTarget#hashString()}.
      *
      * @param hash the {@link IAndroidTarget} hash string.
@@ -202,14 +224,6 @@ public final class SdkManager {
         setTargets(list.toArray(new IAndroidTarget[list.size()]));
     }
 
-    private SdkManager(String sdkLocation) {
-        mSdkLocation = sdkLocation;
-    }
-
-    private void setTargets(IAndroidTarget[] targets) {
-        mTargets = targets;
-    }
-
     /**
      * Loads the Platforms from the SDK.
      * @param location Location of the SDK