aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--anttasks/src/com/android/ant/MultiApkExportTask.java21
-rw-r--r--sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java2
-rw-r--r--sdkmanager/app/src/com/android/sdkmanager/Main.java99
-rw-r--r--sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java51
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java3
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java224
-rw-r--r--sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java35
-rw-r--r--templates/build.export.template2
8 files changed, 349 insertions, 88 deletions
diff --git a/anttasks/src/com/android/ant/MultiApkExportTask.java b/anttasks/src/com/android/ant/MultiApkExportTask.java
index 7666fbc..1abbd57 100644
--- a/anttasks/src/com/android/ant/MultiApkExportTask.java
+++ b/anttasks/src/com/android/ant/MultiApkExportTask.java
@@ -21,6 +21,7 @@ import com.android.sdklib.internal.export.MultiApkExportHelper;
import com.android.sdklib.internal.export.ProjectConfig;
import com.android.sdklib.internal.export.MultiApkExportHelper.ExportException;
import com.android.sdklib.internal.export.MultiApkExportHelper.Target;
+import com.android.sdklib.internal.project.ProjectProperties;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
@@ -75,9 +76,9 @@ public class MultiApkExportTask extends Task {
System.out.println("Android SDK Tools Revision " + toolsRevison);
}
- String appPackage = getValidatedProperty(antProject, "package");
+ String appPackage = getValidatedProperty(antProject, ProjectProperties.PROPERTY_PACKAGE);
System.out.println("Multi APK export for: " + appPackage);
- String version = getValidatedProperty(antProject, "versionCode");
+ String version = getValidatedProperty(antProject, ProjectProperties.PROPERTY_VERSIONCODE);
int versionCode;
try {
versionCode = Integer.parseInt(version);
@@ -103,9 +104,9 @@ public class MultiApkExportTask extends Task {
}
} else {
// checks whether the projects can be signed.
- String value = antProject.getProperty("key.store");
+ String value = antProject.getProperty(ProjectProperties.PROPERTY_KEY_STORE);
String keyStore = value != null && value.length() > 0 ? value : null;
- value = antProject.getProperty("key.alias");
+ value = antProject.getProperty(ProjectProperties.PROPERTY_KEY_ALIAS);
String keyAlias = value != null && value.length() > 0 ? value : null;
boolean canSign = keyStore != null && keyAlias != null;
@@ -115,8 +116,8 @@ public class MultiApkExportTask extends Task {
HashSet<String> compiledProject = new HashSet<String>();
mXPathFactory = XPathFactory.newInstance();
- File exportProjectOutput = new File(getValidatedProperty(antProject,
- "out.absolute.dir"));
+ File exportProjectOutput = new File(
+ getValidatedProperty(antProject, "out.absolute.dir"));
// if there's no error, and we can sign, prompt for the passwords.
String keyStorePassword = null;
@@ -307,8 +308,8 @@ public class MultiApkExportTask extends Task {
if (canSign) {
// set the properties for the password.
- addProp(subAnt, "key.store", keyStore);
- addProp(subAnt, "key.alias", keyAlias);
+ addProp(subAnt, ProjectProperties.PROPERTY_KEY_STORE, keyStore);
+ addProp(subAnt, ProjectProperties.PROPERTY_KEY_ALIAS, keyAlias);
addProp(subAnt, "key.store.password", keyStorePassword);
addProp(subAnt, "key.alias.password", keyAliasPassword);
@@ -330,8 +331,8 @@ public class MultiApkExportTask extends Task {
// project. The reason is that if there's more than one project, we don't
// want some to signed and some not to be (and we don't want each project
// to prompt for password.)
- addProp(subAnt, "key.store", "");
- addProp(subAnt, "key.alias", "");
+ addProp(subAnt, ProjectProperties.PROPERTY_KEY_STORE, "");
+ addProp(subAnt, ProjectProperties.PROPERTY_KEY_ALIAS, "");
// final file is the unsigned version. It gets stored locally.
String outputName = finalNameRoot + "-unsigned.apk";
apk.setOutputName(softVariant != null ? softVariant.getKey() : null, outputName);
diff --git a/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java b/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
index 7edee3a..5276bed 100644
--- a/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
+++ b/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
@@ -504,7 +504,7 @@ class CommandLineProcessor {
stdout("\nValid actions are composed of a verb and an optional direct object:");
for (String[] action : mActions) {
if (verb == null || verb.equals(action[ACTION_VERB_INDEX])) {
- stdout("- %1$6s %2$-12s: %3$s",
+ stdout("- %1$6s %2$-14s: %3$s",
action[ACTION_VERB_INDEX],
action[ACTION_OBJECT_INDEX],
action[ACTION_DESC_INDEX]);
diff --git a/sdkmanager/app/src/com/android/sdkmanager/Main.java b/sdkmanager/app/src/com/android/sdkmanager/Main.java
index 4d92467..9ce3006 100644
--- a/sdkmanager/app/src/com/android/sdkmanager/Main.java
+++ b/sdkmanager/app/src/com/android/sdkmanager/Main.java
@@ -231,6 +231,10 @@ public class Main {
} else if (SdkCommandLine.OBJECT_LIB_PROJECT.equals(directObject)) {
createProject(true /*library*/);
+
+ } else if (SdkCommandLine.OBJECT_EXPORT_PROJECT.equals(directObject)) {
+ createExportProject();
+
}
} else if (SdkCommandLine.VERB_UPDATE.equals(verb)) {
if (SdkCommandLine.OBJECT_AVD.equals(directObject)) {
@@ -245,14 +249,19 @@ public class Main {
} else if (SdkCommandLine.OBJECT_LIB_PROJECT.equals(directObject)) {
updateProject(true /*library*/);
+ } else if (SdkCommandLine.OBJECT_EXPORT_PROJECT.equals(directObject)) {
+ updateExportProject();
+
} else if (SdkCommandLine.OBJECT_SDK.equals(directObject)) {
if (mSdkCommandLine.getFlagNoUI()) {
updateSdkNoUI();
} else {
showMainWindow(true /*autoUpdate*/);
}
+
} else if (SdkCommandLine.OBJECT_ADB.equals(directObject)) {
updateAdb();
+
}
} else if (SdkCommandLine.VERB_DELETE.equals(verb) &&
SdkCommandLine.OBJECT_AVD.equals(directObject)) {
@@ -346,6 +355,19 @@ public class Main {
}
/**
+ * Returns a configured {@link ProjectCreator} instance.
+ */
+ private ProjectCreator getProjectCreator() {
+ ProjectCreator creator = new ProjectCreator(mSdkManager, mOsSdkFolder,
+ mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
+ mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
+ OutputLevel.NORMAL,
+ mSdkLog);
+ return creator;
+ }
+
+
+ /**
* Creates a new Android project based on command-line parameters
*/
private void createProject(boolean library) {
@@ -361,11 +383,7 @@ public class Main {
}
IAndroidTarget target = targets[targetId - 1]; // target id is 1-based
- ProjectCreator creator = new ProjectCreator(mSdkManager, mOsSdkFolder,
- mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
- mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
- OutputLevel.NORMAL,
- mSdkLog);
+ ProjectCreator creator = getProjectCreator();
String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
@@ -384,7 +402,6 @@ public class Main {
return;
}
-
if (activityName != null &&
!ProjectCreator.RE_ACTIVITY_NAME.matcher(activityName).matches()) {
errorAndExit(
@@ -506,11 +523,7 @@ public class Main {
mSdkLog.printf("Found main project target: %1$s\n", target.getFullName());
- ProjectCreator creator = new ProjectCreator(mSdkManager, mOsSdkFolder,
- mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
- mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
- OutputLevel.NORMAL,
- mSdkLog);
+ ProjectCreator creator = getProjectCreator();
String projectName = mSdkCommandLine.getParamName();
@@ -531,6 +544,38 @@ public class Main {
pathToMainProject);
}
+ /**
+ * Creates a new Android Export project based on command-line parameters
+ */
+ private void createExportProject() {
+ ProjectCreator creator = getProjectCreator();
+
+ String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
+
+ String projectName = mSdkCommandLine.getParamName();
+ String packageName = mSdkCommandLine.getParamProjectPackage(
+ SdkCommandLine.OBJECT_EXPORT_PROJECT);
+
+ 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;
+ }
+
+ if (packageName != null &&
+ !ProjectCreator.RE_PACKAGE_NAME.matcher(packageName).matches()) {
+ errorAndExit(
+ "Package name '%1$s' contains invalid characters.\n" +
+ "A package name must be constitued of two Java identifiers.\n" +
+ "Each identifier allowed characters are: %2$s",
+ packageName, ProjectCreator.CHARS_PACKAGE_NAME);
+ return;
+ }
+
+ creator.createExportProject(projectDir, projectName, packageName);
+ }
/**
* Updates an existing Android project based on command-line parameters
@@ -553,11 +598,7 @@ public class Main {
target = targets[targetId - 1]; // target id is 1-based
}
- ProjectCreator creator = new ProjectCreator(mSdkManager, mOsSdkFolder,
- mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
- mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
- OutputLevel.NORMAL,
- mSdkLog);
+ ProjectCreator creator = getProjectCreator();
String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
@@ -605,11 +646,7 @@ public class Main {
* Updates an existing test project with a new path to the main project.
*/
private void updateTestProject() {
- ProjectCreator creator = new ProjectCreator(mSdkManager, mOsSdkFolder,
- mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
- mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
- OutputLevel.NORMAL,
- mSdkLog);
+ ProjectCreator creator = getProjectCreator();
String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
@@ -618,6 +655,26 @@ public class Main {
}
/**
+ * Updates an existing Android export project based on command-line parameters
+ */
+ private void updateExportProject() {
+ ProjectCreator creator = getProjectCreator();
+
+ String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
+
+ 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.updateExportProject(projectDir, projectName, mSdkCommandLine.getFlagForce());
+ }
+
+ /**
* Adjusts the project location to make it absolute & canonical relative to the
* working directory, if any.
*
diff --git a/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java b/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
index d4da959..906c1ac 100644
--- a/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
+++ b/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
@@ -44,15 +44,16 @@ class SdkCommandLine extends CommandLineProcessor {
public final static String VERB_DELETE = "delete";
public final static String VERB_UPDATE = "update";
- public static final String OBJECT_SDK = "sdk";
- 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_LIB_PROJECT = "lib-project";
- public static final String OBJECT_ADB = "adb";
+ public static final String OBJECT_SDK = "sdk";
+ 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_LIB_PROJECT = "lib-project";
+ public static final String OBJECT_EXPORT_PROJECT = "export-project";
+ public static final String OBJECT_ADB = "adb";
public static final String ARG_ALIAS = "alias";
public static final String ARG_ACTIVITY = "activity";
@@ -125,6 +126,11 @@ class SdkCommandLine extends CommandLineProcessor {
{ VERB_UPDATE, OBJECT_LIB_PROJECT,
"Updates an Android Library Project (must have an AndroidManifest.xml)." },
+ { VERB_CREATE, OBJECT_EXPORT_PROJECT,
+ "Creates a new Android Export Project." },
+ { VERB_UPDATE, OBJECT_EXPORT_PROJECT,
+ "Updates an Android Export Project (must have an export.properties)." },
+
{ VERB_UPDATE, OBJECT_ADB,
"Updates adb to support the USB devices declared in the SDK add-ons." },
@@ -267,6 +273,19 @@ class SdkCommandLine extends CommandLineProcessor {
VERB_CREATE, OBJECT_LIB_PROJECT, "k", KEY_PACKAGE,
"Package name", null);
+ // --- create export-project ---
+
+ define(Mode.STRING, true,
+ VERB_CREATE, OBJECT_EXPORT_PROJECT,
+ "p", KEY_PATH,
+ "Location path of new project", null);
+ define(Mode.STRING, false,
+ VERB_CREATE, OBJECT_EXPORT_PROJECT, "n", KEY_NAME,
+ "Project name", null);
+ define(Mode.STRING, true,
+ VERB_CREATE, OBJECT_EXPORT_PROJECT, "k", KEY_PACKAGE,
+ "Package name", null);
+
// --- update project ---
define(Mode.STRING, true,
@@ -311,6 +330,20 @@ class SdkCommandLine extends CommandLineProcessor {
VERB_UPDATE, OBJECT_LIB_PROJECT,
"t", KEY_TARGET_ID,
"Target id to set for the project", null);
+
+ // --- update export project ---
+
+ define(Mode.STRING, true,
+ VERB_UPDATE, OBJECT_EXPORT_PROJECT,
+ "p", KEY_PATH,
+ "Location path of the project", null);
+ define(Mode.STRING, false,
+ VERB_UPDATE, OBJECT_EXPORT_PROJECT,
+ "n", KEY_NAME,
+ "Project name", null);
+ define(Mode.BOOLEAN, false,
+ VERB_UPDATE, OBJECT_EXPORT_PROJECT, "f", KEY_FORCE,
+ "Force replacing the build.xml file", false);
}
@Override
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
index aa70cfb..e70c8fe 100644
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
@@ -86,6 +86,9 @@ public final class SdkConstants {
/** project property file */
public final static String FN_DEFAULT_PROPERTIES = "default.properties";
+ /** export property file */
+ public final static String FN_EXPORT_PROPERTIES = "export.properties";
+
/** Skin layout file */
public final static String FN_SKIN_LAYOUT = "layout";//$NON-NLS-1$
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java
index ff32a6c..4eda46c 100644
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java
@@ -21,6 +21,7 @@ import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
+import com.android.sdklib.io.StreamException;
import com.android.sdklib.xml.AndroidManifest;
import com.android.sdklib.xml.AndroidXPathFactory;
@@ -175,40 +176,9 @@ public class ProjectCreator {
String pathToMainProject) {
// create project folder if it does not exist
- File projectFolder = new File(folderPath);
- if (!projectFolder.exists()) {
-
- boolean created = false;
- Throwable t = null;
- try {
- created = projectFolder.mkdirs();
- } catch (Exception e) {
- t = e;
- }
-
- if (created) {
- println("Created project directory: %1$s", projectFolder);
- } else {
- mLog.error(t, "Could not create directory: %1$s", projectFolder);
- return;
- }
- } else {
- Exception e = null;
- String error = null;
- try {
- String[] content = projectFolder.list();
- if (content == null) {
- error = "Project folder '%1$s' is not a directory.";
- } else if (content.length != 0) {
- error = "Project folder '%1$s' is not empty. Please consider using '%2$s update' instead.";
- }
- } catch (Exception e1) {
- e = e1;
- }
-
- if (e != null || error != null) {
- mLog.error(e, error, projectFolder, SdkConstants.androidCmdName());
- }
+ File projectFolder = checkNewProjectLocation(folderPath);
+ if (projectFolder == null) {
+ return;
}
try {
@@ -396,6 +366,88 @@ public class ProjectCreator {
}
}
+ public void createExportProject(String folderPath, String projectName, String packageName) {
+ // create project folder if it does not exist
+ File projectFolder = checkNewProjectLocation(folderPath);
+ if (projectFolder == null) {
+ return;
+ }
+
+ try {
+ // location of the SDK goes in localProperty
+ ProjectProperties localProperties = ProjectProperties.create(folderPath,
+ PropertyType.LOCAL);
+ localProperties.setProperty(ProjectProperties.PROPERTY_SDK, mSdkFolder);
+ localProperties.save();
+
+ // package name goes in export properties
+ ProjectProperties exportProperties = ProjectProperties.create(folderPath,
+ PropertyType.EXPORT);
+ exportProperties.setProperty(ProjectProperties.PROPERTY_PACKAGE, packageName);
+ exportProperties.setProperty(ProjectProperties.PROPERTY_VERSIONCODE, "1");
+ exportProperties.setProperty(ProjectProperties.PROPERTY_PROJECTS, "../some/path/here");
+ exportProperties.save();
+
+ // create the map for place-holders of values to replace in the build file template
+ final HashMap<String, String> keywords = new HashMap<String, String>();
+
+ // Take the project name from the command line if there's one
+ if (projectName != null) {
+ keywords.put(PH_PROJECT_NAME, projectName);
+ } else {
+ // We need a project name. Just pick up the basename of the project
+ // directory.
+ projectName = projectFolder.getName();
+ keywords.put(PH_PROJECT_NAME, projectName);
+ }
+
+ installTemplate("build.export.template",
+ new File(projectFolder, SdkConstants.FN_BUILD_XML),
+ keywords);
+ } catch (Exception e) {
+ mLog.error(e, null);
+ }
+ }
+
+ private File checkNewProjectLocation(String folderPath) {
+ File projectFolder = new File(folderPath);
+ if (!projectFolder.exists()) {
+
+ boolean created = false;
+ Throwable t = null;
+ try {
+ created = projectFolder.mkdirs();
+ } catch (Exception e) {
+ t = e;
+ }
+
+ if (created) {
+ println("Created project directory: %1$s", projectFolder);
+ } else {
+ mLog.error(t, "Could not create directory: %1$s", projectFolder);
+ return null;
+ }
+ } else {
+ Exception e = null;
+ String error = null;
+ try {
+ String[] content = projectFolder.list();
+ if (content == null) {
+ error = "Project folder '%1$s' is not a directory.";
+ } else if (content.length != 0) {
+ error = "Project folder '%1$s' is not empty. Please consider using '%2$s update' instead.";
+ }
+ } catch (Exception e1) {
+ e = e1;
+ }
+
+ if (e != null || error != null) {
+ mLog.error(e, error, projectFolder, SdkConstants.androidCmdName());
+ }
+ }
+ return projectFolder;
+ }
+
/**
* Updates an existing project.
* <p/>
@@ -417,7 +469,7 @@ public class ProjectCreator {
public boolean updateProject(String folderPath, IAndroidTarget target, String projectName,
String libraryPath) {
// since this is an update, check the folder does point to a project
- File androidManifest = checkProjectFolder(folderPath);
+ File androidManifest = checkProjectFolder(folderPath, SdkConstants.FN_ANDROID_MANIFEST_XML);
if (androidManifest == null) {
return false;
}
@@ -488,7 +540,7 @@ public class ProjectCreator {
println("Resolved location of library project to: %1$s", resolvedPath);
// check the lib project exists
- if (checkProjectFolder(resolvedPath) == null) {
+ if (checkProjectFolder(resolvedPath, SdkConstants.FN_ANDROID_MANIFEST_XML) == null) {
mLog.error(null, "No Android Manifest at: %1$s", resolvedPath);
return false;
}
@@ -617,7 +669,7 @@ public class ProjectCreator {
public void updateTestProject(final String folderPath, final String pathToMainProject,
final SdkManager sdkManager) {
// since this is an update, check the folder does point to a project
- if (checkProjectFolder(folderPath) == null) {
+ if (checkProjectFolder(folderPath, SdkConstants.FN_ANDROID_MANIFEST_XML) == null) {
return;
}
@@ -639,7 +691,7 @@ public class ProjectCreator {
println("Resolved location of main project to: %1$s", resolvedPath);
// check the main project exists
- if (checkProjectFolder(resolvedPath) == null) {
+ if (checkProjectFolder(resolvedPath, SdkConstants.FN_ANDROID_MANIFEST_XML) == null) {
mLog.error(null, "No Android Manifest at: %1$s", resolvedPath);
return;
}
@@ -726,14 +778,97 @@ public class ProjectCreator {
}
/**
+ * Updates an existing project.
+ * <p/>
+ * Workflow:
+ * <ul>
+ * <li> Check export.properties is present (required)
+ * <li> Refresh/create "sdk" in local.properties
+ * <li> Build.xml: create if not present or no <androidinit(\w|/>) in it
+ * </ul>
+ *
+ * @param folderPath the folder of the project to update. This folder must exist.
+ * @param projectName The project name from --name. Can be null.
+ * @param force whether to force a new build.xml file.
+ * @return true if the project was successfully updated.
+ */
+ public boolean updateExportProject(String folderPath, String projectName, boolean force) {
+ // since this is an update, check the folder does point to a project
+ File androidManifest = checkProjectFolder(folderPath, SdkConstants.FN_EXPORT_PROPERTIES);
+ if (androidManifest == null) {
+ return false;
+ }
+
+ // get the parent File.
+ File projectFolder = androidManifest.getParentFile();
+
+ // Refresh/create "sdk" in local.properties
+ // because the file may already exist and contain other values (like apk config),
+ // we first try to load it.
+ ProjectProperties props = ProjectProperties.load(folderPath, PropertyType.LOCAL);
+ if (props == null) {
+ props = ProjectProperties.create(folderPath, PropertyType.LOCAL);
+ }
+
+ // set or replace the sdk location.
+ props.setProperty(ProjectProperties.PROPERTY_SDK, mSdkFolder);
+ try {
+ props.save();
+ println("Updated %1$s", PropertyType.LOCAL.getFilename());
+ } catch (Exception e) {
+ mLog.error(e, "Failed to write %1$s file in '%2$s'",
+ PropertyType.LOCAL.getFilename(),
+ folderPath);
+ return false;
+ }
+
+ // Build.xml: create if not present
+ File buildXml = new File(projectFolder, SdkConstants.FN_BUILD_XML);
+ boolean needsBuildXml = force || projectName != null || !buildXml.exists();
+
+ if (needsBuildXml) {
+ // create the map for place-holders of values to replace in the templates
+ final HashMap<String, String> keywords = new HashMap<String, String>();
+
+ // Take the project name from the command line if there's one
+ if (projectName != null) {
+ keywords.put(PH_PROJECT_NAME, projectName);
+ } else {
+ // We need a project name. Just pick up the basename of the project
+ // directory.
+ projectName = projectFolder.getName();
+ keywords.put(PH_PROJECT_NAME, projectName);
+ }
+
+ if (mLevel == OutputLevel.VERBOSE) {
+ println("Regenerating %1$s with project name %2$s",
+ SdkConstants.FN_BUILD_XML,
+ keywords.get(PH_PROJECT_NAME));
+ }
+
+ try {
+ installTemplate("build.export.template",
+ new File(projectFolder, SdkConstants.FN_BUILD_XML),
+ keywords);
+ } catch (ProjectCreateException e) {
+ mLog.error(e, null);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
* Checks whether the give <var>folderPath</var> is a valid project folder, and returns
- * a {@link File} to the AndroidManifest.xml file.
+ * a {@link File} to the required file.
* <p/>This checks that the folder exists and contains an AndroidManifest.xml file in it.
* <p/>Any error are output using {@link #mLog}.
* @param folderPath the folder to check
+ * @param requiredFilename the file name of the file that's required.
* @return a {@link File} to the AndroidManifest.xml file, or null otherwise.
*/
- private File checkProjectFolder(String folderPath) {
+ private File checkProjectFolder(String folderPath, String requiredFilename) {
// project folder must exist and be a directory, since this is an update
File projectFolder = new File(folderPath);
if (!projectFolder.isDirectory()) {
@@ -743,16 +878,15 @@ public class ProjectCreator {
}
// Check AndroidManifest.xml is present
- File androidManifest = new File(projectFolder, SdkConstants.FN_ANDROID_MANIFEST_XML);
- if (!androidManifest.isFile()) {
+ File requireFile = new File(projectFolder, requiredFilename);
+ if (!requireFile.isFile()) {
mLog.error(null,
"%1$s is not a valid project (%2$s not found).",
- folderPath,
- SdkConstants.FN_ANDROID_MANIFEST_XML);
+ folderPath, requiredFilename);
return null;
}
- return androidManifest;
+ return requireFile;
}
/**
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java
index 523f45e..68fa817 100644
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java
@@ -57,10 +57,17 @@ public final class ProjectProperties {
public final static String PROPERTY_BUILD_SOURCE_DIR = "source.dir";
+ public final static String PROPERTY_PACKAGE = "package";
+ public final static String PROPERTY_VERSIONCODE = "versionCode";
+ public final static String PROPERTY_PROJECTS = "projects";
+ public final static String PROPERTY_KEY_STORE = "key.store";
+ public final static String PROPERTY_KEY_ALIAS = "key.alias";
+
public static enum PropertyType {
BUILD("build.properties", BUILD_HEADER),
DEFAULT(SdkConstants.FN_DEFAULT_PROPERTIES, DEFAULT_HEADER),
- LOCAL("local.properties", LOCAL_HEADER);
+ LOCAL("local.properties", LOCAL_HEADER),
+ EXPORT("export.properties", EXPORT_HEADER);
private final String mFilename;
private final String mHeader;
@@ -116,6 +123,24 @@ public final class ProjectProperties {
"# The password will be asked during the build when you use the 'release' target.\n" +
"\n";
+ private final static String EXPORT_HEADER =
+// 1-------10--------20--------30--------40--------50--------60--------70--------80
+ "# Export properties\n" +
+ "# \n" +
+ "# This file must be checked in Version Control Systems.\n" +
+ "\n" +
+ "# The main content for this file is:\n" +
+ "# - package name for the application being export\n" +
+ "# - list of the projects being export\n" +
+ "# - version code for the application\n" +
+ "\n" +
+ "# You can also use it define how the release builds are signed by declaring\n" +
+ "# the following properties:\n" +
+ "# 'key.store' for the location of your keystore and\n" +
+ "# 'key.alias' for the name of the key alias to use.\n" +
+ "# The password will be asked during the build when you use the 'release' target.\n" +
+ "\n";
+
private final static Map<String, String> COMMENT_MAP = new HashMap<String, String>();
static {
// 1-------10--------20--------30--------40--------50--------60--------70--------80
@@ -130,6 +155,14 @@ public final class ProjectProperties {
COMMENT_MAP.put(PROPERTY_APP_PACKAGE,
"# The name of your application package as defined in the manifest.\n" +
"# Used by the 'uninstall' rule.\n");
+ COMMENT_MAP.put(PROPERTY_PACKAGE,
+ "# Package of the application being exported\n");
+ COMMENT_MAP.put(PROPERTY_VERSIONCODE,
+ "# Major version code\n");
+ COMMENT_MAP.put(PROPERTY_PROJECTS,
+ "# List of the Android projects being used for the export.\n" +
+ "# The list is made of paths that are relative to this project,\n" +
+ "# using forward-slash (/) as separator, and are separated by colons (:).\n");
}
private final IAbstractFolder mProjectFolder;
diff --git a/templates/build.export.template b/templates/build.export.template
index bdf3032..74c13a6 100644
--- a/templates/build.export.template
+++ b/templates/build.export.template
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project name="Main" default="help">
+<project name="PROJECT_NAME" default="help">
<!-- The local.properties file is created and updated by the 'android'
tool.