aboutsummaryrefslogtreecommitdiff
path: root/gradle/src
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2012-09-27 19:00:08 -0700
committerXavier Ducrohet <xav@android.com>2012-09-28 11:33:51 -0700
commitb2670776c02a0426076565eabe2b92bacae69469 (patch)
tree56e217365eac35df3049551d714ccbfa6ca34226 /gradle/src
parent124edda3d052471b56941b16d1ada16cfcd30216 (diff)
downloadbuild-b2670776c02a0426076565eabe2b92bacae69469.tar.gz
Better detection of dependency conflicts.
Change-Id: I5983d819049f3aca33c343d08e527a6c4db2c4bb
Diffstat (limited to 'gradle/src')
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/AndroidBasePlugin.groovy85
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/DependencyChecker.groovy118
2 files changed, 126 insertions, 77 deletions
diff --git a/gradle/src/main/groovy/com/android/build/gradle/AndroidBasePlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/AndroidBasePlugin.groovy
index e506844..361be5f 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/AndroidBasePlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/AndroidBasePlugin.groovy
@@ -30,7 +30,6 @@ import com.android.builder.ProductFlavor
import com.android.builder.SdkParser
import com.android.builder.VariantConfiguration
import com.android.utils.ILogger
-import com.android.utils.Pair
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Project
@@ -497,6 +496,8 @@ abstract class AndroidBasePlugin {
// TODO - should be able to infer this
prepareDependenciesTask.dependsOn compileClasspath
+ def checker = new DependencyChecker(variant, logger)
+
// TODO - defer downloading until required
// TODO - build the library dependency graph
List<AndroidDependency> bundles = []
@@ -505,7 +506,8 @@ abstract class AndroidBasePlugin {
Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = [:]
collectArtifacts(compileClasspath, artifacts)
compileClasspath.resolvedConfiguration.resolutionResult.root.dependencies.each { ResolvedDependencyResult dep ->
- addDependency(dep.selected, null, prepareDependenciesTask, bundles, jars, modules, artifacts)
+ addDependency(dep.selected, prepareDependenciesTask, checker,
+ bundles, jars, modules, artifacts)
}
variant.config.androidDependencies = bundles
@@ -537,16 +539,17 @@ abstract class AndroidBasePlugin {
}
def addDependency(ResolvedModuleVersionResult moduleVersion,
- ResolvedModuleVersionResult parentModule,
PrepareDependenciesTask prepareDependenciesTask,
+ DependencyChecker checker,
Collection<AndroidDependency> bundles,
Collection<JarDependency> jars,
Map<ModuleVersionIdentifier, List<AndroidDependency>> modules,
Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts) {
def id = moduleVersion.id
- if (excluded(id, parentModule, prepareDependenciesTask)) {
+ if (checker.excluded(id)) {
return
}
+
List<AndroidDependency> bundlesForThisModule = modules[id]
if (bundlesForThisModule == null) {
bundlesForThisModule = []
@@ -554,7 +557,7 @@ abstract class AndroidBasePlugin {
def nestedBundles = []
moduleVersion.dependencies.each { ResolvedDependencyResult dep ->
- addDependency(dep.selected, moduleVersion, prepareDependenciesTask, nestedBundles,
+ addDependency(dep.selected, prepareDependenciesTask, checker, nestedBundles,
jars, modules, artifacts)
}
@@ -578,77 +581,5 @@ abstract class AndroidBasePlugin {
bundles.addAll(bundlesForThisModule)
}
-
- private boolean excluded(ModuleVersionIdentifier id, ResolvedModuleVersionResult parentModule,
- PrepareDependenciesTask prepareDependenciesTask) {
- if (id.group == 'com.google.android' && id.name == 'android') {
- String parentName = null;
- if (parentModule != null) {
- def parentId = parentModule.id
- parentName = parentId.group + ":" + parentId.name + ":" + parentId.version
- }
- prepareDependenciesTask.addDependency(
- Pair.of(getApiLevelFromMavenArtifact(id.version), parentName))
-
- logger.info("Ignoring Android API artifact: " + id)
- return true
- }
- if (id.group == 'org.apache.httpcomponents' && id.name == 'httpclient') {
- logger.info(String.format(
- "Ignoring artifact %s as it is part of the Android API", id))
- return true
- }
- if (id.group == 'xpp3' && id.name == 'xpp3') {
- logger.info(String.format(
- "Ignoring artifact %s as it is part of the Android API", id))
- return true
- }
- if (id.group == 'commons-logging' && id.name == 'commons-logging') {
- logger.info(String.format(
- "Ignoring artifact %s as it is part of the Android API", id))
- return true
- }
- if (id.group == 'xerces' && id.name == 'xmlParserAPIs') {
- logger.info(String.format(
- "Ignoring artifact %s as it is part of the Android API", id))
- return true
- }
- if (id.group == 'org.json' && id.name == 'json') {
- logger.info(String.format(
- "Ignoring artifact %s as it is part of the Android API", id))
- return true
- }
- if (id.group == 'org.khronos' && id.name == 'opengl-api') {
- logger.info(String.format(
- "Ignoring artifact %s as it is part of the Android API", id))
- return true
- }
-
- // TODO - need to exclude everything that is included in the Android API
- return false
- }
-
- private int getApiLevelFromMavenArtifact(String version) {
- switch (version) {
- case "1.5_r3":
- case "1.5_r4":
- return 3;
- case "1.6_r2":
- return 4;
- case "2.1_r1":
- case "2.1.2":
- return 7;
- case "2.2.1":
- return 8;
- case "2.3.1":
- return 9;
- case "2.3.3":
- return 10;
- case "4.0.1.2":
- return 14;
- case "4.1.1.4":
- return 15;
- }
- }
}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/DependencyChecker.groovy b/gradle/src/main/groovy/com/android/build/gradle/DependencyChecker.groovy
new file mode 100644
index 0000000..f727999
--- /dev/null
+++ b/gradle/src/main/groovy/com/android/build/gradle/DependencyChecker.groovy
@@ -0,0 +1,118 @@
+/*
+ * 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 com.android.utils.ILogger
+import org.gradle.api.artifacts.ModuleVersionIdentifier
+
+/**
+ * Checks for dependencies to ensure Android compatibility
+ */
+class DependencyChecker {
+
+ final ApplicationVariant variant
+ final logger
+ final int minSdkVersion
+
+ DependencyChecker(ApplicationVariant variant, ILogger logger) {
+ this.variant = variant
+ this.logger = logger;
+ this.minSdkVersion = variant.config.getMinSdkVersion()
+ }
+
+ private 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))
+ }
+
+ logger.info("Ignoring Android API artifact: " + id)
+ return true
+ }
+
+ if ((id.group == 'org.apache.httpcomponents' && id.name == 'httpclient') ||
+ (id.group == 'xpp3' && id.name == 'xpp3') ||
+ (id.group == 'commons-logging' && id.name == 'commons-logging') ||
+ (id.group == 'xerces' && id.name == 'xmlParserAPIs')) {
+
+ logger.warning(
+ "WARNING: Dependency %s is ignored as it may be conflicting with the internal version provided by Android.\n" +
+ " In case of problem, please repackage with jarjar to change the class packages",
+ id)
+ return true;
+ }
+
+ if (id.group == 'org.json' && id.name == 'json') {
+ logger.warning(
+ "WARNING: Dependency %s is ignored as it may be conflicting with the internal version provided by Android.\n" +
+ " In case of problem, please repackage with jarjar to change the class packages",
+ id)
+ return true
+ }
+
+ if (id.group == 'org.khronos' && id.name == 'opengl-api') {
+ logger.warning(
+ "WARNING: Dependency %s is ignored as it may be conflicting with the internal version provided by Android.\n" +
+ " In case of problem, please repackage with jarjar to change the class packages",
+ id)
+ return true
+ }
+
+ 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))
+ }
+
+ return false
+ }
+
+
+ private int getApiLevelFromMavenArtifact(String version) {
+ switch (version) {
+ case "1.5_r3":
+ case "1.5_r4":
+ return 3;
+ case "1.6_r2":
+ return 4;
+ case "2.1_r1":
+ case "2.1.2":
+ return 7;
+ case "2.2.1":
+ return 8;
+ case "2.3.1":
+ return 9;
+ case "2.3.3":
+ return 10;
+ case "4.0.1.2":
+ return 14;
+ case "4.1.1.4":
+ return 15;
+ }
+ }
+}