Gradle:如何使规则创建的ZipTask成为maven发布工件 [英] Gradle: how to make rule-created ZipTask as maven publication artifact

查看:228
本文介绍了Gradle:如何使规则创建的ZipTask成为maven发布工件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在RuleSource中创建一个Maven发布,该发布将通过 maven-publish 插件发布。该出版物的工件是从规则创建的一系列Zip任务的输出。当我尝试添加工件时,出现循环规则异常。



这是我非常简单的 build.gradle

  buildscript {
存储库{
mavenCentral()
}

依赖项{
}
}

任务包装器(类型:包装器){
gradleVersion ='3.3'
}

申请插件:'groovy'
申请插件:'testpub'

仓库{
mavenCentral()
}

依赖关系{
compile'org.codehaus.groovy:groovy-all:2.4.7'
}

testpub 插件存在于 buildSrc 目录中。为了能够像上面那样应用它,它需要以下属性文件:

  // buildSrc / src / main / resources / META_INF / gradle-plugins / testpub.properties 
implementation-class = TestPubPlugin

这里是非常简单的插件文件:

  import org.gradle.api.Project 
import org.gradle.api.Plugin
import org.gradle.model.RuleSource
import org.gradle.api.Task
import org.gradle.model.Mutate
import org.gradle.model.Finalize
import org.gradle.api.tasks.bundling.Zip
import org.gradle.model.ModelMap
import org.gradle.api.publish.PublishingExtension
import org.gradle.api。 publish.maven.MavenPublication


class TestPubPlugin implements Plugin< Project> {
void apply(Project project){
project.configure(project){
apply plugin:'maven-publish'

publishing {
repositories {
maven {
urlsomeUrl
}
}
}

}
}

static class TestPubPluginRules extends RuleSource {

@Mutate
public void createSomeTasks(final ModelMap< Task> tasks){
5.times {suffix - >
tasks.create(someTask $ {suffix},Zip){
fromsrc
destinationDir(new File(build))
baseNamesomeZip $ {后缀}
}
}
}

@Mutate
public void configurePublishingPublications(final PublishingExtension publishing,final ModelMap< Task> tasks){

//意图是创建一个出版物,其工件由`someTaskx`任务形成
//其中x = [0..4]
发布{
出版物{
mavPub(MavenPublication){
tasks.matching {it.name.startsWith('someTask')}。each {task - >
artifact(任务)
}
}
}
}
}
}
}

该插件创建了一些称为 someTaskx 的任务,其中 X = [0..4] 。他们只需将src目录压缩即可。我想将输出文件作为工件添加到单个MavenPublication中。但是,我得到以下异常:

  *出错:
配置根项目'testpub'时出现问题。
>在模型规则依赖关系中检测到循环。形成循环的参考:
任务
\ - TestPubPlugin.TestPubPluginRules#createSomeTasks(ModelMap< Task>)
\ - MavenPublishPlugin.Rules #realPublishingTasks(ModelMap< Task> ;, PublishingExtension,File)
\- PublishingPlugin.Rules#tasksConfiguredPublicationsToProjectPublicationRegistry(ProjectPublicationRegistry,PublishingExtension,ProjectIdentifier)
\- PublishingPlugin.Rules#tasksDependOnProjectPublicationRegistry(ModelMap< Task>,ProjectPublicationRegistry)
\ projectPublicationRegistry
\- publishing
\- TestPubPlugin.TestPubPluginRules#configurePublishingPublications(PublishingExtension,ModelMap< Task>)
\- tasks

什么是错误的,我该如何解决它?

解决方案

完全理解为什么这是一个循环,但是规则方法总是有一个可变部分(主体)和零个或多个不可变(输入)。在第二种方法中,您将发布作为要更改的主题,将任务作为输入。我认为这样可以,但显然它不是。

您可能试图切换方法参数,先传递任务,然后再传入 PublishingExtension ,但您可能无法更改它(因为gradle文档说它是不可变的)。



我不确定是什么恰恰是你的用例,可能有一个更简单的解决方案,根本不使用规则或插件。也许你可以用原来的要求提出另一个问题,而不是这个具体问题。



但回到你的问题。解决您的问题可能是这样的:

  import org.gradle.api.Plugin 
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish .maven.MavenPublication
import org.gradle.api.tasks.bundling.Zip
import org.gradle.model.Defaults
import org.gradle.model.ModelMap
import org .gradle.model.Mutate
import org.gradle.model.RuleSource

class TestPubPlugin implements Plugin< Project> {
void apply(Project project){
project.configure(project){
apply plugin:'maven-publish'

publishing {
publications {
maven(MavenPublication){
groupId'com.example'
artifactId'artifact'
}
}
存储库{
maven {
urlsomeUrl
}
}
}

}
}

static class TestPubPluginRules extends RuleSource {
static final def buffer = []

@Defaults
public void createSomeTasks(final ModelMap< Task> tasks){
5.times {suffix - >
tasks.create(someTask $ {suffix},Zip){
fromsrc
destinationDir(new File(build))
baseNamesomeZip $ {后缀}
}
}
tasks.each {任务 - >
if(task.name.startsWith('someTask'))
buffer<<任务
}
}

@Mutate
public void configurePublishingPublications(PublishingExtension extension){
MavenPublication p = extension.publications [0]
buffer.each {任务 - >
p.artifact(任务)
}
}
}
}

这里的破解是首先运行任务的修改器(@Defaults阶段应该在@Mutate之前运行)并保存任务,因此我们不需要稍后再提问。规则可以包括静态最终字段,所以我们在这里使用一个列表。

然后我们运行出版物增强器。您使用的代码不起作用。它在config部分工作,但不在groovy类中。所以我准备了发布,然后只是从缓冲区中添加了工件。



