Gradle自定义插件:从扩展对象添加依赖项

时间:2013-09-03 14:17:33

标签: gradle

我正在尝试编写一个插件,根据插件扩展对象中收集的信息,将依赖项添加到project.dependencies。但这似乎是不可能的。

实际上,来自扩展对象的数据仅在新任务或project.afterEvaluate闭包中可用,但忽略了在这些位置添加的依赖项。


以下代码尝试在afterEvaluate中添加依赖项,但忽略依赖项:

apply plugin: MyPlugin

myplugin {
  version '1.0'
}

class MyPlugin implements Plugin<Project> {
  void apply(Project project) {
    project.extensions.create('myplugin', MyPluginExtension)

    project.afterEvaluate {
       def version = project.myplugin.version
       project.dependencies.add("compile", "org.foo:bar:$version") // --> ignored
    }
  }
}

class MyPluginExtension {
  def version
}

在以下代码中,依赖项注入有效,但我无权访问扩展对象:

apply plugin: MyPlugin

myplugin {
  version '1.0'
}

class MyPlugin implements Plugin<Project> {
  void apply(Project project) {
    project.extensions.create('myplugin', MyPluginExtension)    

    def version = project.myplugin.version // == null
    project.dependencies.add("compile", "org.foo:bar:$version") // --> fail because $version is null

  }
}

class MyPluginExtension {
  def version
}

有解决方案吗?

4 个答案:

答案 0 :(得分:16)

更新:自从我的原始答案以来,我设法解决了这个问题。这样做的方法是添加DependencyResolutionListener,在其中添加依赖项,然后删除侦听器,以便它不会尝试在以后的解析步骤中添加它们。

compileDeps = project.getConfigurations().getByName("compile").getDependencies()
project.getGradle().addListener(new DependencyResolutionListener() {
    @Override
    void beforeResolve(ResolvableDependencies resolvableDependencies) {
        compileDeps.add(project.getDependencies().create("org.foo:bar:$version"))
        project.getGradle().removeListener(this)
    }

    @Override
    void afterResolve(ResolvableDependencies resolvableDependencies) {}
})

我有一个使用此here

的插件的工作示例

原始答案:

这也迟到了,但对于任何人来说。使用最新的gradle(写作时为2.6),您可以添加DependencyResolutionListener并在依赖关系解析之前添加任何依赖项。

project.getGradle().addListener(new DependencyResolutionListener() {
    @Override
    void beforeResolve(ResolvableDependencies resolvableDependencies) {
        depsToAdd.each { dep ->
            compileConfig.getDependencies()
                .add(project.getDependencies().create(dep))
        }
    }

    @Override
    void afterResolve(ResolvableDependencies resolvableDependencies) {

    }
})

但是,在撰写本文时,我遇到了一些与Android Studio IDE一起使用的问题。我的问题here

会跟踪问题

答案 1 :(得分:3)

我最初使用Saad的DependencyResolutionListener方法实现了此解决方案。但是,侦听器本身称为only when something iterates over the configuration associated with the dependency。例如,如果要向compile动态添加依赖项,则必须确保稍后会执行以下操作:

project.configurations.compile.each {
   ...
}

但这是理所当然的事情,因为compile是使用java插件的任何项目的已知配置。但是,如果您使用自定义配置(就像我一样),那么除非您明确地迭代自定义配置,否则侦听器方法将无法工作。

我能够找到一种更好的方法来实现这一点,并且在afterEvaluate内,就像OP最初想要的那样。我在这里使用自定义配置,但我不明白为什么它不适用于compile

project.afterEvaluate {
    def version = project.myPlugin.version
    project.configurations.myConfig.dependencies.add(
        project.dependencies.add("myConfig", "org.foo:bar:$version")
    )
}

当然,在某些时候仍然需要迭代依赖关系,以便实际解决它们。

答案 2 :(得分:1)

不知道这是否仍然相关,但您可以通过在doFirst中将编译配置显式添加到Java类路径来解决此问题:

variant.javaCompile.doFirst {
    variant.javaCompile.classpath += project.configurations.myconfiguration
}

答案 3 :(得分:1)

最简单的方法:

project.dependencies {
  delegate.compile("com.android.support:appcompat-v7:25.0.1")
}