diff --git a/src/docs/changes/README.md b/src/docs/changes/README.md index a9dfcd1d3..6d38e2b34 100644 --- a/src/docs/changes/README.md +++ b/src/docs/changes/README.md @@ -7,6 +7,8 @@ **Changed** +- `ShadowExtension.component` has been deprecated, now you can use `component.shadow` instead. ([#956](https://github.com/GradleUp/shadow/pull/956)) + **Fixed** - Stop publishing Shadow self fat jar to Maven repository. ([#967](https://github.com/GradleUp/shadow/pull/967)) diff --git a/src/docs/publishing/README.md b/src/docs/publishing/README.md index 66da927f0..16c4fb400 100644 --- a/src/docs/publishing/README.md +++ b/src/docs/publishing/README.md @@ -15,8 +15,8 @@ apply plugin: 'com.gradleup.shadow' publishing { publications { - shadow(MavenPublication) { publication -> - project.shadow.component(publication) + shadow(MavenPublication) { + components.shadow } } repositories { diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowExtension.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowExtension.groovy index 03a575d54..53fc8b38d 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowExtension.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowExtension.groovy @@ -1,74 +1,22 @@ package com.github.jengelman.gradle.plugins.shadow -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.gradle.api.Project -import org.gradle.api.artifacts.ProjectDependency -import org.gradle.api.artifacts.SelfResolvingDependency -import org.gradle.api.file.RegularFile -import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider -import org.gradle.api.publish.maven.MavenPom +import org.gradle.api.component.SoftwareComponentContainer import org.gradle.api.publish.maven.MavenPublication +@Deprecated class ShadowExtension { - private final Provider archive - private final Provider> allDependencies + private final SoftwareComponentContainer components ShadowExtension(Project project) { - archive = project.provider { - def archiveTask = project.tasks.withType(ShadowJar).getByName("shadowJar") - new Archive(archiveTask.archiveFile, archiveTask.archiveClassifier) - } - allDependencies = project.provider { - project.configurations.getByName("shadow").allDependencies.collect { - if ((it instanceof ProjectDependency) || !(it instanceof SelfResolvingDependency)) { - new Dep(it.group, it.name, it.version) - } - } - } + components = project.components } + /** + * @deprecated configure publication using component.shadow directly. + */ + @Deprecated void component(MavenPublication publication) { - publication.artifact([ - source : archive.get().file, - classifier: archive.get().classifier.get() - ]) - - // Don't inline this variable, it seems Groovy closure capturing is confused by the field instead of a local variable. - final def allDeps = allDependencies - publication.pom { MavenPom pom -> - pom.withXml { xml -> - def dependenciesNode = xml.asNode().get('dependencies') ?: xml.asNode().appendNode('dependencies') - allDeps.get().each { - def dependencyNode = dependenciesNode.appendNode('dependency') - dependencyNode.appendNode('groupId', it.group) - dependencyNode.appendNode('artifactId', it.name) - dependencyNode.appendNode('version', it.version) - dependencyNode.appendNode('scope', 'runtime') - } - } - } - } - - private class Archive { - Provider file - Property classifier - - Archive(Provider file, Property classifier) { - this.file = file - this.classifier = classifier - } - } - - private class Dep { - String group - String name - String version - - Dep(String group, String name, String version) { - this.group = group - this.name = name - this.version = version - } + publication.from(components.findByName("shadow")) } } diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy index d3926974e..f1f2800e4 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy @@ -8,8 +8,9 @@ import org.gradle.api.attributes.Category import org.gradle.api.attributes.LibraryElements import org.gradle.api.attributes.Usage import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.component.AdhocComponentWithVariants +import org.gradle.api.component.SoftwareComponentFactory import org.gradle.api.tasks.SourceSetContainer -import org.gradle.configuration.project.ProjectConfigurationActionContainer import org.gradle.plugin.devel.plugins.JavaGradlePluginPlugin import javax.inject.Inject @@ -19,11 +20,11 @@ class ShadowJavaPlugin implements Plugin { public static final String SHADOW_JAR_TASK_NAME = 'shadowJar' public static final String SHADOW_GROUP = 'Shadow' - private final ProjectConfigurationActionContainer configurationActionContainer + private final SoftwareComponentFactory softwareComponentFactory @Inject - ShadowJavaPlugin(ProjectConfigurationActionContainer configurationActionContainer) { - this.configurationActionContainer = configurationActionContainer + ShadowJavaPlugin(SoftwareComponentFactory softwareComponentFactory) { + this.softwareComponentFactory = softwareComponentFactory } @Override @@ -54,6 +55,12 @@ class ShadowJavaPlugin implements Plugin { } } + AdhocComponentWithVariants shadow = softwareComponentFactory.adhoc("shadow") + project.components.add(shadow) + shadow.addVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + it.mapToMavenScope("runtime") + } + project.plugins.withType(JavaGradlePluginPlugin).configureEach { // Remove the gradleApi so it isn't merged into the jar file. // This is required because 'java-gradle-plugin' adds gradleApi() to the 'api' configuration. diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/PublishingSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/PublishingSpec.groovy index 450f2a698..bc6221a1b 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/PublishingSpec.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/PublishingSpec.groovy @@ -6,6 +6,7 @@ import groovy.json.JsonSlurper import groovy.xml.XmlSlurper import org.gradle.api.attributes.Bundling import org.gradle.api.attributes.Usage +import spock.lang.Issue class PublishingSpec extends PluginSpecification { @@ -41,8 +42,8 @@ class PublishingSpec extends PluginSpecification { publishing { publications { - shadow(MavenPublication) { publication -> - project.shadow.component(publication) + shadow(MavenPublication) { + from components.shadow artifactId = 'maven-all' } } @@ -78,6 +79,10 @@ class PublishingSpec extends PluginSpecification { assert dependency.version.text() == '1.0' } + @Issue([ + "https://github.com/GradleUp/shadow/issues/860", + "https://github.com/GradleUp/shadow/issues/945", + ]) def "publish shadow jar with maven-publish plugin using custom classifier and extension"() { given: repo.module('shadow', 'a', '1.0') @@ -97,12 +102,6 @@ class PublishingSpec extends PluginSpecification { shadow 'shadow:b:1.0' } - tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { - archiveClassifier = 'my-classifier' - archiveExtension = 'my-ext' - archiveBaseName = 'maven-all' - } - publishing { publications { shadow(MavenPublication) { publication -> @@ -116,6 +115,12 @@ class PublishingSpec extends PluginSpecification { } } } + + tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { + archiveClassifier = 'my-classifier' + archiveExtension = 'my-ext' + archiveBaseName = 'maven-all' + } """.stripIndent() when: @@ -191,8 +196,8 @@ class PublishingSpec extends PluginSpecification { publishing { publications { - shadow(MavenPublication) { publication -> - project.shadow.component(publication) + shadow(MavenPublication) { + from components.shadow artifactId = 'maven-all' } } @@ -250,6 +255,10 @@ class PublishingSpec extends PluginSpecification { java(MavenPublication) { from components.java } + shadow(MavenPublication) { + from components.shadow + artifactId = "maven-all" + } } repositories { maven { @@ -316,5 +325,42 @@ class PublishingSpec extends PluginSpecification { shadowRuntimeVariant.dependencies.size() == 1 shadowRuntimeVariant.dependencies.module as Set == ['b'] as Set + and: "verify shadow publication" + assertions { + shadowJar = publishingRepo.rootDir.file('com/acme/maven-all/1.0/maven-all-1.0-all.jar').canonicalFile + assert shadowJar.exists() + contains(shadowJar, ['a.properties', 'a2.properties']) + } + + assertions { + pom = publishingRepo.rootDir.file('com/acme/maven-all/1.0/maven-all-1.0.pom').canonicalFile + assert pom.exists() + pomContents = new XmlSlurper().parse(pom) + assert pomContents.dependencies[0].dependency.size() == 1 + + dependency1 = pomContents.dependencies[0].dependency[0] + assert dependency1.groupId.text() == 'shadow' + assert dependency1.artifactId.text() == 'b' + assert dependency1.version.text() == '1.0' + + dependency2 = pomContents.dependencies[0].dependency[1] + dependency2.groupId.text() == 'shadow' + dependency2.artifactId.text() == 'b' + dependency2.version.text() == '1.0' + } + + assertions { + gmm = publishingRepo.rootDir.file('com/acme/maven-all/1.0/maven-all-1.0.module').canonicalFile + assert gmm.exists() + gmmContents = new JsonSlurper().parse(gmm) + assert gmmContents.variants.size() == 1 + assert gmmContents.variants.name as Set == ['shadowRuntimeElements'] as Set + + runtimeVariant = gmmContents.variants.find { it.name == 'shadowRuntimeElements' } + assert runtimeVariant.attributes[Usage.USAGE_ATTRIBUTE.name] == Usage.JAVA_RUNTIME + assert runtimeVariant.attributes[Bundling.BUNDLING_ATTRIBUTE.name] == Bundling.SHADOWED + assert runtimeVariant.dependencies.size() == 1 + assert runtimeVariant.dependencies.module as Set == ['b'] as Set + } } } diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy index eb7ffa2fa..9e5fc66f4 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy @@ -150,6 +150,15 @@ abstract class PluginSpecification extends Specification { jar.close() } + /** + * Helper method to allow scoping variables into a closure in a spock test + * Prevents variable expansion + * When using this you *must* include explicit `assert` statements as Spock will not do it for you + */ + void assertions(Closure closure) { + closure() + } + AppendableJar buildJar(String path) { return new AppendableJar(file(path)) }