Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complex plugin setup fix #71

Closed
wants to merge 9 commits into from
87 changes: 87 additions & 0 deletions src/main/groovy/nebula/plugin/publishing/PublicationBase.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package nebula.plugin.publishing

import nebula.plugin.publishing.ivy.IvyBasePublishPlugin
import nebula.plugin.publishing.maven.MavenBasePublishPlugin
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.publish.ivy.IvyPublication
import org.gradle.api.publish.ivy.plugins.IvyPublishPlugin
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin

trait PublicationBase implements Plugin<Project>, StandardTextValues {

/**
* Checks to see if the task already exists or not on the project. If it does not, then it creates it.
* @param project project to add the task too
* @param task Map configuration of the task to create
* @return Null if it was not created, the task object if it was.
*/
Task addTaskLocal(Project project, Map<String, ?> task) {
if (!project.tasks.findByName(task.get('name').toString())) {
project.tasks.create(task)
} else {
null
}
}

void checkAddMavenPublish(Project project, Task createdTask) {
project.plugins.withType(MavenPublishPlugin) {
project.plugins.apply(MavenBasePublishPlugin)

project.publishing.publications {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding publishing.publications accesses the publishing block, where as the series of closures will apply later when a publishing task is run.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it has something to do with the timing. ive heard several discussions on what causes it. What i do know for sure is this is universally referred to as the fix and Gradle's answer for the past 2 or so years is publish-maven is in incubation.

Copy link
Contributor

@rspieldenner rspieldenner Feb 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to see a test that fails with

project.publishing {
  publications {
    // config
  }
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, thats going to be tough because its buried about three layers of custom plugins deep in a CI server. It has to do with the core publish being in the core plugin that everything else inherits, with child plugins and such. Its really tough, I do know its a well known groovy/gradle issue because it only took me a minute or two to find the solution when i hit it. I can track down the research when im on my work machine tomorrow.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

researchgate/gradle-release#125

https://stackoverflow.com/questions/28020520/custom-gradle-plugin-causes-cannot-configure-the-publishing-extension

are where i got the fix for the "can not modify publish after its been accessed" error. As i said, its a well known gradle/groovy issue in their maven-publish plugin.

Still trying to figure out a way to boil it down to a unit test. the conditions are pretty specific and not easy to replicate.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http://stackoverflow.com/questions/21190230/how-can-plugin-programmatically-configure-maven-publish-publishing-and-allow-bui

Apparently Justin Ryan built a class in a very early version of nebula publish to try to handle this specific issue. but just changing the syntax is far easier than his fix.

It looks like i have no choice but to build an additional custom plugin (a build.gradle file is nothing more than a plugin). It seams you can't replicate the problem from a single plugin closure, like a build.gradle file. It seems like you can only replicate it from a parent/child plugin relationship, where the parent introduces publishing and finishes its apply method, then a child method attempts to access the publishing from its apply method. At least i think so.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be ok if I put the prelim stuff in https://github.com/nebula-plugins/gradle-nothing-plugin

create a new plugin in that project to use to replicate this here? I can't figure out any other way to replicate it than with an external plugin. but ill keep thinking

nebula(MavenPublication) {
artifact createdTask
}
}
}
}

void checkAddIvyPublish(Project project, Task createdTask, String classifier) {
project.plugins.withType(IvyPublishPlugin) {
project.plugins.apply(IvyBasePublishPlugin)

project.publishing.publications {
nebulaIvy(IvyPublication) {
artifact(createdTask) {
type classifier
conf classifier
}
}
}
}
}

void buildConfigureTask(Project project, Task createdTask, String classifierString, String dependsOnTask,
String artifactExtension, boolean fromSources = false, sourceSetNames = []) {

if (createdTask != null) {
/*
the addTaskLocal checks to see if the task already exists or not. If it returns null,
that means it did not create the task. If it returned the task object, then it created it
We dont want to configure things if we didn't create the task
*/

// this means it was just created correctly, now reprocess it
def dependsOnTaskObject = project.tasks.getByName(dependsOnTask)

createdTask.configure {
dependsOn dependsOnTaskObject
if (fromSources) {
sourceSetNames.each {
from project.sourceSets.findByName(it).allSource
}
} else {
from dependsOnTaskObject.destinationDir
}

classifier classifierString
extension artifactExtension
}

checkAddMavenPublish(project, createdTask)
checkAddIvyPublish(project, createdTask, classifierString)
}
}
}
29 changes: 29 additions & 0 deletions src/main/groovy/nebula/plugin/publishing/StandardTextValues.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package nebula.plugin.publishing


interface StandardTextValues {
public static final String CORE_GROUP_BUILD = "build"

public static final String CORE_TASK_GROOVYDOC = "groovydoc"
public static final String CORE_TASK_JAVADOC = "javadoc"
public static final String CORE_TASK_SCALADOC = "scaladoc"
public static final String CORE_TASK_CLASSES = "classes"


public static final String TASK_NAME_GROOVYDOC_JAR = "groovydocJar"
public static final String TASK_DESC_GROOVYDOC_JAR = "Jars the groovydoc files for the project"
public static final String TASK_NAME_JAVADOC_JAR = "javadocJar"
public static final String TASK_DESC_JAVADOC_JAR = "Jars the javadoc files for the project"
public static final String TASK_NAME_SCALADOC_JAR = "scaladocJar"
public static final String TASK_DESC_SCALADOC_JAR = "Jars the groovydoc files for the project"

public static final String TASK_NAME_SOURCE_JAR = "sourceJar"
public static final String TASK_DESC_SOURCE_JAR = "Jars the source files for the project"

public static final String ARCHIVE_CLASSIFIER_GROOVYDOC = "groovydoc"
public static final String ARCHIVE_CLASSIFIER_SOURCES = "sources"
public static final String ARCHIVE_CLASSIFIER_JAVADOC = "javadoc"
public static final String ARCHIVE_CLASSIFIER_SCALADOC = "scaladoc"

public static final String EXTENSION_JAR = "jar"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package nebula.plugin.publishing.publications

import nebula.plugin.publishing.PublicationBase
import org.gradle.api.Project
import org.gradle.api.plugins.GroovyPlugin
import org.gradle.api.tasks.bundling.Jar

class GroovydocJarPlugin implements PublicationBase {
@Override
void apply(Project project) {
project.plugins.withType(GroovyPlugin) {

def groovyJar = addTaskLocal(project, [name : TASK_NAME_GROOVYDOC_JAR,
description: TASK_DESC_GROOVYDOC_JAR,
group : CORE_GROUP_BUILD,
type : Jar])

buildConfigureTask(project, groovyJar, ARCHIVE_CLASSIFIER_GROOVYDOC, CORE_TASK_GROOVYDOC, EXTENSION_JAR)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,55 +14,23 @@
* limitations under the License.
*/
package nebula.plugin.publishing.publications
import nebula.plugin.publishing.ivy.IvyBasePublishPlugin
import nebula.plugin.publishing.maven.MavenBasePublishPlugin
import org.gradle.api.Plugin

import nebula.plugin.publishing.PublicationBase
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.publish.ivy.IvyPublication
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.javadoc.Javadoc

class JavadocJarPlugin implements Plugin<Project> {
class JavadocJarPlugin implements PublicationBase {
@Override
void apply(Project project) {
project.plugins.withType(JavaPlugin) {
Javadoc javadocTask = (Javadoc) project.tasks.getByName('javadoc')
project.tasks.create('javadocJar', Jar) {
dependsOn javadocTask
from javadocTask.destinationDir
classifier 'javadoc'
extension 'jar'
group 'build'
}

project.plugins.withType(org.gradle.api.publish.maven.plugins.MavenPublishPlugin) {
project.plugins.apply(MavenBasePublishPlugin)

project.publishing {
publications {
nebula(MavenPublication) {
artifact project.tasks.javadocJar
}
}
}
}

project.plugins.withType(org.gradle.api.publish.ivy.plugins.IvyPublishPlugin) {
project.plugins.apply(IvyBasePublishPlugin)
def javadocJar = addTaskLocal(project, [name : TASK_NAME_JAVADOC_JAR,
description: TASK_DESC_JAVADOC_JAR,
group : CORE_GROUP_BUILD,
type : Jar])

project.publishing {
publications {
nebulaIvy(IvyPublication) {
artifact(project.tasks.javadocJar) {
type 'javadoc'
conf 'javadoc'
}
}
}
}
}
buildConfigureTask(project, javadocJar, ARCHIVE_CLASSIFIER_JAVADOC, CORE_TASK_JAVADOC, EXTENSION_JAR)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package nebula.plugin.publishing.publications

import nebula.plugin.publishing.PublicationBase
import org.gradle.api.Project
import org.gradle.api.plugins.scala.ScalaPlugin
import org.gradle.api.tasks.bundling.Jar

class ScaladocJarPlugin implements PublicationBase {
@Override
void apply(Project project) {
project.plugins.withType(ScalaPlugin) {

def scalaJar = addTaskLocal(project, [name : TASK_NAME_SCALADOC_JAR,
description: TASK_DESC_SCALADOC_JAR,
group : CORE_GROUP_BUILD,
type : Jar])

buildConfigureTask(project, scalaJar, ARCHIVE_CLASSIFIER_SCALADOC, CORE_TASK_SCALADOC, EXTENSION_JAR)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,53 +15,22 @@
*/
package nebula.plugin.publishing.publications

import nebula.plugin.publishing.ivy.IvyBasePublishPlugin
import nebula.plugin.publishing.maven.MavenBasePublishPlugin
import org.gradle.api.Plugin
import nebula.plugin.publishing.PublicationBase
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.publish.ivy.IvyPublication
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.bundling.Jar

class SourceJarPlugin implements Plugin<Project> {
class SourceJarPlugin implements PublicationBase {
@Override
void apply(Project project) {
project.plugins.withType(JavaPlugin) {
project.tasks.create('sourceJar', Jar) {
dependsOn project.tasks.getByName('classes')
from project.sourceSets.main.allSource
classifier 'sources'
extension 'jar'
group 'build'
}

project.plugins.withType(org.gradle.api.publish.maven.plugins.MavenPublishPlugin) {
project.plugins.apply(MavenBasePublishPlugin)
def sourceJar = addTaskLocal(project, [name : TASK_NAME_SOURCE_JAR,
description: TASK_DESC_SOURCE_JAR,
group : CORE_GROUP_BUILD,
type : Jar])

project.publishing {
publications {
nebula(MavenPublication) {
artifact project.tasks.sourceJar
}
}
}
}

project.plugins.withType(org.gradle.api.publish.ivy.plugins.IvyPublishPlugin) {
project.plugins.apply(IvyBasePublishPlugin)

project.publishing {
publications {
nebulaIvy(IvyPublication) {
artifact(project.tasks.sourceJar) {
type 'sources'
conf 'sources'
}
}
}
}
}
buildConfigureTask(project, sourceJar, ARCHIVE_CLASSIFIER_SOURCES, CORE_TASK_CLASSES, EXTENSION_JAR, true, ['main'])
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
implementation-class=nebula.plugin.publishing.publications.GroovydocJarPlugin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
implementation-class=nebula.plugin.publishing.publications.ScaladocJarPlugin