Maven-publish pom gradle conventions

I’m publishing a multi-module project to maven central, there are a bunch of similar configurations in each of the module’s poms, and I’m trying to figure out how to pull that into a buildSrc convention.

For example, every module has the same MavenPomScm configuration. I’ve tried a couple different ways to implement this in my offthecob-platform.maven-conventions.gradle.kts but have not been successful.

plugins {
    `maven-publish`
}

fun getMavenPomScm(): MavenPomScm {
    return object : MavenPomScm {
        override fun getConnection(): Property<String> {
            val connection = project.objects.property<String>()
            connection.set("scm:git:git://github.com/whodevil/offthecob-platform.git")
            return connection
        }

        override fun getDeveloperConnection(): Property<String> {
            val connection = project.objects.property<String>()
            connection.set("scm:git:ssh://github.com:whodevil/offthecob-platform.git")
            return connection
        }

        override fun getUrl(): Property<String> {
            val url = project.objects.property<String>()
            url.set("https://github.com/whodevil/offthecob-platform/tree/master")
            return url
        }

        override fun getTag(): Property<String> {
            val tag = project.objects.property<String>()
            tag.set("")
            return tag
        }
    }
}

and then in the module

plugins {
    id("offthecob-platform.maven-conventions")
    `java-library`
}

configure<PublishingExtension> {
    publications {
        register<MavenPublication>("Common") {
            from(components["java"])
            pom {

               // excluded for brevity

                scm = getMavenPomScm()
            }
        }
    }
}

The above clearly doesn’t work, can someone point me in the right direction?

I think I’ve at least cleaned up the action a little, but I’m still not sure how to expose it to the module:

offthecob-platform.maven-conventions.gradle.kts

val mavenScmPom = Action<MavenPomScm> {
    connection.set("scm:git:git://github.com/whodevil/offthecob-platform.git")
    developerConnection.set("scm:git:ssh://github.com:whodevil/offthecob-platform.git")
    url.set("https://github.com/whodevil/offthecob-platform/tree/master")
}

configure<PublishingExtension> {
    publications {
        register<MavenPublication>("Common") {
            from(components["java"])
            pom {
                scm(mavenScmPom)
            }
        }
    }
}

This feels closer, but is not working.

Trying the plugin tact, also falls slightly short in that I can access a Publication but not MavenPublication

class PomPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.plugins.apply("maven-publish")
        project.extensions.getByType(PublishingExtension::class.java).publications.registering {
            // this is an instance of Publication
        }
    }
}

I got it!

class PomPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.plugins.apply("maven-publish")
        project.extensions.getByType(PublishingExtension::class.java).publications.withType(MavenPublication::class.java) {
            pom {
                scm {
                    connection.set("scm:git:git://github.com/whodevil/offthecob-platform.git")
                    developerConnection.set("scm:git:ssh://github.com:whodevil/offthecob-platform.git")
                    url.set("https://github.com/whodevil/offthecob-platform/tree/master")
                }
            }
        }
    }
}

offthecob-platform.maven-conventions.gradle.kts

apply<PomPlugin>()
plugins {
    id("offthecob-platform.maven-conventions")
    `java-library`
}

configure<PublishingExtension> {
    publications {
        register<MavenPublication>("Common") {
            from(components["java"])
        }
    }
}

If there is a more straightforward way to do what I ended up accomplishing, I’d love to hear about it.

Just some details.

If you intentionally prefer to write a classic plugin class in a kt file, that’s fine.
But then having a precompiled script plugin to apply it is a bit weird.
Better declare the intended plugin id in your buildSrc build script, pointing to the PomPlugin directly, no need for that additional indirection.

Or if you prefer the build script-y style, just throw away PomPlugin and do the work in the precompiled script plugin directly like

plugins {
    `maven-publish`
}
publishing {
    publications.withType<MavenPublication>().configureEach {
        pom { ... }
    }
}

And in your actual build script, it is not necessary to use configure<PublishingExtension> {.
As you apply your convention plugin in the plugins { ... } block and your convention plugin applies the maven-publish plugin, the accessors for it and its dependencies are generated for your build script too, so you can just use the publishing { ... } accessor.

Ah yeah, I see what you are saying. I’ve been working a lot with the plugin api lately, so I just defaulted to that, I think for this particular task, what you are suggesting makes way more sense.

Thanks!

As I said, having the plugin in a .kt file is fine too.
But then do not make a precompiled script plugin just to assign it an ID, but just configure the ID for that class in your build script. :slight_smile: