Start planning for checking inputs of all tasks.
Xavier Ducrohet [Tue, 28 Aug 2012 17:28:20 +0000 (10:28 -0700)]
Each tasks of AndroidBuilder needs to be able to gather its
inputs to be checked by the front-end to figure out if the
task actually needs to be called.

Change-Id: I494ec06c070c94fe0ebb79a11e08063d199e4621

builder/src/main/java/com/android/builder/AndroidBuilder.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/CrunchResources.groovy

index 6b32aea..ebfe8e5 100644 (file)
@@ -200,16 +200,65 @@ public class AndroidBuilder {
     }
 
     /**
+     * Returns the dynamic list of resource folders.
+     * @return a list of input resource folders, guaranteed to exist.
+     */
+    public List<File> getResourceInputs() {
+        List<File> inputs = new ArrayList<File>();
+
+        if (mVariant.getBuildTypeSourceSet() != null) {
+            File typeResLocation = mVariant.getBuildTypeSourceSet().getAndroidResources();
+            if (typeResLocation != null && typeResLocation.isDirectory()) {
+                inputs.add(typeResLocation);
+            }
+        }
+
+        for (SourceSet sourceSet : mVariant.getFlavorSourceSets()) {
+            File flavorResLocation = sourceSet.getAndroidResources();
+            if (flavorResLocation != null && flavorResLocation.isDirectory()) {
+                inputs.add(flavorResLocation);
+            }
+        }
+
+        File mainResLocation = mVariant.getDefaultSourceSet().getAndroidResources();
+        if (mainResLocation != null && mainResLocation.isDirectory()) {
+            inputs.add(mainResLocation);
+        }
+
+        return inputs;
+    }
+
+    /**
      * Pre-process resources. This crunches images and process 9-patches before they can
      * be packaged.
      * This is incremental.
      *
+     * Call this directly if you don't care about checking whether the inputs have changed.
+     * Otherwise, get the input first to check with {@link #getResourceInputs()}, and then call
+     * (or not), {@link #preprocessResources(String, java.util.List)}.
+     *
      * @param resOutputDir where the processed resources are stored.
      * @throws IOException
      * @throws InterruptedException
      */
     public void preprocessResources(@NonNull String resOutputDir)
             throws IOException, InterruptedException {
+        List<File> inputs = getResourceInputs();
+
+        preprocessResources(resOutputDir, inputs);
+    }
+    /**
+     * Pre-process resources. This crunches images and process 9-patches before they can
+     * be packaged.
+     * This is incremental.
+     *
+     * @param resOutputDir where the processed resources are stored.
+     * @param inputs the input res folders
+     * @throws IOException
+     * @throws InterruptedException
+     */
+    public void preprocessResources(@NonNull String resOutputDir, @NonNull List<File> inputs)
+            throws IOException, InterruptedException {
         if (mVariant == null) {
             throw new IllegalArgumentException("No Variant Configuration has been set.");
         }
@@ -217,6 +266,10 @@ public class AndroidBuilder {
             throw new IllegalArgumentException("Target not set.");
         }
 
+        if (inputs == null || inputs.isEmpty()) {
+            return;
+        }
+
         // launch aapt: create the command line
         ArrayList<String> command = new ArrayList<String>();
 
@@ -230,39 +283,15 @@ public class AndroidBuilder {
             command.add("-v");
         }
 
-        boolean hasResToCrunch = false;
-
-        if (mVariant.getBuildTypeSourceSet() != null) {
-            File typeResLocation = mVariant.getBuildTypeSourceSet().getAndroidResources();
-            if (typeResLocation != null && typeResLocation.isDirectory()) {
-                command.add("-S");
-                command.add(typeResLocation.getAbsolutePath());
-                hasResToCrunch = true;
-            }
-        }
-
-        for (SourceSet sourceSet : mVariant.getFlavorSourceSets()) {
-            File flavorResLocation = sourceSet.getAndroidResources();
-            if (flavorResLocation != null && flavorResLocation.isDirectory()) {
-                command.add("-S");
-                command.add(flavorResLocation.getAbsolutePath());
-                hasResToCrunch = true;
-            }
-        }
-
-        File mainResLocation = mVariant.getDefaultSourceSet().getAndroidResources();
-        if (mainResLocation != null && mainResLocation.isDirectory()) {
+        for (File input : inputs) {
             command.add("-S");
-            command.add(mainResLocation.getAbsolutePath());
-            hasResToCrunch = true;
+            command.add(input.getAbsolutePath());
         }
 
         command.add("-C");
         command.add(resOutputDir);
 
-        if (hasResToCrunch) {
-            mCmdLineRunner.runCmdLine(command);
-        }
+        mCmdLineRunner.runCmdLine(command);
     }
 
     /**
index b425c74..7aa946f 100644 (file)
@@ -180,6 +180,9 @@ abstract class AndroidBasePlugin {
         def crunchTask = project.tasks.add("crunch${variant.name}Res", CrunchResources)
         crunchTask.plugin = this
         crunchTask.variant = variant
+        crunchTask.conventionMapping.resDirectories = {
+            crunchTask.getBuilder().getResourceInputs()
+        }
         crunchTask.conventionMapping.outputDir = {
             project.file("$project.buildDir/res/$variant.dirName")
         }
@@ -206,11 +209,10 @@ abstract class AndroidBasePlugin {
                                                     ProcessManifest processManifestTask,
                                                     CrunchResources crunchTask) {
         def processResources = project.tasks.add("process${variant.name}Res", ProcessResources)
-        processResources.dependsOn processManifestTask, crunchTask
+        processResources.dependsOn processManifestTask
         processResources.plugin = this
         processResources.variant = variant
         processResources.conventionMapping.manifestFile = { processManifestTask.mergedManifest }
-        processResources.conventionMapping.crunchDir = { crunchTask.outputDir }
         // TODO: unify with generateBuilderConfig somehow?
         processResources.conventionMapping.sourceOutputDir = {
             project.file("$project.buildDir/source/$variant.dirName")
@@ -224,6 +226,13 @@ abstract class AndroidBasePlugin {
                 project.file("$project.buildDir/proguard/${variant.dirName}/rules.txt")
             }
         }
+
+        if (crunchTask != null) {
+            processResources.dependsOn crunchTask
+            processResources.conventionMapping.crunchDir = { crunchTask.outputDir }
+        }
+
+
         processResources.aaptOptions = extension.aaptOptions
         return processResources
     }
index 86aec9f..bbfaf93 100644 (file)
@@ -74,14 +74,12 @@ class AndroidLibraryPlugin extends AndroidBasePlugin implements Plugin<Project>
         // Add a task to process the manifest(s)
         ProcessManifest processManifestTask = createProcessManifestTask(variant)
 
-        // Add a task to crunch resource files
-        def crunchTask = createCrunchResTask(variant)
-
         // Add a task to create the BuildConfig class
         def generateBuildConfigTask = createBuildConfigTask(variant, null)
 
         // Add a task to generate resource source files
-        def processResources = createProcessResTask(variant, processManifestTask, crunchTask)
+        def processResources = createProcessResTask(variant, processManifestTask,
+                null /*crunchTask*/)
 
         // Add a compile task
         createCompileTask(variant, null/*testedVariant*/, processResources, generateBuildConfigTask)
@@ -98,7 +96,7 @@ class AndroidLibraryPlugin extends AndroidBasePlugin implements Plugin<Project>
         // mergeRes from 3 sources. the order is important to make sure the override works well.
         // TODO: fix the case of values -- need to merge the XML!
         mergeRes.from(defaultConfigData.androidSourceSet.androidResources,
-                buildTypeData.androidSourceSet.androidResources, crunchTask.outputDir)
+                buildTypeData.androidSourceSet.androidResources)
         mergeRes.into(project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}/res"))
 
         Zip bundle = project.tasks.add("bundle${variant.name}", Zip)
@@ -124,7 +122,6 @@ class AndroidLibraryPlugin extends AndroidBasePlugin implements Plugin<Project>
 
         def testVariant = new TestAppVariant(testVariantConfig, testedVariant.config)
         createTestTasks(testVariant, testedVariant)
-
     }
 
     @Override
index 0d24df6..0ae5275 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.android.build.gradle
 
+import org.gradle.api.tasks.InputFiles
 import org.gradle.api.tasks.OutputDirectory
 import org.gradle.api.tasks.TaskAction
 
@@ -22,8 +23,11 @@ class CrunchResources extends BaseAndroidTask {
     @OutputDirectory
     File outputDir
 
+    @InputFiles
+    Iterable<File> resDirectories
+
     @TaskAction
     void generate() {
-        getBuilder().preprocessResources(getOutputDir().absolutePath)
+        getBuilder().preprocessResources(getOutputDir().absolutePath, getResDirectories())
     }
 }