Update the project creation (from the command line):
- Make the distinction between the activity class name, manifest entry,
fully-qualified name, and tested activity for the template place-holders.
Test activity names now directly contain the full name (including the
"Test" prefix) instead of the template adding it.
This is required by the new 'create test-project'
- New action: create test-project
This requires a path to the main project. It reads the package, activity
name and target from the main project.
The activity is read from the manifest and can be in a more complex form
than previously expected (for instance .subpackage.MyClass, instead of
simply MyClass). This is what required the re-work the activity related
template place holders.
Options:
-m --main Location path of the project to test, relative to the new
project [required]
-n --name Project name
-p --path Location path of the new project [required]
Example: for 2 projects MyProject and MyTests located in the same folder,
calling from their parent folder.
android create test-project -p MyTests -m ../MyProject
- build.properties now only gets application.package for older targets
as the new one get it directly from XPath
- Remove AndroidXPathFactory from the anttasks project as it was already
in sdklib which is a dependency.
- Removed IntelliJ templates for the SDK. We haven't supported them for
a while, and now that IntelliJ has built-in support for Android, it's
not that useful anymore.
While there is the command line parameters for 'update test-project'
it's not yet implemented.
Change-Id: I663d4cb7f439bb2abfe866f893e58f4d13aff975
This commit is contained in:
@@ -460,7 +460,7 @@ class CommandLineProcessor {
|
||||
stdout("\nValid actions are composed of a verb and an optional direct object:");
|
||||
for (String[] action : mActions) {
|
||||
|
||||
stdout("- %1$6s %2$-7s: %3$s",
|
||||
stdout("- %1$6s %2$-12s: %3$s",
|
||||
action[ACTION_VERB_INDEX],
|
||||
action[ACTION_OBJECT_INDEX],
|
||||
action[ACTION_DESC_INDEX]);
|
||||
|
||||
@@ -28,17 +28,27 @@ import com.android.sdklib.internal.avd.HardwareProperties;
|
||||
import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
|
||||
import com.android.sdklib.internal.avd.HardwareProperties.HardwareProperty;
|
||||
import com.android.sdklib.internal.project.ProjectCreator;
|
||||
import com.android.sdklib.internal.project.ProjectProperties;
|
||||
import com.android.sdklib.internal.project.ProjectCreator.OutputLevel;
|
||||
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
|
||||
import com.android.sdklib.xml.AndroidXPathFactory;
|
||||
import com.android.sdkmanager.internal.repository.AboutPage;
|
||||
import com.android.sdkmanager.internal.repository.SettingsPage;
|
||||
import com.android.sdkuilib.repository.UpdaterWindow;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
|
||||
/**
|
||||
* Main class for the 'android' application.
|
||||
*/
|
||||
@@ -221,6 +231,10 @@ public class Main {
|
||||
SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
|
||||
createProject();
|
||||
|
||||
} else if (SdkCommandLine.VERB_CREATE.equals(verb) &&
|
||||
SdkCommandLine.OBJECT_TEST_PROJECT.equals(directObject)) {
|
||||
createTestProject();
|
||||
|
||||
} else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
|
||||
SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
|
||||
updateProject();
|
||||
@@ -314,9 +328,112 @@ public class Main {
|
||||
packageName,
|
||||
activityName,
|
||||
target,
|
||||
false /* isTestProject*/);
|
||||
null /*pathToMain*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Android test project based on command-line parameters
|
||||
*/
|
||||
private void createTestProject() {
|
||||
|
||||
String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
|
||||
|
||||
// first check the path of the parent project, and make sure it's valid.
|
||||
String pathToMainProject = mSdkCommandLine.getParamTestProjectMain();
|
||||
|
||||
File parentProject = new File(pathToMainProject);
|
||||
if (parentProject.isAbsolute() == false) {
|
||||
// if the path is not absolute, we need to resolve it based on the
|
||||
// destination path of the project
|
||||
parentProject = new File(projectDir, pathToMainProject);
|
||||
}
|
||||
|
||||
if (parentProject.isDirectory() == false) {
|
||||
errorAndExit("Main project's directory does not exist: %1$s",
|
||||
pathToMainProject);
|
||||
}
|
||||
|
||||
// now look for a manifest in there
|
||||
File manifest = new File(parentProject, SdkConstants.FN_ANDROID_MANIFEST_XML);
|
||||
if (manifest.isFile() == false) {
|
||||
errorAndExit("No AndroidManifest.xml file found in the main project directory: %1$s",
|
||||
parentProject.getAbsolutePath());
|
||||
}
|
||||
|
||||
// now query the manifest for the package file.
|
||||
XPath xpath = AndroidXPathFactory.newXPath();
|
||||
String packageName, activityName;
|
||||
|
||||
try {
|
||||
packageName = xpath.evaluate("/manifest/@package",
|
||||
new InputSource(new FileInputStream(manifest)));
|
||||
|
||||
mSdkLog.printf("Found main project package: %1$s\n", packageName);
|
||||
|
||||
// now get the name of the first activity we find
|
||||
activityName = xpath.evaluate("/manifest/application/activity[1]/@android:name",
|
||||
new InputSource(new FileInputStream(manifest)));
|
||||
// xpath will return empty string when there's no match
|
||||
if (activityName == null || activityName.length() == 0) {
|
||||
activityName = null;
|
||||
} else {
|
||||
mSdkLog.printf("Found main project activity: %1$s\n", activityName);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
// this shouldn't happen as we test it above.
|
||||
errorAndExit("No AndroidManifest.xml file found in main project.");
|
||||
return; // this is not strictly needed because errorAndExit will stop the execution,
|
||||
// but this makes the java compiler happy, wrt to uninitialized variables.
|
||||
} catch (XPathExpressionException e) {
|
||||
// looks like the main manifest is not valid.
|
||||
errorAndExit("Unable to parse main project manifest to get information.");
|
||||
return; // this is not strictly needed because errorAndExit will stop the execution,
|
||||
// but this makes the java compiler happy, wrt to uninitialized variables.
|
||||
}
|
||||
|
||||
// now get the target hash
|
||||
ProjectProperties p = ProjectProperties.load(parentProject.getAbsolutePath(),
|
||||
PropertyType.DEFAULT);
|
||||
String targetHash = p.getProperty(ProjectProperties.PROPERTY_TARGET);
|
||||
if (targetHash == null) {
|
||||
errorAndExit("Couldn't find the main project target");
|
||||
}
|
||||
|
||||
// and resolve it.
|
||||
IAndroidTarget target = mSdkManager.getTargetFromHashString(targetHash);
|
||||
if (target == null) {
|
||||
errorAndExit(
|
||||
"Unable to resolve main project target '%1$s'. You may want to install the platform in your SDK.",
|
||||
targetHash);
|
||||
}
|
||||
|
||||
mSdkLog.printf("Found main project target: %1$s\n", target.getFullName());
|
||||
|
||||
ProjectCreator creator = new ProjectCreator(mOsSdkFolder,
|
||||
mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
|
||||
mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
|
||||
OutputLevel.NORMAL,
|
||||
mSdkLog);
|
||||
|
||||
String projectName = mSdkCommandLine.getParamName();
|
||||
|
||||
if (projectName != null &&
|
||||
!ProjectCreator.RE_PROJECT_NAME.matcher(projectName).matches()) {
|
||||
errorAndExit(
|
||||
"Project name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
|
||||
projectName, ProjectCreator.CHARS_PROJECT_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
creator.createProject(projectDir,
|
||||
projectName,
|
||||
packageName,
|
||||
activityName,
|
||||
target,
|
||||
pathToMainProject);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates an existing Android project based on command-line parameters
|
||||
*/
|
||||
|
||||
@@ -31,28 +31,30 @@ class SdkCommandLine extends CommandLineProcessor {
|
||||
public final static String VERB_DELETE = "delete";
|
||||
public final static String VERB_UPDATE = "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 OBJECT_ADB = "adb";
|
||||
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 OBJECT_TEST_PROJECT = "test-project";
|
||||
public static final String OBJECT_ADB = "adb";
|
||||
|
||||
public static final String ARG_ALIAS = "alias";
|
||||
public static final String ARG_ACTIVITY = "activity";
|
||||
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";
|
||||
public static final String KEY_RENAME = "rename";
|
||||
public static final String KEY_SUBPROJECTS = "subprojects";
|
||||
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";
|
||||
public static final String KEY_RENAME = "rename";
|
||||
public static final String KEY_SUBPROJECTS = "subprojects";
|
||||
public static final String KEY_MAIN_PROJECT = "main";
|
||||
|
||||
/**
|
||||
* Action definitions for SdkManager command line.
|
||||
@@ -89,6 +91,11 @@ class SdkCommandLine extends CommandLineProcessor {
|
||||
{ VERB_UPDATE, OBJECT_PROJECT,
|
||||
"Updates an Android Project (must have an AndroidManifest.xml)." },
|
||||
|
||||
{ VERB_CREATE, OBJECT_TEST_PROJECT,
|
||||
"Creates a new Android Test Project." },
|
||||
{ VERB_UPDATE, OBJECT_TEST_PROJECT,
|
||||
"Updates an Android Test Project (must have an AndroidManifest.xml)." },
|
||||
|
||||
{ VERB_UPDATE, OBJECT_ADB,
|
||||
"Updates adb to support the USB devices declared in the SDK add-ons." },
|
||||
};
|
||||
@@ -167,6 +174,18 @@ class SdkCommandLine extends CommandLineProcessor {
|
||||
VERB_CREATE, OBJECT_PROJECT, "n", KEY_NAME,
|
||||
"Project name", null);
|
||||
|
||||
// --- create test-project ---
|
||||
define(Mode.STRING, true,
|
||||
VERB_CREATE, OBJECT_TEST_PROJECT,
|
||||
"p", KEY_PATH,
|
||||
"Location path of new project", null);
|
||||
define(Mode.STRING, false,
|
||||
VERB_CREATE, OBJECT_TEST_PROJECT, "n", KEY_NAME,
|
||||
"Project name", null);
|
||||
define(Mode.STRING, true,
|
||||
VERB_CREATE, OBJECT_TEST_PROJECT, "m", KEY_MAIN_PROJECT,
|
||||
"Location path of the project to test, relative to the new project", null);
|
||||
|
||||
// --- update project ---
|
||||
|
||||
define(Mode.STRING, true,
|
||||
@@ -185,6 +204,17 @@ class SdkCommandLine extends CommandLineProcessor {
|
||||
VERB_UPDATE, OBJECT_PROJECT,
|
||||
"s", KEY_SUBPROJECTS,
|
||||
"Also update any projects in sub-folders, such as test projects.", false);
|
||||
|
||||
// --- update test project ---
|
||||
|
||||
define(Mode.STRING, true,
|
||||
VERB_UPDATE, OBJECT_TEST_PROJECT,
|
||||
"p", KEY_PATH,
|
||||
"Location path of the project", null);
|
||||
define(Mode.STRING, true,
|
||||
VERB_UPDATE, OBJECT_TEST_PROJECT,
|
||||
"m", KEY_MAIN_PROJECT,
|
||||
"Location path of the project to test", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -255,4 +285,11 @@ class SdkCommandLine extends CommandLineProcessor {
|
||||
public boolean getParamSubProject() {
|
||||
return ((Boolean) getValue(null, OBJECT_PROJECT, KEY_SUBPROJECTS)).booleanValue();
|
||||
}
|
||||
|
||||
// -- some helpers for test-project action flags
|
||||
|
||||
/** Helper to retrieve the --main value. */
|
||||
public String getParamTestProjectMain() {
|
||||
return ((String) getValue(null, OBJECT_TEST_PROJECT, KEY_MAIN_PROJECT));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user