Skip to content

Commit 1c49ca5

Browse files
authored
use Extension to control the targets container, so that Gradle will generate Kotlin DSL accessors (#9)
1 parent d2c5a51 commit 1c49ca5

File tree

8 files changed

+84
-24
lines changed

8 files changed

+84
-24
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ binaryCompatibilityValidator {
131131
}
132132

133133
// BCV will automatically register a target for testFixtures, but it must be enabled manually
134-
targets.named("testFixtures") {
134+
targets.testFixtures {
135135
enabled.set(true)
136136
}
137137

modules/bcv-gradle-plugin-functional-tests/src/functionalTest/kotlin/kotlinx/validation/test/JavaTestFixturesTest.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ private fun FunSpec.createTestFixturesProject(
130130
|}
131131
|
132132
|binaryCompatibilityValidator {
133-
| testFixtures {
133+
| targets.testFixtures {
134134
| enabled.set($bcvTestFixturesTargetEnabled)
135135
| }
136136
|}

modules/bcv-gradle-plugin-functional-tests/src/functionalTest/resources/examples/gradle/configuration/jarAsInput/inputJar.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ tasks.jar {
44
}
55

66
binaryCompatibilityValidator {
7-
kotlinJvm {
7+
targets.kotlinJvm {
88
inputJar.set(tasks.jar.flatMap { it.archiveFile })
99
}
1010
}

modules/bcv-gradle-plugin/api/bcv-gradle-plugin.api

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public abstract class dev/adamko/kotlin/binary_compatibility_validator/BCVPlugin
1111
public final class dev/adamko/kotlin/binary_compatibility_validator/BCVPlugin$Companion {
1212
}
1313

14-
public abstract interface class dev/adamko/kotlin/binary_compatibility_validator/BCVProjectExtension : dev/adamko/kotlin/binary_compatibility_validator/targets/BCVTargetSpec, org/gradle/api/plugins/ExtensionAware {
14+
public abstract class dev/adamko/kotlin/binary_compatibility_validator/BCVProjectExtension : dev/adamko/kotlin/binary_compatibility_validator/targets/BCVTargetSpec, org/gradle/api/plugins/ExtensionAware {
1515
public abstract fun getEnabled ()Lorg/gradle/api/provider/Property;
1616
public abstract fun getIgnoredClasses ()Lorg/gradle/api/provider/SetProperty;
1717
public abstract fun getIgnoredMarkers ()Lorg/gradle/api/provider/SetProperty;
@@ -23,7 +23,7 @@ public abstract interface class dev/adamko/kotlin/binary_compatibility_validator
2323
public abstract fun getPublicClasses ()Lorg/gradle/api/provider/SetProperty;
2424
public abstract fun getPublicMarkers ()Lorg/gradle/api/provider/SetProperty;
2525
public abstract fun getPublicPackages ()Lorg/gradle/api/provider/SetProperty;
26-
public abstract fun getTargets ()Lorg/gradle/api/NamedDomainObjectContainer;
26+
public final fun getTargets ()Lorg/gradle/api/NamedDomainObjectContainer;
2727
}
2828

2929
public abstract class dev/adamko/kotlin/binary_compatibility_validator/BCVProjectPlugin : org/gradle/api/Plugin {
@@ -94,7 +94,7 @@ public abstract class dev/adamko/kotlin/binary_compatibility_validator/tasks/BCV
9494
public abstract fun getOutputApiBuildDir ()Lorg/gradle/api/file/DirectoryProperty;
9595
public abstract fun getProjectName ()Lorg/gradle/api/provider/Property;
9696
public abstract fun getRuntimeClasspath ()Lorg/gradle/api/file/ConfigurableFileCollection;
97-
public abstract fun getTargets ()Lorg/gradle/api/NamedDomainObjectContainer;
97+
public final fun getTargets ()Lorg/gradle/api/NamedDomainObjectContainer;
9898
}
9999

100100
public abstract class dev/adamko/kotlin/binary_compatibility_validator/tasks/BCVDefaultTask : org/gradle/api/DefaultTask {
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,62 @@
11
package dev.adamko.kotlin.binary_compatibility_validator
22

3+
import dev.adamko.kotlin.binary_compatibility_validator.internal.BCVInternalApi
4+
import dev.adamko.kotlin.binary_compatibility_validator.internal.adding
5+
import dev.adamko.kotlin.binary_compatibility_validator.internal.domainObjectContainer
36
import dev.adamko.kotlin.binary_compatibility_validator.targets.BCVTarget
47
import dev.adamko.kotlin.binary_compatibility_validator.targets.BCVTargetSpec
8+
import javax.inject.Inject
59
import org.gradle.api.NamedDomainObjectContainer
610
import org.gradle.api.file.DirectoryProperty
11+
import org.gradle.api.model.ObjectFactory
712
import org.gradle.api.model.ReplacedBy
813
import org.gradle.api.plugins.ExtensionAware
914
import org.gradle.api.provider.Property
1015
import org.gradle.api.provider.SetProperty
1116

12-
interface BCVProjectExtension : BCVTargetSpec, ExtensionAware {
17+
abstract class BCVProjectExtension
18+
@BCVInternalApi
19+
@Inject
20+
constructor(
21+
private val objects: ObjectFactory
22+
) : BCVTargetSpec, ExtensionAware {
1323

1424
/** Sets the default [BCVTarget.enabled] value for all [targets]. */
15-
override val enabled: Property<Boolean>
25+
abstract override val enabled: Property<Boolean>
1626

1727
/** Sets the default [BCVTarget.ignoredPackages] value for all [targets]. */
18-
override val ignoredPackages: SetProperty<String>
28+
abstract override val ignoredPackages: SetProperty<String>
1929

2030
/** Sets the default [BCVTarget.publicMarkers] for all [targets] */
21-
override val publicMarkers: SetProperty<String>
31+
abstract override val publicMarkers: SetProperty<String>
2232

2333
/** Sets the default [BCVTarget.publicPackages] for all [targets] */
24-
override val publicPackages: SetProperty<String>
34+
abstract override val publicPackages: SetProperty<String>
2535

2636
/** Sets the default [BCVTarget.publicClasses] for all [targets] */
27-
override val publicClasses: SetProperty<String>
37+
abstract override val publicClasses: SetProperty<String>
2838

2939
/** Sets the default [BCVTarget.ignoredMarkers] value for all [targets]. */
30-
override val ignoredMarkers: SetProperty<String>
40+
abstract override val ignoredMarkers: SetProperty<String>
3141

3242
@get:ReplacedBy("ignoredMarkers")
3343
@Deprecated("renamed to ignoredMarkers", ReplaceWith("ignoredMarkers"))
34-
val nonPublicMarkers: SetProperty<String>
44+
abstract val nonPublicMarkers: SetProperty<String>
3545

3646
/** Sets the default [BCVTarget.ignoredClasses] value for all [targets]. */
37-
override val ignoredClasses: SetProperty<String>
47+
abstract override val ignoredClasses: SetProperty<String>
3848

3949
/**
4050
* The directory that contains the API declarations.
4151
*
4252
* Defaults to [BCVPlugin.API_DIR].
4353
*/
44-
val outputApiDir: DirectoryProperty
54+
abstract val outputApiDir: DirectoryProperty
4555

46-
val projectName: Property<String>
56+
abstract val projectName: Property<String>
4757

48-
val kotlinxBinaryCompatibilityValidatorVersion: Property<String>
58+
abstract val kotlinxBinaryCompatibilityValidatorVersion: Property<String>
4959

50-
val targets: NamedDomainObjectContainer<BCVTarget>
60+
val targets: NamedDomainObjectContainer<BCVTarget> =
61+
extensions.adding("targets") { objects.domainObjectContainer() }
5162
}

modules/bcv-gradle-plugin/src/main/kotlin/BCVProjectPlugin.kt

-4
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,6 @@ constructor(
119119
ignoredPackages.convention(extension.ignoredPackages)
120120
}
121121

122-
extension.targets.all {
123-
extension.extensions.add(platformType, this)
124-
}
125-
126122
return extension
127123
}
128124

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package dev.adamko.kotlin.binary_compatibility_validator.internal
2+
3+
import org.gradle.api.NamedDomainObjectContainer
4+
import org.gradle.api.NamedDomainObjectFactory
5+
import org.gradle.api.model.ObjectFactory
6+
import org.gradle.api.plugins.ExtensionContainer
7+
import org.gradle.kotlin.dsl.*
8+
9+
10+
/**
11+
* Create a new [NamedDomainObjectContainer], using
12+
* [org.gradle.kotlin.dsl.domainObjectContainer]
13+
* (but [T] is `reified`).
14+
*
15+
* @param[factory] an optional factory for creating elements
16+
* @see org.gradle.kotlin.dsl.domainObjectContainer
17+
*/
18+
internal inline fun <reified T : Any> ObjectFactory.domainObjectContainer(
19+
factory: NamedDomainObjectFactory<T>? = null
20+
): NamedDomainObjectContainer<T> =
21+
if (factory == null) {
22+
domainObjectContainer(T::class)
23+
} else {
24+
domainObjectContainer(T::class, factory)
25+
}
26+
27+
28+
/**
29+
* [Add][ExtensionContainer.add] a value (from [valueProvider]) with [name], and return the value.
30+
*
31+
* Adding an extension is especially useful for improving the DSL in build scripts when [T] is a
32+
* [NamedDomainObjectContainer].
33+
* Using an extension will allow Gradle to generate
34+
* [type-safe model accessors](https://docs.gradle.org/current/userguide/kotlin_dsl.html#kotdsl:accessor_applicability)
35+
* for added types.
36+
*
37+
* ([name] should match the property name. This has to be done manually because using a
38+
* delegated-property provider means Gradle can't introspect the types properly, so it fails to
39+
* create accessors).
40+
*/
41+
internal inline fun <reified T : Any> ExtensionContainer.adding(
42+
name: String,
43+
crossinline valueProvider: () -> T,
44+
): T {
45+
val value: T = valueProvider()
46+
add<T>(name, value)
47+
return value
48+
}

modules/bcv-gradle-plugin/src/main/kotlin/tasks/BCVApiGenerateTask.kt

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package dev.adamko.kotlin.binary_compatibility_validator.tasks
22

33
import dev.adamko.kotlin.binary_compatibility_validator.internal.BCVInternalApi
4+
import dev.adamko.kotlin.binary_compatibility_validator.internal.adding
5+
import dev.adamko.kotlin.binary_compatibility_validator.internal.domainObjectContainer
46
import dev.adamko.kotlin.binary_compatibility_validator.targets.BCVTarget
57
import dev.adamko.kotlin.binary_compatibility_validator.workers.BCVSignaturesWorker
68
import java.io.*
79
import javax.inject.Inject
810
import kotlinx.validation.api.*
911
import org.gradle.api.*
1012
import org.gradle.api.file.*
13+
import org.gradle.api.model.ObjectFactory
1114
import org.gradle.api.provider.Property
1215
import org.gradle.api.tasks.*
1316
import org.gradle.kotlin.dsl.*
@@ -21,10 +24,12 @@ abstract class BCVApiGenerateTask
2124
constructor(
2225
private val workers: WorkerExecutor,
2326
private val fs: FileSystemOperations,
27+
private val objects: ObjectFactory,
2428
) : BCVDefaultTask() {
2529

2630
@get:Nested
27-
abstract val targets: NamedDomainObjectContainer<BCVTarget>
31+
val targets: NamedDomainObjectContainer<BCVTarget> =
32+
extensions.adding("targets") { objects.domainObjectContainer() }
2833

2934
@get:InputFiles
3035
@get:PathSensitive(PathSensitivity.RELATIVE)

0 commit comments

Comments
 (0)