From 3b9787050e7beda9f16b8200753e9d32f3ad1a42 Mon Sep 17 00:00:00 2001 From: Thomas Hack <39602241+tha00@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:32:10 +0200 Subject: [PATCH] Explicitly add classifier to maven publication (#904) It seems that after [960617f](https://github.com/johnrengelman/shadow/commit/960617fc1689e60763e650492e3bf1df88d5a0fc), archive classifiers are dropped from the archive file name due to the addition of the artifact via `publication.artifact(File)`. According to the [Gradle docs](https://docs.gradle.org/current/javadoc/org/gradle/api/publish/maven/MavenPublication.html#artifact-java.lang.Object-) > Extension and classifier values are interpolated from the file name. but for some reason it is not happening in `ShadowExtension`. This PR provides a workaround by explicitly adding the classifier using the option to pass a `Map` to `MavenPublication#artifact`: > A Map that contains a 'source' entry that can be resolved as any of the other input types, including file. This map can contain a 'classifier' and an 'extension' entry to further configure the constructed artifact. --------- Co-authored-by: Zongle Wang --- src/docs/changes/README.md | 15 +++++- .../plugins/shadow/ShadowExtension.groovy | 23 +++++++-- .../plugins/shadow/PublishingSpec.groovy | 48 +++++++++++++++++++ 3 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src/docs/changes/README.md b/src/docs/changes/README.md index efaf578ac..29410d6a9 100644 --- a/src/docs/changes/README.md +++ b/src/docs/changes/README.md @@ -1,5 +1,18 @@ # Change Log + +## [Unreleased] + +**Added** + +**Changed** + +**Fixed** + +- Explicitly add classifier to maven publication. ([#904](https://github.com/GradleUp/shadow/pull/904)) + + + ## [v8.3.0] **Changed** @@ -364,4 +377,4 @@ Instead, use the `enableRelocation = true` and `relocationPrefix = "> archiveFile + private final Provider archive private final Provider> allDependencies ShadowExtension(Project project) { - archiveFile = project.provider { project.tasks.withType(ShadowJar).getByName("shadowJar").archiveFile } + 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)) { @@ -25,7 +29,10 @@ class ShadowExtension { } void component(MavenPublication publication) { - publication.artifact(archiveFile.get()) + 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 @@ -43,6 +50,16 @@ class ShadowExtension { } } + 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 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 3c18f81a7..7daefa46f 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 @@ -78,6 +78,54 @@ class PublishingSpec extends PluginSpecification { assert dependency.version.text() == '1.0' } + def "publish shadow jar with maven-publish plugin using custom classifier and extension"() { + given: + repo.module('shadow', 'a', '1.0') + .insertFile('a.properties', 'a') + .insertFile('a2.properties', 'a2') + .publish() + repo.module('shadow', 'b', '1.0') + .insertFile('b.properties', 'b') + .publish() + + settingsFile << "rootProject.name = 'maven'" + buildFile << """ + apply plugin: 'maven-publish' + + dependencies { + implementation 'shadow:a:1.0' + shadow 'shadow:b:1.0' + } + + shadowJar { + archiveClassifier = 'my-classifier' + archiveExtension = 'my-ext' + archiveBaseName = 'maven-all' + } + + publishing { + publications { + shadow(MavenPublication) { publication -> + project.shadow.component(publication) + artifactId = 'maven-all' + } + } + repositories { + maven { + url "${publishingRepo.uri}" + } + } + } + """.stripIndent() + + when: + run('publish') + + then: + File publishedFile = publishingRepo.rootDir.file('shadow/maven-all/1.0/maven-all-1.0-my-classifier.my-ext').canonicalFile + assert publishedFile.exists() + } + def "publish multiproject shadow jar with maven-publish plugin"() { given: