diff --git a/build.gradle.kts b/build.gradle.kts index bf84d0158..d28ae0509 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -48,7 +48,7 @@ val testKitImplementation: Configuration by configurations.getting val intiTest: SourceSet by sourceSets.creating val intiTestImplementation: Configuration by configurations.getting { - extendsFrom(configurations.testImplementation.get()) + extendsFrom(testKitImplementation, configurations.testImplementation.get()) } val intiTestRuntimeOnly: Configuration by configurations.getting { extendsFrom(configurations.testRuntimeOnly.get()) @@ -56,7 +56,7 @@ val intiTestRuntimeOnly: Configuration by configurations.getting { val funcTest: SourceSet by sourceSets.creating val funcTestImplementation: Configuration by configurations.getting { - extendsFrom(configurations.testImplementation.get()) + extendsFrom(testKitImplementation, configurations.testImplementation.get()) } val funcTestRuntimeOnly: Configuration by configurations.getting { extendsFrom(configurations.testRuntimeOnly.get()) @@ -80,6 +80,8 @@ dependencies { val mainOutput = sourceSets.main.map { it.output } testKitImplementation(mainOutput) testKitImplementation(gradleTestKit()) + testKitImplementation(libs.apache.maven) + testKitImplementation(libs.assertk) testImplementation(testKit.output) testImplementation(platform(libs.junit.bom)) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4228ce9d8..487ea9295 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,6 +3,7 @@ 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.2" +apache-maven = "org.apache.maven:maven-repository-metadata: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" diff --git a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformerSpec.groovy b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformerSpec.groovy index 6fc067a6b..c479cbb0d 100644 --- a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformerSpec.groovy +++ b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformerSpec.groovy @@ -22,7 +22,7 @@ package com.github.jengelman.gradle.plugins.shadow.transformers import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer.MergeStrategy import spock.lang.Unroll -import static com.github.jengelman.gradle.plugins.shadow.testkit.util.Utils.testObjectFactory +import static com.github.jengelman.gradle.plugins.shadow.testkit.Utils.testObjectFactory import static groovy.lang.Closure.IDENTITY @Unroll diff --git a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/AppendableJar.groovy b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/AppendableJar.groovy deleted file mode 100644 index b6fad7012..000000000 --- a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/AppendableJar.groovy +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.jengelman.gradle.plugins.shadow.util - -class AppendableJar { - - Map contents = [:] - File file - - AppendableJar(File file) { - this.file = file - } - - AppendableJar insertFile(String path, String content) { - contents[path] = content - return this - } - - File write() { - JarBuilder builder = new JarBuilder(file.newOutputStream()) - contents.each { path, contents -> - builder.withFile(path, contents) - } - builder.build() - return file - } -} diff --git a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenFileModule.groovy b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenFileModule.groovy index 689f84994..1e4689347 100644 --- a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenFileModule.groovy +++ b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenFileModule.groovy @@ -1,6 +1,7 @@ package com.github.jengelman.gradle.plugins.shadow.util import com.github.jengelman.gradle.plugins.shadow.util.repo.maven.MavenFileModule +import com.github.jengelman.gradle.plugins.shadow.testkit.JarBuilder import groovy.transform.InheritConstructors import org.apache.commons.io.IOUtils diff --git a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashUtil.java b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashUtil.java deleted file mode 100644 index b4cb8404d..000000000 --- a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashUtil.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.github.jengelman.gradle.plugins.shadow.util; - -import org.gradle.api.UncheckedIOException; -import org.gradle.internal.UncheckedException; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -public class HashUtil { - public static HashValue createHash(File file, String algorithm) { - try { - return createHash(new FileInputStream(file), algorithm); - } catch (UncheckedIOException e) { - // Catch any unchecked io exceptions and add the file path for troubleshooting - throw new UncheckedIOException(String.format("Failed to create %s hash for file %s.", algorithm, file.getAbsolutePath()), e.getCause()); - } catch (FileNotFoundException e) { - throw new UncheckedIOException(e); - } - } - - private static HashValue createHash(InputStream instr, String algorithm) { - MessageDigest messageDigest; - try { - messageDigest = createMessageDigest(algorithm); - byte[] buffer = new byte[4096]; - try { - while (true) { - int nread = instr.read(buffer); - if (nread < 0) { - break; - } - messageDigest.update(buffer, 0, nread); - } - } finally { - instr.close(); - } - } catch (IOException e) { - throw new UncheckedIOException(e); - } - return new HashValue(messageDigest.digest()); - } - - private static MessageDigest createMessageDigest(String algorithm) { - try { - return MessageDigest.getInstance(algorithm); - } catch (NoSuchAlgorithmException e) { - throw UncheckedException.throwAsUncheckedException(e); - } - } - - public static HashValue sha1(byte[] bytes) { - return createHash(new ByteArrayInputStream(bytes), "SHA1"); - } - - public static HashValue sha1(InputStream inputStream) { - return createHash(inputStream, "SHA1"); - } - - public static HashValue md5(File file) { - return createHash(file, "MD5"); - } - - public static HashValue sha1(File file) { - return createHash(file, "SHA1"); - } - - public static HashValue sha256(byte[] bytes) { - return createHash(new ByteArrayInputStream(bytes), "SHA-256"); - } - - public static HashValue sha256(InputStream inputStream) { - return createHash(inputStream, "SHA-256"); - } - - public static HashValue sha256(File file) { - return createHash(file, "SHA-256"); - } - - public static HashValue sha512(InputStream inputStream) { - return createHash(inputStream, "SHA-512"); - } - - public static HashValue sha512(File file) { - return createHash(file, "SHA-512"); - } -} - diff --git a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashValue.java b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashValue.java deleted file mode 100644 index 967afe7ea..000000000 --- a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/HashValue.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.github.jengelman.gradle.plugins.shadow.util; - -import java.math.BigInteger; - -public class HashValue { - private final BigInteger digest; - - public HashValue(byte[] digest) { - this.digest = new BigInteger(1, digest); - } - - public HashValue(String hexString) { - this.digest = new BigInteger(hexString, 16); - } - - public static HashValue parse(String inputString) { - if (inputString == null || inputString.isEmpty()) { - return null; - } - return new HashValue(parseInput(inputString)); - } - - private static String parseInput(String inputString) { - if (inputString == null) { - return null; - } - String cleaned = inputString.trim().toLowerCase(); - int spaceIndex = cleaned.indexOf(' '); - if (spaceIndex != -1) { - String firstPart = cleaned.substring(0, spaceIndex); - if (firstPart.startsWith("md") || firstPart.startsWith("sha")) { - cleaned = cleaned.substring(cleaned.lastIndexOf(' ') + 1); - } else if (firstPart.endsWith(":")) { - cleaned = cleaned.substring(spaceIndex + 1).replace(" ", ""); - } else { - cleaned = cleaned.substring(0, spaceIndex); - } - } - return cleaned; - } - - public String asCompactString() { - return digest.toString(36); - } - - public String asHexString() { - return digest.toString(16); - } - - public byte[] asByteArray() { - return digest.toByteArray(); - } - - public BigInteger asBigInteger() { - return digest; - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (!(other instanceof HashValue)) { - return false; - } - - HashValue otherHashValue = (HashValue) other; - return digest.equals(otherHashValue.digest); - } - - @Override - public int hashCode() { - return digest.hashCode(); - } -} diff --git a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/JarBuilder.groovy b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/JarBuilder.groovy deleted file mode 100644 index b24eb994c..000000000 --- a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/JarBuilder.groovy +++ /dev/null @@ -1,51 +0,0 @@ -package com.github.jengelman.gradle.plugins.shadow.util - -import org.codehaus.plexus.util.IOUtil - -import java.util.jar.JarEntry -import java.util.jar.JarOutputStream - -class JarBuilder { - - List entries = [] - JarOutputStream jos - - JarBuilder(OutputStream os) { - jos = new JarOutputStream(os) - } - - private void addDirectory(String name) { - if (!entries.contains(name)) { - if (name.lastIndexOf('/') > 0) { - String parent = name.substring(0, name.lastIndexOf('/')) - if (!entries.contains(parent)) { - addDirectory(parent) - } - } - - // directory entries must end in "/" - JarEntry entry = new JarEntry(name + "/") - jos.putNextEntry(entry) - - entries.add(name) - } - } - - JarBuilder withFile(String path, String data) { - def idx = path.lastIndexOf('/') - if (idx != -1) { - addDirectory(path.substring(0, idx)) - } - if (!entries.contains(path)) { - JarEntry entry = new JarEntry(path) - jos.putNextEntry(entry) - entries << path - IOUtil.copy(data.bytes, jos) - } - return this - } - - void build() { - jos.close() - } -} diff --git a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy index 23b88c502..e77963cb2 100644 --- a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy +++ b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy @@ -1,5 +1,6 @@ package com.github.jengelman.gradle.plugins.shadow.util +import com.github.jengelman.gradle.plugins.shadow.testkit.AppendableJar import org.codehaus.plexus.util.IOUtil import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.GradleRunner diff --git a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/AbstractModule.groovy b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/AbstractModule.groovy index 7e5b983d0..1f7df9537 100644 --- a/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/AbstractModule.groovy +++ b/src/funcTest/groovy/com/github/jengelman/gradle/plugins/shadow/util/repo/AbstractModule.groovy @@ -1,6 +1,6 @@ package com.github.jengelman.gradle.plugins.shadow.util.repo -import com.github.jengelman.gradle.plugins.shadow.util.HashUtil +import com.github.jengelman.gradle.plugins.shadow.testkit.HashUtil abstract class AbstractModule { /** diff --git a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformerTest.kt b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformerTest.kt index f8cf651ff..014da0387 100644 --- a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformerTest.kt +++ b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ApacheNoticeResourceTransformerTest.kt @@ -4,7 +4,7 @@ import assertk.assertThat import assertk.assertions.isFalse import assertk.assertions.isTrue import assertk.fail -import com.github.jengelman.gradle.plugins.shadow.testkit.util.testObjectFactory +import com.github.jengelman.gradle.plugins.shadow.testkit.testObjectFactory import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformerTest.kt b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformerTest.kt index 681000705..3edfc2743 100644 --- a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformerTest.kt +++ b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformerTest.kt @@ -3,7 +3,7 @@ package com.github.jengelman.gradle.plugins.shadow.transformers import assertk.assertThat import assertk.assertions.isFalse import assertk.assertions.isTrue -import com.github.jengelman.gradle.plugins.shadow.testkit.util.testObjectFactory +import com.github.jengelman.gradle.plugins.shadow.testkit.testObjectFactory import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ManifestAppenderTransformerTest.kt b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ManifestAppenderTransformerTest.kt index 935c98da6..ab575c063 100644 --- a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ManifestAppenderTransformerTest.kt +++ b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ManifestAppenderTransformerTest.kt @@ -6,7 +6,7 @@ import assertk.assertions.isFalse import assertk.assertions.isGreaterThan import assertk.assertions.isNotEmpty import assertk.assertions.isTrue -import com.github.jengelman.gradle.plugins.shadow.testkit.util.testObjectFactory +import com.github.jengelman.gradle.plugins.shadow.testkit.testObjectFactory import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformerTest.kt b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformerTest.kt index 81e084d43..78100bb5a 100644 --- a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformerTest.kt +++ b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformerTest.kt @@ -6,7 +6,7 @@ import assertk.assertions.isEqualTo import assertk.assertions.isFalse import assertk.assertions.isNotEmpty import assertk.assertions.isTrue -import com.github.jengelman.gradle.plugins.shadow.testkit.util.testObjectFactory +import com.github.jengelman.gradle.plugins.shadow.testkit.testObjectFactory import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/XmlAppendingTransformerTest.kt b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/XmlAppendingTransformerTest.kt index 32895d9fc..22cd28e74 100644 --- a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/XmlAppendingTransformerTest.kt +++ b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/XmlAppendingTransformerTest.kt @@ -3,7 +3,7 @@ package com.github.jengelman.gradle.plugins.shadow.transformers import assertk.assertThat import assertk.assertions.isFalse import assertk.assertions.isTrue -import com.github.jengelman.gradle.plugins.shadow.testkit.util.testObjectFactory +import com.github.jengelman.gradle.plugins.shadow.testkit.testObjectFactory import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test diff --git a/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/AppendableJar.kt b/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/AppendableJar.kt new file mode 100644 index 000000000..c6cdc9ab8 --- /dev/null +++ b/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/AppendableJar.kt @@ -0,0 +1,20 @@ +package com.github.jengelman.gradle.plugins.shadow.testkit + +import java.io.File + +class AppendableJar(private val file: File) { + private val contents = mutableMapOf() + + fun insertFile(path: String, content: String): AppendableJar = apply { + contents[path] = content + } + + fun write(): File { + val builder = JarBuilder(file.outputStream()) + contents.forEach { (path, content) -> + builder.withFile(path, content) + } + builder.build() + return file + } +} diff --git a/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/HashUtil.kt b/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/HashUtil.kt new file mode 100644 index 000000000..2476bc086 --- /dev/null +++ b/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/HashUtil.kt @@ -0,0 +1,56 @@ +package com.github.jengelman.gradle.plugins.shadow.testkit + +import java.io.File +import java.io.FileInputStream +import java.io.FileNotFoundException +import java.io.IOException +import java.io.InputStream +import java.security.MessageDigest +import java.security.NoSuchAlgorithmException +import org.gradle.api.UncheckedIOException +import org.gradle.internal.UncheckedException + +object HashUtil { + @JvmStatic + fun createHash(file: File, algorithm: String): HashValue { + try { + return createHash(FileInputStream(file), algorithm) + } catch (e: UncheckedIOException) { + // Catch any unchecked io exceptions and add the file path for troubleshooting + throw UncheckedIOException( + String.format("Failed to create %s hash for file %s.", algorithm, file.absolutePath), + e.cause!!, + ) + } catch (e: FileNotFoundException) { + throw UncheckedIOException(e) + } + } + + private fun createHash(inputStream: InputStream, algorithm: String): HashValue { + val messageDigest: MessageDigest + try { + messageDigest = createMessageDigest(algorithm) + val buffer = ByteArray(4096) + inputStream.use { + while (true) { + val nread = it.read(buffer) + if (nread < 0) { + break + } + messageDigest.update(buffer, 0, nread) + } + } + } catch (e: IOException) { + throw UncheckedIOException(e) + } + return HashValue(messageDigest.digest()) + } + + private fun createMessageDigest(algorithm: String): MessageDigest { + try { + return MessageDigest.getInstance(algorithm) + } catch (e: NoSuchAlgorithmException) { + throw UncheckedException.throwAsUncheckedException(e) + } + } +} diff --git a/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/HashValue.kt b/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/HashValue.kt new file mode 100644 index 000000000..38b3620b4 --- /dev/null +++ b/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/HashValue.kt @@ -0,0 +1,26 @@ +package com.github.jengelman.gradle.plugins.shadow.testkit + +import java.math.BigInteger + +class HashValue(digest: ByteArray) { + private val digest = BigInteger(1, digest) + + fun asBigInteger(): BigInteger { + return digest + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + if (other !is HashValue) { + return false + } + + return digest == other.digest + } + + override fun hashCode(): Int { + return digest.hashCode() + } +} diff --git a/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/JarBuilder.kt b/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/JarBuilder.kt new file mode 100644 index 000000000..1f1f61b86 --- /dev/null +++ b/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/JarBuilder.kt @@ -0,0 +1,42 @@ +package com.github.jengelman.gradle.plugins.shadow.testkit + +import java.io.OutputStream +import java.util.jar.JarEntry +import java.util.jar.JarOutputStream + +class JarBuilder(os: OutputStream) { + private val entries = mutableListOf() + private val jos = JarOutputStream(os) + + private fun addDirectory(name: String) { + if (!entries.contains(name)) { + val parent = name.substringBeforeLast('/', "") + if (parent.isNotEmpty() && !entries.contains(parent)) { + addDirectory(parent) + } + + // directory entries must end in "/" + val entry = JarEntry("$name/") + jos.putNextEntry(entry) + entries.add(name) + } + } + + fun withFile(path: String, data: String): JarBuilder { + val idx = path.lastIndexOf('/') + if (idx != -1) { + addDirectory(path.substring(0, idx)) + } + if (!entries.contains(path)) { + val entry = JarEntry(path) + jos.putNextEntry(entry) + entries.add(path) + data.toByteArray().inputStream().use { it.copyTo(jos) } + } + return this + } + + fun build() { + jos.close() + } +} diff --git a/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/util/Utils.kt b/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/Utils.kt similarity index 75% rename from src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/util/Utils.kt rename to src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/Utils.kt index 0785681b0..8fbd60b9d 100644 --- a/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/util/Utils.kt +++ b/src/testKit/kotlin/com/github/jengelman/gradle/plugins/shadow/testkit/Utils.kt @@ -1,6 +1,6 @@ @file:JvmName("Utils") -package com.github.jengelman.gradle.plugins.shadow.testkit.util +package com.github.jengelman.gradle.plugins.shadow.testkit import org.gradle.api.model.ObjectFactory import org.gradle.testfixtures.ProjectBuilder