Remove the default java tasks and fix packaging java res
Xavier Ducrohet [Fri, 21 Sep 2012 23:39:16 +0000 (16:39 -0700)]
Until we use custom source set more adapted to our needs,
we delete the default java tasks after each source set is created.

This also fixes the packaging of java resources. Right now
this reads directly from the source folder, instead of copying
to a build folder based on a configurable source set. This should
be fixed once we use our own source set.

Also fixed packaging java resources from jars and libraries
which was missing. This led me to clean up a bit how
we handle library deps (especially related to test projects
for libraries) and fixed an issue related to merging manifests.

Change-Id: I0cc7fb833c2319da501cb92258be7d79b1c3771b

builder/src/main/java/com/android/builder/AndroidBuilder.java
builder/src/main/java/com/android/builder/VariantConfiguration.java
gradle/src/main/groovy/com/android/build/gradle/AndroidBasePlugin.groovy
gradle/src/main/groovy/com/android/build/gradle/AndroidLibraryPlugin.groovy
gradle/src/main/groovy/com/android/build/gradle/AndroidPlugin.groovy
testapps/libsTest/app/src/main/resources/com/android/tests/libstest/app/App.txt [moved from testapps/libsTest/app/src/main/java/com/android/tests/libstest/app/App.txt with 100% similarity]
testapps/libsTest/lib1/src/main/resources/com/android/tests/libstest/lib1/Lib1.txt [moved from testapps/libsTest/lib1/src/main/java/com/android/tests/libstest/lib1/Lib1.txt with 100% similarity]
testapps/libsTest/lib2/src/main/resources/com/android/tests/libstest/lib2/Lib2.txt [moved from testapps/libsTest/lib2/src/main/java/com/android/tests/libstest/lib2/Lib2.txt with 100% similarity]

index fb91ca6..8eaa18a 100644 (file)
@@ -35,9 +35,9 @@ import com.android.manifmerger.MergerLog;
 import com.android.prefs.AndroidLocation.AndroidLocationException;
 import com.android.sdklib.IAndroidTarget;
 import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
-import com.android.sdklib.io.FileOp;
 import com.android.utils.ILogger;
 import com.google.common.collect.Lists;
