diff --git a/gradle-module-plugin/build.gradle.kts b/gradle-module-plugin/build.gradle.kts index d0ba81e..31f0908 100644 --- a/gradle-module-plugin/build.gradle.kts +++ b/gradle-module-plugin/build.gradle.kts @@ -20,7 +20,7 @@ repositories { } group = "io.ia.sdk" -version = "0.4.1" +version = "0.5.0" configurations { val functionalTestImplementation by registering { diff --git a/gradle-module-plugin/src/functionalTest/kotlin/io/ia/sdk/gradle/modl/task/ZipModuleTests.kt b/gradle-module-plugin/src/functionalTest/kotlin/io/ia/sdk/gradle/modl/task/ZipModuleTests.kt index 7f180dd..57d0424 100644 --- a/gradle-module-plugin/src/functionalTest/kotlin/io/ia/sdk/gradle/modl/task/ZipModuleTests.kt +++ b/gradle-module-plugin/src/functionalTest/kotlin/io/ia/sdk/gradle/modl/task/ZipModuleTests.kt @@ -3,11 +3,67 @@ package io.ia.sdk.gradle.modl.task import io.ia.ignition.module.generator.ModuleGenerator import io.ia.sdk.gradle.modl.BaseTest import io.ia.sdk.gradle.modl.util.unsignedModuleName -import org.junit.Test +import org.gradle.api.Project +import org.gradle.api.internal.project.DefaultProject +import org.gradle.testfixtures.ProjectBuilder +import java.io.File +import kotlin.io.path.createTempDirectory +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertFailsWith import kotlin.test.assertTrue class ZipModuleTests : BaseTest() { + private lateinit var tempDir: File + private lateinit var project: Project + private lateinit var task: ZipModule + + @BeforeTest + fun setup() { + tempDir = createTempDirectory().toFile() + project = ProjectBuilder.builder().withProjectDir(tempDir).build() as DefaultProject + task = project.tasks.create("testTask", ZipModule::class.java) + + // Set up the task properties with the temp directory + task.content.set(project.objects.directoryProperty().fileValue(File(tempDir, "content"))) + task.unsignedModule.set(project.objects.fileProperty().fileValue(File(tempDir, "output.modl"))) + } + + @AfterTest + fun cleanup() { + tempDir.deleteRecursively() + } + + @Test + fun `task succeeds when no duplicate jars exist`() { + // Arrange + val contentDir = task.content.asFile.get().apply { mkdirs() } + File(contentDir, "my-lib-1.0.jar").createNewFile() + File(contentDir, "another-lib-2.0.jar").createNewFile() + + // Act: The task should not throw an exception + task.execute() + } + + @Test + fun `task fails when duplicate jars with different versions exist`() { + // Arrange + val contentDir = task.content.asFile.get().apply { mkdirs() } + File(contentDir, "my-lib-1.0.jar").createNewFile() + File(contentDir, "my-lib-2.0.jar").createNewFile() // This is the duplicate + + // Act & Assert: The task should throw a IllegalArgumentException + val exception = assertFailsWith { + task.execute() + } + + // Verify the exception message + val expectedMessage = "Library 'my-lib' exists in multiple versions" + assertTrue(exception.message!!.contains(expectedMessage)) + } + @Test fun `unsigned module is built and has appropriate name`() { val name = "Some Thing" diff --git a/gradle-module-plugin/src/main/kotlin/io/ia/sdk/gradle/modl/task/ZipModule.kt b/gradle-module-plugin/src/main/kotlin/io/ia/sdk/gradle/modl/task/ZipModule.kt index 26e9c92..a395276 100644 --- a/gradle-module-plugin/src/main/kotlin/io/ia/sdk/gradle/modl/task/ZipModule.kt +++ b/gradle-module-plugin/src/main/kotlin/io/ia/sdk/gradle/modl/task/ZipModule.kt @@ -13,6 +13,7 @@ import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction +import java.io.File import javax.inject.Inject /** @@ -46,10 +47,39 @@ open class ZipModule @Inject constructor(objects: ObjectFactory) : DefaultTask() val unsignedFile = unsignedModule.get() val contentDir = content.get().asFile + checkDuplicateJars(contentDir) + project.logger.info("Zipping '${contentDir.absolutePath}' into ' ${unsignedFile.asFile.absolutePath}'") project.ant.invokeMethod( "zip", mapOf("basedir" to contentDir, "destfile" to unsignedFile) ) } + + /** + * Fail the build when jars in the contentDir with the same name has + * multiple versions detected. + **/ + fun checkDuplicateJars(contentDir: File) { + project.logger.info("Parsing file name in: ${contentDir.absolutePath}") + + val fileSet = mutableSetOf() + val regex = "^(.+?)-(?:\\d+.*)(?:\\.jar)".toRegex() + + contentDir.walk().filter { it.isFile }.forEach { file -> + val matchResult = regex.find(file.name) // Match all the jar files + + if (matchResult != null) { + val name = matchResult.groupValues[1] + + if (fileSet.contains(name)) { + throw IllegalArgumentException( + "Library '$name' exists in multiple versions in ${contentDir.absolutePath}" + ) + } else { + fileSet.add(name) + } + } + } + } }