aboutsummaryrefslogtreecommitdiff
path: root/gradle/src
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2012-10-05 10:56:03 -0700
committerXavier Ducrohet <xav@android.com>2012-10-05 17:59:45 -0700
commitdc71ab2627ac4f4f8843dd0d5a1d84ac0f04662d (patch)
tree77c79f6230302df67176b79f4d616a1c3e9f449b /gradle/src
parentd14ea2c706561925d45feb30a1b57732bcefc383 (diff)
downloadbuild-dc71ab2627ac4f4f8843dd0d5a1d84ac0f04662d.tar.gz
Support compile config for flavors and build types.
Read dependency graph and create list of JarDependency and AndroidDependency for each configuration. Set Jars and AndroidDependency on each VariantConfig object. Add a AndroidDependency report task (called androidDependency) The prepareDependenciesTask will prepare the same artifact multiple time if it's used by different variants and they are all built. This will be fixed in the next patch. Change-Id: I4f11565c3629a54f022ecc82f81d4900ef2bd0c9
Diffstat (limited to 'gradle/src')
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/AndroidDependencyTask.groovy70
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy103
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy125
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/DependencyChecker.groovy29
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy53
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/PrepareDependenciesTask.groovy1
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/AndroidAsciiReportRenderer.java123
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/AndroidDependencyImpl.groovy7
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/ApplicationVariant.groovy4
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/BuildTypeData.groovy8
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/ConfigurationDependencies.groovy49
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/internal/ProductFlavorData.groovy12
12 files changed, 513 insertions, 71 deletions
diff --git a/gradle/src/main/groovy/com/android/build/gradle/AndroidDependencyTask.groovy b/gradle/src/main/groovy/com/android/build/gradle/AndroidDependencyTask.groovy
new file mode 100644
index 0000000..882572c
--- /dev/null
+++ b/gradle/src/main/groovy/com/android/build/gradle/AndroidDependencyTask.groovy
@@ -0,0 +1,70 @@
+/*
+ * 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.build.gradle
+
+import com.android.build.gradle.internal.ApplicationVariant
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.tasks.TaskAction
+import org.gradle.logging.StyledTextOutputFactory
+import com.android.build.gradle.internal.AndroidAsciiReportRenderer
+
+/**
+ */
+class AndroidDependencyTask extends DefaultTask {
+
+ private AndroidAsciiReportRenderer renderer = new AndroidAsciiReportRenderer();
+
+ private Set<ApplicationVariant> variants = [];
+
+ @TaskAction
+ public void generate() throws IOException {
+ renderer.setOutput(getServices().get(StyledTextOutputFactory.class).create(getClass()));
+
+ SortedSet<ApplicationVariant> sortedConfigurations = new TreeSet<Configuration>(
+ new Comparator<ApplicationVariant>() {
+ public int compare(ApplicationVariant conf1, ApplicationVariant conf2) {
+ return conf1.getName().compareTo(conf2.getName());
+ }
+ });
+ sortedConfigurations.addAll(getVariants());
+ for (ApplicationVariant variant : sortedConfigurations) {
+ renderer.startVariant(variant);
+ renderer.render(variant);
+ }
+ }
+
+ /**
+ * Returns the configurations to generate the report for. Default to all configurations of
+ * this task's containing project.
+ *
+ * @return the configurations.
+ */
+ public Set<ApplicationVariant> getVariants() {
+ return variants;
+ }
+
+ /**
+ * Sets the configurations to generate the report for.
+ *
+ * @param configurations The configuration. Must not be null.
+ */
+ public void setVariants(Collection<ApplicationVariant> variants) {
+ this.variants.addAll(variants);
+ }
+}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy
index 3d49b75..068c86d 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy
@@ -17,11 +17,14 @@ package com.android.build.gradle
import com.android.build.gradle.internal.BuildTypeData
import com.android.build.gradle.internal.BuildTypeDsl
+import com.android.build.gradle.internal.ConfigurationDependencies
import com.android.build.gradle.internal.ProductFlavorData
import com.android.build.gradle.internal.ProductFlavorDsl
import com.android.build.gradle.internal.ProductionAppVariant
import com.android.build.gradle.internal.TestAppVariant
+import com.android.builder.AndroidDependency
import com.android.builder.BuildType
+import com.android.builder.JarDependency
import com.android.builder.VariantConfiguration
import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.ListMultimap
@@ -106,6 +109,13 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl
}
private void createAndroidTasks() {
+ // resolve dependencies for all config
+ List<ConfigurationDependencies> dependencies = []
+ dependencies.addAll(buildTypes.values())
+ dependencies.addAll(productFlavors.values())
+ resolveDependencies(dependencies)
+
+ // now create the tasks.
if (productFlavors.isEmpty()) {
createTasksForDefaultBuild()
} else {
@@ -142,6 +152,8 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl
createTasksForMultiFlavoredBuilds(array, 0, map)
}
}
+
+ createDependencyReportTask()
}
private createTasksForMultiFlavoredBuilds(ProductFlavorData[] datas, int i,
@@ -177,13 +189,32 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl
ProductFlavorData defaultConfigData = getDefaultConfigData();
for (BuildTypeData buildTypeData : buildTypes.values()) {
+ List<ConfigurationDependencies> configDependencies = []
+ configDependencies.add(defaultConfigData)
+ configDependencies.add(buildTypeData)
+
+ // list of dependency to set on the variantConfig
+ List<JarDependency> jars = []
+ jars.addAll(defaultConfigData.jars)
+ jars.addAll(buildTypeData.jars)
+
+ // the order of the libraries is important. In descending order:
+ // build types, flavors, defaultConfig.
+ List<AndroidDependency> libs = []
+ libs.addAll(buildTypeData.libraries)
+ // no flavors, just add the default config
+ libs.addAll(defaultConfigData.libraries)
def variantConfig = new VariantConfiguration(
defaultConfigData.productFlavor, defaultConfigData.sourceSet,
buildTypeData.buildType, buildTypeData.sourceSet)
+ variantConfig.setJarDependencies(jars)
+ variantConfig.setAndroidDependencies(libs)
+
ProductionAppVariant productionAppVariant = addVariant(variantConfig,
- buildTypeData.assembleTask)
+ buildTypeData.assembleTask, configDependencies)
+ variants.add(productionAppVariant)
if (buildTypeData == testData) {
testedVariant = productionAppVariant
@@ -197,11 +228,21 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl
testData.buildType, null,
VariantConfiguration.Type.TEST, testedVariant.config)
- // TODO: add actual dependencies
- testVariantConfig.setAndroidDependencies(null)
+ List<ConfigurationDependencies> testConfigDependencies = []
+ testConfigDependencies.add(defaultConfigData.testConfigDependencies)
+
+ // list of dependency to set on the variantConfig
+ List<JarDependency> testJars = []
+ testJars.addAll(defaultConfigData.testConfigDependencies.jars)
+ List<AndroidDependency> testLibs = []
+ testLibs.addAll(defaultConfigData.testConfigDependencies.libraries)
+
+ testVariantConfig.setJarDependencies(testJars)
+ testVariantConfig.setAndroidDependencies(testLibs)
def testVariant = new TestAppVariant(testVariantConfig)
- createTestTasks(testVariant, testedVariant)
+ variants.add(testVariant)
+ createTestTasks(testVariant, testedVariant, testConfigDependencies)
}
/**
@@ -222,6 +263,19 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl
def assembleTask
for (BuildTypeData buildTypeData : buildTypes.values()) {
+ List<ConfigurationDependencies> configDependencies = []
+ configDependencies.add(defaultConfigData)
+ configDependencies.add(buildTypeData)
+
+ // list of dependency to set on the variantConfig
+ List<JarDependency> jars = []
+ jars.addAll(defaultConfigData.jars)
+ jars.addAll(buildTypeData.jars)
+
+ // the order of the libraries is important. In descending order:
+ // build types, flavors, defaultConfig.
+ List<AndroidDependency> libs = []
+ libs.addAll(buildTypeData.libraries)
def variantConfig = new VariantConfiguration(
extension.defaultConfig, getDefaultConfigData().sourceSet,
@@ -229,9 +283,20 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl
for (ProductFlavorData data : flavorDataList) {
variantConfig.addProductFlavor(data.productFlavor, data.sourceSet)
+ jars.addAll(data.jars)
+ libs.addAll(data.libraries)
+ configDependencies.add(data)
}
- ProductionAppVariant productionAppVariant = addVariant(variantConfig, null)
+ // now add the defaultConfig
+ libs.addAll(defaultConfigData.libraries)
+
+ variantConfig.setJarDependencies(jars)
+ variantConfig.setAndroidDependencies(libs)
+
+ ProductionAppVariant productionAppVariant = addVariant(variantConfig, null,
+ configDependencies)
+ variants.add(productionAppVariant)
buildTypeData.assembleTask.dependsOn productionAppVariant.assembleTask
@@ -254,15 +319,32 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl
testData.buildType, null,
VariantConfiguration.Type.TEST, testedVariant.config)
+ List<ConfigurationDependencies> testConfigDependencies = []
+ testConfigDependencies.add(defaultConfigData.testConfigDependencies)
+
+ // list of dependency to set on the variantConfig
+ List<JarDependency> testJars = []
+ testJars.addAll(defaultConfigData.testConfigDependencies.jars)
+
+ // the order of the libraries is important. In descending order:
+ // flavors, defaultConfig.
+ List<AndroidDependency> testLibs = []
+
for (ProductFlavorData data : flavorDataList) {
testVariantConfig.addProductFlavor(data.productFlavor, data.testSourceSet)
+ testJars.addAll(data.testConfigDependencies.jars)
+ testLibs.addAll(data.testConfigDependencies.libraries)
}
- // TODO: add actual dependencies
- testVariantConfig.setAndroidDependencies(null)
+ // now add the default config
+ testLibs.addAll(defaultConfigData.testConfigDependencies.libraries)
+
+ testVariantConfig.setJarDependencies(testJars)
+ testVariantConfig.setAndroidDependencies(testLibs)
def testVariant = new TestAppVariant(testVariantConfig)
- createTestTasks(testVariant, testedVariant)
+ variants.add(testVariant)
+ createTestTasks(testVariant, testedVariant, testConfigDependencies)
}
private Task createAssembleTask(ProductFlavorData[] flavorDataList) {
@@ -281,11 +363,12 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl
* @param assembleTask an optional assembleTask to be used. If null, a new one is created.
* @return
*/
- private ProductionAppVariant addVariant(VariantConfiguration variantConfig, Task assembleTask) {
+ private ProductionAppVariant addVariant(VariantConfiguration variantConfig, Task assembleTask,
+ List<ConfigurationDependencies> configDependencies) {
def variant = new ProductionAppVariant(variantConfig)
- def prepareDependenciesTask = createPrepareDependenciesTask(variant)
+ def prepareDependenciesTask = createPrepareDependenciesTask(variant, configDependencies)
// Add a task to process the manifest(s)
def processManifestTask = createProcessManifestTask(variant, "manifests")
diff --git a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
index a07766b..954d5dd 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
@@ -18,6 +18,7 @@ package com.android.build.gradle
import com.android.SdkConstants
import com.android.build.gradle.internal.AndroidDependencyImpl
import com.android.build.gradle.internal.ApplicationVariant
+import com.android.build.gradle.internal.ConfigurationDependencies
import com.android.build.gradle.internal.ProductFlavorData
import com.android.build.gradle.internal.ProductionAppVariant
import com.android.build.gradle.internal.TestAppVariant
@@ -57,6 +58,8 @@ abstract class BasePlugin {
private final Map<Object, AndroidBuilder> builders = [:]
+ final List<ApplicationVariant> variants = []
+
protected Project project
protected File sdkDir
private DefaultSdkParser androidSdkParser
@@ -370,9 +373,15 @@ abstract class BasePlugin {
variant.compileTask = compileTask
}
- protected void createTestTasks(TestAppVariant variant, ProductionAppVariant testedVariant) {
+ protected void createTestTasks(TestAppVariant variant, ProductionAppVariant testedVariant,
+ List<ConfigurationDependencies> configDependencies) {
+
+ def prepareDependenciesTask = createPrepareDependenciesTask(variant, configDependencies)
+
// Add a task to process the manifest
def processManifestTask = createProcessManifestTask(variant, "manifests")
+ // TODO - move this
+ processManifestTask.dependsOn prepareDependenciesTask
// Add a task to crunch resource files
def crunchTask = createCrunchResTask(variant)
@@ -395,6 +404,8 @@ abstract class BasePlugin {
createProcessJavaResTask(variant)
def compileAidl = createAidlTask(variant)
+ // TODO - move this
+ compileAidl.dependsOn prepareDependenciesTask
// Add a task to compile the test application
createCompileTask(variant, testedVariant, processResources, generateBuildConfigTask,
@@ -521,41 +532,82 @@ abstract class BasePlugin {
uninstallAll.dependsOn uninstallTask
}
- PrepareDependenciesTask createPrepareDependenciesTask(ProductionAppVariant variant) {
- // TODO - include variant specific dependencies too
- def compileClasspath = project.configurations.compile
-
- // TODO - shouldn't need to do this - fix this in Gradle
- ensureConfigured(compileClasspath)
+ protected void createDependencyReportTask() {
+ def androidDependencyTask = project.tasks.add("androidDependencies", AndroidDependencyTask)
+ androidDependencyTask.setDescription("Displays the Android dependencies of the project")
+ androidDependencyTask.setVariants(variants)
+ androidDependencyTask.setGroup("Help")
+ }
+ PrepareDependenciesTask createPrepareDependenciesTask(ApplicationVariant variant,
+ List<ConfigurationDependencies> configDependenciesList) {
def prepareDependenciesTask = project.tasks.add("prepare${variant.name}Dependencies",
PrepareDependenciesTask)
prepareDependenciesTask.plugin = this
prepareDependenciesTask.variant = variant
- // TODO - should be able to infer this
- prepareDependenciesTask.dependsOn compileClasspath
+ // look at all the flavors/build types of the variant and get all the libraries
+ // to make sure they are unarchived before the build runs.
+ for (ConfigurationDependencies configDependencies : configDependenciesList) {
+ prepareDependenciesTask.dependsOn configDependencies.configuration.buildDependencies
+ for (AndroidDependencyImpl lib : configDependencies.libraries) {
+ addDependencyToPrepareTask(prepareDependenciesTask, lib)
+ prepareDependenciesTask.add(lib.bundle, lib.bundleFolder)
+ }
+ }
+
+ return prepareDependenciesTask
+ }
+
+ def resolveDependencies(List<ConfigurationDependencies> configs) {
+ // start with the default config and its test
+ resolveDependencyForConfig(defaultConfigData)
+ resolveDependencyForConfig(defaultConfigData.testConfigDependencies)
+
+ // and then loop on all the other configs
+ for (ConfigurationDependencies config : configs) {
+ resolveDependencyForConfig(config)
+ if (config.testConfigDependencies != null) {
+ resolveDependencyForConfig(config.testConfigDependencies)
+ }
+ }
+ }
+
+ def resolveDependencyForConfig(
+ ConfigurationDependencies configDependencies) {
+
+ def compileClasspath = configDependencies.configuration
+
+ // TODO - shouldn't need to do this - fix this in Gradle
+ ensureConfigured(compileClasspath)
- def checker = new DependencyChecker(variant, logger)
+ def checker = new DependencyChecker(logger)
- // TODO - defer downloading until required
- // TODO - build the library dependency graph
+ // TODO - defer downloading until required -- This is hard to do as we need the info to build the variant config.
List<AndroidDependency> bundles = []
List<JarDependency> jars = []
Map<ModuleVersionIdentifier, List<AndroidDependency>> modules = [:]
Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = [:]
collectArtifacts(compileClasspath, artifacts)
compileClasspath.resolvedConfiguration.resolutionResult.root.dependencies.each { ResolvedDependencyResult dep ->
- addDependency(dep.selected, prepareDependenciesTask, checker,
- bundles, jars, modules, artifacts)
+ addDependency(dep.selected, checker, bundles, jars, modules, artifacts)
}
- variant.config.androidDependencies = bundles
- variant.config.jarDependencies = jars
+ configDependencies.libraries = bundles
+ configDependencies.jars = jars
// TODO - filter bundles out of source set classpath
- return prepareDependenciesTask
+ configureBuild(configDependencies)
+ }
+
+ def addDependencyToPrepareTask(PrepareDependenciesTask prepareDependenciesTask,
+ AndroidDependencyImpl lib) {
+ prepareDependenciesTask.add(lib.bundle, lib.bundleFolder)
+
+ for (AndroidDependencyImpl childLib : lib.dependencies) {
+ addDependencyToPrepareTask(prepareDependenciesTask, childLib)
+ }
}
def ensureConfigured(Configuration config) {
@@ -579,7 +631,6 @@ abstract class BasePlugin {
}
def addDependency(ResolvedModuleVersionResult moduleVersion,
- PrepareDependenciesTask prepareDependenciesTask,
DependencyChecker checker,
Collection<AndroidDependency> bundles,
Collection<JarDependency> jars,
@@ -597,7 +648,7 @@ abstract class BasePlugin {
def nestedBundles = []
moduleVersion.dependencies.each { ResolvedDependencyResult dep ->
- addDependency(dep.selected, prepareDependenciesTask, checker, nestedBundles,
+ addDependency(dep.selected, checker, nestedBundles,
jars, modules, artifacts)
}
@@ -606,8 +657,9 @@ abstract class BasePlugin {
if (artifact.type == 'alb') {
def explodedDir = project.file(
"$project.buildDir/exploded-bundles/$artifact.file.name")
- bundlesForThisModule << new AndroidDependencyImpl(explodedDir, nestedBundles)
- prepareDependenciesTask.add(artifact.file, explodedDir)
+ bundlesForThisModule << new AndroidDependencyImpl(
+ id.group + ":" + id.name + ":" + id.version,
+ explodedDir, nestedBundles, artifact.file)
} else {
// TODO - need the correct values for the boolean flags
jars << new JarDependency(artifact.file.absolutePath, true, true, true)
@@ -621,5 +673,36 @@ abstract class BasePlugin {
bundles.addAll(bundlesForThisModule)
}
+
+ private void configureBuild(ConfigurationDependencies configurationDependencies) {
+ def configuration = configurationDependencies.configuration
+
+ addDependsOnTaskInOtherProjects(
+ project.getTasks().getByName(JavaBasePlugin.BUILD_NEEDED_TASK_NAME), true,
+ JavaBasePlugin.BUILD_NEEDED_TASK_NAME, configuration);
+ addDependsOnTaskInOtherProjects(
+ project.getTasks().getByName(JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME), false,
+ JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME, configuration);
+ }
+
+ /**
+ * Adds a dependency on tasks with the specified name in other projects. The other projects
+ * are determined from project lib dependencies using the specified configuration name.
+ * These may be projects this project depends on or projects that depend on this project
+ * based on the useDependOn argument.
+ *
+ * @param task Task to add dependencies to
+ * @param useDependedOn if true, add tasks from projects this project depends on, otherwise
+ * use projects that depend on this one.
+ * @param otherProjectTaskName name of task in other projects
+ * @param configurationName name of configuration to use to find the other projects
+ */
+ private void addDependsOnTaskInOtherProjects(final Task task, boolean useDependedOn,
+ String otherProjectTaskName,
+ Configuration configuration) {
+ Project project = task.getProject();
+ task.dependsOn(configuration.getTaskDependencyFromProjectDependency(
+ useDependedOn, otherProjectTaskName));
+ }
}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/DependencyChecker.groovy b/gradle/src/main/groovy/com/android/build/gradle/DependencyChecker.groovy
index f727999..a9ca472 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/DependencyChecker.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/DependencyChecker.groovy
@@ -15,7 +15,6 @@
*/
package com.android.build.gradle
-import com.android.build.gradle.internal.ApplicationVariant
import com.android.utils.ILogger
import org.gradle.api.artifacts.ModuleVersionIdentifier
@@ -24,25 +23,18 @@ import org.gradle.api.artifacts.ModuleVersionIdentifier
*/
class DependencyChecker {
- final ApplicationVariant variant
final logger
- final int minSdkVersion
+ final List<Integer> mFoundAndroidApis = []
+ final List<String> mFoundBouncyCastle = []
- DependencyChecker(ApplicationVariant variant, ILogger logger) {
- this.variant = variant
+ DependencyChecker(ILogger logger) {
this.logger = logger;
- this.minSdkVersion = variant.config.getMinSdkVersion()
}
- private boolean excluded(ModuleVersionIdentifier id) {
+ boolean excluded(ModuleVersionIdentifier id) {
if (id.group == 'com.google.android' && id.name == 'android') {
int moduleLevel = getApiLevelFromMavenArtifact(id.version)
-
- if (minSdkVersion < moduleLevel) {
- throw new RuntimeException(String.format(
- "ERROR: Android API level %d is in the dependency graph, but minSdkVersion for '%s' is %d",
- moduleLevel, variant.name, minSdkVersion))
- }
+ mFoundAndroidApis.add(moduleLevel)
logger.info("Ignoring Android API artifact: " + id)
return true
@@ -77,16 +69,7 @@ class DependencyChecker {
}
if (id.group == 'org.bouncycastle' && id.name.startsWith("bcprov")) {
- if (minSdkVersion >= 11) {
- // this is when the version of BouncyCastle inside Android was jarjar'ed so this
- // is fine
- return false;
- }
-
- // TODO check which version of BC is used by the platform and the app.
- throw new RuntimeException(String.format(
- "ERROR: Dependency %s is conflicting with the internal version provided by Android. To use, please repackage with jarjar to change the class packages",
- id))
+ mFoundBouncyCastle.add(id.version)
}
return false
diff --git a/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy
index 5f256a2..8c57944 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy
@@ -16,12 +16,14 @@
package com.android.build.gradle
import com.android.build.gradle.internal.BuildTypeData
+import com.android.build.gradle.internal.ConfigurationDependencies
import com.android.build.gradle.internal.ProductFlavorData
import com.android.build.gradle.internal.ProductionAppVariant
import com.android.build.gradle.internal.TestAppVariant
import com.android.builder.AndroidDependency
import com.android.builder.BuildType
import com.android.builder.BundleDependency
+import com.android.builder.JarDependency
import com.android.builder.VariantConfiguration
import org.gradle.api.Plugin
import org.gradle.api.Project
@@ -81,22 +83,48 @@ class LibraryPlugin extends BasePlugin implements Plugin<Project> {
}
void createAndroidTasks() {
+ // resolve dependencies for all config
+ List<ConfigurationDependencies> dependencies = []
+ dependencies.add(debugBuildTypeData)
+ dependencies.add(releaseBuildTypeData)
+ resolveDependencies(dependencies)
+
ProductionAppVariant testedVariant = createLibraryTasks(debugBuildTypeData)
createLibraryTasks(releaseBuildTypeData)
createTestTasks(testedVariant)
+ createDependencyReportTask()
}
ProductionAppVariant createLibraryTasks(BuildTypeData buildTypeData) {
ProductFlavorData defaultConfigData = getDefaultConfigData();
+ List<ConfigurationDependencies> configDependencies = []
+ configDependencies.add(defaultConfigData)
+ configDependencies.add(buildTypeData)
+
+ // list of dependency to set on the variantConfig
+ List<JarDependency> jars = []
+ jars.addAll(defaultConfigData.jars)
+ jars.addAll(buildTypeData.jars)
+
+ // the order of the libraries is important. In descending order:
+ // build types, defaultConfig.
+ List<AndroidDependency> libs = []
+ libs.addAll(buildTypeData.libraries)
+ libs.addAll(defaultConfigData.libraries)
+
def variantConfig = new VariantConfiguration(
defaultConfigData.productFlavor, defaultConfigData.sourceSet,
buildTypeData.buildType, buildTypeData.sourceSet,
VariantConfiguration.Type.LIBRARY)
+ variantConfig.setJarDependencies(jars)
+ variantConfig.setAndroidDependencies(libs)
+
ProductionAppVariant variant = new ProductionAppVariant(variantConfig)
+ variants.add(variant)
- def prepareDependenciesTask = createPrepareDependenciesTask(variant)
+ def prepareDependenciesTask = createPrepareDependenciesTask(variant, configDependencies)
// Add a task to process the manifest(s)
ProcessManifestTask processManifestTask = createProcessManifestTask(variant, DIR_BUNDLES)
@@ -171,7 +199,8 @@ class LibraryPlugin extends BasePlugin implements Plugin<Project> {
// configure the variant to be testable.
variantConfig.output = new BundleDependency(
- project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}")) {
+ project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}"),
+ variant.getName()) {
@Override
List<AndroidDependency> getDependencies() {
@@ -185,15 +214,29 @@ class LibraryPlugin extends BasePlugin implements Plugin<Project> {
void createTestTasks(ProductionAppVariant testedVariant) {
ProductFlavorData defaultConfigData = getDefaultConfigData();
+ List<ConfigurationDependencies> configDependencies = []
+ configDependencies.add(defaultConfigData.testConfigDependencies)
+
+ // list of dependency to set on the variantConfig
+ List<JarDependency> jars = []
+ jars.addAll(defaultConfigData.testConfigDependencies.jars)
+
+ // the order of the libraries is important. In descending order:
+ // build types, defaultConfig.
+ List<AndroidDependency> libs = []
+ libs.addAll(defaultConfigData.testConfigDependencies.libraries)
+
def testVariantConfig = new VariantConfiguration(
defaultConfigData.productFlavor, defaultConfigData.testSourceSet,
debugBuildTypeData.buildType, null,
VariantConfiguration.Type.TEST, testedVariant.config)
- // TODO: add actual dependencies
- testVariantConfig.setAndroidDependencies(null)
+
+ testVariantConfig.setJarDependencies(jars)
+ testVariantConfig.setAndroidDependencies(libs)
def testVariant = new TestAppVariant(testVariantConfig,)
- createTestTasks(testVariant, testedVariant)
+ variants.add(testVariant)
+ createTestTasks(testVariant, testedVariant, configDependencies)
}
@Override
diff --git a/gradle/src/main/groovy/com/android/build/gradle/PrepareDependenciesTask.groovy b/gradle/src/main/groovy/com/android/build/gradle/PrepareDependenciesTask.groovy
index f104b30..121434a 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/PrepareDependenciesTask.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/PrepareDependenciesTask.groovy
@@ -37,7 +37,6 @@ class PrepareDependenciesTask extends BaseTask {
return bundles.keySet()
}
-
@OutputDirectories
Iterable<File> getExplodedBundles() {
return bundles.values()
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/AndroidAsciiReportRenderer.java b/gradle/src/main/groovy/com/android/build/gradle/internal/AndroidAsciiReportRenderer.java
new file mode 100644
index 0000000..315daf8
--- /dev/null
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/AndroidAsciiReportRenderer.java
@@ -0,0 +1,123 @@
+/*
+ * 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.build.gradle.internal;
+
+import com.android.builder.AndroidDependency;
+import com.android.builder.BundleDependency;
+import org.gradle.api.Action;
+import org.gradle.api.Project;
+import org.gradle.api.artifacts.Configuration;
+import org.gradle.api.tasks.diagnostics.internal.GraphRenderer;
+import org.gradle.api.tasks.diagnostics.internal.TextReportRenderer;
+import org.gradle.logging.StyledTextOutput;
+import org.gradle.util.GUtil;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.gradle.logging.StyledTextOutput.Style.Description;
+import static org.gradle.logging.StyledTextOutput.Style.Identifier;
+import static org.gradle.logging.StyledTextOutput.Style.Info;
+
+/**
+ * android version of the AsciiReportRenderer that outputs Android Library dependencies.
+ */
+public class AndroidAsciiReportRenderer extends TextReportRenderer {
+ private boolean hasConfigs;
+ private boolean hasCyclicDependencies;
+ private GraphRenderer renderer;
+
+ @Override
+ public void startProject(Project project) {
+ super.startProject(project);
+ hasConfigs = false;
+ hasCyclicDependencies = false;
+ }
+
+ @Override
+ public void completeProject(Project project) {
+ if (!hasConfigs) {
+ getTextOutput().withStyle(Info).println("No dependencies");
+ }
+ super.completeProject(project);
+ }
+
+ public void startVariant(final ApplicationVariant variant) {
+ if (hasConfigs) {
+ getTextOutput().println();
+ }
+ hasConfigs = true;
+ renderer = new GraphRenderer(getTextOutput());
+ renderer.visit(new Action<StyledTextOutput>() {
+ public void execute(StyledTextOutput styledTextOutput) {
+ getTextOutput().withStyle(Identifier).text(variant.getName());
+ getTextOutput().withStyle(Description).text("");
+ }
+ }, true);
+ }
+
+ private String getDescription(Configuration configuration) {
+ return GUtil.isTrue(
+ configuration.getDescription()) ? " - " + configuration.getDescription() : "";
+ }
+
+ public void completeConfiguration(ApplicationVariant variant) {}
+
+ public void render(ApplicationVariant variant) throws IOException {
+ List<AndroidDependency> libraries = variant.getVariantConfiguration().getDirectLibraries();
+
+ renderNow(libraries);
+ }
+
+ void renderNow(List<AndroidDependency> libraries) {
+ if (libraries.isEmpty()) {
+ getTextOutput().withStyle(Info).text("No dependencies");
+ getTextOutput().println();
+ return;
+ }
+
+ renderChildren(libraries);
+ }
+
+ public void complete() throws IOException {
+ if (hasCyclicDependencies) {
+ getTextOutput().withStyle(Info).println(
+ "\n(*) - dependencies omitted (listed previously)");
+ }
+
+ super.complete();
+ }
+
+ private void render(final AndroidDependency lib, boolean lastChild) {
+ renderer.visit(new Action<StyledTextOutput>() {
+ public void execute(StyledTextOutput styledTextOutput) {
+ getTextOutput().text(((BundleDependency)lib).getName());
+ }
+ }, lastChild);
+
+ renderChildren(lib.getDependencies());
+ }
+
+ private void renderChildren(List<AndroidDependency> libraries) {
+ renderer.startChildren();
+ for (int i = 0; i < libraries.size(); i++) {
+ AndroidDependency lib = libraries.get(i);
+ render(lib, i == libraries.size() - 1);
+ }
+ renderer.completeChildren();
+ }
+}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/AndroidDependencyImpl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/AndroidDependencyImpl.groovy
index 8cadb24..96482d1 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/AndroidDependencyImpl.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/AndroidDependencyImpl.groovy
@@ -20,9 +20,12 @@ import com.android.builder.BundleDependency
class AndroidDependencyImpl extends BundleDependency {
final List<AndroidDependency> dependencies;
+ final File bundle
- AndroidDependencyImpl(File explodedBundle, List<AndroidDependency> dependencies) {
- super(explodedBundle)
+ AndroidDependencyImpl(String name, File explodedBundle, List<AndroidDependency> dependencies,
+ File bundle) {
+ super(explodedBundle, name)
this.dependencies = dependencies
+ this.bundle = bundle
}
}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/ApplicationVariant.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/ApplicationVariant.groovy
index 826f206..c3e2850 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/ApplicationVariant.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/ApplicationVariant.groovy
@@ -56,6 +56,10 @@ public abstract class ApplicationVariant {
return config.buildConfigLines
}
+ public VariantConfiguration getVariantConfiguration() {
+ return config
+ }
+
abstract String getName()
abstract String getDescription()
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/BuildTypeData.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/BuildTypeData.groovy
index 679b5e3..1b543d5 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/BuildTypeData.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/BuildTypeData.groovy
@@ -20,16 +20,16 @@ import com.android.builder.BuildType
import org.gradle.api.Project
import org.gradle.api.Task
-class BuildTypeData {
- final BuildType buildType
+class BuildTypeData extends ConfigurationDependencies {
- final AndroidSourceSet sourceSet
+ final BuildType buildType
final Task assembleTask
BuildTypeData(BuildType buildType, AndroidSourceSet sourceSet, Project project) {
+ super(project, sourceSet)
+
this.buildType = buildType
- this.sourceSet = sourceSet
assembleTask = project.tasks.add("assemble${buildType.name.capitalize()}")
assembleTask.description = "Assembles all ${buildType.name.capitalize()} builds"
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/ConfigurationDependencies.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/ConfigurationDependencies.groovy
new file mode 100644
index 0000000..1e48c10
--- /dev/null
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/ConfigurationDependencies.groovy
@@ -0,0 +1,49 @@
+/*
+ * 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.build.gradle.internal
+
+import com.android.build.gradle.AndroidSourceSet
+import com.android.builder.JarDependency
+import org.gradle.api.Project
+import org.gradle.api.artifacts.Configuration
+
+/**
+ * Object that represents the dependencies of a configuration, and optionally contains the
+ * dependencies for a test config for the given config.
+ */
+class ConfigurationDependencies {
+
+ final Project project
+ final AndroidSourceSet sourceSet
+ ConfigurationDependencies testConfigDependencies;
+
+ ConfigurationDependencies(Project project, AndroidSourceSet sourceSet) {
+ this.project = project
+ this.sourceSet = sourceSet
+ }
+
+ List<AndroidDependencyImpl> libraries
+ List<JarDependency> jars
+
+ Configuration getConfiguration() {
+ return project.configurations[sourceSet.compileConfigurationName]
+ }
+
+ String getConfigBaseName() {
+ return sourceSet.name
+ }
+}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/ProductFlavorData.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/ProductFlavorData.groovy
index 68f59ff..39266b4 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/ProductFlavorData.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/ProductFlavorData.groovy
@@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.android.build.gradle.internal
import com.android.build.gradle.AndroidSourceSet
import org.gradle.api.Project
import org.gradle.api.Task
-class ProductFlavorData {
- final ProductFlavorDsl productFlavor
+class ProductFlavorData extends ConfigurationDependencies {
- final AndroidSourceSet sourceSet
+ final ProductFlavorDsl productFlavor
final AndroidSourceSet testSourceSet
@@ -31,10 +31,12 @@ class ProductFlavorData {
ProductFlavorData(ProductFlavorDsl productFlavor,
AndroidSourceSet sourceSet, AndroidSourceSet testSourceSet,
Project project) {
- this.productFlavor = productFlavor
+ super(project, sourceSet)
- this.sourceSet = sourceSet
+ this.productFlavor = productFlavor
this.testSourceSet = testSourceSet
+
+ setTestConfigDependencies(new ConfigurationDependencies(project, testSourceSet))
}