Plugins 如何在自定义gradle插件中迭代gradle依赖项?

Plugins 如何在自定义gradle插件中迭代gradle依赖项?,plugins,gradle,Plugins,Gradle,我遵循了以下指南: 要创建具有以下结构/文件的独立gradle插件: my-gradle-plugin > src > main > java > com > mygroup > MyGradlePlugin.groovy > build.gradle > settings.gradle 构建.渐变: apply plugin: 'groovy'

我遵循了以下指南:

要创建具有以下结构/文件的独立gradle插件:

  my-gradle-plugin
    > src
     > main
      > java
       > com
        > mygroup
         > MyGradlePlugin.groovy
    > build.gradle
    > settings.gradle
构建.渐变

apply plugin: 'groovy'

dependencies {
  compile gradleApi()
  groovy localGroovy()
}

apply plugin: 'maven'
repositories {
  mavenCentral()
}

group = 'com.mygroup'
version = '1.0.0-SNAPSHOT'
package com.mygroup

import org.gradle.api.*

class MyGradlePlugin implements Plugin<Project> {

  void apply(Project project) {
    print " project.name " + project.name + "\n"
    print " project.dependencies " + project.dependencies + "\n"
     // How do we iterate each dependency and print artifactId, group, version??
     // project.dependencies.each {
     //        compile(it) {
     //        print it.next()
     //        print it.name
     //      }
     //    }
   project.configurations.each {
  print it.dump()

}
   }
  }
MyGradlePlugin.groovy

apply plugin: 'groovy'

dependencies {
  compile gradleApi()
  groovy localGroovy()
}

apply plugin: 'maven'
repositories {
  mavenCentral()
}

group = 'com.mygroup'
version = '1.0.0-SNAPSHOT'
package com.mygroup

import org.gradle.api.*

class MyGradlePlugin implements Plugin<Project> {

  void apply(Project project) {
    print " project.name " + project.name + "\n"
    print " project.dependencies " + project.dependencies + "\n"
     // How do we iterate each dependency and print artifactId, group, version??
     // project.dependencies.each {
     //        compile(it) {
     //        print it.next()
     //        print it.name
     //      }
     //    }
   project.configurations.each {
  print it.dump()

}
   }
  }

但是我如何从MyGradlePlugin.groovy中的apply方法迭代公共依赖项,并打印它们的坐标(artifactId、groupId、version)?

问题是依赖关系图只有在项目完全评估后才可用。这就是为什么在
apply
方法中不能直接依赖它的原因。您必须使用
afterEvaluate
方法推迟执行。以下代码将完成此操作:

class MyGradlePlugin implements Plugin<Project> {

  void apply(Project project) {
    project.afterEvaluate {
      println "  Project:" + project.name
      project.configurations.each { conf ->
        println "    Configuration: ${conf.name}"
        conf.allDependencies.each { dep ->
          println "      ${dep.group}:${dep.name}:${dep.version}"
        }
      }
    }
  }

}
类MyGradlePlugin实现插件{
无效申请(项目){
项目后评估{
println“Project:+Project.name
project.configurations.each{conf->
println“配置:${conf.name}”
conf.allDependencies.each{dep->
println“${dep.group}:${dep.name}:${dep.version}”
}
}
}
}
}
更新:以下是评论和聊天中的问题更新和讨论,您还可以执行以下操作:

class MyGradlePlugin implements Plugin<Project> {

  void apply(Project project) {
    project.tasks.findByName('install')?.doLast {
      ...
    }
  }

}
类MyGradlePlugin实现插件{
无效申请(项目){
project.tasks.findByName('install')?.doLast{
...
}
}
}

我知道这是一个老问题,但由于没有选定的答案,我将举一个我使用过的例子。这基于gradle文件第49.8.2.2节中的示例

我用它来做自定义依赖项解析,但是你可以在依赖项迭代中做任何你想做的事情。请注意,这是因为它传递的闭包是在配置阶段之后执行的

插件代码:

package com.overtherainbow

import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.api.artifacts.DependencyResolveDetails

class DefaultVersionPlugin implements Plugin<Project> {

    // This is where dependency versions are defined
    def defaultVersionsMap = [
        'javax.servlet:servlet-api' : '2.5',
        'log4j:log4j' : '1.2.16']

    void apply(Project project) {
        project.configurations.all {
            resolutionStrategy.eachDependency {
                DependencyResolveDetails details -> resolveDependencyVersion(project, details)
            }
        }
    }

    def resolveDependencyVersion(Project project, DependencyResolveDetails details) {
        if (details.requested.version == 'default') {
            def version = resolveDefaultVersion(project, details.requested.group, details.requested.name)
            details.useVersion version
        }
    }

    def resolveDefaultVersion(Project project, String group, String name) {
        project.logger.debug("Resolving default dependency for $group:$name")
        println "Resolving default dependency for $group:$name"
        defaultVersionsMap["$group:$name"]
    }
}
package com.overtherainbow
导入org.gradle.api.Project
导入org.gradle.api.Plugin
导入org.gradle.api.artifacts.DependencyResolveDetails
类DefaultVersionPlugin实现插件{
//这是定义依赖项版本的地方
def defaultVersionsMap=[
'javax.servlet:ServletAPI':'2.5',
'log4j:log4j':'1.2.16']
无效申请(项目){
project.configurations.all{
解决策略。每个依赖项{
DependencyResolveDetails详细信息->resolveDependencyVersion(项目,详细信息)
}
}
}
def resolveDependencyVersion(项目,DependencyResolveDetails){
如果(details.requested.version=='default'){
def version=resolveDefaultVersion(项目,details.requested.group,details.requested.name)
details.useVersion版本
}
}
def resolveDefaultVersion(项目、字符串组、字符串名称){
project.logger.debug(“解析$group:$name的默认依赖项”)
println“解析$group:$name的默认依赖项”
DefaultVersionMap[“$group:$name”]
}
}

我假设您希望迭代配置的所有依赖项
编译
?如果我不在“afterEvaluate”范围内执行,它会工作。该插件现在作为安装后的最后一步应用:install.doLast{apply plugin:'my gradle plugin'}答案中的代码有效,我用gradle 1.2测试了它。在你的install.doLast中,我会说,这是一个有点奇怪的插件用法,如果你真的只需要在安装任务完成后打印依赖项列表,那么你可以将代码放入doLast中,为什么要使用插件呢?这样做的动机是多个项目需要应用这个插件,我不想重复所有这些项目的代码。将它放入插件中,只可能编写一次脚本。是的,但Gradle插件系统足够先进,可以避免“仅在install.onLast中调用插件以获得此公共功能”之类的特殊技巧。您可以在插件的apply方法中定义所需的行为,并将评估推迟到需要的时候。顺便说一句。在您最初的问题中,不清楚您是否希望打印出依赖项作为生成的最后一步。您可以使用gradle.buildFinished闭包定义您想要的任何特殊行为:。