Skip to content

Commit 48021de

Browse files
committed
Refactored configuring interface and annotate all public properties with task annotations to instrument Gradle when should rebuild custom distributions
1 parent 1e8c480 commit 48021de

File tree

5 files changed

+84
-54
lines changed

5 files changed

+84
-54
lines changed

README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Gradle automatically applies [init scripts](https://docs.gradle.org/current/user
7171
**mandatory settings:**
7272
* `gradleVersion` - base Gradle wrapper version
7373
* `customDistributionVersion` - custom distribution version (`project.version` is used by default)
74-
* `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*
74+
* `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*
7575
* `gradleVersion` - base gradle distribution version as defined above
7676
* `customDistributionVersion` - custom distribution mixing version as defined above
7777
* `gradleDistributionType` - gradle distribution type as defined below
@@ -118,10 +118,13 @@ Gradle automatically applies [init scripts](https://docs.gradle.org/current/user
118118
}
119119
}
120120
```
121-
*Note: it's necessary to specify this property or 'customDistributionFileNameMapper' property. It's an error to define the both/none of them*
121+
*Note: it's necessary to specify this property or `customDistributionFileNameMapper` property. It's an error to define the both/none of them*
122+
123+
* `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`.
122124
123125
**optional settings:**
124-
* `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
126+
* `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
127+
* `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`.
125128
* `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.
126129
Example: consider the following project structure:
127130
```
@@ -270,6 +273,16 @@ Gradle automatically applies [init scripts](https://docs.gradle.org/current/user
270273
271274
The distribution(s) are located in the `build/gradle-dist`
272275
276+
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:
277+
```groovy
278+
import tech.harmonysoft.oss.gradle.dist.BuildCustomGradleDistributionTask
279+
280+
tasks.named('buildGradleDist', BuildCustomGradleDistributionTask) {
281+
gradleDownloadDir = project.layout.buildDirectory.dir('own-gradle-download')
282+
customDistributionOutputDir = project.layout.buildDirectory.dir('own-gradle-dist')
283+
}
284+
```
285+
273286
### Configure Client Project
274287
275288
Just define your custom Gradle wrapper's location in the *gradle/wrapper/gradle-wrapper.properties* file:

src/main/kotlin/tech/harmonysoft/oss/gradle/dist/BuildCustomGradleDistributionTask.kt

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import java.io.FileFilter
55
import java.io.FileInputStream
66
import java.io.FileOutputStream
77
import java.net.URI
8-
import java.net.URL
98
import java.nio.channels.Channels
109
import java.nio.file.FileSystem
1110
import java.nio.file.FileSystems
@@ -14,72 +13,56 @@ import java.util.Properties
1413
import java.util.Stack
1514
import org.gradle.api.DefaultTask
1615
import org.gradle.api.file.DirectoryProperty
17-
import org.gradle.api.provider.Property
18-
import org.gradle.api.tasks.InputDirectory
1916
import org.gradle.api.tasks.Internal
20-
import org.gradle.api.tasks.Optional
17+
import org.gradle.api.tasks.Nested
2118
import org.gradle.api.tasks.OutputDirectory
2219
import org.gradle.api.tasks.TaskAction
2320
import org.gradle.tooling.BuildException
2421
import tech.harmonysoft.oss.gradle.dist.config.CustomGradleDistConfig
22+
import javax.inject.Inject
2523

2624
@Suppress("LeakingThis")
27-
abstract class BuildCustomGradleDistributionTask : DefaultTask() {
25+
abstract class BuildCustomGradleDistributionTask @Inject constructor(
26+
@get:Nested val config: CustomGradleDistConfig
27+
) : DefaultTask() {
2828

2929
@get:Internal
30-
abstract val config: Property<CustomGradleDistConfig>
31-
32-
@get:Internal
33-
abstract val downloadRootDir: DirectoryProperty
34-
35-
@get:Optional
36-
@get:InputDirectory
37-
abstract val includeRootDir: DirectoryProperty
38-
39-
@get:InputDirectory
40-
abstract val extensionsRootDir: DirectoryProperty
30+
abstract val gradleDownloadDir: DirectoryProperty
4131

4232
@get:OutputDirectory
43-
abstract val customDistributionsRootDir: DirectoryProperty
33+
abstract val customDistributionOutputDir: DirectoryProperty
4434

4535
init {
46-
downloadRootDir.convention(
47-
project.layout.buildDirectory.dir("download")
36+
gradleDownloadDir.convention(
37+
project.layout.buildDirectory.dir("gradle-download")
4838
)
49-
project.layout.projectDirectory.dir("src/main/resources/include").let {
50-
if (it.asFile.exists()) includeRootDir.convention(it)
51-
}
52-
extensionsRootDir.convention(
53-
project.layout.projectDirectory.dir("src/main/resources/init.d")
54-
)
55-
customDistributionsRootDir.convention(
39+
customDistributionOutputDir.convention(
5640
project.layout.buildDirectory.dir("gradle-dist")
5741
)
5842
}
5943

6044
@TaskAction
6145
fun build() {
62-
val baseDistribution = getBaseGradleDistribution(config.get())
63-
val customDistributionsDir = customDistributionsRootDir.get().asFile
46+
val baseDistribution = getBaseGradleDistribution(config)
47+
val customDistributionsDir = customDistributionOutputDir.get().asFile
6448
remove(customDistributionsDir)
6549
Files.createDirectories(customDistributionsDir.toPath())
6650

67-
val currentConfig = config.get()
6851
val replacements = prepareReplacements()
6952
val distributions = getDistributions()
7053
if (distributions.isEmpty()) {
7154
prepareCustomDistribution(
7255
distribution = null,
7356
baseDistribution = baseDistribution,
74-
extension = currentConfig,
57+
extension = config,
7558
replacements = replacements
7659
)
7760
} else {
7861
for (distribution in distributions) {
7962
prepareCustomDistribution(
8063
distribution = distribution,
8164
baseDistribution = baseDistribution,
82-
extension = currentConfig,
65+
extension = config,
8366
replacements = replacements
8467
)
8568
}
@@ -100,7 +83,7 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() {
10083
private fun doGetBaseGradleDistribution(extension: CustomGradleDistConfig): File {
10184
val gradleBaseName = "gradle-${extension.gradleVersion.get()}"
10285
val gradleZip = "$gradleBaseName-${extension.gradleDistributionType.get()}.zip"
103-
val baseGradleArchive = downloadRootDir.map { it.file(gradleZip) }.get().asFile
86+
val baseGradleArchive = gradleDownloadDir.map { it.file(gradleZip) }.get().asFile
10487
if (!baseGradleArchive.isFile) {
10588
val archiveDir = baseGradleArchive.parentFile
10689
if (!archiveDir.isDirectory) {
@@ -123,7 +106,7 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() {
123106
}
124107

125108
private fun download(fromUrl: String, toFile: File) {
126-
val from = Channels.newChannel(URL(fromUrl).openStream())
109+
val from = Channels.newChannel(URI(fromUrl).toURL().openStream())
127110
project.logger.lifecycle("about to download a gradle distribution from $fromUrl to ${toFile.canonicalPath}")
128111
FileOutputStream(toFile).channel.use {
129112
it.transferFrom(from, 0, Long.MAX_VALUE)
@@ -149,8 +132,7 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() {
149132
}
150133

151134
private fun getDistributions(): Collection<String> {
152-
val extensionsRootDir = this.extensionsRootDir.get().asFile
153-
val childDirectories = extensionsRootDir.listFiles(FileFilter { it.isDirectory })
135+
val childDirectories = config.initScriptsSourceDir.get().asFile.listFiles(FileFilter { it.isDirectory })
154136
return if (childDirectories == null || childDirectories.size < 2) {
155137
project.logger.lifecycle("using a single custom gradle distribution")
156138
emptyList()
@@ -188,7 +170,8 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() {
188170
}
189171

190172
private fun loadReplacementsFromFiles(): Map<String, RichValue> {
191-
return includeRootDir.orNull
173+
return config.utilityScriptsSourceDir
174+
.orNull
192175
?.asFile
193176
?.listFiles()
194177
?.filter {
@@ -325,7 +308,7 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() {
325308
gradleDistributionType = extension.gradleDistributionType.get(),
326309
distributionName = distribution
327310
).toString()
328-
val customDistributionsDir = customDistributionsRootDir.get().asFile
311+
val customDistributionsDir = customDistributionOutputDir.get().asFile
329312
val result = File(customDistributionsDir, customDistributionFileName)
330313

331314
copyBaseDistribution(baseDistribution, result)
@@ -387,14 +370,12 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() {
387370
mapOf("create" to "true")
388371
)
389372
.use { zipFileSystem ->
390-
val extensionsRootDir = this.extensionsRootDir.get().asFile
391-
392-
extensionsRootDir.let { extensionsRootDir ->
373+
config.initScriptsSourceDir.get().asFile.let { initScriptsSourceDir ->
393374
addToZip(
394375
zip = zipFileSystem,
395376
includeRootDir = distribution?.let {
396-
File(extensionsRootDir, it)
397-
} ?: extensionsRootDir,
377+
File(initScriptsSourceDir, it)
378+
} ?: initScriptsSourceDir,
398379
gradleVersion = gradleVersion,
399380
pathsToExcludeFromContentExpansion = pathsToExcludeFromContentExpansion,
400381
replacements = replacements
@@ -505,6 +486,6 @@ abstract class BuildCustomGradleDistributionTask : DefaultTask() {
505486

506487
companion object {
507488
private val PATTERN = """\$(\S+)\$""".toRegex()
508-
private val REPLACEMENTS_FILE_NAME = "replacements.properties"
489+
private const val REPLACEMENTS_FILE_NAME = "replacements.properties"
509490
}
510491
}

src/main/kotlin/tech/harmonysoft/oss/gradle/dist/CustomGradleDistributionPlugin.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ class CustomGradleDistributionPlugin : Plugin<Project> {
1111
override fun apply(project: Project) {
1212
val config = createAndConfigureExtension(project)
1313

14-
project.tasks.register("buildGradleDist", BuildCustomGradleDistributionTask::class.java) {
15-
it.config.set(config)
16-
}
14+
project.tasks.register(
15+
"buildGradleDist",
16+
BuildCustomGradleDistributionTask::class.java,
17+
config
18+
)
1719
project.afterEvaluate {
1820
validateAndEnrich(config)
1921
}
@@ -28,6 +30,12 @@ class CustomGradleDistributionPlugin : Plugin<Project> {
2830
project.provider { project.version.toString() }
2931
)
3032
config.gradleDistributionType.convention("bin")
33+
project.layout.projectDirectory.dir("src/main/resources/include").let {
34+
if (it.asFile.exists()) config.utilityScriptsSourceDir.convention(it)
35+
}
36+
config.initScriptsSourceDir.convention(
37+
project.layout.projectDirectory.dir("src/main/resources/init.d")
38+
)
3139
config.skipContentExpansionFor.convention(emptyList())
3240
config.rootUrlMapper.convention(GradleUrlMapper { version, type ->
3341
"https://services.gradle.org/distributions/gradle-$version-${type}.zip"
Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,42 @@
11
package tech.harmonysoft.oss.gradle.dist.config
22

3+
import org.gradle.api.file.DirectoryProperty
34
import org.gradle.api.provider.Property
5+
import org.gradle.api.tasks.Input
6+
import org.gradle.api.tasks.InputDirectory
7+
import org.gradle.api.tasks.Internal
8+
import org.gradle.api.tasks.Nested
9+
import org.gradle.api.tasks.Optional
410

511
interface CustomGradleDistConfig {
612

13+
@get:Input
714
val gradleVersion: Property<String>
15+
16+
@get:Optional
17+
@get:Input
818
val customDistributionName: Property<String>
19+
20+
@get:Optional
21+
@get:Nested
922
val customDistributionFileNameMapper: Property<CustomDistributionNameMapper>
23+
24+
@get:Input
1025
val customDistributionVersion: Property<String>
26+
27+
@get:Input
1128
val gradleDistributionType: Property<String>
29+
30+
@get:Optional
31+
@get:InputDirectory
32+
val utilityScriptsSourceDir: DirectoryProperty
33+
34+
@get:InputDirectory
35+
val initScriptsSourceDir: DirectoryProperty
36+
37+
@get:Input
1238
val skipContentExpansionFor: Property<Collection<String>>
39+
40+
@get:Internal
1341
val rootUrlMapper: Property<GradleUrlMapper>
14-
}
42+
}

src/test/kotlin/tech/harmonysoft/oss/gradle/dist/CustomGradleDistributionPluginTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,12 @@ class CustomGradleDistributionPluginTest {
181181
gradleVersion = "$GRADLE_VERSION"
182182
customDistributionVersion = "$PROJECT_VERSION"
183183
customDistributionName = "$PROJECT_NAME"
184+
utilityScriptsSourceDir = project.layout.projectDirectory.dir("src/main/resources/own-include")
185+
initScriptsSourceDir = project.layout.projectDirectory.dir("src/main/resources/own-init.d")
184186
}
185187
186188
tasks.named<BuildCustomGradleDistributionTask>("buildGradleDist") {
187-
includeRootDir = project.layout.projectDirectory.dir("src/main/resources/own-include")
188-
extensionsRootDir = project.layout.projectDirectory.dir("src/main/resources/own-init.d")
189-
customDistributionsRootDir = project.layout.buildDirectory.dir("own-gradle-dist")
189+
customDistributionOutputDir = project.layout.buildDirectory.dir("own-gradle-dist")
190190
}
191191
""".trimIndent(), "build/own-gradle-dist")
192192
val expectedCustomDistributionFile = File(
@@ -444,7 +444,7 @@ class CustomGradleDistributionPluginTest {
444444
}
445445

446446
private fun prepareGradleDistributionZip(projectRootDir: File) {
447-
val downloadDir = File(projectRootDir, "build/download")
447+
val downloadDir = File(projectRootDir, "build/gradle-download")
448448
Files.createDirectories(downloadDir.toPath())
449449
listOf("bin", "all").forEach {
450450
val zip = File(downloadDir, "gradle-${GRADLE_VERSION}-${it}.zip")

0 commit comments

Comments
 (0)