我正在为Android编写Gradle插件,该插件使用新的Transform API。不幸的是,我遇到了添加Android插件作为我的插件的依赖项的问题。我的插件的简化Gradle配置如下所示:
插件/的build.gradle :
apply plugin: "groovy"
dependencies {
compile gradleApi()
compile localGroovy()
compile "com.android.tools.build:gradle:1.4.0-beta2"
}
这是使用我的Gradle插件的应用程序项目的简化配置:
应用/的build.gradle :
buildscript {
dependencies {
classpath "com.android.tools.build:gradle:1.4.0-beta2"
classpath "my-plugin:my-plugin:1.0.0"
}
}
apply plugin: "com.android.application"
apply plugin: "my-plugin"
android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
applicationId 'com.myapplication'
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName version
}
}
使用此配置一切正常但我也希望我的插件能够正常使用以前版本的Android插件的项目。所以我尝试在我的应用程序的配置文件中更改Android插件版本:
application / build.gradle(使用Android插件1.3.1):
buildscript {
dependencies {
classpath "com.android.tools.build:gradle:1.3.1"
classpath "my-plugin:my-plugin:1.0.0"
}
}
/* Everything else is the same. */
但在这种情况下仍然使用Android插件1.4.0-beta2
。我相信这是因为当Gradle解析类路径依赖关系时,它更喜欢1.4.0-beta2
而不是1.3.1
,因此整个项目开始使用Android插件的1.4.0-beta2
版本。
我还尝试将Android插件添加为runtime
依赖项,但在进行此更改后,我的插件停止编译,因为“无法解决”这样的错误:
Unable to resolve class com.android.build.gradle.api.BaseVariant @ line 19, column 1.
import com.android.build.gradle.api.BaseVariant
有没有办法针对最新版本的Android插件构建我的插件,但在运行时使用构建环境提供的Android插件版本?
答案 0 :(得分:3)
最后,我设法通过手动添加provided
范围来解决此问题。这是一篇关于将provided
范围添加到Gradle的好文章:http://www.sinking.in/blog/provided-scope-in-gradle/。不幸的是,它没有解释如何使maven-publish
插件处理provided
范围。所以我要解释如何做到这一点。
在我的项目中,我在buildSrc
中有一个小插件,负责发布到Maven。我将所有与provided
相关的代码添加到此插件中,但可以将其添加到build.gradle
文件中。
插件框架如下所示:
class PublishPlugin implements Plugin<Project> {
private static final PROVIDED_CONFIGURATION_NAME = "provided"
private Project project
@Override
void apply(final Project project) {
project.apply plugin: 'java'
project.apply plugin: 'maven-publish'
project.apply plugin: 'com.jfrog.bintray'
project.apply plugin: 'idea'
addProvidedConfiguration()
configureIdeaModule()
project.afterEvaluate {
modifyPomDependencyScopes()
}
}
然后我们创建一个provided
范围。在编译期间可以使用随此范围添加的依赖项。在生成的pom.xml
文件中,这些依赖项将具有provided
范围。
private void addProvidedConfiguration() {
final Configuration provided =
addConfiguration(project.configurations,
PROVIDED_CONFIGURATION_NAME)
final Javadoc javadoc =
project.tasks.getByName(JavaPlugin.JAVADOC_TASK_NAME) as Javadoc
javadoc.classpath = javadoc.classpath.plus(provided)
}
private static Configuration addConfiguration(
final ConfigurationContainer configurations, final String name) {
final Configuration compile =
configurations.getByName(JavaPlugin.COMPILE_CONFIGURATION_NAME)
final Configuration configuration = configurations.create(name)
compile.extendsFrom(configuration)
configuration.visible = false
configuration.transitive = false
configuration.allDependencies.all { final dependency ->
configurations.default.exclude(
group: dependency.group, module: dependency.name)
}
return configuration
}
我使用IntelliJ IDEA所以我需要让它理解&#39; provided
范围。 private void configureIdeaModule() {
project.idea.module {
scopes.PROVIDED.plus += [project.configurations.provided]
}
}
。如果你使用它,你必须对Eclipse做同样的事情。
pom.xml
最后,我们需要更改生成的runtime
文件中的范围。默认情况下,Gradle将所有依赖项的范围设置为compile
。如有必要,以下代码会将其更改为provided
或 private void modifyPomDependencyScopes() {
modifyPomDependencyScope(JavaPlugin.COMPILE_CONFIGURATION_NAME)
modifyPomDependencyScope(PROVIDED_CONFIGURATION_NAME)
}
private void modifyPomDependencyScope(final String scope) {
project.publishing.publications.all {
pom.withXml {
final DependencySet dependencies =
project.configurations.getByName(scope).allDependencies
asNode().dependencies.'*'.findAll() {
dependencies.find { it.name == node.artifactId.text()
}.each { it.scope*.value = scope }
}
}
}
}
。
compile
那就是它。然后,您只需将此插件应用于需要发布到Maven的项目,并将依赖关系类型从provided
更改为apply plugin: "groovy"
apply plugin: "my-publish-plugin"
dependencies {
compile gradleApi()
compile localGroovy()
provided "com.android.tools.build:gradle:1.4.0-beta2"
}
:
android:focusable="true"
android:focusableInTouchMode="true"
android:clickable="true"