添加 Android Gradle 插件作为运行时依赖
Add Android Gradle plugin as a runtime dependency
我正在为 Android 编写一个 Gradle 插件,它使用新的 Transform API。不幸的是,我在将 Android 插件添加为我的插件的依赖项时遇到了问题。我的插件的简化 Gradle 配置如下所示:
plugin/build.gradle:
apply plugin: "groovy"
dependencies {
compile gradleApi()
compile localGroovy()
compile "com.android.tools.build:gradle:1.4.0-beta2"
}
这是使用我的 Gradle 插件的应用程序项目的简化配置:
application/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
所以整个项目开始使用 1.4.0-beta2
版本的 Android 插件。
我也尝试过将 Android 插件添加为 runtime
依赖项,但在进行此更改后,我的插件停止编译,因为 'unable to resolve' 错误如下:
Unable to resolve class com.android.build.gradle.api.BaseVariant @ line 19, column 1.
import com.android.build.gradle.api.BaseVariant
有没有办法根据最新版本的 Android 插件构建我的插件,但在运行时使用构建环境提供的 Android 插件版本?
最后,我通过手动添加 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,所以我需要将其设为 'understand' provided
范围。如果你使用它,你必须对 Eclipse 做同样的事情。
private void configureIdeaModule() {
project.idea.module {
scopes.PROVIDED.plus += [project.configurations.provided]
}
}
最后我们需要更改生成的 pom.xml
文件中的范围。默认情况下 Gradle 将所有依赖项的范围设置为 runtime
。如果需要,以下代码将它们更改为 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 }
}
}
}
}
就是这样。然后你只需要将这个插件应用到一个需要发布到 Maven 的项目中,并将依赖类型从 compile
更改为 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 编写一个 Gradle 插件,它使用新的 Transform API。不幸的是,我在将 Android 插件添加为我的插件的依赖项时遇到了问题。我的插件的简化 Gradle 配置如下所示:
plugin/build.gradle:
apply plugin: "groovy"
dependencies {
compile gradleApi()
compile localGroovy()
compile "com.android.tools.build:gradle:1.4.0-beta2"
}
这是使用我的 Gradle 插件的应用程序项目的简化配置:
application/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
所以整个项目开始使用 1.4.0-beta2
版本的 Android 插件。
我也尝试过将 Android 插件添加为 runtime
依赖项,但在进行此更改后,我的插件停止编译,因为 'unable to resolve' 错误如下:
Unable to resolve class com.android.build.gradle.api.BaseVariant @ line 19, column 1.
import com.android.build.gradle.api.BaseVariant
有没有办法根据最新版本的 Android 插件构建我的插件,但在运行时使用构建环境提供的 Android 插件版本?
最后,我通过手动添加 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,所以我需要将其设为 'understand' provided
范围。如果你使用它,你必须对 Eclipse 做同样的事情。
private void configureIdeaModule() {
project.idea.module {
scopes.PROVIDED.plus += [project.configurations.provided]
}
}
最后我们需要更改生成的 pom.xml
文件中的范围。默认情况下 Gradle 将所有依赖项的范围设置为 runtime
。如果需要,以下代码将它们更改为 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 }
}
}
}
}
就是这样。然后你只需要将这个插件应用到一个需要发布到 Maven 的项目中,并将依赖类型从 compile
更改为 provided
:
apply plugin: "groovy"
apply plugin: "my-publish-plugin"
dependencies {
compile gradleApi()
compile localGroovy()
provided "com.android.tools.build:gradle:1.4.0-beta2"
}