在Gradle中,如何生成具有动态依赖关系的POM文件,该文件已解析为使用的实际版本?

时间:2014-01-06 21:25:57

标签: java maven dependencies gradle pom.xml

在Gradle中,如何生成一个POM文件,其动态依赖关系已解析为实际使用的版本?

dependencies {
    testCompile(group: 'junit', name: 'junit', version: '4.+')
}

这是从上面的依赖项生成的。

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.+</version>
        <scope>test</scope>
    </dependency>
</dependencies>

我希望将+解析为如下的应计版本。

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

关于Maven Publishing的Gradle指南章节讨论了这样做,但未提及如何做。

  

使用此挂钩,您可以修改POM的任何方面。例如,您可以使用用于生成构建的实际版本替换依赖项的版本范围。

解决方案

使用Peter Niederwieser的答案中的信息,我创建了一个任务,该任务读取包含动态依赖关系的POM,并使用已解析依赖关系的新pom覆盖它。

/**
 * Reads and Overwrites POM file resolving dynamic dependencies
 */
task cleanPom(dependsOn: writeNewPom) << {
    // Get existing pom file
    Node xml = new XmlParser().parse(pomFileLocation)

    // Generate map of resolved versions
    Map resolvedVersionMap = new HashMap()
    Set<ResolvedArtifact> resolvedArtifacts = configurations.compile.getResolvedConfiguration().getResolvedArtifacts()
    resolvedArtifacts.addAll(configurations.testCompile.getResolvedConfiguration().getResolvedArtifacts())
    resolvedArtifacts.each {
        resolvedVersionMap.put(it.getName(), it.getModuleVersion().getId().getVersion())
    }

    // Update dependencies with resolved versions
    xml.dependencies.first().each {
        Node artifactId = it.get("artifactId").first()
        def artifactName = artifactId.value().first()
        def artifactVersion = resolvedVersionMap.get(artifactName)

        Node version = it.get("version").first()
        version.value = artifactVersion
    }

    // Overwrite existing pom file
    new XmlNodePrinter(new PrintWriter(new FileWriter(pomFileLocation))).print(xml)
}

3 个答案:

答案 0 :(得分:5)

需要一些努力才能对此进行编码。两个主要部分是:

  • 使用Configuration#getIncomingConfiguration#getResolvedConfiguration API
  • 查询已解决的版本
  • 使用Groovy的XMlParser API操作POM(假设使用了新的maven-publish插件)

有关Configuration API的信息可以在Gradle Build Language Reference中找到,它进一步链接到Javadoc。 完整的Gradle分布包含一个演示POM操作的tiny sample。有关XmlParser的信息可以在Groovy文档中找到。

答案 1 :(得分:2)

我已经尝试将其集成到可以应用的插件中,具体代码可在此处获取:https://github.com/nebula-plugins/nebula-publishing-plugin/blob/master/src/main/groovy/nebula/plugin/publishing/maven/ResolvedMavenPlugin.groovy

它可以通过jcenter()通过'com.netflix.nebula:nebula-publishing-plugin:1.9.1'包含。

答案 2 :(得分:2)

Peter建议的pom.withXml()解决方案如下:

publishing {
  publications {
    mavenCustom(MavenPublication) {
        from components.java
            pom.withXml {
                // Generate map of resolved versions
                Map resolvedVersionMap = [:]
                Set<ResolvedArtifact> resolvedArtifacts = configurations.compile.getResolvedConfiguration().getResolvedArtifacts()
                resolvedArtifacts.addAll(configurations.testCompile.getResolvedConfiguration().getResolvedArtifacts())
                resolvedArtifacts.each {
                    ModuleVersionIdentifier mvi = it.getModuleVersion().getId();
                    resolvedVersionMap.put("${mvi.getGroup()}:${mvi.getName()}", mvi.getVersion())
                }

              // Update dependencies with resolved versions
              def hasDependencies = !asNode().dependencies.isEmpty()
              if (hasDependencies) {
                  asNode().dependencies.first().each {
                      def groupId = it.get("groupId").first().value().first()
                      def artifactId = it.get("artifactId").first().value().first()
                      it.get("version").first().value = resolvedVersionMap.get("${groupId}:${artifactId}")
              }
          }
      }
   }
}