【问题标题】:How to iterate gradle dependencies in custom gradle plugin?如何在自定义 gradle 插件中迭代 gradle 依赖项?
【发布时间】:2012-10-23 13:01:10
【问题描述】:

我已遵循本指南:

http://www.gradle.org/docs/current/userguide/custom_plugins.html

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

  my-gradle-plugin
    > src
     > main
      > java
       > com
        > mygroup
         > MyGradlePlugin.groovy
    > build.gradle
    > settings.gradle

build.gradle

apply plugin: 'groovy'

dependencies {
  compile gradleApi()
  groovy localGroovy()
}

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

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

MyGradlePlugin.groovy

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()

}
   }
  }

在另一个项目中我使用/应用这个插件:

apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'eclipse'

repositories {
  mavenLocal()
}

buildscript {
  repositories {
    mavenLocal()
  }
  dependencies {
    classpath group: 'com.mygroup', name: 'my-gradle-plugin', version: '1.0.0-SNAPSHOT'
  }
}



dependencies {
  compile group: 'commons-codec', name: 'commons-codec', version: '1.4'
  compile group: 'commons-beanutils', name: 'commons-beanutils', version: '1.7.0'
}

install.doLast {
 apply plugin: 'my-gradle-plugin'

}

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

【问题讨论】:

  • 我假设您想遍历配置compile的所有依赖项?

标签: plugins gradle


【解决方案1】:

我知道这是一个老问题,但由于没有选定的答案,我将举一个我用过的例子。这是基于 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"]
    }
}

【讨论】:

    【解决方案2】:

    问题是依赖关系图只有在项目完全评估后才可用。这就是为什么您不能在 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}"
            }
          }
        }
      }
    
    }
    

    更新:在 cmets 和聊天中关注问题更新和讨论,您还可以执行以下操作:

    class MyGradlePlugin implements Plugin<Project> {
    
      void apply(Project project) {
        project.tasks.findByName('install')?.doLast {
          ...
        }
      }
    
    }
    

    【讨论】:

    • 如果我不在“afterEvaluate”范围内这样做,它会起作用。该插件现在作为最后一步应用(安装后): install.doLast { apply plugin: 'my-gradle-plugin' }
    • 答案中的代码有效,我用 gradle 1.2 对其进行了测试。在您使用 install.doLast 的情况下,我会说,这有点奇怪的插件用法,如果您真的只需要在安装任务之后打印出依赖项列表,那么您可以将代码放入 doLast,为什么要使用插件呢?
    • 这样做的动机是多个项目需要应用这个插件,我不想为所有这些项目复制代码。将其放入插件中可以只编写一次脚本。
    • 是的,但是 Gradle 插件系统足够先进,可以避免像“仅在 install.onLast 中调用 apply on the plugin 以获取此通用功能”之类的特殊技巧。您可以在插件的 apply 方法中定义所需的行为,并将评估推迟到需要的地方。顺便提一句。在您最初的问题中,不清楚您是否希望将依赖项打印为构建的最后一步。
    • 您可以使用 gradle.buildFinished 闭包来定义您想要的任何特殊行为:gradle.org/docs/current/groovydoc/org/gradle/api/invocation/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    相关资源
    最近更新 更多