Repository: GradleUp/shadow (kotlin)

Issue:
Publishing a shaded JAR
### Describe your use-case which is not covered by existing documentation.

I need to shade a specific library that does not maintain binary compatibility, I thus want to publish a JAR that has shadowed and relocated a specific library, while all other libraries are exposes in the POM like normal.

This worked fine until 8.3.1 when #904 was merged. 

The issue is that the shadowJar task uses the `all` classifier by default which isn't supported by non Gradle clients. You can manually set the classifier to `null` or `''` but then it conflicts with the `jar` task.

It would be great to call this specific use case out in the docs as it's quite common.

### Reference any relevant documentation, other materials or issues/pull requests that can be used for inspiration.

My current solution can be found in my [auto-dagger](https://github.com/ansman/auto-dagger/blob/main/build-logic/src/main/kotlin/library.publishing.gradle.kts) project. 

Here is the relevant snippet:
```kotlin
pluginManager.withPlugin("com.gradleup.shadow") {
    val compileShaded: Configuration by configurations.creating
    configurations.named("compileOnly") { extendsFrom(compileShaded) }
    configurations.named("testRuntimeOnly") { extendsFrom(compileShaded) }
    // Since we use a custom configuration we make the shadow configuration extend the implementation
    // configuration to correctly include dependencies in the POM
    configurations.named("shadow") { extendsFrom(configurations["implementation"]) }

    // Since we change the classifier of the shadowJar we need to disable the default jar task or we'll get two
    // artifacts that have the same classifier
    tasks.named<Jar>("jar") {
        archiveClassifier.set("ignored")
    }

    tasks.named<ShadowJar>("shadowJar") {
        archiveClassifier.set("")
        configurations = listOf(compileShaded)
        isEnableRelocation = true
        relocationPrefix = "se.ansman.dagger.auto${project.path.replace(':', '.').replace('-', '_')}"
        mergeServiceFiles()
    }

    pluginManager.withPlugin("org.gradle.java-test-fixtures") {
        configurations.named("testFixturesImplementation") { extendsFrom(compileShaded) }
        configurations.named("testFixturesImplementation") { extendsFrom(configurations["implementation"]) }
        configurations.named("testFixturesApi") { extendsFrom(configurations["api"]) }
    }
}
```

The main downside of this is that other projects that depend on this would have to depend on the `shadow` configuration which in my case isn't an issue since none of these dependant modules are published but I can imagine it would be an issue if they were.

### Are you interested in contributing to the documentation?

_No response_

Pull request:
Closes #986.

Patch:
diff --git a/src/docs/publishing/README.md b/src/docs/publishing/README.md
index d87ccf8fc..e912b5137 100644
--- a/src/docs/publishing/README.md
+++ b/src/docs/publishing/README.md
@@ -44,3 +44,45 @@ configuration of the POM file.
 This automatic configuration occurs _only_ when using the above methods for
 configuring publishing. If this behavior is not desirable, then publishing **must**
 be manually configured.
+
+
+## Publish the Shadowed JAR instead of the Original JAR
+
+You may want to publish the shadowed JAR instead of the original JAR. This can be done by trimming 
+the `archiveClassifier` of the shadowed JAR like the following:
+
+```groovy
+apply plugin: 'java'
+apply plugin: 'maven-publish'
+apply plugin: 'com.gradleup.shadow'
+
+group = 'shadow'
+version = '1.0'
+
+dependencies {
+  // This will be bundled in the shadowed JAR and not declared in the POM.
+  implementation 'some:a:1.0'
+  // This will be excluded from the shadowed JAR but declared as a runtime dependency in `META-INF/MANIFEST.MF`
+  // file's `Class-Path` entry, and also in the POM file.
+  shadow 'some:b:1.0'
+  // This will be excluded from the shadowed JAR and not declared in the POM or `META-INF/MANIFEST.MF`.
+  compileOnly 'some:c:1.0'
+}
+
+tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
+  archiveClassifier = ''
+}
+
+publishing {
+  publications {
+    shadow(MavenPublication) {
+      from components.shadow
+    }
+  }
+  repositories {
+    maven {
+      url = "https://repo.myorg.com"
+    }
+  }
+}
+```


Test patch:
diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt
index 4d42a48de..18cd42fe6 100644
--- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt
+++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt
@@ -11,6 +11,7 @@ import com.github.jengelman.gradle.plugins.shadow.util.Issue
 import com.github.jengelman.gradle.plugins.shadow.util.JarPath
 import com.github.jengelman.gradle.plugins.shadow.util.containsEntries
 import com.github.jengelman.gradle.plugins.shadow.util.doesNotContainEntries
+import com.github.jengelman.gradle.plugins.shadow.util.getMainAttr
 import com.squareup.moshi.JsonAdapter
 import com.squareup.moshi.Moshi
 import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
@@ -62,6 +63,37 @@ class PublishingTest : BasePluginTest() {
     assertPomCommon(repoPath("shadow/maven-all/1.0/maven-all-1.0.pom"))
   }
 
+  @Test
+  fun publishShadowJarInsteadOfJarWithMavenPublishPlugin() {
+    projectScriptPath.appendText(
+      publishConfiguration(
+        shadowBlock = """
+          archiveClassifier = ''
+        """.trimIndent(),
+        publicationsBlock = """
+          shadow(MavenPublication) {
+            from components.shadow
+          }
+        """.trimIndent(),
+      ),
+    )
+
+    publish()
+
+    assertThat(repoJarPath("shadow/maven/1.0/maven-1.0.jar")).useAll {
+      containsEntries(
+        "a.properties",
+        "a2.properties",
+      )
+      doesNotContainEntries(
+        "b.properties",
+      )
+      getMainAttr("Class-Path").isEqualTo("b-1.0.jar")
+    }
+    assertPomCommon(repoPath("shadow/maven/1.0/maven-1.0.pom"))
+    assertShadowVariantCommon(gmmAdapter.fromJson(repoPath("shadow/maven/1.0/maven-1.0.module")))
+  }
+
   @Issue(
     "https://github.com/GradleUp/shadow/issues/860",
     "https://github.com/GradleUp/shadow/issues/945",