我运行了 gradlew publish 并得到了:

 任务':publishMavenPublicationToMavenRepository'的执行失败。 
>无法将发布'maven'发布到资源库'maven'
>无效的发布'maven':工件文件不存在:'build \someZip0.zip'

它似乎工作。


I want to create a maven publication from inside a RuleSource that will be published via the maven-publish plugin. The artifacts of the publication are the outputs from a series of Zip tasks that are created from rules. When I try to add the artifacts, I get a circular rule exception.

Here is my very simple build.gradle:

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '3.3'
}

apply plugin: 'groovy'
apply plugin: 'testpub'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.4.7'
}

The testpub plugin exists in the buildSrc directory. To be able to apply it as above, it requires the following properties file:

// buildSrc/src/main/resources/META_INF/gradle-plugins/testpub.properties
implementation-class=TestPubPlugin

Here is the very simple plugin file:

import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.model.RuleSource
import org.gradle.api.Task
import org.gradle.model.Mutate
import org.gradle.model.Finalize
import org.gradle.api.tasks.bundling.Zip
import org.gradle.model.ModelMap
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication


class TestPubPlugin implements Plugin<Project> {
    void apply(Project project) {    
        project.configure(project) {
            apply plugin: 'maven-publish'

            publishing {
                repositories {
                    maven {
                        url "someUrl"
                    }
                }
            }

        }
    }

    static class TestPubPluginRules extends RuleSource {

        @Mutate
        public void createSomeTasks(final ModelMap<Task> tasks) {
            5.times { suffix ->
                tasks.create("someTask${suffix}", Zip) {
                    from "src"
                    destinationDir(new File("build"))
                    baseName "someZip${suffix}"
                }
            }
        }

        @Mutate
        public void configurePublishingPublications(final PublishingExtension publishing, final ModelMap<Task> tasks) {    

            // Intention is to create a single publication whose artifacts are formed by the `someTaskx` tasks
            // where x = [0..4]
            publishing {
                publications {
                    mavPub(MavenPublication) {
                        tasks.matching {it.name.startsWith('someTask')}.each { task ->
                            artifact(task)
                        }
                    }       
                }        
            }
        }
    }
}

The plugin creates a number of tasks called someTaskx where x=[0..4]. They simply zip up the src directory. I want to add the output files as artifacts to the single MavenPublication. However, I get the following exception:

* What went wrong:
A problem occurred configuring root project 'testpub'.
> A cycle has been detected in model rule dependencies. References forming the cycle:
  tasks
  \- TestPubPlugin.TestPubPluginRules#createSomeTasks(ModelMap<Task>)
     \- MavenPublishPlugin.Rules#realizePublishingTasks(ModelMap<Task>, PublishingExtension, File)
        \- PublishingPlugin.Rules#tasksDependOnProjectPublicationRegistry(ModelMap<Task>, ProjectPublicationRegistry)
           \- projectPublicationRegistry
              \- PublishingPlugin.Rules#addConfiguredPublicationsToProjectPublicationRegistry(ProjectPublicationRegistry, PublishingExtension, ProjectIdentifier)
                 \- publishing
                    \- TestPubPlugin.TestPubPluginRules#configurePublishingPublications(PublishingExtension, ModelMap<Task>)
                       \- tasks

What is wrong and how do I fix it?

解决方案

I don't fully understand why is this a "cycle", but the rule methods always have one mutable part (the subject) and zero or more immutable (the inputs). In your second method, you are passing the publishing as the subject you want to change and the tasks as the input. I thought that would be ok, but obviously it isn't.

You might have tried to switch the method arguments, pass the tasks first and then the PublishingExtension, but you would likely not be able to change it (as gradle docs say it's immutable).

I am not sure what exactly is your use case and there might be an easier solution that doesn't use the rules, or plugin at all. Maybe you could ask another question with the original requirement instead of this specific problem.

But back to your issue. The solution to your problem might be something like this:

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.bundling.Zip
import org.gradle.model.Defaults
import org.gradle.model.ModelMap
import org.gradle.model.Mutate
import org.gradle.model.RuleSource

class TestPubPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.configure(project) {
            apply plugin: 'maven-publish'

            publishing {
                publications {
                    maven(MavenPublication) {
                        groupId 'com.example'
                        artifactId 'artifact'
                    }
                }
                repositories {
                    maven {
                        url "someUrl"
                    }
                }
            }

        }
    }

    static class TestPubPluginRules extends RuleSource {
        static final def buffer = []

        @Defaults
        public void createSomeTasks(final ModelMap<Task> tasks) {
            5.times { suffix ->
                tasks.create("someTask${suffix}", Zip) {
                    from "src"
                    destinationDir(new File("build"))
                    baseName "someZip${suffix}"
                }
            }
            tasks.each { task ->
                if (task.name.startsWith('someTask'))
                    buffer << task
            }
        }

        @Mutate
        public void configurePublishingPublications(PublishingExtension extension) {
            MavenPublication p = extension.publications[0]
            buffer.each { task ->
                p.artifact(task)
            }
        }
    }
}

The hack here is to run the mutator of the tasks first (@Defaults phase should run before @Mutate) and save the tasks, so we don't need to ask for them later. Rules can include static final fields, so we use a list here.

Then we run the publication enhancer. The code you have used won't work. It works in the config part, but not in the groovy class. So I have prepared the publication and then just added the artifacts from the buffer.

I ran gradlew publish and got:

Execution failed for task ':publishMavenPublicationToMavenRepository'.
> Failed to publish publication 'maven' to repository 'maven'
   > Invalid publication 'maven': artifact file does not exist: 'build\someZip0.zip' 

So it seems it's working.

这篇关于Gradle:如何使规则创建的ZipTask成为maven发布工件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