diff --git a/build.gradle.kts b/build.gradle.kts index 4b1a05d86..03f2e1838 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,11 +2,10 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.KotlinVersion plugins { - alias(libs.plugins.kotlin) + alias(libs.plugins.kotlin.jvm) alias(libs.plugins.android.lint) alias(libs.plugins.jetbrains.bcv) alias(libs.plugins.spotless) - groovy // Required for Spock tests. id("shadow.convention.publish") id("shadow.convention.deploy") } @@ -30,6 +29,8 @@ kotlin { lint { baseline = file("lint-baseline.xml") + ignoreTestSources = true + warningsAsErrors = true } spotless { @@ -54,15 +55,12 @@ val intiTestRuntimeOnly: Configuration by configurations.getting { val funcTest: SourceSet by sourceSets.creating val funcTestImplementation: Configuration by configurations.getting { extendsFrom(configurations.testImplementation.get()) - // TODO: this will be removed after we migrated all functional tests to Kotlin. - extendsFrom(intiTestImplementation) } val funcTestRuntimeOnly: Configuration by configurations.getting { extendsFrom(configurations.testRuntimeOnly.get()) } gradlePlugin { - testSourceSets.add(intiTest) testSourceSets.add(funcTest) } @@ -80,26 +78,14 @@ dependencies { testImplementation(libs.junit.jupiter) testImplementation(libs.assertk) testImplementation(libs.xmlunit) - testImplementation(libs.apache.commonsLang) testRuntimeOnly(libs.junit.platformLauncher) - funcTestImplementation(libs.spock) { - exclude(group = "org.codehaus.groovy") - exclude(group = "org.hamcrest") - } funcTestImplementation(sourceSets.main.get().output) - funcTestImplementation(intiTest.output) - - intiTestImplementation(libs.okio) - intiTestImplementation(libs.apache.maven.modelBuilder) - intiTestImplementation(libs.apache.maven.repositoryMetadata) - // TODO: this will be removed after we migrated all functional tests to Kotlin. - intiTestImplementation(sourceSets.main.get().output) - intiTestImplementation(libs.moshi) - intiTestImplementation(libs.moshi.kotlin) + funcTestImplementation(libs.apache.maven.modelBuilder) + funcTestImplementation(libs.moshi) + funcTestImplementation(libs.moshi.kotlin) lintChecks(libs.androidx.gradlePluginLints) - lintChecks(libs.assertk.lint) } val integrationTest by tasks.registering(Test::class) { @@ -108,10 +94,6 @@ val integrationTest by tasks.registering(Test::class) { testClassesDirs = intiTest.output.classesDirs classpath = intiTest.runtimeClasspath - // TODO: this should be moved into functionalTest after we migrated all functional tests to Kotlin. - // Required to enable `IssueExtension` for all tests. - systemProperty("junit.jupiter.extensions.autodetection.enabled", true) - val docsDir = file("src/docs") // Add src/docs as an input directory to trigger ManualCodeSnippetTests re-run on changes. inputs.dir(docsDir) @@ -123,6 +105,9 @@ val functionalTest by tasks.registering(Test::class) { group = LifecycleBasePlugin.VERIFICATION_GROUP testClassesDirs = funcTest.output.classesDirs classpath = funcTest.runtimeClasspath + + // Required to enable `IssueExtension` for all tests. + systemProperty("junit.jupiter.extensions.autodetection.enabled", true) } tasks.check { @@ -147,14 +132,6 @@ tasks.withType().configureEach { ) } -tasks.whenTaskAdded { - if (name == "lintAnalyzeJvmTest") { - // This task often fails on Windows CI devices. - enabled = !providers.systemProperty("os.name").get().startsWith("Windows") && - !providers.environmentVariable("CI").isPresent - } -} - tasks.clean { val includedBuilds = gradle.includedBuilds dependsOn(includedBuilds.map { it.task(path) }) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e48c47590..478001332 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,21 +1,17 @@ [versions] -maven = "3.9.9" moshi = "1.15.2" [libraries] apache-ant = "org.apache.ant:ant:1.10.15" apache-commonsIo = "commons-io:commons-io:2.18.0" -apache-commonsLang = "org.apache.commons:commons-lang3:3.17.0" apache-log4j = "org.apache.logging.log4j:log4j-core:2.24.3" -apache-maven-modelBuilder = { module = "org.apache.maven:maven-model-builder", version.ref = "maven" } -apache-maven-repositoryMetadata = { module = "org.apache.maven:maven-repository-metadata", version.ref = "maven" } +apache-maven-modelBuilder = "org.apache.maven:maven-model-builder:3.9.9" asm = "org.ow2.asm:asm-commons:9.7.1" jdependency = "org.vafer:jdependency:2.11" jdom2 = "org.jdom:jdom2:2.0.6.1" plexus-utils = "org.codehaus.plexus:plexus-utils:4.0.2" plexus-xml = "org.codehaus.plexus:plexus-xml:4.0.4" xmlunit = "org.xmlunit:xmlunit-legacy:2.10.0" -okio = "com.squareup.okio:okio:3.10.2" moshi = { module = "com.squareup.moshi:moshi", version.ref = "moshi" } moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" } @@ -26,18 +22,16 @@ jetbrains-dokka = "org.jetbrains.dokka:dokka-gradle-plugin:2.0.0" node = "com.github.node-gradle:gradle-node-plugin:7.1.0" androidx-gradlePluginLints = "androidx.lint:lint-gradle:1.0.0-alpha03" -assertk-lint = "com.jzbrooks:assertk-lint:1.4.0" # Dummy to get renovate updates, the version is used in rootProject build.gradle with spotless. ktlint = "com.pinterest.ktlint:ktlint-cli:1.5.0" -spock = "org.spockframework:spock-core:2.3-groovy-3.0" junit-bom = "org.junit:junit-bom:5.11.4" junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" } junit-platformLauncher = { module = "org.junit.platform:junit-platform-launcher" } assertk = "com.willowtreeapps.assertk:assertk:0.28.1" [plugins] -kotlin = "org.jetbrains.kotlin.jvm:2.1.0" +kotlin-jvm = "org.jetbrains.kotlin.jvm:2.1.0" android-lint = "com.android.lint:8.8.0" jetbrains-bcv = "org.jetbrains.kotlinx.binary-compatibility-validator:0.17.0" spotless = "com.diffplug.spotless:7.0.1" diff --git a/lint-baseline.xml b/lint-baseline.xml index 6f209b0af..494ab0b7c 100644 --- a/lint-baseline.xml +++ b/lint-baseline.xml @@ -107,7 +107,7 @@ errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -118,7 +118,7 @@ errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -129,7 +129,7 @@ errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -140,7 +140,7 @@ errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> diff --git a/src/funcTest/.editorconfig b/src/funcTest/.editorconfig deleted file mode 100755 index 3c75e2d26..000000000 --- a/src/funcTest/.editorconfig +++ /dev/null @@ -1,2 +0,0 @@ -[*.{groovy,java}] -indent_size = 4 diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ApplicationTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ApplicationTest.kt similarity index 71% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ApplicationTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ApplicationTest.kt index 2d05cec1a..8f3ea3e97 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ApplicationTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ApplicationTest.kt @@ -1,12 +1,14 @@ package com.github.jengelman.gradle.plugins.shadow +import assertk.all import assertk.assertThat import assertk.assertions.contains import assertk.assertions.containsAtLeast import assertk.assertions.exists import assertk.assertions.isEqualTo -import assertk.assertions.isNotEmpty import com.github.jengelman.gradle.plugins.shadow.util.containsEntries +import com.github.jengelman.gradle.plugins.shadow.util.getMainAttr +import com.github.jengelman.gradle.plugins.shadow.util.isRegular import kotlin.io.path.appendText import kotlin.io.path.readText import kotlin.io.path.writeText @@ -36,23 +38,33 @@ class ApplicationTest : BasePluginTest() { val result = run(runShadowTask) - assertThat(result.output).contains("Running application with JDK 17") - assertThat(result.output).contains("TestApp: Hello World! (foo)") - - val installedJar = jarPath("build/install/myapp-shadow/lib/myapp-1.0-all.jar") - assertThat(installedJar).containsEntries( - "a.properties", - "a2.properties", - "myapp/Main.class", + assertThat(result.output).contains( + "Running application with JDK 17", + "TestApp: Hello World! (foo)", ) - assertThat(installedJar.manifest.mainAttributes.getValue("Main-Class")) - .isEqualTo("myapp.Main") - path("build/install/myapp-shadow/bin/myapp").let { startScript -> - assertThat(startScript).exists() - assertThat(startScript.readText()).contains("CLASSPATH=\$APP_HOME/lib/myapp-1.0-all.jar") - assertThat(startScript.readText()).contains("-jar \"\\\"\$CLASSPATH\\\"\" \"\$APP_ARGS\"") - assertThat(startScript.readText()).contains("exec \"\$JAVACMD\" \"\$@\"") + assertThat(jarPath("build/install/myapp-shadow/lib/myapp-1.0-all.jar")).useAll { + containsEntries( + "a.properties", + "a2.properties", + "myapp/Main.class", + ) + getMainAttr("Main-Class").isEqualTo("myapp.Main") + } + + assertThat(path("build/install/myapp-shadow/bin/myapp")).all { + exists() + transform { it.readText() }.contains( + "CLASSPATH=\$APP_HOME/lib/myapp-1.0-all.jar", + "-jar \"\\\"\$CLASSPATH\\\"\" \"\$APP_ARGS\"", + "exec \"\$JAVACMD\" \"\$@\"", + ) + } + assertThat(path("build/install/myapp-shadow/bin/myapp.bat")).all { + exists() + transform { it.readText() }.contains( + "set CLASSPATH=%APP_HOME%\\lib\\myapp-1.0-all.jar", + ) } } @@ -71,7 +83,7 @@ class ApplicationTest : BasePluginTest() { val zip = path("build/distributions/myapp-shadow-1.0.zip") assertThat(zip).exists() - val entries = ZipFile(zip.toFile()).entries.toList().map { it.name } + val entries = ZipFile(zip.toFile()).use { it.entries }.toList().map { it.name } assertThat(entries).containsAtLeast( "myapp-shadow-1.0/lib/myapp-1.0-all.jar", "myapp-shadow-1.0/lib/a-1.0.jar", @@ -84,7 +96,7 @@ class ApplicationTest : BasePluginTest() { run(ShadowApplicationPlugin.SHADOW_INSTALL_TASK_NAME) - assertThat(jarPath("build/install/myapp-shadow/lib/myapp-1.0-all.jar").entries().toList()).isNotEmpty() + assertThat(jarPath("build/install/myapp-shadow/lib/myapp-1.0-all.jar")).isRegular() } private fun prepare( diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt similarity index 78% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt index 01779d04d..2564ddfa3 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt @@ -1,5 +1,11 @@ package com.github.jengelman.gradle.plugins.shadow +import assertk.Assert +import assertk.all +import assertk.assertThat +import assertk.assertions.doesNotContain +import assertk.assertions.isEqualTo +import assertk.assertions.isNotNull import com.github.jengelman.gradle.plugins.shadow.ShadowApplicationPlugin.Companion.SHADOW_RUN_TASK_NAME import com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin.Companion.SHADOW_JAR_TASK_NAME import com.github.jengelman.gradle.plugins.shadow.tasks.JavaJarExec @@ -7,6 +13,8 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer import com.github.jengelman.gradle.plugins.shadow.util.AppendableMavenRepository import com.github.jengelman.gradle.plugins.shadow.util.JarPath +import java.io.Closeable +import java.nio.file.NoSuchFileException import java.nio.file.Path import java.util.Properties import kotlin.io.path.ExperimentalPathApi @@ -18,20 +26,22 @@ import kotlin.io.path.createFile import kotlin.io.path.createTempDirectory import kotlin.io.path.deleteRecursively import kotlin.io.path.exists -import kotlin.io.path.isRegularFile import kotlin.io.path.readText import kotlin.io.path.toPath import kotlin.io.path.writeText import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.GradleRunner +import org.gradle.testkit.runner.TaskOutcome import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.io.TempDir @TestInstance(TestInstance.Lifecycle.PER_CLASS) abstract class BasePluginTest { - lateinit var root: Path + @TempDir + lateinit var projectRoot: Path lateinit var localRepo: AppendableMavenRepository @BeforeAll @@ -56,20 +66,12 @@ abstract class BasePluginTest { @BeforeEach open fun setup() { - root = createTempDirectory() - projectScriptPath.writeText(getDefaultProjectBuildScript(withGroup = true, withVersion = true)) settingsScriptPath.writeText(getDefaultSettingsBuildScript()) } - @ExperimentalPathApi @AfterEach fun cleanup() { - runCatching { - // TODO: workaround for https://github.com/junit-team/junit5/issues/2811. - root.deleteRecursively() - } - println(projectScriptPath.readText()) } @@ -78,6 +80,15 @@ abstract class BasePluginTest { localRepo.root.deleteRecursively() } + open val shadowJarTask = ":$SHADOW_JAR_TASK_NAME" + open val runShadowTask = ":$SHADOW_RUN_TASK_NAME" + val serverShadowJarTask = ":server:$SHADOW_JAR_TASK_NAME" + + val projectScriptPath: Path get() = path("build.gradle") + val settingsScriptPath: Path get() = path("settings.gradle") + open val outputShadowJar: JarPath get() = jarPath("build/libs/shadow-1.0-all.jar") + val outputServerShadowJar: JarPath get() = jarPath("server/build/libs/server-1.0-all.jar") + fun getDefaultProjectBuildScript( javaPlugin: String = "java", withGroup: Boolean = false, @@ -97,6 +108,10 @@ abstract class BasePluginTest { fun getDefaultSettingsBuildScript( startBlock: String = "", + // Use a test-specific build cache directory. This ensures that we'll only use cached outputs generated during + // this test, and we won't accidentally use cached outputs from a different test or a different build. + // https://docs.gradle.org/current/userguide/build_cache.html#sec:build_cache_configure_local + buildCacheBlock: String = "local { directory = file('build-cache') }", endBlock: String = "rootProject.name = 'shadow'", ): String { return """ @@ -107,36 +122,19 @@ abstract class BasePluginTest { mavenCentral() } } + buildCache { + $buildCacheBlock + } $endBlock """.trimIndent() + System.lineSeparator() } - open val shadowJarTask = ":$SHADOW_JAR_TASK_NAME" - open val runShadowTask = ":$SHADOW_RUN_TASK_NAME" - val serverShadowJarTask = ":server:$SHADOW_JAR_TASK_NAME" - - val projectScriptPath: Path - get() = path("build.gradle") - - val settingsScriptPath: Path - get() = path("settings.gradle") - - open val outputShadowJar: JarPath - get() = jarPath("build/libs/shadow-1.0-all.jar") - - val outputServerShadowJar: JarPath - get() = jarPath("server/build/libs/server-1.0-all.jar") - - fun jarPath(path: String): JarPath { - val realPath = root.resolve(path).also { - check(it.exists()) { "Path not found: $it" } - check(it.isRegularFile()) { "Path is not a regular file: $it" } - } - return JarPath(realPath) + fun jarPath(relative: String, parent: Path = projectRoot): JarPath { + return JarPath(parent.resolve(relative)) } - fun path(path: String): Path { - return root.resolve(path).also { + fun path(relative: String, parent: Path = projectRoot): Path { + return parent.resolve(relative).also { if (it.exists()) return@also it.parent.createDirectories() // We should create text file only if it doesn't exist. @@ -296,7 +294,7 @@ abstract class BasePluginTest { fun runner( arguments: Iterable = emptyList(), - projectDir: Path? = root, + projectDir: Path? = projectRoot, ): GradleRunner = GradleRunner.create() .forwardOutput() .withPluginClasspath() @@ -317,11 +315,9 @@ abstract class BasePluginTest { Path(gradleUserHome, "testkit") } - val testJar: Path = requireNotNull(this::class.java.classLoader.getResource("junit-3.8.2.jar")).toURI().toPath() - val artifactJar: Path = - requireNotNull(this::class.java.classLoader.getResource("test-artifact-1.0-SNAPSHOT.jar")).toURI().toPath() - val projectJar: Path = - requireNotNull(this::class.java.classLoader.getResource("test-project-1.0-SNAPSHOT.jar")).toURI().toPath() + val testJar: Path = requireResourceAsPath("junit-3.8.2.jar") + val artifactJar: Path = requireResourceAsPath("test-artifact-1.0-SNAPSHOT.jar") + val projectJar: Path = requireResourceAsPath("test-project-1.0-SNAPSHOT.jar") val shadowJar: String = """ tasks.named('$SHADOW_JAR_TASK_NAME', ${ShadowJar::class.java.name}) @@ -334,6 +330,7 @@ abstract class BasePluginTest { val commonArguments = listOf( "--warning-mode=fail", "--configuration-cache", + "--build-cache", "--stacktrace", ) @@ -358,14 +355,26 @@ abstract class BasePluginTest { } fun BuildResult.assertNoDeprecationWarnings() = apply { - output.lines().forEach { - assert(!containsDeprecationWarning(it)) - } + assertThat(output).doesNotContain( + "has been deprecated and is scheduled to be removed in Gradle", + "has been deprecated. This is scheduled to be removed in Gradle", + ) + } + + fun Assert.useAll(body: Assert.() -> Unit) = all { + body() + // Close the resource after all assertions are done. + given { it.use(block = {}) } + } + + fun Assert.taskOutcomeEquals(taskPath: String, expectedOutcome: TaskOutcome) { + return transform { it.task(taskPath)?.outcome }.isNotNull().isEqualTo(expectedOutcome) } - private fun containsDeprecationWarning(output: String): Boolean { - return output.contains("has been deprecated and is scheduled to be removed in Gradle") || - output.contains("has been deprecated. This is scheduled to be removed in Gradle") + private fun requireResourceAsPath(name: String): Path { + val resource = this::class.java.classLoader.getResource(name) + ?: throw NoSuchFileException("Resource $name not found.") + return resource.toURI().toPath() } } } diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt similarity index 67% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt index a79f2b32c..fd7f0fe64 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt @@ -1,14 +1,12 @@ package com.github.jengelman.gradle.plugins.shadow import assertk.assertThat -import assertk.assertions.isEqualTo -import assertk.assertions.isNotNull import com.github.jengelman.gradle.plugins.shadow.util.containsEntries import com.github.jengelman.gradle.plugins.shadow.util.doesNotContainEntries import kotlin.io.path.appendText import kotlin.io.path.readText import kotlin.io.path.writeText -import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.TaskOutcome.SUCCESS import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -36,11 +34,13 @@ class FilteringTest : BasePluginTest() { @Test fun includeAllDependencies() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "a.properties", - "a2.properties", - "b.properties", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "a.properties", + "a2.properties", + "b.properties", + ) + } } @Test @@ -55,13 +55,15 @@ class FilteringTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "a.properties", - "b.properties", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "a2.properties", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "a.properties", + "b.properties", + ) + doesNotContainEntries( + "a2.properties", + ) + } } @Test @@ -106,17 +108,18 @@ class FilteringTest : BasePluginTest() { projectScriptPath.writeText(replaced) val result = run(shadowJarTask) - assertThat(result.task(shadowJarTask)).isNotNull() - .transform { it.outcome }.isEqualTo(TaskOutcome.SUCCESS) - assertThat(outputShadowJar).containsEntries( - "a.properties", - "a2.properties", - "b.properties", - "d.properties", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "c.properties", - ) + assertThat(result).taskOutcomeEquals(shadowJarTask, SUCCESS) + assertThat(outputShadowJar).useAll { + containsEntries( + "a.properties", + "a2.properties", + "b.properties", + "d.properties", + ) + doesNotContainEntries( + "c.properties", + ) + } } @Test @@ -133,17 +136,18 @@ class FilteringTest : BasePluginTest() { val result = run(shadowJarTask) - assertThat(result.task(shadowJarTask)).isNotNull() - .transform { it.outcome }.isEqualTo(TaskOutcome.SUCCESS) - assertThat(outputShadowJar).containsEntries( - "a2.properties", - "b.properties", - "c.properties", - "d.properties", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "a.properties", - ) + assertThat(result).taskOutcomeEquals(shadowJarTask, SUCCESS) + assertThat(outputShadowJar).useAll { + containsEntries( + "a2.properties", + "b.properties", + "c.properties", + "d.properties", + ) + doesNotContainEntries( + "a.properties", + ) + } } @Test @@ -169,16 +173,18 @@ class FilteringTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "d.properties", - "shadow/Passed.class", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "a.properties", - "a2.properties", - "b.properties", - "c.properties", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "d.properties", + "shadow/Passed.class", + ) + doesNotContainEntries( + "a.properties", + "a2.properties", + "b.properties", + "c.properties", + ) + } } @Test @@ -193,13 +199,15 @@ class FilteringTest : BasePluginTest() { run(serverShadowJarTask) - assertThat(outputServerShadowJar).doesNotContainEntries( - "client/Client.class", - ) - assertThat(outputServerShadowJar).containsEntries( - "server/Server.class", - "junit/framework/Test.class", - ) + assertThat(outputServerShadowJar).useAll { + containsEntries( + "server/Server.class", + "junit/framework/Test.class", + ) + doesNotContainEntries( + "client/Client.class", + ) + } } @Test @@ -214,13 +222,15 @@ class FilteringTest : BasePluginTest() { run(serverShadowJarTask) - assertThat(outputServerShadowJar).doesNotContainEntries( - "junit/framework/Test.class", - ) - assertThat(outputServerShadowJar).containsEntries( - "client/Client.class", - "server/Server.class", - ) + assertThat(outputServerShadowJar).useAll { + containsEntries( + "client/Client.class", + "server/Server.class", + ) + doesNotContainEntries( + "junit/framework/Test.class", + ) + } } @Test @@ -237,13 +247,15 @@ class FilteringTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "a.properties", - "b.properties", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "a2.properties", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "a.properties", + "b.properties", + ) + doesNotContainEntries( + "a2.properties", + ) + } } @Test @@ -272,15 +284,17 @@ class FilteringTest : BasePluginTest() { } private fun commonAssertions() { - assertThat(outputShadowJar).containsEntries( - "a.properties", - "a2.properties", - "b.properties", - "c.properties", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "d.properties", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "a.properties", + "a2.properties", + "b.properties", + "c.properties", + ) + doesNotContainEntries( + "d.properties", + ) + } } private fun publishArtifactCD(circular: Boolean = false) { diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt similarity index 90% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt index b0fa6f58e..167ba3626 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt @@ -1,6 +1,5 @@ package com.github.jengelman.gradle.plugins.shadow -import assertk.all import assertk.assertThat import assertk.assertions.containsOnly import assertk.assertions.isEmpty @@ -33,12 +32,12 @@ class PublishingTest : BasePluginTest() { private val gmmAdapter = moshi.adapter(GradleModuleMetadata::class.java) private val pomReader = MavenXpp3Reader() - private lateinit var remoteRepo: Path + private lateinit var remoteRepoPath: Path @BeforeEach override fun setup() { super.setup() - remoteRepo = root.resolve("remote-maven-repo") + remoteRepoPath = projectRoot.resolve("remote-maven-repo") settingsScriptPath.appendText("rootProject.name = 'maven'" + System.lineSeparator()) } @@ -122,18 +121,18 @@ class PublishingTest : BasePluginTest() { publish() - val publishedJar = repoJarPath("shadow/maven-all/1.0/maven-all-1.0.jar") - assertThat(publishedJar).containsEntries( - "aa.properties", - "aa2.properties", - ) - assertThat(publishedJar).doesNotContainEntries( - "a.properties", - "a2.properties", - "b.properties", - "bb.properties", - ) - + assertThat(repoJarPath("shadow/maven-all/1.0/maven-all-1.0.jar")).useAll { + containsEntries( + "aa.properties", + "aa2.properties", + ) + doesNotContainEntries( + "a.properties", + "a2.properties", + "b.properties", + "bb.properties", + ) + } assertPomCommon(repoPath("shadow/maven-all/1.0/maven-all-1.0.pom")) } @@ -165,8 +164,12 @@ class PublishingTest : BasePluginTest() { publish() val entries = arrayOf("a.properties", "a2.properties", "b.properties") - assertThat(repoJarPath("com/acme/maven/1.0/maven-1.0.jar")).doesNotContainEntries(*entries) - assertThat(repoJarPath("com/acme/maven/1.0/maven-1.0-all.jar")).containsEntries(*entries) + assertThat(repoJarPath("com/acme/maven/1.0/maven-1.0.jar")).useAll { + doesNotContainEntries(*entries) + } + assertThat(repoJarPath("com/acme/maven/1.0/maven-1.0-all.jar")).useAll { + containsEntries(*entries) + } pomReader.read(repoPath("com/acme/maven/1.0/maven-1.0.pom")).let { pomContents -> assertThat(pomContents.dependencies.size).isEqualTo(2) @@ -211,15 +214,15 @@ class PublishingTest : BasePluginTest() { } } - private fun repoPath(path: String): Path { - return remoteRepo.resolve(path).also { + private fun repoPath(relative: String): Path { + return remoteRepoPath.resolve(relative).also { check(it.exists()) { "Path not found: $it" } check(it.isRegularFile()) { "Path is not a regular file: $it" } } } - private fun repoJarPath(path: String): JarPath { - return JarPath(repoPath(path)) + private fun repoJarPath(relative: String): JarPath { + return JarPath(remoteRepoPath.resolve(relative)) } private fun publish(): BuildResult = run("publish") @@ -253,7 +256,7 @@ class PublishingTest : BasePluginTest() { } repositories { maven { - url = '${remoteRepo.toUri()}' + url = '${remoteRepoPath.toUri()}' } } } @@ -278,7 +281,7 @@ class PublishingTest : BasePluginTest() { } private fun assertShadowJarCommon(jarPath: JarPath) { - assertThat(jarPath).all { + assertThat(jarPath).useAll { containsEntries( "a.properties", "a2.properties", @@ -290,7 +293,7 @@ class PublishingTest : BasePluginTest() { } private companion object { - fun MavenXpp3Reader.read(path: Path): Model = read(path.inputStream()) + fun MavenXpp3Reader.read(path: Path): Model = path.inputStream().use { read(it) } fun JsonAdapter.fromJson(path: Path): T = requireNotNull(fromJson(path.readText())) } diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt similarity index 54% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt index 8571c350d..fa1f6f380 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt @@ -4,17 +4,19 @@ import assertk.assertFailure import assertk.assertThat import assertk.assertions.isEqualTo import assertk.assertions.isInstanceOf +import assertk.fail import com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin.Companion.SHADOW_JAR_TASK_NAME import com.github.jengelman.gradle.plugins.shadow.util.Issue 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 java.net.URLClassLoader import kotlin.io.path.appendText import kotlin.io.path.writeText import org.junit.jupiter.api.Test +import org.opentest4j.AssertionFailedError class RelocationTest : BasePluginTest() { - @Test fun defaultEnableRelocation() { projectScriptPath.appendText( @@ -27,26 +29,29 @@ class RelocationTest : BasePluginTest() { } """.trimIndent(), ) + run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "META-INF/MANIFEST.MF", - "shadow/junit/textui/ResultPrinter.class", - "shadow/junit/textui/TestRunner.class", - "shadow/junit/framework/Assert.class", - "shadow/junit/framework/AssertionFailedError.class", - "shadow/junit/framework/ComparisonCompactor.class", - "shadow/junit/framework/ComparisonFailure.class", - "shadow/junit/framework/Protectable.class", - "shadow/junit/framework/Test.class", - "shadow/junit/framework/TestCase.class", - "shadow/junit/framework/TestFailure.class", - "shadow/junit/framework/TestListener.class", - "shadow/junit/framework/TestResult$1.class", - "shadow/junit/framework/TestResult.class", - "shadow/junit/framework/TestSuite$1.class", - "shadow/junit/framework/TestSuite.class", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "META-INF/MANIFEST.MF", + "shadow/junit/textui/ResultPrinter.class", + "shadow/junit/textui/TestRunner.class", + "shadow/junit/framework/Assert.class", + "shadow/junit/framework/AssertionFailedError.class", + "shadow/junit/framework/ComparisonCompactor.class", + "shadow/junit/framework/ComparisonFailure.class", + "shadow/junit/framework/Protectable.class", + "shadow/junit/framework/Test.class", + "shadow/junit/framework/TestCase.class", + "shadow/junit/framework/TestFailure.class", + "shadow/junit/framework/TestListener.class", + "shadow/junit/framework/TestResult$1.class", + "shadow/junit/framework/TestResult.class", + "shadow/junit/framework/TestSuite$1.class", + "shadow/junit/framework/TestSuite.class", + ) + } } @Issue( @@ -71,44 +76,44 @@ class RelocationTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "META-INF/MANIFEST.MF", - "a/ResultPrinter.class", - "a/TestRunner.class", - "b/Assert.class", - "b/AssertionFailedError.class", - "b/ComparisonCompactor.class", - "b/ComparisonFailure.class", - "b/Protectable.class", - "b/Test.class", - "b/TestCase.class", - "b/TestFailure.class", - "b/TestListener.class", - "b/TestResult\$1.class", - "b/TestResult.class", - "b/TestSuite\$1.class", - "b/TestSuite.class", - ) - - assertThat(outputShadowJar).doesNotContainEntries( - "junit/textui/ResultPrinter.class", - "junit/textui/TestRunner.class", - "junit/framework/Assert.class", - "junit/framework/AssertionFailedError.class", - "junit/framework/ComparisonCompactor.class", - "junit/framework/ComparisonFailure.class", - "junit/framework/Protectable.class", - "junit/framework/Test.class", - "junit/framework/TestCase.class", - "junit/framework/TestFailure.class", - "junit/framework/TestListener.class", - "junit/framework/TestResult\$1.class", - "junit/framework/TestResult.class", - "junit/framework/TestSuite\$1.class", - "junit/framework/TestSuite.class", - ) - assertThat(outputShadowJar.manifest.mainAttributes.getValue("TEST-VALUE")) - .isEqualTo("FOO") + assertThat(outputShadowJar).useAll { + containsEntries( + "META-INF/MANIFEST.MF", + "a/ResultPrinter.class", + "a/TestRunner.class", + "b/Assert.class", + "b/AssertionFailedError.class", + "b/ComparisonCompactor.class", + "b/ComparisonFailure.class", + "b/Protectable.class", + "b/Test.class", + "b/TestCase.class", + "b/TestFailure.class", + "b/TestListener.class", + "b/TestResult\$1.class", + "b/TestResult.class", + "b/TestSuite\$1.class", + "b/TestSuite.class", + ) + doesNotContainEntries( + "junit/textui/ResultPrinter.class", + "junit/textui/TestRunner.class", + "junit/framework/Assert.class", + "junit/framework/AssertionFailedError.class", + "junit/framework/ComparisonCompactor.class", + "junit/framework/ComparisonFailure.class", + "junit/framework/Protectable.class", + "junit/framework/Test.class", + "junit/framework/TestCase.class", + "junit/framework/TestFailure.class", + "junit/framework/TestListener.class", + "junit/framework/TestResult\$1.class", + "junit/framework/TestResult.class", + "junit/framework/TestSuite\$1.class", + "junit/framework/TestSuite.class", + ) + getMainAttr("TEST-VALUE").isEqualTo("FOO") + } } @Test @@ -131,32 +136,33 @@ class RelocationTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "a/ResultPrinter.class", - "b/Test.class", - "b/TestCase.class", - "b/TestFailure.class", - "b/TestListener.class", - "b/TestResult\$1.class", - "b/TestResult.class", - "b/TestSuite\$1.class", - "b/TestSuite.class", - "junit/textui/TestRunner.class", - "junit/framework/Assert.class", - "junit/framework/AssertionFailedError.class", - "junit/framework/ComparisonCompactor.class", - "junit/framework/ComparisonFailure.class", - "junit/framework/Protectable.class", - ) - - assertThat(outputShadowJar).doesNotContainEntries( - "a/TestRunner.class", - "b/Assert.class", - "b/AssertionFailedError.class", - "b/ComparisonCompactor.class", - "b/ComparisonFailure.class", - "b/Protectable.class", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "a/ResultPrinter.class", + "b/Test.class", + "b/TestCase.class", + "b/TestFailure.class", + "b/TestListener.class", + "b/TestResult\$1.class", + "b/TestResult.class", + "b/TestSuite\$1.class", + "b/TestSuite.class", + "junit/textui/TestRunner.class", + "junit/framework/Assert.class", + "junit/framework/AssertionFailedError.class", + "junit/framework/ComparisonCompactor.class", + "junit/framework/ComparisonFailure.class", + "junit/framework/Protectable.class", + ) + doesNotContainEntries( + "a/TestRunner.class", + "b/Assert.class", + "b/AssertionFailedError.class", + "b/ComparisonCompactor.class", + "b/ComparisonFailure.class", + "b/Protectable.class", + ) + } } @Issue( @@ -192,27 +198,27 @@ class RelocationTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "shadow/ShadowTest.class", - "shadow/junit/Test.class", - "shadow/junit", - ) - - assertThat(outputShadowJar).doesNotContainEntries( - "junit/framework", - "junit/framework/Test.class", - ) - - val classLoader = URLClassLoader( - arrayOf(outputShadowJar.toUri().toURL()), - ClassLoader.getSystemClassLoader().parent, - ) - assertFailure { - // check that the class can be loaded. If the file was not relocated properly, we should get a NoDefClassFound - // Isolated class loader with only the JVM system jars and the output jar from the test project - classLoader.loadClass("shadow.ShadowTest") - error("Should not reach here.") - }.isInstanceOf(IllegalStateException::class) + assertThat(outputShadowJar).useAll { + containsEntries( + "shadow/ShadowTest.class", + "shadow/junit/Test.class", + "shadow/junit", + ) + doesNotContainEntries( + "junit/framework", + "junit/framework/Test.class", + ) + } + + val url = outputShadowJar.use { it.toUri().toURL() } + URLClassLoader(arrayOf(url), ClassLoader.getSystemClassLoader().parent).use { classLoader -> + assertFailure { + // check that the class can be loaded. If the file was not relocated properly, we should get a NoDefClassFound + // Isolated class loader with only the JVM system jars and the output jar from the test project + classLoader.loadClass("shadow.ShadowTest") + fail("Should not reach here.") + }.isInstanceOf(AssertionFailedError::class) + } } @Test @@ -272,15 +278,16 @@ class RelocationTest : BasePluginTest() { run(":app:$SHADOW_JAR_TASK_NAME") - val appOutput = jarPath("app/build/libs/app-all.jar") - assertThat(appOutput).containsEntries( - "TEST", - "APP-TEST", - "test.properties", - "app/core/Core.class", - "app/App.class", - "app/junit/framework/Test.class", - ) + assertThat(jarPath("app/build/libs/app-all.jar")).useAll { + containsEntries( + "TEST", + "APP-TEST", + "test.properties", + "app/core/Core.class", + "app/App.class", + "app/junit/framework/Test.class", + ) + } } @Issue( @@ -316,16 +323,18 @@ class RelocationTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "bar/Foo.class", - "bar/foo.properties", - "bar/dep.properties", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "foo/Foo.class", - "foo/foo.properties", - "foo/dep.properties", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "bar/Foo.class", + "bar/foo.properties", + "bar/dep.properties", + ) + doesNotContainEntries( + "foo/Foo.class", + "foo/foo.properties", + "foo/dep.properties", + ) + } } @Issue( diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowPluginTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowPluginTest.kt similarity index 74% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowPluginTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowPluginTest.kt index bb1343508..46570901d 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowPluginTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowPluginTest.kt @@ -18,14 +18,14 @@ import kotlin.io.path.readText import kotlin.io.path.writeText import org.gradle.api.plugins.JavaPlugin import org.gradle.testfixtures.ProjectBuilder -import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.TaskOutcome.SUCCESS +import org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import org.junit.jupiter.api.condition.EnabledForJreRange import org.junit.jupiter.api.condition.JRE class ShadowPluginTest : BasePluginTest() { - @Test fun applyPlugin() { val projectName = "my-shadow" @@ -120,15 +120,13 @@ class ShadowPluginTest : BasePluginTest() { run(shadowJarTask) - val outputShadowJar = jarPath("build/libs/shadow.jar") - - assertThat(outputShadowJar).containsEntries( - "shadow/Passed.class", - "junit/framework/Test.class", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "/", - ) + assertThat(jarPath("build/libs/shadow.jar")).useAll { + containsEntries( + "shadow/Passed.class", + "junit/framework/Test.class", + ) + doesNotContainEntries("/") + } } @Test @@ -137,11 +135,13 @@ class ShadowPluginTest : BasePluginTest() { run(serverShadowJarTask) - assertThat(outputServerShadowJar).containsEntries( - "client/Client.class", - "server/Server.class", - "junit/framework/Test.class", - ) + assertThat(outputServerShadowJar).useAll { + containsEntries( + "client/Client.class", + "server/Server.class", + "junit/framework/Test.class", + ) + } } /** @@ -168,13 +168,15 @@ class ShadowPluginTest : BasePluginTest() { run(serverShadowJarTask) - assertThat(outputServerShadowJar).containsEntries( - "client/Client.class", - "server/Server.class", - ) - assertThat(outputServerShadowJar).doesNotContainEntries( - "junit/framework/Test.class", - ) + assertThat(outputServerShadowJar).useAll { + containsEntries( + "client/Client.class", + "server/Server.class", + ) + doesNotContainEntries( + "junit/framework/Test.class", + ) + } } /** @@ -194,13 +196,15 @@ class ShadowPluginTest : BasePluginTest() { run(serverShadowJarTask) - assertThat(outputServerShadowJar).containsEntries( - "server/Server.class", - "junit/framework/Test.class", - ) - assertThat(outputServerShadowJar).doesNotContainEntries( - "client/Client.class", - ) + assertThat(outputServerShadowJar).useAll { + containsEntries( + "server/Server.class", + "junit/framework/Test.class", + ) + doesNotContainEntries( + "client/Client.class", + ) + } } /** @@ -219,10 +223,12 @@ class ShadowPluginTest : BasePluginTest() { run(serverShadowJarTask) - assertThat(outputServerShadowJar).containsEntries( - "client/Client.class", - "server/Server.class", - ) + assertThat(outputServerShadowJar).useAll { + containsEntries( + "client/Client.class", + "server/Server.class", + ) + } } /** @@ -250,11 +256,13 @@ class ShadowPluginTest : BasePluginTest() { run(serverShadowJarTask) - assertThat(outputServerShadowJar).containsEntries( - "client/Client.class", - "server/Server.class", - "junit/framework/TestCase.class", - ) + assertThat(outputServerShadowJar).useAll { + containsEntries( + "client/Client.class", + "server/Server.class", + "junit/framework/TestCase.class", + ) + } path("client/src/main/java/client/Client.java").writeText( """ @@ -264,13 +272,13 @@ class ShadowPluginTest : BasePluginTest() { ) run(serverShadowJarTask) - // TODO: I don't think junit classes should be in the output jar, but it's the test case - // from https://github.com/GradleUp/shadow/pull/420, need to investigate more... - assertThat(outputServerShadowJar).containsEntries( - "client/Client.class", - "server/Server.class", - "junit/framework/TestCase.class", - ) + assertThat(outputServerShadowJar).useAll { + containsEntries( + "client/Client.class", + "server/Server.class", + "junit/framework/TestCase.class", + ) + } } /** @@ -284,17 +292,18 @@ class ShadowPluginTest : BasePluginTest() { run(":impl:$SHADOW_JAR_TASK_NAME") - val implOutput = jarPath("impl/build/libs/impl-all.jar") - assertThat(implOutput).containsEntries( - "impl/SimpleEntity.class", - "api/Entity.class", - "api/UnusedEntity.class", - "lib/LibEntity.class", - ) - assertThat(implOutput).doesNotContainEntries( - "junit/framework/Test.class", - "lib/UnusedLibEntity.class", - ) + assertThat(jarPath("impl/build/libs/impl-all.jar")).useAll { + containsEntries( + "impl/SimpleEntity.class", + "api/Entity.class", + "api/UnusedEntity.class", + "lib/LibEntity.class", + ) + doesNotContainEntries( + "junit/framework/Test.class", + "lib/UnusedLibEntity.class", + ) + } } /** @@ -317,17 +326,18 @@ class ShadowPluginTest : BasePluginTest() { run(":impl:$SHADOW_JAR_TASK_NAME") - val implOutput = jarPath("impl/build/libs/impl-all.jar") - assertThat(implOutput).containsEntries( - "impl/SimpleEntity.class", - "api/Entity.class", - "api/UnusedEntity.class", - "lib/LibEntity.class", - "lib/UnusedLibEntity.class", - ) - assertThat(implOutput).doesNotContainEntries( - "junit/framework/Test.class", - ) + assertThat(jarPath("impl/build/libs/impl-all.jar")).useAll { + containsEntries( + "impl/SimpleEntity.class", + "api/Entity.class", + "api/UnusedEntity.class", + "lib/LibEntity.class", + "lib/UnusedLibEntity.class", + ) + doesNotContainEntries( + "junit/framework/Test.class", + ) + } } @Test @@ -336,21 +346,22 @@ class ShadowPluginTest : BasePluginTest() { run(":server:jar") - val serverOutput = jarPath("server/build/libs/server-1.0.jar") - assertThat(serverOutput).containsEntries( - "server/Server.class", - ) - assertThat(serverOutput).doesNotContainEntries( - "client/Client.class", - "junit/framework/Test.class", - "client/junit/framework/Test.class", - ) - - val clientOutput = jarPath("client/build/libs/client-all.jar") - assertThat(clientOutput).containsEntries( - "client/Client.class", - "client/junit/framework/Test.class", - ) + assertThat(jarPath("server/build/libs/server-1.0.jar")).useAll { + containsEntries( + "server/Server.class", + ) + doesNotContainEntries( + "client/Client.class", + "junit/framework/Test.class", + "client/junit/framework/Test.class", + ) + } + assertThat(jarPath("client/build/libs/client-all.jar")).useAll { + containsEntries( + "client/Client.class", + "client/junit/framework/Test.class", + ) + } } @Test @@ -359,20 +370,22 @@ class ShadowPluginTest : BasePluginTest() { run(serverShadowJarTask) - assertThat(outputServerShadowJar).containsEntries( - "client/Client.class", - "client/junit/framework/Test.class", - "server/Server.class", - ) - assertThat(outputServerShadowJar).doesNotContainEntries( - "junit/framework/Test.class", - ) - - val clientOutput = jarPath("client/build/libs/client-all.jar") - assertThat(clientOutput).containsEntries( - "client/Client.class", - "client/junit/framework/Test.class", - ) + assertThat(outputServerShadowJar).useAll { + containsEntries( + "client/Client.class", + "client/junit/framework/Test.class", + "server/Server.class", + ) + doesNotContainEntries( + "junit/framework/Test.class", + ) + } + assertThat(jarPath("client/build/libs/client-all.jar")).useAll { + containsEntries( + "client/Client.class", + "client/junit/framework/Test.class", + ) + } } @Test @@ -405,18 +418,20 @@ class ShadowPluginTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "shadow/Passed.class", - "a.properties", - "META-INF/a.properties", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "META-INF/INDEX.LIST", - "META-INF/a.SF", - "META-INF/a.DSA", - "META-INF/a.RSA", - "module-info.class", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "shadow/Passed.class", + "a.properties", + "META-INF/a.properties", + ) + doesNotContainEntries( + "META-INF/INDEX.LIST", + "META-INF/a.SF", + "META-INF/a.DSA", + "META-INF/a.RSA", + "module-info.class", + ) + } } @Test @@ -432,13 +447,15 @@ class ShadowPluginTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "a.properties", - "a2.properties", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "b.properties", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "a.properties", + "a2.properties", + ) + doesNotContainEntries( + "b.properties", + ) + } } @Test @@ -475,12 +492,14 @@ class ShadowPluginTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "api.properties", - "implementation.properties", - "runtimeOnly.properties", - "implementation-dep.properties", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "api.properties", + "implementation.properties", + "runtimeOnly.properties", + "implementation-dep.properties", + ) + } } @Test @@ -496,13 +515,15 @@ class ShadowPluginTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar).containsEntries( - "a.properties", - "a2.properties", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "b.properties", - ) + assertThat(outputShadowJar).useAll { + containsEntries( + "a.properties", + "a2.properties", + ) + doesNotContainEntries( + "b.properties", + ) + } } @Test @@ -528,7 +549,8 @@ class ShadowPluginTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar.entries().toList().size).isEqualTo(2) + val entries = outputShadowJar.use { it.entries().toList() } + assertThat(entries.size).isEqualTo(2) } @Test @@ -543,7 +565,8 @@ class ShadowPluginTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar.manifest.mainAttributes.getValue("Class-Path")).isNull() + val value = outputShadowJar.use { it.getMainAttr("Class-Path") } + assertThat(value).isNull() } @Issue( @@ -566,8 +589,8 @@ class ShadowPluginTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar.manifest.mainAttributes.getValue("Class-Path")) - .isEqualTo("/libs/a.jar junit-3.8.2.jar") + val value = outputShadowJar.use { it.getMainAttr("Class-Path") } + assertThat(value).isEqualTo("/libs/a.jar junit-3.8.2.jar") } @Issue( @@ -585,8 +608,8 @@ class ShadowPluginTest : BasePluginTest() { run(shadowJarTask) - assertThat(outputShadowJar.manifest.mainAttributes.getValue("Class-Path")) - .isEqualTo("junit-3.8.2.jar") + val value = outputShadowJar.use { it.getMainAttr("Class-Path") } + assertThat(value).isEqualTo("junit-3.8.2.jar") } @Issue( @@ -740,7 +763,7 @@ class ShadowPluginTest : BasePluginTest() { run(shadowJarTask) - val entries = outputShadowJar.entries().toList() + val entries = outputShadowJar.use { it.entries().toList() } assertThat(entries.count { it.name.endsWith(".class") }).isEqualTo(1) } @@ -767,10 +790,44 @@ class ShadowPluginTest : BasePluginTest() { val result = run(testShadowJarTask) - assertThat(result.task(":$testShadowJarTask")).isNotNull() - .transform { it.outcome }.isEqualTo(TaskOutcome.SUCCESS) - val testJar = jarPath("build/libs/shadow-1.0-tests.jar") - assertThat(testJar.getEntry("junit")).isNotNull() + assertThat(result).taskOutcomeEquals(":$testShadowJarTask", SUCCESS) + val junitEntry = jarPath("build/libs/shadow-1.0-tests.jar").use { it.getEntry("junit") } + assertThat(junitEntry).isNotNull() + } + + @Test + fun configurationCachingOfConfigurationsIsUpToDate() { + settingsScriptPath.appendText( + """ + include 'lib' + """.trimIndent(), + ) + projectScriptPath.writeText("") + + path("lib/src/main/java/lib/Lib.java").writeText( + """ + package lib; + public class Lib {} + """.trimIndent(), + ) + path("lib/build.gradle").writeText( + """ + ${getDefaultProjectBuildScript()} + dependencies { + implementation 'junit:junit:3.8.2' + } + $shadowJar { + configurations = [project.configurations.compileClasspath] + } + """.trimIndent(), + ) + + val libShadowJarTask = ":lib:$SHADOW_JAR_TASK_NAME" + run(libShadowJarTask) + val result = run(libShadowJarTask) + + assertThat(result).taskOutcomeEquals(libShadowJarTask, UP_TO_DATE) + assertThat(result.output).contains("Reusing configuration cache.") } private fun writeShadowedClientAndServerModules() { diff --git a/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/BaseCachingTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/BaseCachingTest.kt new file mode 100644 index 000000000..077d7b579 --- /dev/null +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/BaseCachingTest.kt @@ -0,0 +1,46 @@ +package com.github.jengelman.gradle.plugins.shadow.caching + +import assertk.assertFailure +import assertk.assertThat +import assertk.assertions.isEmpty +import assertk.assertions.isInstanceOf +import com.github.jengelman.gradle.plugins.shadow.BasePluginTest +import java.nio.file.NoSuchFileException +import kotlin.io.path.ExperimentalPathApi +import kotlin.io.path.isDirectory +import kotlin.io.path.name +import kotlin.io.path.walk +import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.TaskOutcome.FROM_CACHE +import org.gradle.testkit.runner.TaskOutcome.SUCCESS +import org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE + +abstract class BaseCachingTest : BasePluginTest() { + fun assertFirstExecutionSuccess() { + // task was executed and not pulled from cache + assertRunWithOutcome(SUCCESS) + } + + /** + * This should be called after [assertFirstExecutionSuccess] to ensure that the shadowJar task is cached. + */ + fun assertExecutionsAreCachedAndUpToDate() { + run("clean") + // Make sure the output shadow jar has been deleted. + assertFailure { outputShadowJar.close() }.isInstanceOf(NoSuchFileException::class) + @OptIn(ExperimentalPathApi::class) + val buildDirs = projectRoot.walk().filter { it.isDirectory() && it.name == "build" } + // Make sure build folders are deleted by clean task. + assertThat(buildDirs).isEmpty() + + // check that shadowJar pulls from cache in the original directory + assertRunWithOutcome(FROM_CACHE) + // check that shadowJar pulls from cache in a different directory + assertRunWithOutcome(UP_TO_DATE) + } + + private fun assertRunWithOutcome(expectedOutcome: TaskOutcome) { + val result = run(shadowJarTask) + assertThat(result).taskOutcomeEquals(shadowJarTask, expectedOutcome) + } +} diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/MinimizationCachingTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/MinimizationCachingTest.kt similarity index 90% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/MinimizationCachingTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/MinimizationCachingTest.kt index e1558090c..3921a87a1 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/MinimizationCachingTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/MinimizationCachingTest.kt @@ -4,7 +4,6 @@ import assertk.assertThat 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.useAll import kotlin.io.path.appendText import kotlin.io.path.writeText import org.junit.jupiter.api.Test @@ -23,7 +22,7 @@ class MinimizationCachingTest : BaseCachingTest() { """.trimIndent(), ) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries( "server/Server.class", @@ -42,7 +41,7 @@ class MinimizationCachingTest : BaseCachingTest() { """.trimIndent(), ) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries( "server/Server.class", @@ -53,7 +52,7 @@ class MinimizationCachingTest : BaseCachingTest() { ) } - assertShadowJarIsCachedAndRelocatable() + assertExecutionsAreCachedAndUpToDate() assertThat(outputShadowJar).useAll { containsEntries( "server/Server.class", diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/RelocationCachingTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/RelocationCachingTest.kt similarity index 90% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/RelocationCachingTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/RelocationCachingTest.kt index a62b217d5..43a05f563 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/RelocationCachingTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/RelocationCachingTest.kt @@ -3,7 +3,6 @@ package com.github.jengelman.gradle.plugins.shadow.caching import assertk.assertThat 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.useAll import kotlin.io.path.appendText import org.junit.jupiter.api.Test @@ -22,7 +21,7 @@ class RelocationCachingTest : BaseCachingTest() { ) writeMainClass(withImports = true) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries( "shadow/Main.class", @@ -38,7 +37,7 @@ class RelocationCachingTest : BaseCachingTest() { """.trimIndent(), ) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries( "shadow/Main.class", @@ -49,7 +48,7 @@ class RelocationCachingTest : BaseCachingTest() { ) } - assertShadowJarIsCachedAndRelocatable() + assertExecutionsAreCachedAndUpToDate() assertThat(outputShadowJar).useAll { containsEntries( "shadow/Main.class", diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/ShadowJarCachingTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/ShadowJarCachingTest.kt similarity index 86% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/ShadowJarCachingTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/ShadowJarCachingTest.kt index 3c99cc192..3af4c28ed 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/ShadowJarCachingTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/ShadowJarCachingTest.kt @@ -4,11 +4,9 @@ import assertk.assertThat 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.isRegular -import com.github.jengelman.gradle.plugins.shadow.util.useAll import kotlin.io.path.appendText import kotlin.io.path.readText import kotlin.io.path.writeText -import org.gradle.testkit.runner.TaskOutcome.FROM_CACHE import org.junit.jupiter.api.Test class ShadowJarCachingTest : BaseCachingTest() { @@ -25,14 +23,14 @@ class ShadowJarCachingTest : BaseCachingTest() { """.trimIndent(), ) - assertShadowJarExecutes() - assertShadowJarIsCachedAndRelocatable() + assertFirstExecutionSuccess() + assertExecutionsAreCachedAndUpToDate() val replaced = projectScriptPath.readText().lines().filter { it != fromJar(projectJar) }.joinToString(System.lineSeparator()) projectScriptPath.writeText(replaced) - assertShadowJarExecutes() + assertFirstExecutionSuccess() } @Test @@ -45,7 +43,7 @@ class ShadowJarCachingTest : BaseCachingTest() { """.trimIndent() + System.lineSeparator(), ) - assertShadowJarExecutes() + assertFirstExecutionSuccess() projectScriptPath.appendText( """ @@ -54,8 +52,7 @@ class ShadowJarCachingTest : BaseCachingTest() { } """.trimIndent(), ) - // TODO: need to investigate why secondOutcome is FROM_CACHE instead of UP_TO_DATE. - assertShadowJarIsCachedAndRelocatable(secondOutcome = FROM_CACHE) + assertExecutionsAreCachedAndUpToDate() assertThat(jarPath("build/libs/foo-1.0-all.jar")).isRegular() } @@ -87,7 +84,7 @@ class ShadowJarCachingTest : BaseCachingTest() { """.trimIndent(), ) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries( "server/Server.class", @@ -105,7 +102,7 @@ class ShadowJarCachingTest : BaseCachingTest() { } """.trimIndent(), ) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries( "server/Server.class", @@ -116,7 +113,7 @@ class ShadowJarCachingTest : BaseCachingTest() { ) } - assertShadowJarIsCachedAndRelocatable() + assertExecutionsAreCachedAndUpToDate() assertThat(outputShadowJar).useAll { containsEntries( "server/Server.class", @@ -140,7 +137,7 @@ class ShadowJarCachingTest : BaseCachingTest() { writeMainClass(withImports = true) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries( "shadow/Main.class", @@ -157,7 +154,7 @@ class ShadowJarCachingTest : BaseCachingTest() { } """.trimIndent(), ) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries( "shadow/Main.class", @@ -167,7 +164,7 @@ class ShadowJarCachingTest : BaseCachingTest() { ) } - assertShadowJarIsCachedAndRelocatable() + assertExecutionsAreCachedAndUpToDate() assertThat(outputShadowJar).useAll { containsEntries( "shadow/Main.class", diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/TransformCachingTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/TransformCachingTest.kt similarity index 76% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/TransformCachingTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/TransformCachingTest.kt index c749a6582..63257e886 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/TransformCachingTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/TransformCachingTest.kt @@ -3,45 +3,20 @@ package com.github.jengelman.gradle.plugins.shadow.caching import assertk.assertThat import com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer import com.github.jengelman.gradle.plugins.shadow.transformers.GroovyExtensionModuleTransformer -import com.github.jengelman.gradle.plugins.shadow.transformers.NoOpTransformer import com.github.jengelman.gradle.plugins.shadow.transformers.ServiceFileTransformer import com.github.jengelman.gradle.plugins.shadow.transformers.XmlAppendingTransformer import com.github.jengelman.gradle.plugins.shadow.util.containsEntries -import com.github.jengelman.gradle.plugins.shadow.util.useAll import kotlin.io.path.appendText import kotlin.io.path.readText import kotlin.io.path.writeText import org.junit.jupiter.api.Test class TransformCachingTest : BaseCachingTest() { - @Test - fun shadowJarIsNotCachedWhenCustomTransformsAreUsed() { - writeMainClass() - projectScriptPath.appendText( - """ - $shadowJar { - // Use NoOpTransformer to mock a custom transformer here. - transform(${NoOpTransformer::class.java.name}.INSTANCE) - } - """.trimIndent(), - ) - - assertShadowJarExecutes() - assertThat(outputShadowJar).useAll { - containsEntries("shadow/Main.class") - } - - assertShadowJarExecutes() - assertThat(outputShadowJar).useAll { - containsEntries("shadow/Main.class") - } - } - @Test fun shadowJarIsCachedCorrectlyWhenUsingServiceFileTransformer() { writeMainClass() - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class") } @@ -54,12 +29,12 @@ class TransformCachingTest : BaseCachingTest() { ), ) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class") } - assertShadowJarIsCachedAndRelocatable() + assertExecutionsAreCachedAndUpToDate() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class") } @@ -67,12 +42,12 @@ class TransformCachingTest : BaseCachingTest() { val replaced = projectScriptPath.readText().replace("META-INF/foo", "META-INF/bar") projectScriptPath.writeText(replaced) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class") } - assertShadowJarIsCachedAndRelocatable() + assertExecutionsAreCachedAndUpToDate() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class") } @@ -83,7 +58,7 @@ class TransformCachingTest : BaseCachingTest() { path("src/main/resources/foo/bar.properties").writeText("foo=bar") writeMainClass() - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class") } @@ -96,12 +71,12 @@ class TransformCachingTest : BaseCachingTest() { ), ) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class", "foo/bar.properties") } - assertShadowJarIsCachedAndRelocatable() + assertExecutionsAreCachedAndUpToDate() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class", "foo/bar.properties") } @@ -111,12 +86,12 @@ class TransformCachingTest : BaseCachingTest() { val replaced = projectScriptPath.readText().replace("foo/bar.properties", "foo/baz.properties") projectScriptPath.writeText(replaced) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class", "foo/baz.properties") } - assertShadowJarIsCachedAndRelocatable() + assertExecutionsAreCachedAndUpToDate() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class", "foo/baz.properties") } @@ -127,7 +102,7 @@ class TransformCachingTest : BaseCachingTest() { path("src/main/resources/foo/bar.xml").writeText("bar") writeMainClass() - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class") } @@ -140,12 +115,12 @@ class TransformCachingTest : BaseCachingTest() { ), ) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class", "foo/bar.xml") } - assertShadowJarIsCachedAndRelocatable() + assertExecutionsAreCachedAndUpToDate() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class", "foo/bar.xml") } @@ -155,12 +130,12 @@ class TransformCachingTest : BaseCachingTest() { val replaced = projectScriptPath.readText().replace("foo/bar.xml", "foo/baz.xml") projectScriptPath.writeText(replaced) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class", "foo/baz.xml") } - assertShadowJarIsCachedAndRelocatable() + assertExecutionsAreCachedAndUpToDate() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class", "foo/baz.xml") } @@ -170,7 +145,7 @@ class TransformCachingTest : BaseCachingTest() { fun shadowJarIsCachedCorrectlyWhenUsingGroovyExtensionModuleTransformer() { writeMainClass() - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class") } @@ -179,12 +154,12 @@ class TransformCachingTest : BaseCachingTest() { transform(), ) - assertShadowJarExecutes() + assertFirstExecutionSuccess() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class") } - assertShadowJarIsCachedAndRelocatable() + assertExecutionsAreCachedAndUpToDate() assertThat(outputShadowJar).useAll { containsEntries("shadow/Main.class") } diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformerTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformerTest.kt similarity index 80% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformerTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformerTest.kt index 24e12cd09..04807f7f4 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformerTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformerTest.kt @@ -25,8 +25,8 @@ class AppendingTransformerTest : BaseTransformerTest() { run(shadowJarTask) - assertThat(outputShadowJar.getContent(ENTRY_TEST_PROPERTIES).trimIndent()) - .isEqualTo(CONTENT_ONE_TWO) + val content = outputShadowJar.use { it.getContent(ENTRY_TEST_PROPERTIES) }.trimIndent() + assertThat(content).isEqualTo(CONTENT_ONE_TWO) } @Test @@ -48,7 +48,7 @@ class AppendingTransformerTest : BaseTransformerTest() { run(shadowJarTask) - assertThat(outputShadowJar.getContent(ENTRY_TEST_PROPERTIES).trimIndent()) - .isEqualTo(CONTENT_ONE_TWO) + val content = outputShadowJar.use { it.getContent(ENTRY_TEST_PROPERTIES) }.trimIndent() + assertThat(content).isEqualTo(CONTENT_ONE_TWO) } } diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/BaseTransformerTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/BaseTransformerTest.kt similarity index 86% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/BaseTransformerTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/BaseTransformerTest.kt index 557275a4d..b4ee8444b 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/BaseTransformerTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/BaseTransformerTest.kt @@ -4,8 +4,7 @@ import com.github.jengelman.gradle.plugins.shadow.BasePluginTest import com.github.jengelman.gradle.plugins.shadow.util.JarBuilder import java.nio.file.Path -sealed class BaseTransformerTest : BasePluginTest() { - +abstract class BaseTransformerTest : BasePluginTest() { fun buildJarOne( builder: JarBuilder.() -> Unit = { insert(ENTRY_SERVICES_SHADE, CONTENT_ONE) @@ -24,8 +23,8 @@ sealed class BaseTransformerTest : BasePluginTest() { return buildJar("two.jar", builder) } - inline fun buildJar(path: String, builder: JarBuilder.() -> Unit): Path { - return JarBuilder(path(path)).apply(builder).write() + inline fun buildJar(relative: String, builder: JarBuilder.() -> Unit): Path { + return JarBuilder(path("temp/$relative")).apply(builder).write() } protected companion object { diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/GroovyExtensionModuleTransformerTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/GroovyExtensionModuleTransformerTest.kt similarity index 75% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/GroovyExtensionModuleTransformerTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/GroovyExtensionModuleTransformerTest.kt index 8838f4cd8..c373895f5 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/GroovyExtensionModuleTransformerTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/GroovyExtensionModuleTransformerTest.kt @@ -11,7 +11,6 @@ import com.github.jengelman.gradle.plugins.shadow.transformers.GroovyExtensionMo import com.github.jengelman.gradle.plugins.shadow.transformers.GroovyExtensionModuleTransformer.Companion.PATH_GROOVY_EXTENSION_MODULE_DESCRIPTOR import com.github.jengelman.gradle.plugins.shadow.transformers.GroovyExtensionModuleTransformer.Companion.PATH_LEGACY_GROOVY_EXTENSION_MODULE_DESCRIPTOR import java.nio.file.Path -import java.util.Properties import kotlin.io.path.appendText import org.junit.jupiter.api.Test @@ -26,8 +25,7 @@ class GroovyExtensionModuleTransformerTest : BaseTransformerTest() { run(shadowJarTask) - val props = outputShadowJar.getContent(PATH_GROOVY_EXTENSION_MODULE_DESCRIPTOR).toProperties() - commonAssertions(props) + commonAssertions(PATH_GROOVY_EXTENSION_MODULE_DESCRIPTOR) } @Test @@ -43,8 +41,7 @@ class GroovyExtensionModuleTransformerTest : BaseTransformerTest() { run(shadowJarTask) - val props = outputShadowJar.getContent(PATH_LEGACY_GROOVY_EXTENSION_MODULE_DESCRIPTOR).toProperties() - commonAssertions(props) + commonAssertions(PATH_LEGACY_GROOVY_EXTENSION_MODULE_DESCRIPTOR) } @Test @@ -60,15 +57,14 @@ class GroovyExtensionModuleTransformerTest : BaseTransformerTest() { run(shadowJarTask) - val props = outputShadowJar.getContent(PATH_GROOVY_EXTENSION_MODULE_DESCRIPTOR).toProperties() - commonAssertions(props) + commonAssertions(PATH_GROOVY_EXTENSION_MODULE_DESCRIPTOR) } private fun buildJarFoo( - path: String = PATH_GROOVY_EXTENSION_MODULE_DESCRIPTOR, + entry: String = PATH_GROOVY_EXTENSION_MODULE_DESCRIPTOR, ): Path = buildJar("foo.jar") { insert( - path, + entry, """ $KEY_MODULE_NAME=foo $KEY_MODULE_VERSION=1.0.5 @@ -79,10 +75,10 @@ class GroovyExtensionModuleTransformerTest : BaseTransformerTest() { } private fun buildJarBar( - path: String = PATH_GROOVY_EXTENSION_MODULE_DESCRIPTOR, + entry: String = PATH_GROOVY_EXTENSION_MODULE_DESCRIPTOR, ): Path = buildJar("bar.jar") { insert( - path, + entry, """ $KEY_MODULE_NAME=bar $KEY_MODULE_VERSION=2.3.5 @@ -92,19 +88,21 @@ class GroovyExtensionModuleTransformerTest : BaseTransformerTest() { ) } + private fun commonAssertions(entry: String) { + val properties = outputShadowJar.use { it.getContent(entry) }.toProperties() + + assertThat(properties.getProperty(KEY_MODULE_NAME)).isEqualTo(MERGED_MODULE_NAME) + assertThat(properties.getProperty(KEY_MODULE_VERSION)).isEqualTo(MERGED_MODULE_VERSION) + assertThat(properties.getProperty(KEY_EXTENSION_CLASSES)) + .isEqualTo("$EXTENSION_CLASSES_FOO,$EXTENSION_CLASSES_BAR") + assertThat(properties.getProperty(KEY_STATIC_EXTENSION_CLASSES)) + .isEqualTo("$STATIC_EXTENSION_CLASSES_FOO,$STATIC_EXTENSION_CLASSES_BAR") + } + private companion object { const val EXTENSION_CLASSES_FOO = "com.acme.foo.FooExtension,com.acme.foo.BarExtension" const val EXTENSION_CLASSES_BAR = "com.acme.bar.SomeExtension,com.acme.bar.AnotherExtension" const val STATIC_EXTENSION_CLASSES_FOO = "com.acme.foo.FooStaticExtension" const val STATIC_EXTENSION_CLASSES_BAR = "com.acme.bar.SomeStaticExtension" - - fun commonAssertions(properties: Properties) { - assertThat(properties.getProperty(KEY_MODULE_NAME)).isEqualTo(MERGED_MODULE_NAME) - assertThat(properties.getProperty(KEY_MODULE_VERSION)).isEqualTo(MERGED_MODULE_VERSION) - assertThat(properties.getProperty(KEY_EXTENSION_CLASSES)) - .isEqualTo("$EXTENSION_CLASSES_FOO,$EXTENSION_CLASSES_BAR") - assertThat(properties.getProperty(KEY_STATIC_EXTENSION_CLASSES)) - .isEqualTo("$STATIC_EXTENSION_CLASSES_FOO,$STATIC_EXTENSION_CLASSES_BAR") - } } } diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt similarity index 72% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt index 65923952a..8fef8b325 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt @@ -3,12 +3,12 @@ package com.github.jengelman.gradle.plugins.shadow.transformers import assertk.assertThat import assertk.assertions.isEqualTo import com.github.jengelman.gradle.plugins.shadow.util.Issue +import com.github.jengelman.gradle.plugins.shadow.util.getContent import kotlin.io.path.appendText import kotlin.io.path.writeText import org.junit.jupiter.api.Test class ServiceFileTransformerTest : BaseTransformerTest() { - @Test fun serviceResourceTransformer() { projectScriptPath.appendText( @@ -22,8 +22,10 @@ class ServiceFileTransformerTest : BaseTransformerTest() { run(shadowJarTask) - assertThat(outputShadowJar.getContent(ENTRY_SERVICES_SHADE)).isEqualTo(CONTENT_ONE_TWO) - assertThat(outputShadowJar.getContent(ENTRY_SERVICES_FOO)).isEqualTo("one") + assertThat(outputShadowJar).useAll { + getContent(ENTRY_SERVICES_SHADE).isEqualTo(CONTENT_ONE_TWO) + getContent(ENTRY_SERVICES_FOO).isEqualTo("one") + } } @Test @@ -45,7 +47,8 @@ class ServiceFileTransformerTest : BaseTransformerTest() { run(shadowJarTask) - assertThat(outputShadowJar.getContent(ENTRY_FOO_SHADE)).isEqualTo(CONTENT_ONE_TWO) + val content = outputShadowJar.use { it.getContent(ENTRY_FOO_SHADE) } + assertThat(content).isEqualTo(CONTENT_ONE_TWO) } @Test @@ -63,8 +66,10 @@ class ServiceFileTransformerTest : BaseTransformerTest() { run(shadowJarTask) - assertThat(outputShadowJar.getContent(ENTRY_SERVICES_SHADE)).isEqualTo(CONTENT_ONE_TWO) - assertThat(outputShadowJar.getContent(ENTRY_SERVICES_FOO)).isEqualTo("one") + assertThat(outputShadowJar).useAll { + getContent(ENTRY_SERVICES_SHADE).isEqualTo(CONTENT_ONE_TWO) + getContent(ENTRY_SERVICES_FOO).isEqualTo("one") + } } @Test @@ -119,31 +124,28 @@ class ServiceFileTransformerTest : BaseTransformerTest() { run(shadowJarTask) - val text1 = outputShadowJar.getContent("META-INF/services/java.sql.Driver") - assertThat(text1).isEqualTo( - """ - oracle.jdbc.OracleDriver - myapache.hive.jdbc.HiveDriver - myapache.derby.jdbc.AutoloadedDriver - com.mysql.jdbc.Driver - """.trimIndent(), - ) - - val text2 = outputShadowJar.getContent("META-INF/services/myapache.axis.components.compiler.Compiler") - assertThat(text2).isEqualTo( - """ - myapache.axis.components.compiler.Javac - org.apache.axis.components.compiler.Jikes - """.trimIndent(), - ) - - val text3 = outputShadowJar.getContent("META-INF/services/org.apache.commons.logging.LogFactory") - assertThat(text3).isEqualTo( - """ - myapache.commons.logging.impl.LogFactoryImpl - org.mortbay.log.Factory - """.trimIndent(), - ) + assertThat(outputShadowJar).useAll { + getContent("META-INF/services/java.sql.Driver").isEqualTo( + """ + oracle.jdbc.OracleDriver + myapache.hive.jdbc.HiveDriver + myapache.derby.jdbc.AutoloadedDriver + com.mysql.jdbc.Driver + """.trimIndent(), + ) + getContent("META-INF/services/myapache.axis.components.compiler.Compiler").isEqualTo( + """ + myapache.axis.components.compiler.Javac + org.apache.axis.components.compiler.Jikes + """.trimIndent(), + ) + getContent("META-INF/services/org.apache.commons.logging.LogFactory").isEqualTo( + """ + myapache.commons.logging.impl.LogFactoryImpl + org.mortbay.log.Factory + """.trimIndent(), + ) + } } @Test @@ -165,7 +167,8 @@ class ServiceFileTransformerTest : BaseTransformerTest() { run(shadowJarTask) - assertThat(outputShadowJar.getContent(ENTRY_FOO_SHADE)).isEqualTo(CONTENT_ONE_TWO) + val content = outputShadowJar.use { it.getContent(ENTRY_FOO_SHADE) } + assertThat(content).isEqualTo(CONTENT_ONE_TWO) } @Issue( @@ -199,7 +202,7 @@ class ServiceFileTransformerTest : BaseTransformerTest() { run(shadowJarTask) - assertThat(outputShadowJar.getContent(servicesShadowEntry)) - .isEqualTo(CONTENT_THREE + "\n" + CONTENT_ONE_TWO) + val content = outputShadowJar.use { it.getContent(servicesShadowEntry) } + assertThat(content).isEqualTo(CONTENT_THREE + "\n" + CONTENT_ONE_TWO) } } diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/TransformersTest.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/TransformersTest.kt similarity index 76% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/TransformersTest.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/TransformersTest.kt index 425828c5d..551578cce 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/TransformersTest.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/TransformersTest.kt @@ -6,6 +6,7 @@ import assertk.assertions.isNotNull import assertk.assertions.isNull import com.github.jengelman.gradle.plugins.shadow.util.Issue import com.github.jengelman.gradle.plugins.shadow.util.isRegular +import java.util.jar.Attributes import kotlin.io.path.appendText import kotlin.io.path.writeText import kotlin.reflect.KClass @@ -14,7 +15,6 @@ import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource class TransformersTest : BaseTransformerTest() { - @Test fun manifestRetained() { writeMainClass() @@ -31,10 +31,10 @@ class TransformersTest : BaseTransformerTest() { run(shadowJarTask) - val mf = outputShadowJar.manifest - assertThat(mf).isNotNull() - assertThat(mf.mainAttributes.getValue("Test-Entry")).isEqualTo("PASSED") - assertThat(mf.mainAttributes.getValue("Main-Class")).isEqualTo("shadow.Main") + commonAssertions { + assertThat(getValue("Test-Entry")).isEqualTo("PASSED") + assertThat(getValue("Main-Class")).isEqualTo("shadow.Main") + } } @Test @@ -45,11 +45,7 @@ class TransformersTest : BaseTransformerTest() { run(shadowJarTask) - val mf = outputShadowJar.manifest - assertThat(mf).isNotNull() - assertThat(mf.mainAttributes.getValue("Test-Entry")).isEqualTo("PASSED") - assertThat(mf.mainAttributes.getValue("Main-Class")).isEqualTo("shadow.Main") - assertThat(mf.mainAttributes.getValue("New-Entry")).isEqualTo("NEW") + commonAssertions() } @Test @@ -81,7 +77,8 @@ class TransformersTest : BaseTransformerTest() { run(shadowJarTask) - assertThat(outputShadowJar.getContent(propertiesXml).trimIndent()).isEqualTo( + val content = outputShadowJar.use { it.getContent(propertiesXml) }.trimIndent() + assertThat(content).isEqualTo( """ @@ -101,17 +98,30 @@ class TransformersTest : BaseTransformerTest() { run("jar", shadowJarTask) - val mf1 = outputShadowJar.manifest - assertThat(mf1).isNotNull() - assertThat(mf1.mainAttributes.getValue("Test-Entry")).isEqualTo("PASSED") - assertThat(mf1.mainAttributes.getValue("Main-Class")).isEqualTo("shadow.Main") - assertThat(mf1.mainAttributes.getValue("New-Entry")).isEqualTo("NEW") - - val mf2 = jarPath("build/libs/shadow-1.0.jar").manifest - assertThat(mf2).isNotNull() - assertThat(mf2.mainAttributes.getValue("Test-Entry")).isEqualTo("FAILED") - assertThat(mf2.mainAttributes.getValue("Main-Class")).isEqualTo("shadow.Main") - assertThat(mf2.mainAttributes.getValue("New-Entry")).isNull() + commonAssertions() + + val mf = jarPath("build/libs/shadow-1.0.jar").use { it.manifest } + assertThat(mf).isNotNull() + assertThat(mf.mainAttributes.getValue("Test-Entry")).isEqualTo("FAILED") + assertThat(mf.mainAttributes.getValue("Main-Class")).isEqualTo("shadow.Main") + assertThat(mf.mainAttributes.getValue("New-Entry")).isNull() + } + + @Test + fun canUseCustomTransformer() { + writeMainClass() + projectScriptPath.appendText( + """ + $shadowJar { + // Use NoOpTransformer to mock a custom transformer here. + transform(${NoOpTransformer::class.java.name}.INSTANCE) + } + """.trimIndent(), + ) + + run(shadowJarTask) + + assertThat(outputShadowJar).isRegular() } @ParameterizedTest @@ -134,6 +144,18 @@ class TransformersTest : BaseTransformerTest() { assertThat(outputShadowJar).isRegular() } + private fun commonAssertions( + mainAttributesBlock: Attributes.() -> Unit = { + assertThat(getValue("Test-Entry")).isEqualTo("PASSED") + assertThat(getValue("Main-Class")).isEqualTo("shadow.Main") + assertThat(getValue("New-Entry")).isEqualTo("NEW") + }, + ) { + val mf = outputShadowJar.use { it.manifest } + assertThat(mf).isNotNull() + mainAttributesBlock(mf.mainAttributes) + } + private companion object { val MANIFEST_ATTRS = """ jar { diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenRepository.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenRepository.kt similarity index 96% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenRepository.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenRepository.kt index 5786ec8bd..a9764473b 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenRepository.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenRepository.kt @@ -20,7 +20,7 @@ class AppendableMavenRepository( private val modules = mutableListOf() init { - root.createDirectories() + root.resolve("temp").createDirectories() root.resolve("settings.gradle").createFile() .writeText("rootProject.name = '${root.name}'") projectBuildScript = root.resolve("build.gradle").createFile() @@ -109,7 +109,7 @@ class AppendableMavenRepository( fun buildJar(builder: JarBuilder.() -> Unit) { val jarName = coordinate.replace(":", "-") + ".jar" - existingJar = JarBuilder(root.resolve(jarName)).apply(builder).write() + existingJar = JarBuilder(root.resolve("temp/$jarName")).apply(builder).write() } fun addDependency(groupId: String, artifactId: String, version: String, scope: String = "runtime") { diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/GradleModuleMetadata.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/GradleModuleMetadata.kt similarity index 100% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/GradleModuleMetadata.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/GradleModuleMetadata.kt diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/Issue.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/Issue.kt similarity index 100% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/Issue.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/Issue.kt diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarBuilder.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarBuilder.kt similarity index 87% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarBuilder.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarBuilder.kt index d59675a6c..6da7edaf8 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarBuilder.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarBuilder.kt @@ -12,8 +12,8 @@ class JarBuilder( private val entries = mutableSetOf() private val jos = JarOutputStream(outputPath.outputStream()) - fun insert(path: String, content: String): JarBuilder = apply { - contents[path] = content + fun insert(entry: String, content: String): JarBuilder = apply { + contents[entry] = content } fun write(): Path { @@ -25,7 +25,7 @@ class JarBuilder( } if (entries.add(entry)) { jos.putNextEntry(JarEntry(entry)) - content.byteInputStream().copyTo(jos) + content.byteInputStream().use { it.copyTo(jos) } } } } diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarPath.kt b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarPath.kt similarity index 66% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarPath.kt rename to src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarPath.kt index d7f7b3c9f..9e10f3395 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarPath.kt +++ b/src/funcTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/JarPath.kt @@ -6,7 +6,6 @@ import assertk.assertions.isNotEmpty import assertk.fail import java.nio.file.Path import java.util.jar.JarFile -import kotlin.io.path.deleteExisting /** * A wrapper for [JarFile] that also implements [Path]. @@ -18,9 +17,8 @@ class JarPath(val path: Path) : JarFile(path.toFile()), Path by path { - fun deleteExisting() { - close() - path.deleteExisting() + fun getMainAttr(name: String): String? { + return manifest.mainAttributes.getValue(name) } fun getContent(entryName: String): String { @@ -29,23 +27,26 @@ class JarPath(val path: Path) : } } -fun Assert.useAll(body: Assert.() -> Unit) = all { - body() - given { it.close() } -} - /** * Common regular assertions for [JarPath]. */ -fun Assert.isRegular() = transform { it.entries().toList() }.isNotEmpty() +fun Assert.isRegular() = all { + transform { it.entries().toList() }.isNotEmpty() + // Close the resource after all assertions are done. + given { it.use(block = {}) } +} + +fun Assert.getContent(entryName: String) = transform { it.getContent(entryName) } + +fun Assert.getMainAttr(name: String) = transform { it.getMainAttr(name) } -fun Assert.containsEntries(vararg entries: String) = transform { actual -> +fun Assert.containsEntries(vararg entries: String) = given { actual -> entries.forEach { entry -> actual.getEntry(entry) ?: fail("Jar file ${actual.path} does not contain entry $entry") } } -fun Assert.doesNotContainEntries(vararg entries: String) = transform { actual -> +fun Assert.doesNotContainEntries(vararg entries: String) = given { actual -> entries.forEach { entry -> actual.getEntry(entry) ?: return@forEach fail("Jar file ${actual.path} contains entry $entry") diff --git a/src/intiTest/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/src/funcTest/resources/META-INF/services/org.junit.jupiter.api.extension.Extension similarity index 100% rename from src/intiTest/resources/META-INF/services/org.junit.jupiter.api.extension.Extension rename to src/funcTest/resources/META-INF/services/org.junit.jupiter.api.extension.Extension diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ConfigurationCacheTest.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ConfigurationCacheTest.kt deleted file mode 100644 index 29539c00f..000000000 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ConfigurationCacheTest.kt +++ /dev/null @@ -1,140 +0,0 @@ -package com.github.jengelman.gradle.plugins.shadow - -import assertk.assertThat -import assertk.assertions.contains -import assertk.assertions.isEqualTo -import assertk.assertions.isNotNull -import com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin.Companion.SHADOW_JAR_TASK_NAME -import com.github.jengelman.gradle.plugins.shadow.util.containsEntries -import com.github.jengelman.gradle.plugins.shadow.util.doesNotContainEntries -import kotlin.io.path.appendText -import kotlin.io.path.writeText -import org.gradle.testkit.runner.BuildResult -import org.gradle.testkit.runner.TaskOutcome -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test - -class ConfigurationCacheTest : BasePluginTest() { - @BeforeEach - override fun setup() { - super.setup() - projectScriptPath.appendText( - """ - dependencies { - implementation 'shadow:a:1.0' - implementation 'shadow:b:1.0' - } - """.trimIndent() + System.lineSeparator(), - ) - } - - @Test - fun supportsConfigurationCache() { - writeMainClass() - - projectScriptPath.appendText( - """ - apply plugin: 'application' - - application { - mainClass = 'myapp.Main' - } - $runShadow { - args 'foo' - } - """.trimIndent(), - ) - - run(shadowJarTask) - val result = run(shadowJarTask) - - result.assertCcReused() - } - - @Test - fun configurationCachingSupportsExcludes() { - projectScriptPath.appendText( - """ - $shadowJar { - exclude 'a2.properties' - } - """.trimIndent(), - ) - - run(shadowJarTask) - outputShadowJar.deleteExisting() - val result = run(shadowJarTask) - - assertThat(outputShadowJar).containsEntries( - "a.properties", - "b.properties", - ) - assertThat(outputShadowJar).doesNotContainEntries( - "a2.properties", - ) - result.assertCcReused() - } - - @Test - fun configurationCachingSupportsMinimize() { - writeClientAndServerModules( - serverShadowBlock = """ - minimize { - exclude(dependency('junit:junit:.*')) - } - """.trimIndent(), - ) - - run(serverShadowJarTask) - outputServerShadowJar.deleteExisting() - val result = run(serverShadowJarTask) - - assertThat(outputServerShadowJar).containsEntries( - "server/Server.class", - "junit/framework/Test.class", - ) - assertThat(outputServerShadowJar).doesNotContainEntries( - "client/Client.class", - ) - result.assertCcReused() - } - - @Test - fun configurationCachingOfConfigurationsIsUpToDate() { - settingsScriptPath.appendText( - """ - include 'lib' - """.trimIndent(), - ) - - path("lib/src/main/java/lib/Lib.java").writeText( - """ - package lib; - public class Lib {} - """.trimIndent(), - ) - path("lib/build.gradle").writeText( - """ - ${getDefaultProjectBuildScript()} - dependencies { - implementation 'junit:junit:3.8.2' - } - $shadowJar { - configurations = [project.configurations.compileClasspath] - } - """.trimIndent(), - ) - - val libShadowJarTask = ":lib:$SHADOW_JAR_TASK_NAME" - run(libShadowJarTask) - val result = run(libShadowJarTask) - - assertThat(result.task(libShadowJarTask)).isNotNull() - .transform { it.outcome }.isEqualTo(TaskOutcome.UP_TO_DATE) - result.assertCcReused() - } - - private fun BuildResult.assertCcReused() { - assertThat(output).contains("Reusing configuration cache.") - } -} diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/DocCodeSnippetTest.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/DocCodeSnippetTest.kt similarity index 67% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/DocCodeSnippetTest.kt rename to src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/DocCodeSnippetTest.kt index 887c4a273..76363f9c4 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/DocCodeSnippetTest.kt +++ b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/DocCodeSnippetTest.kt @@ -1,9 +1,9 @@ -package com.github.jengelman.gradle.plugins.shadow.doc +package com.github.jengelman.gradle.plugins.shadow -import com.github.jengelman.gradle.plugins.shadow.doc.executable.CodeSnippetExtractor -import com.github.jengelman.gradle.plugins.shadow.doc.executor.GroovyBuildExecutor -import com.github.jengelman.gradle.plugins.shadow.doc.executor.NoopExecutor -import com.github.jengelman.gradle.plugins.shadow.doc.fixture.GroovyDslFixture +import com.github.jengelman.gradle.plugins.shadow.executable.CodeSnippetExtractor +import com.github.jengelman.gradle.plugins.shadow.executor.GroovyBuildExecutor +import com.github.jengelman.gradle.plugins.shadow.executor.NoopExecutor +import com.github.jengelman.gradle.plugins.shadow.fixture.GroovyDslFixture import java.nio.file.Path import kotlin.io.path.Path import org.junit.jupiter.api.DynamicTest diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/BaseCachingTest.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/BaseCachingTest.kt deleted file mode 100644 index b12cf69fa..000000000 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/caching/BaseCachingTest.kt +++ /dev/null @@ -1,83 +0,0 @@ -package com.github.jengelman.gradle.plugins.shadow.caching - -import assertk.assertThat -import assertk.assertions.isEqualTo -import assertk.assertions.isNotNull -import com.github.jengelman.gradle.plugins.shadow.BasePluginTest -import java.nio.file.Path -import kotlin.io.path.ExperimentalPathApi -import kotlin.io.path.appendText -import kotlin.io.path.copyToRecursively -import kotlin.io.path.deleteRecursively -import kotlin.io.path.listDirectoryEntries -import org.gradle.testkit.runner.GradleRunner -import org.gradle.testkit.runner.TaskOutcome -import org.gradle.testkit.runner.TaskOutcome.FROM_CACHE -import org.gradle.testkit.runner.TaskOutcome.SUCCESS -import org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.io.TempDir - -abstract class BaseCachingTest : BasePluginTest() { - - @TempDir - lateinit var alternateDir: Path - - @BeforeEach - override fun setup() { - super.setup() - // Use a test-specific build cache directory. This ensures that we'll only use cached outputs generated during - // this test, and we won't accidentally use cached outputs from a different test or a different build. - settingsScriptPath.appendText( - """ - buildCache { - local { - directory = file('build-cache') - } - } - """.trimIndent() + System.lineSeparator(), - ) - } - - @OptIn(ExperimentalPathApi::class) - fun assertShadowJarIsCachedAndRelocatable( - firstOutcome: TaskOutcome = FROM_CACHE, - secondOutcome: TaskOutcome = UP_TO_DATE, - ) { - try { - outputShadowJar.deleteExisting() - } catch (ignored: IllegalStateException) { - // ignore if the file does not exist - } - alternateDir.deleteRecursively() - root.copyToRecursively(alternateDir, followLinks = false, overwrite = false) - // check that shadowJar pulls from cache in the original directory - assertShadowJarHasResult(firstOutcome) - // check that shadowJar pulls from cache in a different directory - assertShadowJarHasResult(secondOutcome) { - if (alternateDir.listDirectoryEntries().isEmpty()) { - error("Directory was not copied to alternate directory") - } - it.withProjectDir(alternateDir.toFile()) - } - } - - fun assertShadowJarExecutes() { - try { - outputShadowJar.deleteExisting() - } catch (ignored: IllegalStateException) { - // ignore if the file does not exist - } - // task was executed and not pulled from cache - assertShadowJarHasResult(SUCCESS) - } - - private fun assertShadowJarHasResult( - expectedOutcome: TaskOutcome, - runnerBlock: (GradleRunner) -> GradleRunner = { it }, - ) { - val result = run("--build-cache", shadowJarTask, runnerBlock = runnerBlock) - assertThat(result.task(shadowJarTask)).isNotNull() - .transform { it.outcome }.isEqualTo(expectedOutcome) - } -} diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executor/SnippetExecutor.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executor/SnippetExecutor.kt deleted file mode 100644 index 09f87c315..000000000 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executor/SnippetExecutor.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.jengelman.gradle.plugins.shadow.doc.executor - -import com.github.jengelman.gradle.plugins.shadow.doc.fixture.SnippetFixture -import java.nio.file.Path - -interface SnippetExecutor { - val fixture: SnippetFixture - - fun execute(tempDir: Path, snippet: String) -} diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/fixture/SnippetFixture.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/fixture/SnippetFixture.kt deleted file mode 100644 index 8a20af065..000000000 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/fixture/SnippetFixture.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.github.jengelman.gradle.plugins.shadow.doc.fixture - -interface SnippetFixture { - val pre: String -} diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executable/CodeSnippetExecutable.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executable/CodeSnippetExecutable.kt similarity index 81% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executable/CodeSnippetExecutable.kt rename to src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executable/CodeSnippetExecutable.kt index 7a734b6b3..0eaf65ad6 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executable/CodeSnippetExecutable.kt +++ b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executable/CodeSnippetExecutable.kt @@ -1,6 +1,6 @@ -package com.github.jengelman.gradle.plugins.shadow.doc.executable +package com.github.jengelman.gradle.plugins.shadow.executable -import com.github.jengelman.gradle.plugins.shadow.doc.executor.SnippetExecutor +import com.github.jengelman.gradle.plugins.shadow.executor.SnippetExecutor import java.nio.file.Path import kotlin.io.path.createTempDirectory import org.junit.jupiter.api.function.Executable diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executable/CodeSnippetExtractor.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executable/CodeSnippetExtractor.kt similarity index 92% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executable/CodeSnippetExtractor.kt rename to src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executable/CodeSnippetExtractor.kt index 334cdee26..650fb9554 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executable/CodeSnippetExtractor.kt +++ b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executable/CodeSnippetExtractor.kt @@ -1,7 +1,7 @@ -package com.github.jengelman.gradle.plugins.shadow.doc.executable +package com.github.jengelman.gradle.plugins.shadow.executable -import com.github.jengelman.gradle.plugins.shadow.doc.DocCodeSnippetTest -import com.github.jengelman.gradle.plugins.shadow.doc.executor.SnippetExecutor +import com.github.jengelman.gradle.plugins.shadow.DocCodeSnippetTest +import com.github.jengelman.gradle.plugins.shadow.executor.SnippetExecutor import java.nio.file.Path import java.util.regex.Pattern import kotlin.io.path.ExperimentalPathApi diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executor/GroovyBuildExecutor.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executor/GroovyBuildExecutor.kt similarity index 92% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executor/GroovyBuildExecutor.kt rename to src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executor/GroovyBuildExecutor.kt index 556f93fb2..fbe45440d 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executor/GroovyBuildExecutor.kt +++ b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executor/GroovyBuildExecutor.kt @@ -1,6 +1,6 @@ -package com.github.jengelman.gradle.plugins.shadow.doc.executor +package com.github.jengelman.gradle.plugins.shadow.executor -import com.github.jengelman.gradle.plugins.shadow.doc.fixture.SnippetFixture +import com.github.jengelman.gradle.plugins.shadow.fixture.SnippetFixture import java.nio.file.Path import kotlin.io.path.createDirectory import kotlin.io.path.writeText diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executor/NoopExecutor.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executor/NoopExecutor.kt similarity index 61% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executor/NoopExecutor.kt rename to src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executor/NoopExecutor.kt index 3820b8aef..1123baddb 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/executor/NoopExecutor.kt +++ b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executor/NoopExecutor.kt @@ -1,6 +1,6 @@ -package com.github.jengelman.gradle.plugins.shadow.doc.executor +package com.github.jengelman.gradle.plugins.shadow.executor -import com.github.jengelman.gradle.plugins.shadow.doc.fixture.SnippetFixture +import com.github.jengelman.gradle.plugins.shadow.fixture.SnippetFixture import java.nio.file.Path object NoopExecutor : SnippetExecutor { diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executor/SnippetExecutor.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executor/SnippetExecutor.kt new file mode 100644 index 000000000..0b445e007 --- /dev/null +++ b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/executor/SnippetExecutor.kt @@ -0,0 +1,10 @@ +package com.github.jengelman.gradle.plugins.shadow.executor + +import com.github.jengelman.gradle.plugins.shadow.fixture.SnippetFixture +import java.nio.file.Path + +interface SnippetExecutor { + val fixture: SnippetFixture + + fun execute(tempDir: Path, snippet: String) +} diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/fixture/GroovyDslFixture.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/fixture/GroovyDslFixture.kt similarity index 90% rename from src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/fixture/GroovyDslFixture.kt rename to src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/fixture/GroovyDslFixture.kt index e7dacf74d..525dbce85 100644 --- a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/doc/fixture/GroovyDslFixture.kt +++ b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/fixture/GroovyDslFixture.kt @@ -1,4 +1,4 @@ -package com.github.jengelman.gradle.plugins.shadow.doc.fixture +package com.github.jengelman.gradle.plugins.shadow.fixture object GroovyDslFixture : SnippetFixture { diff --git a/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/fixture/SnippetFixture.kt b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/fixture/SnippetFixture.kt new file mode 100644 index 000000000..95a2ebf5d --- /dev/null +++ b/src/intiTest/kotlin/com/github/jengelman/gradle/plugins/shadow/fixture/SnippetFixture.kt @@ -0,0 +1,5 @@ +package com.github.jengelman.gradle.plugins.shadow.fixture + +interface SnippetFixture { + val pre: String +} diff --git a/src/intiTest/resources/junit-3.8.2.jar b/src/intiTest/resources/junit-3.8.2.jar deleted file mode 100644 index c8f711d05..000000000 Binary files a/src/intiTest/resources/junit-3.8.2.jar and /dev/null differ diff --git a/src/intiTest/resources/test-artifact-1.0-SNAPSHOT.jar b/src/intiTest/resources/test-artifact-1.0-SNAPSHOT.jar deleted file mode 100644 index 009abad49..000000000 Binary files a/src/intiTest/resources/test-artifact-1.0-SNAPSHOT.jar and /dev/null differ diff --git a/src/intiTest/resources/test-project-1.0-SNAPSHOT.jar b/src/intiTest/resources/test-project-1.0-SNAPSHOT.jar deleted file mode 100644 index f80e03f90..000000000 Binary files a/src/intiTest/resources/test-project-1.0-SNAPSHOT.jar and /dev/null differ diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.kt index cdc290c45..0e0fec3c7 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.kt @@ -63,10 +63,15 @@ public abstract class ShadowApplicationPlugin : Plugin { protected open fun addCreateScriptsTask() { project.tasks.register(SHADOW_SCRIPTS_TASK_NAME, CreateStartScripts::class.java) { + val unixStartScript = + requireResourceAsText("com/github/jengelman/gradle/plugins/shadow/internal/unixStartScript.txt") + val windowsStartScript = + requireResourceAsText("com/github/jengelman/gradle/plugins/shadow/internal/windowsStartScript.txt") + (it.unixStartScriptGenerator as TemplateBasedScriptGenerator).template = - project.resources.text.fromString(this::class.java.requireResourceAsText("internal/unixStartScript.txt")) + project.resources.text.fromString(unixStartScript) (it.windowsStartScriptGenerator as TemplateBasedScriptGenerator).template = - project.resources.text.fromString(this::class.java.requireResourceAsText("internal/windowsStartScript.txt")) + project.resources.text.fromString(windowsStartScript) it.description = "Creates OS specific scripts to run the project as a JVM application using the shadow jar" it.group = ApplicationPlugin.APPLICATION_GROUP it.classpath = project.files(shadowJar) diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/Utils.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/Utils.kt index daac5eae8..97557c31c 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/Utils.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/Utils.kt @@ -3,9 +3,9 @@ package com.github.jengelman.gradle.plugins.shadow.internal import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.File -import java.io.FileNotFoundException import java.io.InputStream import java.nio.charset.Charset +import java.nio.file.NoSuchFileException import java.util.Properties import org.gradle.api.file.RelativePath import org.gradle.api.internal.file.DefaultFileTreeElement @@ -37,12 +37,13 @@ internal fun Properties.inputStream( return os.toByteArray().inputStream() } -internal fun Class<*>.requireResourceAsText(name: String): String { - return requireResourceAsStream(name).bufferedReader().readText() +internal fun requireResourceAsText(name: String): String { + return requireResourceAsStream(name).bufferedReader().use { it.readText() } } -private fun Class<*>.requireResourceAsStream(name: String): InputStream { - return getResourceAsStream(name) ?: throw FileNotFoundException("Resource $name not found.") +internal fun requireResourceAsStream(name: String): InputStream { + return Utils::class.java.classLoader.getResourceAsStream(name) + ?: throw NoSuchFileException("Resource $name not found.") } private val DummyFile = File("dummy") @@ -51,3 +52,5 @@ private val DummyStat = object : Stat { override fun getUnixMode(f: File): Int = error("This is a dummy implementation.") override fun stat(f: File): FileMetadata = error("This is a dummy implementation.") } + +private object Utils diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/KnowsTask.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/KnowsTask.kt index fdffe3788..1c5314bba 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/KnowsTask.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/KnowsTask.kt @@ -12,7 +12,7 @@ public abstract class KnowsTask : DefaultTask() { """ No, The Shadow Knows.... - ${this::class.java.requireResourceAsText("/shadowBanner.txt")} + ${requireResourceAsText("shadowBanner.txt")} """.trimIndent(), ) } diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt index 77fe69a6c..2ef97d17a 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt @@ -61,6 +61,7 @@ public abstract class ShadowJar : manifest = DefaultInheritManifest(services.get(FileResolver::class.java)) outputs.doNotCacheIf("Has one or more transforms or relocators that are not cacheable") { + // TODO: this has been called but the cache is still working fine, need to investigate why. transformers.get().any { !isCacheableTransform(it::class.java) } || relocators.get().any { !isCacheableRelocator(it::class.java) } } diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformer.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformer.kt index 029d2e5b8..182d12f33 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformer.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformer.kt @@ -53,6 +53,7 @@ public open class AppendingTransformer @Inject constructor( entry.time = TransformerContext.getEntryTimestamp(preserveFileTimestamps, entry.time) os.putNextEntry(entry) + // Closing a ByteArrayOutputStream has no effect, so we don't use a use block here. data.toByteArray().inputStream().copyTo(os) data.reset() } diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.kt index 2950715ae..27560fd88 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.kt @@ -169,7 +169,7 @@ public open class PropertiesFileTransformer @Inject constructor( private fun loadAndTransformKeys(inputStream: InputStream): CleanProperties { val props = CleanProperties() // InputStream closed by caller, so we don't do it here. - props.load(inputStream.reader(charset)) + props.load(inputStream.bufferedReader(charset)) return transformKeys(props) } @@ -225,7 +225,7 @@ public open class PropertiesFileTransformer @Inject constructor( val entry = ZipEntry(path) entry.time = TransformerContext.getEntryTimestamp(preserveFileTimestamps, entry.time) os.putNextEntry(entry) - props.inputStream(charset).reader(charset).use { + props.inputStream(charset).bufferedReader(charset).use { it.copyTo(zipWriter) } zipWriter.flush() diff --git a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/BaseTransformerTest.kt b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/BaseTransformerTest.kt index 18b0c4dbc..6e94fcf97 100644 --- a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/BaseTransformerTest.kt +++ b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/BaseTransformerTest.kt @@ -2,10 +2,9 @@ package com.github.jengelman.gradle.plugins.shadow.transformers import com.github.jengelman.gradle.plugins.shadow.ShadowStats import com.github.jengelman.gradle.plugins.shadow.internal.createDefaultFileTreeElement +import com.github.jengelman.gradle.plugins.shadow.internal.requireResourceAsStream import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer.Companion.create import com.github.jengelman.gradle.plugins.shadow.util.testObjectFactory -import java.io.FileNotFoundException -import java.io.InputStream import java.lang.reflect.ParameterizedType import java.nio.file.Path import java.util.Locale @@ -23,10 +22,6 @@ abstract class BaseTransformerTest { protected val manifestTransformerContext: TransformerContext get() = TransformerContext(MANIFEST_NAME, requireResourceAsStream(MANIFEST_NAME)) - protected fun requireResourceAsStream(name: String): InputStream { - return this::class.java.classLoader.getResourceAsStream(name) ?: throw FileNotFoundException("Resource $name not found.") - } - @BeforeEach fun setup() { @Suppress("UNCHECKED_CAST") @@ -66,6 +61,7 @@ abstract class BaseTransformerTest { * choice to test for improper case-less string comparisons. */ fun setupTurkishLocale() { + @Suppress("DEPRECATION") Locale.setDefault(Locale("tr")) } } diff --git a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformerTest.kt b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformerTest.kt index 43640d449..73b68d961 100644 --- a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformerTest.kt +++ b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformerTest.kt @@ -2,6 +2,7 @@ package com.github.jengelman.gradle.plugins.shadow.transformers import assertk.assertThat import assertk.assertions.isTrue +import com.github.jengelman.gradle.plugins.shadow.internal.requireResourceAsStream import org.custommonkey.xmlunit.XMLUnit import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformerTest.kt b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformerTest.kt index f411b33a4..945b9bc8d 100644 --- a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformerTest.kt +++ b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformerTest.kt @@ -3,10 +3,11 @@ package com.github.jengelman.gradle.plugins.shadow.transformers import assertk.assertThat import assertk.assertions.isEqualTo import assertk.assertions.isTrue +import com.github.jengelman.gradle.plugins.shadow.internal.requireResourceAsStream import com.github.jengelman.gradle.plugins.shadow.relocation.SimpleRelocator import com.github.jengelman.gradle.plugins.shadow.util.SimpleRelocator import java.io.File -import java.net.URL +import java.net.URI import java.util.Collections import org.apache.logging.log4j.core.config.plugins.processor.PluginCache import org.apache.tools.zip.ZipOutputStream @@ -39,8 +40,9 @@ class Log4j2PluginsCacheFileTransformerTest : BaseTransformerTest() { diff --git a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt index 55bec8828..debd4001e 100644 --- a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt +++ b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt @@ -28,8 +28,8 @@ class ServiceFileTransformerTest : BaseTransformerTest() } assertThat(transformer.hasTransformedResource()).isTrue() - assertThat(transformer.serviceEntries.getValue(path).toInputStream().bufferedReader().readText()) - .isEqualTo(output) + val entry = transformer.serviceEntries.getValue(path).toInputStream().bufferedReader().use { it.readText() } + assertThat(entry).isEqualTo(output) } @Test