diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d56b250 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Ignore Gradle project-specific cache directory +.gradle/ + +# Ignore Gradle build output directory +build/ diff --git a/README.md b/README.md index 24c01a8..d4f7c35 100644 --- a/README.md +++ b/README.md @@ -70,8 +70,8 @@ Gradle automatically applies [init scripts](https://docs.gradle.org/current/user 3. Specify target settings in the `gradleDist {}` block. **mandatory settings:** * `gradleVersion` - base Gradle wrapper version - * `customDistributionVersion` - custom distribution version - * `customDistributionFileNameMapper` - a property of type [CustomDistributionNameMapper](./src/main/kotlin/tech/harmonysoft/oss/gradle/dist/config/CustomDistributionNameMapper.kt) which generates resulting custom distribution file name for the given parameters. *Note: it's necessary to specify this property or 'distributionNameMapper' property. It's an error to define the both/none of them* + * `customDistributionVersion` - custom distribution version (`project.version` is used by default) + * `customDistributionFileNameMapper` - a property of type [CustomDistributionNameMapper](./src/main/kotlin/tech/harmonysoft/oss/gradle/dist/config/CustomDistributionNameMapper.kt) which generates resulting custom distribution file name for the given parameters. *Note: it's necessary to specify this property or `distributionNameMapper` property. It's an error to define the both/none of them* * `gradleVersion` - base gradle distribution version as defined above * `customDistributionVersion` - custom distribution mixing version as defined above * `gradleDistributionType` - gradle distribution type as defined below @@ -118,10 +118,13 @@ Gradle automatically applies [init scripts](https://docs.gradle.org/current/user } } ``` - *Note: it's necessary to specify this property or 'customDistributionFileNameMapper' property. It's an error to define the both/none of them* + *Note: it's necessary to specify this property or `customDistributionFileNameMapper` property. It's an error to define the both/none of them* + + * `initScriptsSourceDir` - a path to the directory where your initialization scripts are located (see below docs for more details). The path to the directory must be set, and the pointed directory must exist. The default path is `src/main/resources/init.d`. **optional settings:** - * `gradleDistributionType` - allows to specify base Gradle distribution type. `bin` and `all` [are available](https://docs.gradle.org/current/userguide/gradle_wrapper.html#sec:adding_wrapper) at the moment, `bin` is used by default + * `gradleDistributionType` - allows to specify base Gradle distribution type. `bin` and `all` [are available](https://docs.gradle.org/current/userguide/gradle_wrapper.html#sec:adding_wrapper) at the moment, `bin` is used by default + * `utilityScriptsSourceDir` - a path to the directory where your utility scripts and replacements are located (see below docs for more details). The path to the directory is optional, but the pointed directory must exist. The default path is `src/main/resources/include`. * `skipContentExpansionFor` - the plugin by default expands content of the files included into custom Gradle distribution by default (see below). That might cause a problem if we want to add some binary file like `*.jar` or `*.so`. This property holds a list of root paths relative to `init.d` which content shouldn't be expanded. Example: consider the following project structure: ``` @@ -270,6 +273,16 @@ Gradle automatically applies [init scripts](https://docs.gradle.org/current/user The distribution(s) are located in the `build/gradle-dist` +6. In addition, if you need, you can configure the properties of the `buildGradleDist` task, such as the path to the directory where downloaded Gradle distributions and built custom Gradle distributions should be located. You can do this as follows: + ```groovy + import tech.harmonysoft.oss.gradle.dist.BuildCustomGradleDistributionTask + + tasks.named('buildGradleDist', BuildCustomGradleDistributionTask) { + gradleDownloadDir = project.layout.buildDirectory.dir('own-gradle-download') + customDistributionOutputDir = project.layout.buildDirectory.dir('own-gradle-dist') + } + ``` + ### Configure Client Project Just define your custom Gradle wrapper's location in the *gradle/wrapper/gradle-wrapper.properties* file: diff --git a/sample/multiple-custom-gradle-distributions/README.md b/sample/multiple-custom-gradle-distributions/README.md index 0995886..ba72c69 100644 --- a/sample/multiple-custom-gradle-distributions/README.md +++ b/sample/multiple-custom-gradle-distributions/README.md @@ -17,10 +17,10 @@ Note: a cool feature of init scripts is that we can apply Gradle plugins from th ## In Action 1. Build custom distribution - `pushd custom-distribution; ./gradlew build; popd` + `pushd custom-distribution; ./gradlew buildGradleDist; popd` 2. Run the client project `pushd client-project; ./gradlew bootRun; popd` -3. Call a web server server started by the client project and ensure that it works +3. Call a web server started by the client project and ensure that it works ``` curl 127.0.0.1:8080/ping Hi there! diff --git a/sample/multiple-custom-gradle-distributions/client-project/gradle/wrapper/gradle-wrapper.properties b/sample/multiple-custom-gradle-distributions/client-project/gradle/wrapper/gradle-wrapper.properties index bd74a91..695368c 100644 --- a/sample/multiple-custom-gradle-distributions/client-project/gradle/wrapper/gradle-wrapper.properties +++ b/sample/multiple-custom-gradle-distributions/client-project/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=../../../custom-distribution/build/gradle-dist/gradle-8.4-test-multi-distributions-1.0-service.zip +distributionUrl=../../../custom-distribution/build/gradle-dist/gradle-8.4-test-multi-distributions-1.0-service-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/sample/multiple-custom-gradle-distributions/custom-distribution/build.gradle b/sample/multiple-custom-gradle-distributions/custom-distribution/build.gradle index cf4f37d..86fe5a7 100644 --- a/sample/multiple-custom-gradle-distributions/custom-distribution/build.gradle +++ b/sample/multiple-custom-gradle-distributions/custom-distribution/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'tech.harmonysoft.oss.custom-gradle-dist-plugin' version '1.9' + id 'tech.harmonysoft.oss.custom-gradle-dist-plugin' version '1.17' } gradleDist { diff --git a/sample/multiple-custom-gradle-distributions/custom-distribution/settings.gradle b/sample/multiple-custom-gradle-distributions/custom-distribution/settings.gradle index 928d27c..3742067 100644 --- a/sample/multiple-custom-gradle-distributions/custom-distribution/settings.gradle +++ b/sample/multiple-custom-gradle-distributions/custom-distribution/settings.gradle @@ -1 +1,9 @@ +pluginManagement { + includeBuild('../../../') { + logger.warn( + 'Replaced indicated version of the Plugin with the current implementation from the root project directory.' + ) + } +} + rootProject.name = 'multiple-custom-gradle-distributions' \ No newline at end of file diff --git a/sample/single-custom-gradle-distribution/README.md b/sample/single-custom-gradle-distribution/README.md index a8d32f6..2ceba3d 100644 --- a/sample/single-custom-gradle-distribution/README.md +++ b/sample/single-custom-gradle-distribution/README.md @@ -15,10 +15,10 @@ This is an example of using custom Gradle distribution for projects with the sam ## In Action 1. Build custom distribution - `pushd custom-distribution; ./gradlew build; popd` + `pushd custom-distribution; ./gradlew buildGradleDist; popd` 2. Run the client project `pushd client-project; ./gradlew bootRun; popd` -3. Call a web server server started by the client project and ensure that it works +3. Call a web server started by the client project and ensure that it works ``` curl 127.0.0.1:8080/ping Hi there! diff --git a/sample/single-custom-gradle-distribution/client-project/gradle/wrapper/gradle-wrapper.properties b/sample/single-custom-gradle-distribution/client-project/gradle/wrapper/gradle-wrapper.properties index 8b35a07..63fe364 100644 --- a/sample/single-custom-gradle-distribution/client-project/gradle/wrapper/gradle-wrapper.properties +++ b/sample/single-custom-gradle-distribution/client-project/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=../../../custom-distribution/build/gradle-dist/gradle-8.4-test-single-distribution-1.0.zip +distributionUrl=../../../custom-distribution/build/gradle-dist/gradle-8.4-test-single-distribution-1.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/sample/single-custom-gradle-distribution/custom-distribution/build.gradle b/sample/single-custom-gradle-distribution/custom-distribution/build.gradle index e589755..4ad00f0 100644 --- a/sample/single-custom-gradle-distribution/custom-distribution/build.gradle +++ b/sample/single-custom-gradle-distribution/custom-distribution/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'tech.harmonysoft.oss.custom-gradle-dist-plugin' version '1.9' + id 'tech.harmonysoft.oss.custom-gradle-dist-plugin' version '1.17' } gradleDist { diff --git a/sample/single-custom-gradle-distribution/custom-distribution/settings.gradle b/sample/single-custom-gradle-distribution/custom-distribution/settings.gradle index 35d84be..45b3ce3 100644 --- a/sample/single-custom-gradle-distribution/custom-distribution/settings.gradle +++ b/sample/single-custom-gradle-distribution/custom-distribution/settings.gradle @@ -1 +1,9 @@ +pluginManagement { + includeBuild('../../../') { + logger.warn( + 'Replaced indicated version of the Plugin with the current implementation from the root project directory.' + ) + } +} + rootProject.name = 'single-custom-gradle-distribution' \ No newline at end of file diff --git a/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/BuildCustomGradleDistributionTask.kt b/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/BuildCustomGradleDistributionTask.kt index ec078d5..ec93745 100644 --- a/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/BuildCustomGradleDistributionTask.kt +++ b/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/BuildCustomGradleDistributionTask.kt @@ -5,7 +5,6 @@ import java.io.FileFilter import java.io.FileInputStream import java.io.FileOutputStream import java.net.URI -import java.net.URL import java.nio.channels.Channels import java.nio.file.FileSystem import java.nio.file.FileSystems @@ -13,38 +12,49 @@ import java.nio.file.Files import java.util.Properties import java.util.Stack import org.gradle.api.DefaultTask -import org.gradle.api.provider.Property +import org.gradle.api.file.DirectoryProperty import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.Nested +import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction import org.gradle.tooling.BuildException import tech.harmonysoft.oss.gradle.dist.config.CustomGradleDistConfig +import javax.inject.Inject -abstract class BuildCustomGradleDistributionTask : DefaultTask() { +@Suppress("LeakingThis") +abstract class BuildCustomGradleDistributionTask @Inject constructor( + @get:Nested val config: CustomGradleDistConfig +) : DefaultTask() { @get:Internal - abstract val config: Property + abstract val gradleDownloadDir: DirectoryProperty - private val includeRootDir: File - get() = project.file("src/main/resources/include") + @get:OutputDirectory + abstract val customDistributionOutputDir: DirectoryProperty - private val extensionsRootDir: File - get() = project.file("src/main/resources/init.d") + init { + gradleDownloadDir.convention( + project.layout.buildDirectory.dir("gradle-download") + ) + customDistributionOutputDir.convention( + project.layout.buildDirectory.dir("gradle-dist") + ) + } @TaskAction fun build() { - val baseDistribution = getBaseGradleDistribution(config.get()) - val customDistributionsDir = getCustomDistributionsRootDir() + val baseDistribution = getBaseGradleDistribution(config) + val customDistributionsDir = customDistributionOutputDir.get().asFile remove(customDistributionsDir) Files.createDirectories(customDistributionsDir.toPath()) - val currentConfig = config.get() val replacements = prepareReplacements() val distributions = getDistributions() if (distributions.isEmpty()) { prepareCustomDistribution( distribution = null, baseDistribution = baseDistribution, - extension = currentConfig, + extension = config, replacements = replacements ) } else { @@ -52,7 +62,7 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() { prepareCustomDistribution( distribution = distribution, baseDistribution = baseDistribution, - extension = currentConfig, + extension = config, replacements = replacements ) } @@ -73,7 +83,7 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() { private fun doGetBaseGradleDistribution(extension: CustomGradleDistConfig): File { val gradleBaseName = "gradle-${extension.gradleVersion.get()}" val gradleZip = "$gradleBaseName-${extension.gradleDistributionType.get()}.zip" - val baseGradleArchive = project.layout.buildDirectory.file("download/$gradleZip").get().asFile + val baseGradleArchive = gradleDownloadDir.map { it.file(gradleZip) }.get().asFile if (!baseGradleArchive.isFile) { val archiveDir = baseGradleArchive.parentFile if (!archiveDir.isDirectory) { @@ -96,7 +106,7 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() { } private fun download(fromUrl: String, toFile: File) { - val from = Channels.newChannel(URL(fromUrl).openStream()) + val from = Channels.newChannel(URI(fromUrl).toURL().openStream()) project.logger.lifecycle("about to download a gradle distribution from $fromUrl to ${toFile.canonicalPath}") FileOutputStream(toFile).channel.use { it.transferFrom(from, 0, Long.MAX_VALUE) @@ -104,10 +114,6 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() { project.logger.lifecycle("downloaded a gradle distribution from $fromUrl to ${toFile.canonicalPath}") } - private fun getCustomDistributionsRootDir(): File { - return project.layout.buildDirectory.file("gradle-dist").get().asFile - } - private fun remove(toRemove: File) { if (toRemove.isDirectory) { toRemove.listFiles()?.forEach { @@ -126,7 +132,7 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() { } private fun getDistributions(): Collection { - val childDirectories = extensionsRootDir.listFiles(FileFilter { it.isDirectory }) + val childDirectories = config.initScriptsSourceDir.get().asFile.listFiles(FileFilter { it.isDirectory }) return if (childDirectories == null || childDirectories.size < 2) { project.logger.lifecycle("using a single custom gradle distribution") emptyList() @@ -164,8 +170,10 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() { } private fun loadReplacementsFromFiles(): Map { - return includeRootDir - .listFiles() + return config.utilityScriptsSourceDir + .orNull + ?.asFile + ?.listFiles() ?.filter { it.name != REPLACEMENTS_FILE_NAME }?.associate { file -> @@ -300,7 +308,7 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() { gradleDistributionType = extension.gradleDistributionType.get(), distributionName = distribution ).toString() - val customDistributionsDir = getCustomDistributionsRootDir() + val customDistributionsDir = customDistributionOutputDir.get().asFile val result = File(customDistributionsDir, customDistributionFileName) copyBaseDistribution(baseDistribution, result) @@ -357,20 +365,23 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() { pathsToExcludeFromContentExpansion: Set, replacements: Map ) { - val zipFileSystem = FileSystems.newFileSystem( + FileSystems.newFileSystem( URI.create("jar:${zip.toPath().toUri()}"), mapOf("create" to "true") ) - addToZip( - zip = zipFileSystem, - includeRootDir = distribution?.let { - File(extensionsRootDir, it) - } ?: extensionsRootDir, - gradleVersion = gradleVersion, - pathsToExcludeFromContentExpansion = pathsToExcludeFromContentExpansion, - replacements = replacements - ) - zipFileSystem.close() + .use { zipFileSystem -> + config.initScriptsSourceDir.get().asFile.let { initScriptsSourceDir -> + addToZip( + zip = zipFileSystem, + includeRootDir = distribution?.let { + File(initScriptsSourceDir, it) + } ?: initScriptsSourceDir, + gradleVersion = gradleVersion, + pathsToExcludeFromContentExpansion = pathsToExcludeFromContentExpansion, + replacements = replacements + ) + } + } } private fun addToZip( @@ -441,14 +452,18 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() { } if (exclusionRule == null) { val tempFile = Files.createTempFile("", "${fileToInclude.name}.tmp").toFile() - val expandedContent = expand(RichValue( - value = fileToInclude.readText(), - description = "file ${fileToInclude.name}" - )) { - replacements[it] + try { + val expandedContent = expand(RichValue( + value = fileToInclude.readText(), + description = "file ${fileToInclude.name}" + )) { + replacements[it] + } + tempFile.writeText(expandedContent) + Files.copy(tempFile.toPath(), to) + } finally { + tempFile.delete() } - tempFile.writeText(expandedContent) - Files.copy(tempFile.toPath(), to) } else { project.logger.lifecycle( "skipped content expansion for file $relativePath because of exclusion rule '$exclusionRule'" @@ -471,6 +486,6 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() { companion object { private val PATTERN = """\$(\S+)\$""".toRegex() - private val REPLACEMENTS_FILE_NAME = "replacements.properties" + private const val REPLACEMENTS_FILE_NAME = "replacements.properties" } } \ No newline at end of file diff --git a/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/CustomGradleDistributionPlugin.kt b/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/CustomGradleDistributionPlugin.kt index 32b2268..9976e04 100644 --- a/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/CustomGradleDistributionPlugin.kt +++ b/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/CustomGradleDistributionPlugin.kt @@ -9,22 +9,45 @@ import tech.harmonysoft.oss.gradle.dist.config.GradleUrlMapper class CustomGradleDistributionPlugin : Plugin { override fun apply(project: Project) { - val config = project.extensions.create("gradleDist", CustomGradleDistConfig::class.java) + val config = createAndConfigureExtension(project) + + project.tasks.register( + "buildGradleDist", + BuildCustomGradleDistributionTask::class.java, + config + ) project.afterEvaluate { validateAndEnrich(config) - project.tasks.register("buildGradleDist", BuildCustomGradleDistributionTask::class.java) { - it.config.set(config) - } } } + private fun createAndConfigureExtension(project: Project): CustomGradleDistConfig { + val config = project.extensions.create( + "gradleDist", CustomGradleDistConfig::class.java + ) + + config.customDistributionVersion.convention( + project.provider { project.version.toString() } + ) + config.gradleDistributionType.convention("bin") + project.layout.projectDirectory.dir("src/main/resources/include").let { + if (it.asFile.exists()) config.utilityScriptsSourceDir.convention(it) + } + config.initScriptsSourceDir.convention( + project.layout.projectDirectory.dir("src/main/resources/init.d") + ) + config.skipContentExpansionFor.convention(emptyList()) + config.rootUrlMapper.convention(GradleUrlMapper { version, type -> + "https://services.gradle.org/distributions/gradle-$version-${type}.zip" + }) + + return config + } + private fun validateAndEnrich(config: CustomGradleDistConfig) { validateGradleVersion(config) validateCustomDistributionVersion(config) configureCustomDistributionName(config) - configureDistributionTypeIfNecessary(config) - configureGradleUrlMapperIfNecessary(config) - configurePathToExcludeFromExpansionIfNecessary(config) } private fun validateGradleVersion(config: CustomGradleDistConfig) { @@ -81,24 +104,4 @@ class CustomGradleDistributionPlugin : Plugin { } } } - - private fun configureDistributionTypeIfNecessary(config: CustomGradleDistConfig) { - if (!config.gradleDistributionType.isPresent) { - config.gradleDistributionType.set("bin") - } - } - - private fun configureGradleUrlMapperIfNecessary(config: CustomGradleDistConfig) { - if (!config.rootUrlMapper.isPresent) { - config.rootUrlMapper.set(GradleUrlMapper { version, type -> - "https://services.gradle.org/distributions/gradle-$version-${type}.zip" - }) - } - } - - private fun configurePathToExcludeFromExpansionIfNecessary(config: CustomGradleDistConfig) { - if (!config.skipContentExpansionFor.isPresent) { - config.skipContentExpansionFor.set(emptyList()) - } - } } \ No newline at end of file diff --git a/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/config/CustomGradleDistConfig.kt b/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/config/CustomGradleDistConfig.kt index de4c147..b639fba 100644 --- a/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/config/CustomGradleDistConfig.kt +++ b/src/main/kotlin/tech/harmonysoft/oss/gradle/dist/config/CustomGradleDistConfig.kt @@ -1,14 +1,42 @@ package tech.harmonysoft.oss.gradle.dist.config +import org.gradle.api.file.DirectoryProperty import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.Nested +import org.gradle.api.tasks.Optional interface CustomGradleDistConfig { + @get:Input val gradleVersion: Property + + @get:Optional + @get:Input val customDistributionName: Property + + @get:Optional + @get:Nested val customDistributionFileNameMapper: Property + + @get:Input val customDistributionVersion: Property + + @get:Input val gradleDistributionType: Property + + @get:Optional + @get:InputDirectory + val utilityScriptsSourceDir: DirectoryProperty + + @get:InputDirectory + val initScriptsSourceDir: DirectoryProperty + + @get:Input val skipContentExpansionFor: Property> + + @get:Internal val rootUrlMapper: Property -} \ No newline at end of file +} diff --git a/src/test/kotlin/tech/harmonysoft/oss/gradle/dist/CustomGradleDistributionPluginTest.kt b/src/test/kotlin/tech/harmonysoft/oss/gradle/dist/CustomGradleDistributionPluginTest.kt index fb02d6a..ab2c75b 100644 --- a/src/test/kotlin/tech/harmonysoft/oss/gradle/dist/CustomGradleDistributionPluginTest.kt +++ b/src/test/kotlin/tech/harmonysoft/oss/gradle/dist/CustomGradleDistributionPluginTest.kt @@ -12,6 +12,8 @@ import java.util.zip.ZipOutputStream import org.assertj.core.api.Assertions.assertThat import org.gradle.testkit.runner.GradleRunner import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.CleanupMode +import org.junit.jupiter.api.io.TempDir import tech.harmonysoft.oss.test.util.TestUtil.fail class CustomGradleDistributionPluginTest { @@ -46,6 +48,27 @@ class CustomGradleDistributionPluginTest { doTest("multiple-distributions") } + @Test + fun `when custom single gradle distribution is built with project distribution version`() { + val testFiles = doTest("single-distribution-no-templates", """ + plugins { + id("tech.harmonysoft.oss.custom-gradle-dist-plugin") + } + + version = "1.1" + + gradleDist { + gradleVersion = "$GRADLE_VERSION" + customDistributionName = "$PROJECT_NAME" + } + """.trimIndent()) + val expectedCustomDistributionFile = File( + testFiles.inputRootDir, + "$BUILT_DISTS_DIR/gradle-$GRADLE_VERSION-$PROJECT_NAME-1.1-bin.zip" + ) + verifyDistributionName(expectedCustomDistributionFile) + } + @Test fun `when cyclic expansion chain is detected then it is reported`() { try { @@ -118,7 +141,7 @@ class CustomGradleDistributionPluginTest { val testFiles = doTest("single-distribution-no-templates") val expectedCustomDistributionFile = File( testFiles.inputRootDir, - "build/gradle-dist/gradle-$GRADLE_VERSION-$PROJECT_NAME-$PROJECT_VERSION-bin.zip" + "$BUILT_DISTS_DIR/gradle-$GRADLE_VERSION-$PROJECT_NAME-$PROJECT_VERSION-bin.zip" ) verifyDistributionName(expectedCustomDistributionFile) assertThat(expectedCustomDistributionFile).exists() @@ -140,7 +163,35 @@ class CustomGradleDistributionPluginTest { """.trimIndent()) val expectedCustomDistributionFile = File( testFiles.inputRootDir, - "build/gradle-dist/gradle-$GRADLE_VERSION-$PROJECT_NAME-$PROJECT_VERSION-all.zip" + "$BUILT_DISTS_DIR/gradle-$GRADLE_VERSION-$PROJECT_NAME-$PROJECT_VERSION-all.zip" + ) + verifyDistributionName(expectedCustomDistributionFile) + } + + @Test + fun `when custom single gradle distribution is built with non-standard directories`() { + val testFiles = doTest("non-standard-directories", """ + import tech.harmonysoft.oss.gradle.dist.BuildCustomGradleDistributionTask + + plugins { + id("tech.harmonysoft.oss.custom-gradle-dist-plugin") + } + + gradleDist { + gradleVersion = "$GRADLE_VERSION" + customDistributionVersion = "$PROJECT_VERSION" + customDistributionName = "$PROJECT_NAME" + utilityScriptsSourceDir = project.layout.projectDirectory.dir("src/main/resources/own-include") + initScriptsSourceDir = project.layout.projectDirectory.dir("src/main/resources/own-init.d") + } + + tasks.named("buildGradleDist") { + customDistributionOutputDir = project.layout.buildDirectory.dir("own-gradle-dist") + } + """.trimIndent(), "build/own-gradle-dist") + val expectedCustomDistributionFile = File( + testFiles.inputRootDir, + "build/own-gradle-dist/gradle-$GRADLE_VERSION-$PROJECT_NAME-$PROJECT_VERSION-bin.zip" ) verifyDistributionName(expectedCustomDistributionFile) } @@ -172,7 +223,7 @@ class CustomGradleDistributionPluginTest { for (distribution in listOf("library", "service")) { val expectedCustomDistributionFile = File( testFiles.inputRootDir, - "build/gradle-dist/gradle-$GRADLE_VERSION-$PROJECT_NAME-$PROJECT_VERSION-$distribution-all.zip" + "$BUILT_DISTS_DIR/gradle-$GRADLE_VERSION-$PROJECT_NAME-$PROJECT_VERSION-$distribution-all.zip" ) verifyDistributionName(expectedCustomDistributionFile) } @@ -199,7 +250,7 @@ class CustomGradleDistributionPluginTest { runAndVerify(testFiles) val expectedCustomDistributionFile = File( testFiles.inputRootDir, - "build/gradle-dist/all-custom-${PROJECT_VERSION}-base-$GRADLE_VERSION.zip" + "$BUILT_DISTS_DIR/all-custom-${PROJECT_VERSION}-base-$GRADLE_VERSION.zip" ) verifyDistributionName(expectedCustomDistributionFile) } @@ -224,7 +275,7 @@ class CustomGradleDistributionPluginTest { """.trimIndent()) val expectedCustomDistributionFile = File( testFiles.inputRootDir, - "build/gradle-dist/all-custom-${PROJECT_VERSION}-base-$GRADLE_VERSION.zip" + "$BUILT_DISTS_DIR/all-custom-${PROJECT_VERSION}-base-$GRADLE_VERSION.zip" ) verifyDistributionName(expectedCustomDistributionFile) } @@ -290,7 +341,7 @@ class CustomGradleDistributionPluginTest { @Test fun `when custom base gradle distribution mapper is defined in gradle groovy script then it's respected`() { - val customBaseGradleDistFile = Files.createTempFile("base-gradle-dist", "").toFile() + val customBaseGradleDistFile = Files.createTempFile(TESTS_ARTIFACTS_ROOT_DIR, "base-gradle-dist", "").toFile() createGradleDistributionZip(customBaseGradleDistFile) val testFiles = prepareInput("single-distribution-no-templates",""" import tech.harmonysoft.oss.gradle.dist.config.GradleUrlMapper @@ -313,7 +364,7 @@ class CustomGradleDistributionPluginTest { @Test fun `when custom base gradle distribution mapper is defined in gradle kotlin script then it's respected`() { - val customBaseGradleDistFile = Files.createTempFile("base-gradle-dist", "").toFile() + val customBaseGradleDistFile = Files.createTempFile(TESTS_ARTIFACTS_ROOT_DIR, "base-gradle-dist", "").toFile() createGradleDistributionZip(customBaseGradleDistFile) val testFiles = prepareInput("single-distribution-no-templates", """ import tech.harmonysoft.oss.gradle.dist.config.GradleUrlMapper @@ -338,9 +389,9 @@ class CustomGradleDistributionPluginTest { return doTest(testName, BUILD_TEMPLATE) } - private fun doTest(testName: String, buildGradleContent: String): TestFiles { + private fun doTest(testName: String, buildGradleContent: String, buildDistsDir: String = BUILT_DISTS_DIR): TestFiles { val testFiles = prepareInput(testName, buildGradleContent) - runAndVerify(testFiles) + runAndVerify(testFiles, buildDistsDir) return testFiles } @@ -361,9 +412,7 @@ class CustomGradleDistributionPluginTest { } private fun copy(dir: File): File { - val result = Files.createTempDirectory("${dir.name}-tmp").toFile().apply { - deleteOnExit() - } + val result = Files.createTempDirectory(TESTS_ARTIFACTS_ROOT_DIR, dir.name).toFile() val resourcesRoot = File(result, "src/main/resources") Files.createDirectories(resourcesRoot.toPath()) dir.listFiles()?.forEach { child -> @@ -395,10 +444,12 @@ class CustomGradleDistributionPluginTest { } private fun prepareGradleDistributionZip(projectRootDir: File) { - val downloadDir = File(projectRootDir, "build/download") + val downloadDir = File(projectRootDir, "build/gradle-download") Files.createDirectories(downloadDir.toPath()) - val zip = File(downloadDir, "gradle-${GRADLE_VERSION}-bin.zip") - createGradleDistributionZip(zip) + listOf("bin", "all").forEach { + val zip = File(downloadDir, "gradle-${GRADLE_VERSION}-${it}.zip") + createGradleDistributionZip(zip) + } } private fun createGradleDistributionZip(zip: File) { @@ -482,7 +533,7 @@ class CustomGradleDistributionPluginTest { ) } val zip = zips.first() - val rootUnzipDir = Files.createTempDirectory(zip.name).toFile() + val rootUnzipDir = Files.createTempDirectory(TESTS_ARTIFACTS_ROOT_DIR, zip.name).toFile() val zipFile = ZipFile(zip) for (zipEntry in zipFile.entries()) { val path = File(rootUnzipDir, zipEntry.name).toPath() @@ -521,7 +572,7 @@ class CustomGradleDistributionPluginTest { return result } - private fun runAndVerify(testFiles: TestFiles) { + private fun runAndVerify(testFiles: TestFiles, buildDistsDir: String = BUILT_DISTS_DIR) { GradleRunner.create() .withProjectDir(testFiles.inputRootDir) .withArguments("buildGradleDist", "--stacktrace") @@ -529,7 +580,7 @@ class CustomGradleDistributionPluginTest { .withDebug(true) .build() - verify(testFiles.expectedRootDir, File(testFiles.inputRootDir, "build/gradle-dist")) + verify(testFiles.expectedRootDir, File(testFiles.inputRootDir, buildDistsDir)) } data class TestFiles( @@ -542,6 +593,11 @@ class CustomGradleDistributionPluginTest { const val GRADLE_VERSION = "8.3" const val PROJECT_NAME = "my-project" const val PROJECT_VERSION = "1.0" + const val DEFAULT_DISTRIBUTION_TYPE = "bin" + const val BUILT_DISTS_DIR = "build/gradle-dist" + + @field:TempDir(cleanup = CleanupMode.ON_SUCCESS) + lateinit var TESTS_ARTIFACTS_ROOT_DIR: Path val BUILD_TEMPLATE = """ plugins { diff --git a/src/test/resources/cyclic-expansion-in-include-files/input/init.d/.gitkeep b/src/test/resources/cyclic-expansion-in-include-files/input/init.d/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/test/resources/cyclic-expansion-key-in-replacements-file-and-include-files/input/init.d/.gitkeep b/src/test/resources/cyclic-expansion-key-in-replacements-file-and-include-files/input/init.d/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/test/resources/non-standard-directories/expected/init.d/mixin.gradle b/src/test/resources/non-standard-directories/expected/init.d/mixin.gradle new file mode 100644 index 0000000..3c734a8 --- /dev/null +++ b/src/test/resources/non-standard-directories/expected/init.d/mixin.gradle @@ -0,0 +1,5 @@ +initscript { + repositories { + mavenCentral() + } +} \ No newline at end of file diff --git a/src/test/resources/non-standard-directories/input/own-include/repository.gradle b/src/test/resources/non-standard-directories/input/own-include/repository.gradle new file mode 100644 index 0000000..64b6749 --- /dev/null +++ b/src/test/resources/non-standard-directories/input/own-include/repository.gradle @@ -0,0 +1,3 @@ +repositories { + mavenCentral() +} \ No newline at end of file diff --git a/src/test/resources/non-standard-directories/input/own-init.d/mixin.gradle b/src/test/resources/non-standard-directories/input/own-init.d/mixin.gradle new file mode 100644 index 0000000..ae3f850 --- /dev/null +++ b/src/test/resources/non-standard-directories/input/own-init.d/mixin.gradle @@ -0,0 +1,3 @@ +initscript { + $repository$ +} \ No newline at end of file