Gradle: how to create maven publication from inside rule block

software-model
plugins

(john) #1

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?


[rule based model] Select a rule-created tarTask as publication artifact