diff options
author | Xavier Ducrohet <xav@android.com> | 2012-09-27 19:00:08 -0700 |
---|---|---|
committer | Xavier Ducrohet <xav@android.com> | 2012-09-28 11:33:51 -0700 |
commit | b2670776c02a0426076565eabe2b92bacae69469 (patch) | |
tree | 56e217365eac35df3049551d714ccbfa6ca34226 /gradle/src | |
parent | 124edda3d052471b56941b16d1ada16cfcd30216 (diff) | |
download | build-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.groovy | 85 | ||||
-rw-r--r-- | gradle/src/main/groovy/com/android/build/gradle/DependencyChecker.groovy | 118 |
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; + } + } +} |