diff options
17 files changed, 262 insertions, 61 deletions
diff --git a/anttasks/src/anttasks.properties b/anttasks/src/anttasks.properties index 446bbe1..e0854f4 100644 --- a/anttasks/src/anttasks.properties +++ b/anttasks/src/anttasks.properties @@ -1,6 +1,7 @@ checkenv: com.android.ant.CheckEnvTask gettype: com.android.ant.GetTypeTask gettarget: com.android.ant.GetTargetTask +getproperty: com.android.ant.GetProjectPropertyTask getlibs: com.android.ant.GetLibraryListTask dependency: com.android.ant.ComputeDependencyTask testedprojectclasspath: com.android.ant.ComputeProjectClasspathTask diff --git a/anttasks/src/com/android/ant/ComputeDependencyTask.java b/anttasks/src/com/android/ant/ComputeDependencyTask.java index 512f425..fda4e17 100644 --- a/anttasks/src/com/android/ant/ComputeDependencyTask.java +++ b/anttasks/src/com/android/ant/ComputeDependencyTask.java @@ -251,6 +251,10 @@ public class ComputeDependencyTask extends GetLibraryListTask { public String getProperty(String name) { return antProject.getProperty(name); } + + @Override + public void debugPrint() { + } }, jars); // and create a Path object for them diff --git a/anttasks/src/com/android/ant/DependencyHelper.java b/anttasks/src/com/android/ant/DependencyHelper.java index c2a6694..0019b8b 100644 --- a/anttasks/src/com/android/ant/DependencyHelper.java +++ b/anttasks/src/com/android/ant/DependencyHelper.java @@ -140,17 +140,7 @@ public class DependencyHelper { mProjectFolder = projectFolder; mVerbose = verbose; - ProjectProperties properties = ProjectProperties.load(projectFolder.getAbsolutePath(), - PropertyType.ANT); - - if (properties == null) { - properties = ProjectProperties.load(projectFolder.getAbsolutePath(), - PropertyType.PROJECT); - } else { - properties.makeWorkingCopy().merge(PropertyType.PROJECT); - } - - mProperties = properties; + mProperties = TaskHelper.getProperties(projectFolder.getAbsolutePath()); init(projectFolder); } diff --git a/anttasks/src/com/android/ant/GetLibraryListTask.java b/anttasks/src/com/android/ant/GetLibraryListTask.java index e2d5dd7..97d1773 100644 --- a/anttasks/src/com/android/ant/GetLibraryListTask.java +++ b/anttasks/src/com/android/ant/GetLibraryListTask.java @@ -60,6 +60,10 @@ public class GetLibraryListTask extends Task { public String getProperty(String name) { return antProject.getProperty(name); } + + @Override + public void debugPrint() { + } }, true /*verbose*/); diff --git a/anttasks/src/com/android/ant/GetProjectPropertyTask.java b/anttasks/src/com/android/ant/GetProjectPropertyTask.java new file mode 100644 index 0000000..1713cb7 --- /dev/null +++ b/anttasks/src/com/android/ant/GetProjectPropertyTask.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ant; + +import com.android.sdklib.SdkConstants; +import com.android.sdklib.internal.project.ProjectProperties; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +import java.io.File; + +public class GetProjectPropertyTask extends Task { + + private String mProjectPath; + private String mBinName; + private String mSrcName; + + public void setProjectPath(String projectPath) { + mProjectPath = projectPath; + } + + public void setBin(String binName) { + mBinName = binName; + } + + public void setSrc(String srcName) { + mSrcName = srcName; + } + + @Override + public void execute() throws BuildException { + if (mProjectPath == null) { + throw new BuildException("Missing attribute projectPath"); + } + + ProjectProperties props = TaskHelper.getProperties(mProjectPath); + + if (mBinName != null) { + handleProp(props, "out.dir", mBinName, SdkConstants.FD_OUTPUT); + } + + if (mSrcName != null) { + handleProp(props, "source.dir", mSrcName, SdkConstants.FD_SOURCES); + } + + } + + private void handleProp(ProjectProperties props, String inName, String outName, + String defaultValue) { + String value = props.getProperty(inName); + if (value == null) { + value = defaultValue; + } + getProject().setProperty(outName, new File(mProjectPath, value).getAbsolutePath()); + + } +} diff --git a/anttasks/src/com/android/ant/TaskHelper.java b/anttasks/src/com/android/ant/TaskHelper.java index 8a3d6bc..8a9128c 100644 --- a/anttasks/src/com/android/ant/TaskHelper.java +++ b/anttasks/src/com/android/ant/TaskHelper.java @@ -16,8 +16,11 @@ package com.android.ant; +import com.android.annotations.NonNull; import com.android.sdklib.SdkConstants; import com.android.sdklib.internal.project.ProjectProperties; +import com.android.sdklib.internal.project.ProjectProperties.PropertyType; +import com.android.sdklib.internal.project.ProjectPropertiesWorkingCopy; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; @@ -95,4 +98,44 @@ final class TaskHelper { return paths[0]; } + + /** + * Returns the ProjectProperties for a given project path. + * This loads and merge all the .properties files in the same way that Ant does it. + * + * Note that this does not return all the Ant properties but only the one customized by the + * project's own build.xml file. + * + * If the project has no .properties files, this returns an empty {@link ProjectProperties} + * with type {@link PropertyType#PROJECT}. + * + * @param projectPath the path to the project root folder. + * @return a ProjectProperties. + */ + @NonNull + static ProjectProperties getProperties(@NonNull String projectPath) { + // the import order is local, ant, project so we need to respect this. + PropertyType[] types = PropertyType.getOrderedTypes(); + + // make a working copy of the first non null props and then merge the rest into it. + ProjectProperties properties = null; + for (int i = 0 ; i < types.length ; i++) { + properties = ProjectProperties.load(projectPath, types[i]); + + if (properties != null) { + ProjectPropertiesWorkingCopy workingCopy = properties.makeWorkingCopy(); + for (int k = i + 1 ; k < types.length ; k++) { + workingCopy.merge(types[k]); + } + + // revert back to a read-only version + properties = workingCopy.makeReadOnlyCopy(); + + return properties; + } + } + + // return an empty object with type PropertyType.PROJECT (doesn't actually matter). + return ProjectProperties.createEmpty(projectPath, PropertyType.PROJECT); + } } diff --git a/files/ant/build.xml b/files/ant/build.xml index c3073fe..eb8b3d5 100644 --- a/files/ant/build.xml +++ b/files/ant/build.xml @@ -711,7 +711,8 @@ <instr verbosity="${verbosity}" mode="overwrite" instrpath="${out.absolute.dir}/classes" - outdir="${out.absolute.dir}/classes"> + outdir="${out.absolute.dir}/classes" + metadatafile="${out.absolute.dir}/coverage.em"> <filter excludes="${emma.default.filter}" /> <filter value="${emma.filter}" /> </instr> @@ -1185,10 +1186,16 @@ <!-- Application package of the tested project extracted from its manifest file --> <xpath input="${tested.project.absolute.dir}/AndroidManifest.xml" expression="/manifest/@package" output="tested.project.app.package" /> + + <getproperty projectPath="${tested.project.absolute.dir}" + bin="tested.project.out.absolute.dir" + src="tested.project.source.absolute.dir" /> </then> <else> <!-- this is a test app, the tested package is the app's own package --> <property name="tested.project.app.package" value="${project.app.package}" /> + <property name="tested.project.out.absolute.dir" value="${out.absolute.dir}" /> + <property name="tested.project.source.absolute.dir" value="${source.absolute.dir}" /> </else> </if> @@ -1210,25 +1217,23 @@ <arg line="${adb.device.arg}" /> <arg value="pull" /> <arg value="${emma.dump.file}" /> - <arg value="coverage.ec" /> + <arg value="${out.absolute.dir}/coverage.ec" /> </exec> <echo level="info">Extracting coverage report...</echo> <emma> - <report sourcepath="${tested.project.absolute.dir}/${source.dir}" - verbosity="${verbosity}"> + <report sourcepath="${tested.project.source.absolute.dir}" + verbosity="${verbosity}"> <!-- TODO: report.dir or something like should be introduced if necessary --> - <infileset dir="${out.absolute.dir}"> - <include name="coverage.ec" /> - <include name="coverage.em" /> - </infileset> + <infileset file="${out.absolute.dir}/coverage.ec" /> + <infileset file="${tested.project.out.absolute.dir}/coverage.em" /> <!-- TODO: reports in other, indicated by user formats --> - <html outfile="coverage.html" /> + <html outfile="${out.absolute.dir}/coverage.html" /> </report> </emma> <echo level="info">Cleaning up temporary files...</echo> <delete file="${out.absolute.dir}/coverage.ec" /> <delete file="${out.absolute.dir}/coverage.em" /> - <echo level="info">Saving the report file in ${basedir}/coverage/coverage.html</echo> + <echo level="info">Saving the report file in ${out.absolute.dir}/coverage.html</echo> </then> <else> <run-tests-helper /> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkBuilder.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkBuilder.java index 765ec3c..a9b2968 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkBuilder.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkBuilder.java @@ -456,10 +456,14 @@ public final class ApkBuilder implements IArchiveBuilder { } } catch (ApkCreationException e) { - mBuilder.cleanUp(); + if (mBuilder != null) { + mBuilder.cleanUp(); + } throw e; } catch (Exception e) { - mBuilder.cleanUp(); + if (mBuilder != null) { + mBuilder.cleanUp(); + } throw new ApkCreationException(e); } } diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/IPropertySource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/IPropertySource.java index 360c755..92bd6b9 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/IPropertySource.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/IPropertySource.java @@ -22,4 +22,5 @@ package com.android.sdklib.internal.project; */ public interface IPropertySource { String getProperty(String name); + void debugPrint(); } 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 9d578c4..e35a9e6 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 @@ -21,6 +21,7 @@ import static com.android.sdklib.SdkConstants.FD_TOOLS; import static com.android.sdklib.SdkConstants.FN_ANDROID_PROGUARD_FILE; import static com.android.sdklib.SdkConstants.FN_PROJECT_PROGUARD_FILE; +import com.android.annotations.NonNull; import com.android.io.FolderWrapper; import com.android.io.IAbstractFile; import com.android.io.IAbstractFolder; @@ -37,6 +38,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -111,6 +113,15 @@ public class ProjectProperties implements IPropertySource { private final Set<String> mKnownProps; private final Set<String> mRemovedProps; + /** + * Returns the PropertyTypes ordered the same way Ant order them. + */ + public static PropertyType[] getOrderedTypes() { + return new PropertyType[] { + PropertyType.LOCAL, PropertyType.ANT, PropertyType.PROJECT + }; + } + PropertyType(String filename, String header, String[] validProps, String[] removedProps) { mFilename = filename; mHeader = header; @@ -284,9 +295,11 @@ public class ProjectProperties implements IPropertySource { * <p/>The file is not created until {@link ProjectPropertiesWorkingCopy#save()} is called. * @param projectFolderOsPath the project folder. * @param type the type of property file to create + * + * @see #createEmpty(String, PropertyType) */ - public static ProjectPropertiesWorkingCopy create(String projectFolderOsPath, - PropertyType type) { + public static ProjectPropertiesWorkingCopy create(@NonNull String projectFolderOsPath, + @NonNull PropertyType type) { // create and return a ProjectProperties with an empty map. IAbstractFolder folder = new FolderWrapper(projectFolderOsPath); return create(folder, type); @@ -297,14 +310,47 @@ public class ProjectProperties implements IPropertySource { * <p/>The file is not created until {@link ProjectPropertiesWorkingCopy#save()} is called. * @param projectFolder the project folder. * @param type the type of property file to create + * + * @see #createEmpty(IAbstractFolder, PropertyType) */ - public static ProjectPropertiesWorkingCopy create(IAbstractFolder projectFolder, - PropertyType type) { + public static ProjectPropertiesWorkingCopy create(@NonNull IAbstractFolder projectFolder, + @NonNull PropertyType type) { // create and return a ProjectProperties with an empty map. return new ProjectPropertiesWorkingCopy(projectFolder, new HashMap<String, String>(), type); } /** + * Creates a new project properties object, with no properties. + * <p/>Nothing can be added to it, unless a {@link ProjectPropertiesWorkingCopy} is created + * first with {@link #makeWorkingCopy()}. + * @param projectFolderOsPath the project folder. + * @param type the type of property file to create + * + * @see #create(String, PropertyType) + */ + public static ProjectProperties createEmpty(@NonNull String projectFolderOsPath, + @NonNull PropertyType type) { + // create and return a ProjectProperties with an empty map. + IAbstractFolder folder = new FolderWrapper(projectFolderOsPath); + return createEmpty(folder, type); + } + + /** + * Creates a new project properties object, with no properties. + * <p/>Nothing can be added to it, unless a {@link ProjectPropertiesWorkingCopy} is created + * first with {@link #makeWorkingCopy()}. + * @param projectFolder the project folder. + * @param type the type of property file to create + * + * @see #create(IAbstractFolder, PropertyType) + */ + public static ProjectProperties createEmpty(@NonNull IAbstractFolder projectFolder, + @NonNull PropertyType type) { + // create and return a ProjectProperties with an empty map. + return new ProjectProperties(projectFolder, new HashMap<String, String>(), type); + } + + /** * Creates and returns a copy of the current properties as a * {@link ProjectPropertiesWorkingCopy} that can be modified and saved. * @return a new instance of {@link ProjectPropertiesWorkingCopy} @@ -436,8 +482,10 @@ public class ProjectProperties implements IPropertySource { * Use {@link #load(String, PropertyType)} or {@link #create(String, PropertyType)} * to instantiate. */ - protected ProjectProperties(IAbstractFolder projectFolder, Map<String, String> map, - PropertyType type) { + protected ProjectProperties( + @NonNull IAbstractFolder projectFolder, + @NonNull Map<String, String> map, + @NonNull PropertyType type) { mProjectFolder = projectFolder; mProperties = map; mType = type; @@ -450,4 +498,16 @@ public class ProjectProperties implements IPropertySource { protected static String escape(String value) { return value.replaceAll("\\\\", "\\\\\\\\"); } + + @Override + public void debugPrint() { + System.out.println("DEBUG PROJECTPROPERTIES: " + mProjectFolder); + System.out.println("type: " + mType); + for (Entry<String, String> entry : mProperties.entrySet()) { + System.out.println(entry.getKey() + " -> " + entry.getValue()); + } + System.out.println("<<< DEBUG PROJECTPROPERTIES"); + + } + } diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectPropertiesWorkingCopy.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectPropertiesWorkingCopy.java index 2d3f9b7..be23dbd 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectPropertiesWorkingCopy.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectPropertiesWorkingCopy.java @@ -240,4 +240,11 @@ public class ProjectPropertiesWorkingCopy extends ProjectProperties { super(projectFolder, map, type); } + public ProjectProperties makeReadOnlyCopy() { + // copy the current properties in a new map + HashMap<String, String> propList = new HashMap<String, String>(); + propList.putAll(mProperties); + + return new ProjectProperties(mProjectFolder, propList, mType); + } } diff --git a/testapps/testProjectTest/app/build.xml b/testapps/testProjectTest/app/build.xml index a6975a4..1a886ce 100644 --- a/testapps/testProjectTest/app/build.xml +++ b/testapps/testProjectTest/app/build.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<project name="LibActivity" default="help"> +<project name="testProjectTest-app" default="help"> <!-- The local.properties file is created and updated by the 'android' tool. It contains the path to the SDK. It should *NOT* be checked into @@ -28,6 +28,15 @@ --> <property file="ant.properties" /> + <!-- if sdk.dir was not set from one of the property file, then + get it from the ANDROID_HOME env var. + This must be done before we load project.properties since + the proguard config can use sdk.dir --> + <property environment="env" /> + <condition property="sdk.dir" value="${env.ANDROID_HOME}"> + <isset property="env.ANDROID_HOME" /> + </condition> + <!-- The project.properties file is created and updated by the 'android' tool, as well as ADT. @@ -39,13 +48,6 @@ application and should be checked into Version Control Systems. --> <loadproperties srcFile="project.properties" /> - <!-- if sdk.dir was not set from one of the property file, then - get it from the ANDROID_HOME env var. --> - <property environment="env" /> - <condition property="sdk.dir" value="${env.ANDROID_HOME}"> - <isset property="env.ANDROID_HOME" /> - </condition> - <!-- quick check on sdk.dir --> <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." diff --git a/testapps/testProjectTest/app/project.properties b/testapps/testProjectTest/app/project.properties index 60765b6..01b6493 100644 --- a/testapps/testProjectTest/app/project.properties +++ b/testapps/testProjectTest/app/project.properties @@ -13,3 +13,4 @@ # Project target. target=android-15 android.library.reference.1=../lib +manifestmerger.enabled=true diff --git a/testapps/testProjectTest/lib/build.xml b/testapps/testProjectTest/lib/build.xml index aaf0ab1..88c6845 100644 --- a/testapps/testProjectTest/lib/build.xml +++ b/testapps/testProjectTest/lib/build.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<project name="lib" default="help"> +<project name="testProjectTest-lib" default="help"> <!-- The local.properties file is created and updated by the 'android' tool. It contains the path to the SDK. It should *NOT* be checked into @@ -28,6 +28,15 @@ --> <property file="ant.properties" /> + <!-- if sdk.dir was not set from one of the property file, then + get it from the ANDROID_HOME env var. + This must be done before we load project.properties since + the proguard config can use sdk.dir --> + <property environment="env" /> + <condition property="sdk.dir" value="${env.ANDROID_HOME}"> + <isset property="env.ANDROID_HOME" /> + </condition> + <!-- The project.properties file is created and updated by the 'android' tool, as well as ADT. @@ -39,13 +48,6 @@ application and should be checked into Version Control Systems. --> <loadproperties srcFile="project.properties" /> - <!-- if sdk.dir was not set from one of the property file, then - get it from the ANDROID_HOME env var. --> - <property environment="env" /> - <condition property="sdk.dir" value="${env.ANDROID_HOME}"> - <isset property="env.ANDROID_HOME" /> - </condition> - <!-- quick check on sdk.dir --> <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." diff --git a/testapps/testProjectTest/testapp/build.xml b/testapps/testProjectTest/testapp/build.xml index 2682e1c..4f12210 100644 --- a/testapps/testProjectTest/testapp/build.xml +++ b/testapps/testProjectTest/testapp/build.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<project name="testapp" default="help"> +<project name="testProjectTest-testapp" default="help"> <!-- The local.properties file is created and updated by the 'android' tool. It contains the path to the SDK. It should *NOT* be checked into @@ -28,6 +28,15 @@ --> <property file="ant.properties" /> + <!-- if sdk.dir was not set from one of the property file, then + get it from the ANDROID_HOME env var. + This must be done before we load project.properties since + the proguard config can use sdk.dir --> + <property environment="env" /> + <condition property="sdk.dir" value="${env.ANDROID_HOME}"> + <isset property="env.ANDROID_HOME" /> + </condition> + <!-- The project.properties file is created and updated by the 'android' tool, as well as ADT. @@ -39,13 +48,6 @@ application and should be checked into Version Control Systems. --> <loadproperties srcFile="project.properties" /> - <!-- if sdk.dir was not set from one of the property file, then - get it from the ANDROID_HOME env var. --> - <property environment="env" /> - <condition property="sdk.dir" value="${env.ANDROID_HOME}"> - <isset property="env.ANDROID_HOME" /> - </condition> - <!-- quick check on sdk.dir --> <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." diff --git a/testapps/testProjectTest/testlib/build.xml b/testapps/testProjectTest/testlib/build.xml index 7771647..b59cc65 100644 --- a/testapps/testProjectTest/testlib/build.xml +++ b/testapps/testProjectTest/testlib/build.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<project name="testlib" default="help"> +<project name="testProjectTest-testlib" default="help"> <!-- The local.properties file is created and updated by the 'android' tool. It contains the path to the SDK. It should *NOT* be checked into @@ -28,6 +28,15 @@ --> <property file="ant.properties" /> + <!-- if sdk.dir was not set from one of the property file, then + get it from the ANDROID_HOME env var. + This must be done before we load project.properties since + the proguard config can use sdk.dir --> + <property environment="env" /> + <condition property="sdk.dir" value="${env.ANDROID_HOME}"> + <isset property="env.ANDROID_HOME" /> + </condition> + <!-- The project.properties file is created and updated by the 'android' tool, as well as ADT. @@ -39,13 +48,6 @@ application and should be checked into Version Control Systems. --> <loadproperties srcFile="project.properties" /> - <!-- if sdk.dir was not set from one of the property file, then - get it from the ANDROID_HOME env var. --> - <property environment="env" /> - <condition property="sdk.dir" value="${env.ANDROID_HOME}"> - <isset property="env.ANDROID_HOME" /> - </condition> - <!-- quick check on sdk.dir --> <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." diff --git a/testapps/testProjectTest/testlib/project.properties b/testapps/testProjectTest/testlib/project.properties index 60765b6..01b6493 100644 --- a/testapps/testProjectTest/testlib/project.properties +++ b/testapps/testProjectTest/testlib/project.properties @@ -13,3 +13,4 @@ # Project target. target=android-15 android.library.reference.1=../lib +manifestmerger.enabled=true |