Skip to content
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ When adding new features or public APIs:
- Raw multiline strings in tests should be constructed using `.trimMargin()`.
- Prefer `=` property assignment over `.set(...)` in Gradle build scripts (both in documentation snippets and functional
tests) unless `.set(...)` is explicitly required.
- When adding or updating code snippets in documentation (`docs/`), ensure there are corresponding functional or unit
tests covering and verifying the actual behavioral logic. Annotate the snippet group with
`<!-- test: TestClass#testMethod -->` directly above the tab group so that `generateDocTests` can link and validate
the reference.

### Before Submitting a Pull Request

Expand Down
38 changes: 23 additions & 15 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -154,21 +154,6 @@ testing.suites {
named<JvmTestSuite>("test") {
dependencies { implementation(libs.xmlunit) }
}
register<JvmTestSuite>("documentTest") {
targets.configureEach {
testTask {
testLogging.showExceptions = false
addTestListener(
object : TestListener {
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {
// Prettify test failure output in console.
result.exception?.message?.lineSequence()?.firstOrNull()?.let(logger::error)
}
}
)
}
}
}
register<JvmTestSuite>("functionalTest") {
targets.configureEach {
testTask {
Expand All @@ -188,6 +173,25 @@ testing.suites {
implementation(libs.moshi.kotlin)
}
}
register<JvmTestSuite>("documentTest") {
dependencies {
implementation(sourceSets["test"].output)
implementation(sourceSets["functionalTest"].output)
}
targets.configureEach {
testTask {
testLogging.showExceptions = false
addTestListener(
object : TestListener {
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {
// Prettify test failure output in console.
result.exception?.message?.lineSequence()?.firstOrNull()?.let(logger::error)
}
}
)
}
}
}

withType<JvmTestSuite>().configureEach {
useJUnitJupiter(libs.junit.bom.map { checkNotNull(it.version) })
Expand Down Expand Up @@ -239,6 +243,10 @@ val generateDocTests =
description = "Generates Kotlin test source files for code snippets in documentation."
inputDirectory = layout.projectDirectory.dir("docs")
outputDirectory = layout.buildDirectory.dir("generated/sources/documentTest/kotlin")
testSourceDirectories.from(
sourceSets["test"].allSource.sourceDirectories,
sourceSets["functionalTest"].allSource.sourceDirectories,
)
}

kotlin.sourceSets.named("documentTest") {
Expand Down
3 changes: 3 additions & 0 deletions docs/application-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Just like the normal [`Jar`][Jar] task, when the [`application`][application] pl
[`ShadowJar`][ShadowJar] manifest will be configured to contain the `Main-Class` attribute with the value specified in
the project's `application.mainClass` attribute.

<!-- test: ApplicationPluginTest#installShadowOutputs -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -39,6 +40,7 @@ When applied along with the `application` plugin, the `runShadow` task will be c
the shadowed JAR. The `runShadow` task is a [`JavaExec`][JavaExec] task that is configured to execute
`java -jar myproject-all.jar`. It can be configured the same as any other [`JavaExec`][JavaExec] task.

<!-- test: ApplicationPluginTest#integrationWithApplicationPluginAndJavaToolchains -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -88,6 +90,7 @@ files for a distribution to `build/install/<project name>-shadow/`.

You can also add more files into the distribution like:

<!-- test: ApplicationPluginTest#installShadowOutputs -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down
6 changes: 6 additions & 0 deletions docs/configuration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ If working with a Gradle project with the name `myApp` and version `1.0`, the de
output a file at: `build/libs/myApp-1.0-all.jar`. You can override the properties listed above to change the output name
of the shadowed JAR file. e.g.

<!-- test: BasePluginTest -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -112,6 +113,7 @@ Additionally, Shadow automatically configures the manifest of the [`ShadowJar`][
`Class-Path` entry in the JAR manifest. The value of the `Class-Path` entry is the name of all dependencies resolved in
the `shadow` configuration for the project.

<!-- test: JavaPluginsTest#addShadowConfigurationToClassPathInManifest -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -143,6 +145,7 @@ Class-Path: junit-3.8.2.jar
The [`ShadowJar`][ShadowJar] manifest is configured in a number of ways. First, the manifest for the `shadowJar` task is
configured to __inherit__ from the manifest of the standard `jar` task.

<!-- test: JavaPluginsTest -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -172,6 +175,7 @@ Main-Class: my.Main
If it is desired to merge a manifest from another [`Jar`][Jar] task, the `manifest.from` methods can be used to
configure the upstream.

<!-- test: ShadowPropertiesTest#inheritManifestAttrsFromJars -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -211,6 +215,7 @@ into the shadow JAR. If any dependency JAR has the `Multi-Release` manifest attr

You can disable this behavior by setting `addMultiReleaseAttribute` to `false`:

<!-- test: JavaPluginsTest#containsMultiReleaseAttrIfAnyDependencyContainsIt -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand All @@ -235,6 +240,7 @@ dependencies.
The [`ShadowJar`][ShadowJar] task is a subclass of the [`Jar`][Jar] task, which means that the [`Jar.from`][Jar.from]
method can be used to add extra files.

<!-- test: JavaPluginsTest#addExtraFilesViaFrom -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down
13 changes: 13 additions & 0 deletions docs/configuration/dependencies/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Shadow configures the default [`ShadowJar`][ShadowJar] task to merge all depende
merging can be configured using the [`configurations`][ShadowJar.configurations] property of the
[`ShadowJar`][ShadowJar] task type.

<!-- test: JavaPluginsTest#registerCustomShadowJarThatContainsDependenciesOnly -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -41,6 +42,7 @@ be included in the final JAR.
The [`ShadowJar`][ShadowJar] task is a subclass of the [`Jar`][Jar] task, which means that the [`Jar.from`][Jar.from]
method can be used to add extra files.

<!-- test: JavaPluginsTest#addDependenciesViaCustomConfigurationWithoutUnzipping -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -75,6 +77,7 @@ method can be used to add extra files.

Someone may need the unzipped `bar.jar` to be bundled, try out [`zipTree`][Project.zipTree]

<!-- test: JavaPluginsTest#addExtraFilesViaFrom -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -123,6 +126,7 @@ Caused by: java.util.zip.ZipException: Archive is not a ZIP archive
To embed such dependencies into your shadowed JAR, you can use the [`Jar.from`][Jar.from] method with a custom
configuration.

<!-- test: JavaPluginsTest#addExtraFilesViaFrom -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -174,6 +178,7 @@ configuration.
If the non-JAR file is a transitive dependency (e.g., a POM-only metapackage) that you don't actually need in your
shadowed JAR, you can exclude it using the `dependencies` block instead of embedding it.

<!-- test: FilteringTest#excludeNonJarTransitiveDependency -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -214,6 +219,7 @@ dependency does not exclude any of its dependencies from the final JAR.
The `dependency` blocks provides a number of methods for resolving dependencies using the notations familiar from
Gradle's [`project.configurations`][Project.configurations] block.

<!-- test: FilteringTest#excludeDependency -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -242,6 +248,7 @@ Gradle's [`project.configurations`][Project.configurations] block.
}
```

<!-- test: FilteringTest#filterProjectDependencies -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -280,6 +287,7 @@ Gradle's [`project.configurations`][Project.configurations] block.
Dependencies can be filtered using regex patterns. Coupled with the `<group>:<artifact>:<version>` notation for
dependencies, this allows for excluding/including using any of these individual fields.

<!-- test: FilteringTest#excludeDependency -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -310,6 +318,7 @@ dependencies, this allows for excluding/including using any of these individual

Any of the individual fields can be safely absent and will function as though a wildcard was specified.

<!-- test: FilteringTest#excludeDependency -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -349,6 +358,7 @@ This same pattern can be used for any of the dependency notation fields. e.g.
- `.*:log4j-core:.*`
- ...

<!-- test: FilteringTest#excludeDependency -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -377,6 +387,7 @@ This same pattern can be used for any of the dependency notation fields. e.g.
}
```

<!-- test: FilteringTest#excludeDependency -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -409,6 +420,7 @@ This same pattern can be used for any of the dependency notation fields. e.g.

You can also use type-safe project accessors or version catalog accessors to filter dependencies.

<!-- test: FilteringTest#excludeDependency -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down Expand Up @@ -451,6 +463,7 @@ If more complex decisions are needed to select the dependencies to be included,
[`ShadowJar.dependencies`][ShadowJar.dependencies]
block provides a method that accepts a `Closure` for selecting dependencies.

<!-- test: FilteringTest#excludeTransitiveProjectDependency -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down
2 changes: 2 additions & 0 deletions docs/configuration/filtering/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ When using `exclude`/`include` with a [`ShadowJar`][ShadowJar] task, the resulti
JAR contents. This means that, the configuration is applied to the individual files from both the project source set or
_any_ of the dependencies to be merged.

<!-- test: FilteringTest#excludeFiles -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand All @@ -26,6 +27,7 @@ _any_ of the dependencies to be merged.
Excludes and includes can be combined just like a normal [`Jar`][Jar] task, with `excludes` taking precedence over
`includes`. Additionally, ANT style patterns can be used to match multiple files.

<!-- test: FilteringTest#verifyExcludePrecedenceOverInclude -->
=== ":material-language-kotlin: build.gradle.kts"

```kotlin
Expand Down
Loading