26

我正在尝试编写一个插件,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

4 回答 4

19

更新:自从我最初的回答以来,我设法弄清楚了这一点。这样做的方法是添加一个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) {}
})

我有一个使用这里的插件的工作示例

原答案:

这也为时已晚,但对于任何加入的人来说。使用最新的 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

于 2015-09-14T18:07:08.147 回答
4

我最初使用DependencyResolutionListenerSaad 的方法实现了这个解决方案。但是,只有在对与依赖项关联的配置进行迭代时,才会调用侦听器本身。例如,如果你想动态地添加一个依赖项compile,你必须确保稍后执行如下操作:

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

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

我能够找到一种更好的方法来做到这一点,并且在afterEvaluateOP 最初想要的范围内。我在这里使用自定义配置,但我看不出它不适用于compile任何一个的原因:

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

当然,在某些时候,仍然需要迭代依赖项才能真正解决它们。

于 2016-04-02T00:05:06.500 回答
2

最简单的方法是:

project.dependencies {
  delegate.compile("com.android.support:appcompat-v7:25.0.1")
}
于 2016-12-20T04:06:12.320 回答
1

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

variant.javaCompile.doFirst {
    variant.javaCompile.classpath += project.configurations.myconfiguration
}
于 2014-01-11T23:45:49.983 回答