+import com.google.common.io.Files;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -292,7 +292,7 @@ public class AndroidBuilder {
 
                     mergeLibraryManifests(
                             generatedTestManifest,
-                            mVariant.getFullDirectDependencies(),
+                            mVariant.getDirectLibraries(),
                             new File(outManifestLocation));
                 } catch (IOException e) {
                     throw new RuntimeException(e);
@@ -320,53 +320,71 @@ public class AndroidBuilder {
 
     private void mergeManifest(VariantConfiguration config, String outManifestLocation) {
         try {
-            File mainLocation = config.getDefaultSourceSet().getAndroidManifest();
+            // gather the app manifests: main + buildType and Flavors.
+            File mainManifest = config.getDefaultSourceSet().getAndroidManifest();
+
+            List<File> subManifests = Lists.newArrayList();
+
             File typeLocation = config.getBuildTypeSourceSet().getAndroidManifest();
-            if (typeLocation != null && typeLocation.isFile() == false) {
-                typeLocation = null;
+            if (typeLocation != null && typeLocation.isFile()) {
+                subManifests.add(typeLocation);
             }
 
-            List<File> flavorManifests = Lists.newArrayList();
             for (SourceSet sourceSet : config.getFlavorSourceSets()) {
                 File f = sourceSet.getAndroidManifest();
                 if (f != null && f.isFile()) {
-                    flavorManifests.add(f);
+                    subManifests.add(f);
                 }
             }
 
             // if no manifest to merge, just copy to location
-            if (typeLocation == null && flavorManifests.isEmpty() && !config.hasLibraries()) {
-                new FileOp().copyFile(mainLocation, new File(outManifestLocation));
+            if (subManifests.isEmpty() && !config.hasLibraries()) {
+                Files.copy(mainManifest, new File(outManifestLocation));
             } else {
-                if (!config.hasLibraries()) {
+                File outManifest = new File(outManifestLocation);
 
-                    File appMergeOut = new File(outManifestLocation);
+                // first merge the app manifest.
+                if (!subManifests.isEmpty()) {
+                    File mainManifestOut = outManifest;
 
-                    List<File> manifests = Lists.newArrayList();
-                    if (typeLocation != null) {
-                        manifests.add(typeLocation);
+                    // if there is also libraries, put this in a temp file.
+                    if (config.hasLibraries()) {
+                        // TODO find better way of storing intermediary file?
+                        mainManifestOut = File.createTempFile("manifestMerge", ".xml");
+                        mainManifestOut.deleteOnExit();
                     }
-                    manifests.addAll(flavorManifests);
 
                     ManifestMerger merger = new ManifestMerger(MergerLog.wrapSdkLog(mLogger));
                     if (merger.process(
-                            appMergeOut,
-                            mainLocation,
-                            manifests.toArray(new File[manifests.size()])) == false) {
+                            mainManifestOut,
+                            mainManifest,
+                            subManifests.toArray(new File[subManifests.size()])) == false) {
                         throw new RuntimeException();
                     }
-                } else {
+
+                    // now the main manifest is the newly merged one
+                    mainManifest = mainManifestOut;
+                }
+
+                if (config.hasLibraries()) {
                     // recursively merge all manifests starting with the leaves and up toward the
                     // root (the app)
-                    mergeLibraryManifests(mainLocation, config.getDirectLibraries(),
+                    mergeLibraryManifests(mainManifest, config.getDirectLibraries(),
                             new File(outManifestLocation));
-                    }
+                }
             }
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
     }
 
+    /**
+     * Merges library manifests into a main manifest.
+     * @param mainManifest the main manifest
+     * @param directLibraries the libraries to merge
+     * @param outManifest the output file
+     * @throws IOException
+     */
     private void mergeLibraryManifests(
             File mainManifest,
             Iterable<AndroidDependency> directLibraries,
@@ -806,6 +824,18 @@ public class AndroidBuilder {
                 }
             }
 
+            // add the resources from the jar files.
+            List<JarDependency> jars = mVariant.getJars();
+            if (jars != null) {
+                for (JarDependency jar : jars) {
+                    packager.addResourcesFromJar(new File(jar.getLocation()));
+                }
+            }
+
+            // add the resources from the libs jar files
+            List<AndroidDependency> libs = mVariant.getDirectLibraries();
+            addLibJavaResourcesToPackager(packager, libs);
+
             // also add resources from library projects and jars
             if (jniLibsLocation != null) {
                 packager.addNativeLibraries(jniLibsLocation);
@@ -818,4 +848,16 @@ public class AndroidBuilder {
             throw new RuntimeException(e);
         }
     }
+
+    private void addLibJavaResourcesToPackager(Packager packager, List<AndroidDependency> libs)
+            throws PackagerException, SealedPackageException, DuplicateFileException {
+        if (libs != null) {
+            for (AndroidDependency lib : libs) {
+                packager.addResourcesFromJar(lib.getJarFile());
+
+                // recursively add the dependencies of this library.
+                addLibJavaResourcesToPackager(packager, lib.getDependencies());
+            }
+        }
+    }
 }
index 8a5e392..aac7e79 100644 (file)
@@ -57,13 +57,13 @@ public class VariantConfiguration {
 
     private List<JarDependency> mJars;
 
-    /** List of direct library project dependencies. Each object defines its own dependencies. */
-    private final List<AndroidDependency> mDirectLibraryProjects = Lists.newArrayList();
+    /** List of direct library dependencies. Each object defines its own dependencies. */
+    private final List<AndroidDependency> mDirectLibraries = Lists.newArrayList();
 
-    /** list of all library project dependencies in the flat list.
+    /** list of all library dependencies in a flat list.
      * The order is based on the order needed to call aapt: earlier libraries override resources
      * of latter ones. */
-    private final List<AndroidDependency> mFlatLibraryProjects = Lists.newArrayList();
+    private final List<AndroidDependency> mFlatLibraries = Lists.newArrayList();
 
     public static enum Type {
         DEFAULT, LIBRARY, TEST;
@@ -128,6 +128,12 @@ public class VariantConfiguration {
 
         mMergedFlavor = mDefaultConfig;
 
+        if (testedConfig != null &&
+                testedConfig.mType == Type.LIBRARY &&
+                testedConfig.mOutput != null) {
+            mDirectLibraries.add(testedConfig.mOutput);
+        }
+
         validate();
     }
 
@@ -151,47 +157,31 @@ public class VariantConfiguration {
         mJars = jars;
     }
 
-    /**
-     * Set the Library Project dependencies.
-     * @param directLibraryProjects list of direct dependencies. Each library object should contain
-     *            its own dependencies.
-     */
-    public void setAndroidDependencies(@NonNull List<AndroidDependency> directLibraryProjects) {
-        if (directLibraryProjects != null) {
-            mDirectLibraryProjects.addAll(directLibraryProjects);
-        }
-
-        resolveIndirectLibraryDependencies(getFullDirectDependencies(), mFlatLibraryProjects);
+    public List<JarDependency> getJars() {
+        return mJars;
     }
 
     /**
-     * Returns all direct dependencies, including the tested config if it's a library itself.
-     * @return
+     * Set the Library Project dependencies.
+     * @param directLibraries list of direct dependencies. Each library object should contain
+     *            its own dependencies.
      */
-    public List<AndroidDependency> getFullDirectDependencies() {
-        if (mTestedConfig != null && mTestedConfig.getType() == Type.LIBRARY) {
-            // in case of a library we merge all the dependencies together.
-            List<AndroidDependency> list = Lists.newArrayListWithExpectedSize(
-                    mDirectLibraryProjects.size() +
-                            mTestedConfig.mDirectLibraryProjects.size() + 1);
-            list.addAll(mDirectLibraryProjects);
-            list.add(mTestedConfig.mOutput);
-            list.addAll(mTestedConfig.mDirectLibraryProjects);
-
-            return list;
+    public void setAndroidDependencies(@NonNull List<AndroidDependency> directLibraries) {
+        if (directLibraries != null) {
+            mDirectLibraries.addAll(directLibraries);
         }
 
-        return mDirectLibraryProjects;
+        resolveIndirectLibraryDependencies(mDirectLibraries, mFlatLibraries);
     }
 
     public String getLibraryPackages() {
-        if (mFlatLibraryProjects.isEmpty()) {
+        if (mFlatLibraries.isEmpty()) {
             return null;
         }
 
         StringBuilder sb = new StringBuilder();
 
-        for (AndroidDependency dep : mFlatLibraryProjects) {
+        for (AndroidDependency dep : mFlatLibraries) {
             File manifest = dep.getManifest();
             String packageName = sManifestParser.getPackage(manifest);
             if (sb.length() > 0) {
@@ -244,15 +234,11 @@ public class VariantConfiguration {
     }
 
     public boolean hasLibraries() {
-        return !mDirectLibraryProjects.isEmpty();
+        return !mDirectLibraries.isEmpty();
     }
 
     public List<AndroidDependency> getDirectLibraries() {
-        return mDirectLibraryProjects;
-    }
-
-    public List<AndroidDependency> getFlatLibraries() {
-        return mFlatLibraryProjects;
+        return mDirectLibraries;
     }
 
     public Type getType() {
@@ -383,7 +369,7 @@ public class VariantConfiguration {
         list.add(mBuildType);
         list.addAll(mFlavorConfigs);
         // TODO: figure out the deps in here.
-//        list.addAll(mFlatLibraryProjects);
+//        list.addAll(mFlatLibraries);
 
         return list;
     }
@@ -411,7 +397,7 @@ public class VariantConfiguration {
             }
         }
 
-        List<AndroidDependency> libs = getFullDirectDependencies();
+        List<AndroidDependency> libs = mDirectLibraries;
         for (AndroidDependency lib : libs) {
             File manifest = lib.getManifest();
             if (manifest != null && manifest.isFile()) {
@@ -449,7 +435,7 @@ public class VariantConfiguration {
             inputs.add(mainResLocation);
         }
 
-        for (AndroidDependency dependency : mFlatLibraryProjects) {
+        for (AndroidDependency dependency : mFlatLibraries) {
             File resFolder = dependency.getResFolder();
             if (resFolder != null) {
                 inputs.add(resFolder);
@@ -467,7 +453,7 @@ public class VariantConfiguration {
     public List<File> getAidlImports() {
         List<File> list = Lists.newArrayList();
 
-        for (AndroidDependency lib : mFlatLibraryProjects) {
+        for (AndroidDependency lib : mFlatLibraries) {
             File aidlLib = lib.getAidlFolder();
             if (aidlLib != null && aidlLib.isDirectory()) {
                 list.add(aidlLib);
@@ -501,7 +487,7 @@ public class VariantConfiguration {
             }
         }
 
-        for (AndroidDependency lib : mFlatLibraryProjects) {
+        for (AndroidDependency lib : mFlatLibraries) {
             classpath.add(lib.getJarFile());
         }
 
index 9dbe187..baac813 100644 (file)
@@ -73,6 +73,14 @@ abstract class AndroidBasePlugin {
         mainSourceSet = project.sourceSets.add("main")
         testSourceSet = project.sourceSets.add("test")
 
+        // TODO remove when moving to custom source sets
+        project.tasks.remove(project.tasks.getByName("classes"))
+        project.tasks.remove(project.tasks.getByName("compileJava"))
+        project.tasks.remove(project.tasks.getByName("processResources"))
+        project.tasks.remove(project.tasks.getByName("testClasses"))
+        project.tasks.remove(project.tasks.getByName("compileTestJava"))
+        project.tasks.remove(project.tasks.getByName("processTestResources"))
+
         project.tasks.assemble.description =
             "Assembles all variants of all applications and secondary packages."
 
index 3b6155d..3217612 100644 (file)
@@ -51,6 +51,14 @@ class AndroidLibraryPlugin extends AndroidBasePlugin implements Plugin<Project>
         def debugSourceSet = project.sourceSets.add(BuildType.DEBUG)
         def releaseSourceSet = project.sourceSets.add(BuildType.RELEASE)
 
+        // TODO remove when moving to custom source sets
+        project.tasks.remove(project.tasks.getByName("debugClasses"))
+        project.tasks.remove(project.tasks.getByName("compileDebugJava"))
+        project.tasks.remove(project.tasks.getByName("processDebugResources"))
+        project.tasks.remove(project.tasks.getByName("releaseClasses"))
+        project.tasks.remove(project.tasks.getByName("compileReleaseJava"))
+        project.tasks.remove(project.tasks.getByName("processReleaseResources"))
+
         debugBuildTypeData = new BuildTypeData(extension.debug, debugSourceSet, project)
         releaseBuildTypeData = new BuildTypeData(extension.release, releaseSourceSet, project)
         project.tasks.assemble.dependsOn debugBuildTypeData.assembleTask
@@ -120,6 +128,10 @@ class AndroidLibraryPlugin extends AndroidBasePlugin implements Plugin<Project>
         // jar the classes.
         Jar jar = project.tasks.add("${buildTypeData.buildType.name}Jar", Jar);
         jar.from(variant.compileTask.outputs);
+        // TODO: replace with proper ProcessResources task with properly configured SourceDirectorySet
+        jar.from(defaultConfigData.androidSourceSet.javaResources);
+        jar.from(buildTypeData.androidSourceSet.javaResources);
+
         jar.destinationDir = project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}")
         jar.archiveName = "classes.jar"
         String packageName = variantConfig.getPackageFromManifest().replace('.', '/');
@@ -165,7 +177,7 @@ class AndroidLibraryPlugin extends AndroidBasePlugin implements Plugin<Project>
 
             @Override
             List<AndroidDependency> getDependencies() {
-                return []
+                return variantConfig.directLibraries
             }
         };
 
index 7d31e86..7eff8ed 100644 (file)
@@ -81,6 +81,11 @@ class AndroidPlugin extends AndroidBasePlugin implements Plugin<Project> {
 
         def sourceSet = project.sourceSets.add(buildType.name)
 
+        // TODO remove when moving to custom source sets
+        project.tasks.remove(project.tasks.getByName("${buildType.name}Classes"))
+        project.tasks.remove(project.tasks.getByName("compile${buildType.name.capitalize()}Java"))
+        project.tasks.remove(project.tasks.getByName("process${buildType.name.capitalize()}Resources"))
+
         BuildTypeData buildTypeData = new BuildTypeData(buildType, sourceSet, project)
         project.tasks.assemble.dependsOn buildTypeData.assembleTask
 
@@ -96,7 +101,16 @@ class AndroidPlugin extends AndroidBasePlugin implements Plugin<Project> {
         }
 
         def mainSourceSet = project.sourceSets.add(productFlavor.name)
-        def testSourceSet = project.sourceSets.add("test${productFlavor.name.capitalize()}")
+        String testName = "test${productFlavor.name.capitalize()}"
+        def testSourceSet = project.sourceSets.add(testName)
+
+        // TODO remove when moving to custom source sets
+        project.tasks.remove(project.tasks.getByName("${productFlavor.name}Classes"))
+        project.tasks.remove(project.tasks.getByName("compile${productFlavor.name.capitalize()}Java"))
+        project.tasks.remove(project.tasks.getByName("process${productFlavor.name.capitalize()}Resources"))
+        project.tasks.remove(project.tasks.getByName("${testName}Classes"))
+        project.tasks.remove(project.tasks.getByName("compile${testName.capitalize()}Java"))
+        project.tasks.remove(project.tasks.getByName("process${testName.capitalize()}Resources"))
 
         ProductFlavorData productFlavorData = new ProductFlavorData(
                 productFlavor, mainSourceSet, testSourceSet, project)