Skip to content

Commit 7272844

Browse files
committed
tidy up tasks, split Configurations into declarer/resolver
1 parent c257508 commit 7272844

File tree

6 files changed

+172
-44
lines changed

6 files changed

+172
-44
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
public abstract class dev/adamko/kotlin/binary_compatibility_validator/BCVPlugin : org/gradle/api/Plugin {
2+
public static final field API_CHECK_TASK_NAME Ljava/lang/String;
23
public static final field API_DIR Ljava/lang/String;
4+
public static final field API_DUMP_TASK_NAME Ljava/lang/String;
5+
public static final field API_GENERATE_TASK_NAME Ljava/lang/String;
36
public static final field Companion Ldev/adamko/kotlin/binary_compatibility_validator/BCVPlugin$Companion;
47
public static final field EXTENSION_NAME Ljava/lang/String;
58
public static final field RUNTIME_CLASSPATH_CONFIGURATION_NAME Ljava/lang/String;
9+
public static final field RUNTIME_CLASSPATH_RESOLVER_CONFIGURATION_NAME Ljava/lang/String;
610
public static final field TASK_GROUP Ljava/lang/String;
711
public synthetic fun apply (Ljava/lang/Object;)V
812
public fun apply (Lorg/gradle/api/plugins/PluginAware;)V
@@ -27,10 +31,14 @@ public abstract class dev/adamko/kotlin/binary_compatibility_validator/BCVProjec
2731
}
2832

2933
public abstract class dev/adamko/kotlin/binary_compatibility_validator/BCVProjectPlugin : org/gradle/api/Plugin {
34+
public static final field Companion Ldev/adamko/kotlin/binary_compatibility_validator/BCVProjectPlugin$Companion;
3035
public synthetic fun apply (Ljava/lang/Object;)V
3136
public fun apply (Lorg/gradle/api/Project;)V
3237
}
3338

39+
public final class dev/adamko/kotlin/binary_compatibility_validator/BCVProjectPlugin$Companion {
40+
}
41+
3442
public abstract class dev/adamko/kotlin/binary_compatibility_validator/BCVSettingsPlugin : org/gradle/api/Plugin {
3543
public synthetic fun apply (Ljava/lang/Object;)V
3644
public fun apply (Lorg/gradle/api/initialization/Settings;)V

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ constructor() : Plugin<PluginAware> {
2222
companion object {
2323
const val API_DIR = "api"
2424
const val EXTENSION_NAME = "binaryCompatibilityValidator"
25-
const val TASK_GROUP = "bcv mu"
2625
const val RUNTIME_CLASSPATH_CONFIGURATION_NAME = "bcvMuRuntime"
26+
const val RUNTIME_CLASSPATH_RESOLVER_CONFIGURATION_NAME = "bcvMuRuntimeResolver"
27+
28+
const val TASK_GROUP = "bcv mu"
29+
const val API_CHECK_TASK_NAME = "apiCheck"
30+
const val API_DUMP_TASK_NAME = "apiDump"
31+
const val API_GENERATE_TASK_NAME = "apiGenerate"
2732
}
2833
}

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

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
11
package dev.adamko.kotlin.binary_compatibility_validator
22

3+
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.API_CHECK_TASK_NAME
34
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.API_DIR
5+
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.API_DUMP_TASK_NAME
6+
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.API_GENERATE_TASK_NAME
47
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.EXTENSION_NAME
58
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.RUNTIME_CLASSPATH_CONFIGURATION_NAME
6-
import dev.adamko.kotlin.binary_compatibility_validator.internal.BCVInternalApi
7-
import dev.adamko.kotlin.binary_compatibility_validator.internal.sourceSets
9+
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.RUNTIME_CLASSPATH_RESOLVER_CONFIGURATION_NAME
10+
import dev.adamko.kotlin.binary_compatibility_validator.internal.*
11+
import dev.adamko.kotlin.binary_compatibility_validator.internal.Dynamic.Companion.Dynamic
812
import dev.adamko.kotlin.binary_compatibility_validator.tasks.BCVApiCheckTask
913
import dev.adamko.kotlin.binary_compatibility_validator.tasks.BCVApiDumpTask
1014
import dev.adamko.kotlin.binary_compatibility_validator.tasks.BCVApiGenerateTask
1115
import dev.adamko.kotlin.binary_compatibility_validator.tasks.BCVDefaultTask
1216
import javax.inject.Inject
17+
import org.gradle.api.NamedDomainObjectProvider
1318
import org.gradle.api.Plugin
1419
import org.gradle.api.Project
20+
import org.gradle.api.artifacts.Configuration
1521
import org.gradle.api.file.ProjectLayout
22+
import org.gradle.api.logging.Logging
1623
import org.gradle.api.provider.ProviderFactory
1724
import org.gradle.api.tasks.SourceSet
1825
import org.gradle.internal.component.external.model.TestFixturesSupport.TEST_FIXTURE_SOURCESET_NAME
1926
import org.gradle.kotlin.dsl.*
2027
import org.gradle.language.base.plugins.LifecycleBasePlugin
28+
import org.gradle.language.base.plugins.LifecycleBasePlugin.CHECK_TASK_NAME
2129
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
2230
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetContainer
2331
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetsContainer
@@ -37,29 +45,15 @@ constructor(
3745

3846
val extension = createExtension(project)
3947

40-
val bcvGenerateClasspath =
41-
project.configurations.register(RUNTIME_CLASSPATH_CONFIGURATION_NAME) {
42-
isCanBeConsumed = false
43-
isCanBeResolved = true
44-
isVisible = false
45-
defaultDependencies {
46-
addLater(
47-
extension.kotlinxBinaryCompatibilityValidatorVersion.map { version ->
48-
project.dependencies.create(
49-
"org.jetbrains.kotlinx:binary-compatibility-validator:$version"
50-
)
51-
}
52-
)
53-
}
54-
}
48+
val bcvGenerateClasspath = createBcvMuClasspath(project, extension)
5549

5650
project.tasks.withType<BCVDefaultTask>().configureEach {
5751
bcvEnabled.convention(extension.enabled)
5852
onlyIf("BCV is disabled") { bcvEnabled.get() }
5953
}
6054

6155
project.tasks.withType<BCVApiGenerateTask>().configureEach {
62-
runtimeClasspath.from(bcvGenerateClasspath.map { it.incoming.files })
56+
runtimeClasspath.from(bcvGenerateClasspath)
6357
targets.addAllLater(providers.provider { extension.targets })
6458
onlyIf("Must have at least one target") { targets.isNotEmpty() }
6559
outputApiBuildDir.convention(layout.buildDirectory.dir("bcv-api"))
@@ -76,17 +70,17 @@ constructor(
7670
apiDirectory.convention(extension.outputApiDir)
7771
}
7872

79-
val apiGenerateTask = project.tasks.register("apiGenerate", BCVApiGenerateTask::class)
73+
val apiGenerateTask = project.tasks.register(API_GENERATE_TASK_NAME, BCVApiGenerateTask::class)
8074

81-
project.tasks.register("apiDump", BCVApiDumpTask::class) {
75+
project.tasks.register(API_DUMP_TASK_NAME, BCVApiDumpTask::class) {
8276
apiDumpFiles.from(apiGenerateTask.map { it.outputApiBuildDir })
8377
}
8478

85-
val apiCheckTask = project.tasks.register("apiCheck", BCVApiCheckTask::class) {
79+
val apiCheckTask = project.tasks.register(API_CHECK_TASK_NAME, BCVApiCheckTask::class) {
8680
apiBuildDir.convention(apiGenerateTask.flatMap { it.outputApiBuildDir })
8781
}
8882

89-
project.tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME).configure {
83+
project.tasks.named(CHECK_TASK_NAME).configure {
9084
dependsOn(apiCheckTask)
9185
}
9286

@@ -122,6 +116,34 @@ constructor(
122116
return extension
123117
}
124118

119+
private fun createBcvMuClasspath(
120+
project: Project,
121+
extension: BCVProjectExtension,
122+
): NamedDomainObjectProvider<Configuration> {
123+
124+
val bcvGenerateClasspath =
125+
project.configurations.register(RUNTIME_CLASSPATH_CONFIGURATION_NAME) {
126+
description = "Runtime classpath for running binary-compatibility-validator."
127+
declarable()
128+
defaultDependencies {
129+
addLater(
130+
extension.kotlinxBinaryCompatibilityValidatorVersion.map { version ->
131+
project.dependencies.create(
132+
"org.jetbrains.kotlinx:binary-compatibility-validator:$version"
133+
)
134+
}
135+
)
136+
}
137+
}
138+
139+
return project.configurations.register(RUNTIME_CLASSPATH_RESOLVER_CONFIGURATION_NAME) {
140+
description = "Resolve the runtime classpath for running binary-compatibility-validator."
141+
resolvable()
142+
isVisible = false
143+
extendsFrom(bcvGenerateClasspath.get())
144+
}
145+
}
146+
125147
private fun createKotlinJvmTargets(
126148
project: Project,
127149
extension: BCVProjectExtension,
@@ -179,7 +201,7 @@ constructor(
179201
}
180202
}
181203
}
182-
}
204+
}
183205
}
184206

185207
private fun createJavaTestFixtureTargets(
@@ -199,4 +221,8 @@ constructor(
199221
}
200222
}
201223
}
224+
225+
companion object {
226+
private val logger = Logging.getLogger(BCVProjectPlugin::class.java)
227+
}
202228
}

modules/bcv-gradle-plugin/src/main/kotlin/internal/gradleUtils.kt

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,96 @@ package dev.adamko.kotlin.binary_compatibility_validator.internal
22

33
import org.gradle.api.NamedDomainObjectContainer
44
import org.gradle.api.NamedDomainObjectFactory
5+
import org.gradle.api.Project
6+
import org.gradle.api.artifacts.Configuration
57
import org.gradle.api.model.ObjectFactory
68
import org.gradle.api.plugins.ExtensionContainer
79
import org.gradle.kotlin.dsl.*
10+
import org.gradle.util.GradleVersion
11+
12+
13+
/** The current Gradle version */
14+
internal val CurrentGradleVersion: GradleVersion
15+
get() = GradleVersion.current()
16+
17+
18+
/** @see GradleVersion.compareTo */
19+
internal operator fun GradleVersion.compareTo(version: String): Int =
20+
compareTo(GradleVersion.version(version))
21+
22+
23+
/**
24+
* Mark this [Configuration] as one that should be used to declare dependencies in
25+
* [Project.dependencies] block.
26+
*
27+
* Declarable Configurations should be extended by [resolvable] and [consumable] Configurations.
28+
*
29+
* ```
30+
* isCanBeResolved = false
31+
* isCanBeConsumed = false
32+
* isCanBeDeclared = true
33+
* ```
34+
*/
35+
internal fun Configuration.declarable(
36+
visible: Boolean = false,
37+
) {
38+
isCanBeResolved = false
39+
isCanBeConsumed = false
40+
canBeDeclared(true)
41+
isVisible = visible
42+
}
43+
44+
45+
/**
46+
* Mark this [Configuration] as one that will be consumed by other subprojects.
47+
*
48+
* ```
49+
* isCanBeResolved = false
50+
* isCanBeConsumed = true
51+
* isCanBeDeclared = false
52+
* ```
53+
*/
54+
internal fun Configuration.consumable(
55+
visible: Boolean = true,
56+
) {
57+
isCanBeResolved = false
58+
isCanBeConsumed = true
59+
canBeDeclared(false)
60+
isVisible = visible
61+
}
62+
63+
64+
/**
65+
* Mark this [Configuration] as one that will consume artifacts from other subprojects (also known as 'resolving')
66+
*
67+
* ```
68+
* isCanBeResolved = true
69+
* isCanBeConsumed = false
70+
* isCanBeDeclared = false
71+
* ```
72+
*/
73+
internal fun Configuration.resolvable(
74+
visible: Boolean = false,
75+
) {
76+
isCanBeResolved = true
77+
isCanBeConsumed = false
78+
canBeDeclared(false)
79+
isVisible = visible
80+
}
81+
82+
83+
/**
84+
* Enable/disable [Configuration.isCanBeDeclared] only if it is supported by the
85+
* [CurrentGradleVersion]
86+
*
87+
* This function should be removed when the minimal supported Gradle version is 8.2.
88+
*/
89+
@Suppress("UnstableApiUsage")
90+
private fun Configuration.canBeDeclared(value: Boolean) {
91+
if (CurrentGradleVersion >= "8.2") {
92+
isCanBeDeclared = value
93+
}
94+
}
895

996

1097
/**

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

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@ package dev.adamko.kotlin.binary_compatibility_validator.tasks
22

33
import com.github.difflib.DiffUtils
44
import com.github.difflib.UnifiedDiffUtils
5+
import dev.adamko.kotlin.binary_compatibility_validator.BCVPlugin.Companion.API_DUMP_TASK_NAME
56
import dev.adamko.kotlin.binary_compatibility_validator.internal.BCVInternalApi
67
import dev.adamko.kotlin.binary_compatibility_validator.internal.GradlePath
78
import dev.adamko.kotlin.binary_compatibility_validator.internal.fullPath
8-
import java.io.*
9+
import java.io.File
910
import java.util.TreeMap
1011
import javax.inject.Inject
11-
import org.gradle.api.*
12-
import org.gradle.api.file.*
12+
import org.gradle.api.file.DirectoryProperty
13+
import org.gradle.api.file.FileVisitDetails
14+
import org.gradle.api.file.RelativePath
1315
import org.gradle.api.model.ObjectFactory
1416
import org.gradle.api.provider.Property
1517
import org.gradle.api.provider.Provider
1618
import org.gradle.api.provider.ProviderFactory
1719
import org.gradle.api.tasks.*
20+
import org.gradle.api.tasks.PathSensitivity.RELATIVE
1821

1922
@CacheableTask
2023
abstract class BCVApiCheckTask
@@ -27,7 +30,7 @@ constructor(
2730

2831
@get:InputDirectory
2932
@get:Optional
30-
@get:PathSensitive(PathSensitivity.RELATIVE)
33+
@get:PathSensitive(RELATIVE)
3134
val projectApiDir: Provider<File>
3235
// workaround for https://github.com/gradle/gradle/issues/2016
3336
get() = expectedApiDirPath.flatMap { providers.provider { File(it).takeIf(File::exists) } }
@@ -37,15 +40,15 @@ constructor(
3740
abstract val expectedApiDirPath: Property<String>
3841

3942
@get:InputDirectory
40-
@get:PathSensitive(PathSensitivity.RELATIVE)
43+
@get:PathSensitive(RELATIVE)
4144
abstract val apiBuildDir: DirectoryProperty
4245

4346
@get:Input
4447
internal abstract val expectedProjectName: Property<String>
4548

4649
// Project and tasks paths are used for creating better error messages
4750
private val projectFullPath = project.fullPath
48-
private val apiDumpTaskPath = GradlePath(project.path).child("apiDump")
51+
private val apiDumpTaskPath = GradlePath(project.path).child(API_DUMP_TASK_NAME)
4952

5053
private val rootDir = project.rootProject.rootDir
5154

@@ -99,17 +102,16 @@ constructor(
99102
)
100103
}
101104

102-
val diff = compareFiles(
105+
val diffText = compareFiles(
103106
checkFile = checkApiDeclaration,
104107
builtFile = builtApiDeclaration,
105-
)
106-
val diffSet = mutableSetOf<String>()
107-
if (diff != null) diffSet.add(diff)
108-
if (diffSet.isNotEmpty()) {
109-
val diffText = diffSet.joinToString("\n\n")
108+
)?.trim()
109+
110+
if (!diffText.isNullOrBlank()) {
110111
error(
111112
"""
112113
|API check failed for project $projectFullPath.
114+
|
113115
|$diffText
114116
|
115117
|You can run '$apiDumpTaskPath' task to overwrite API declarations
@@ -154,12 +156,11 @@ constructor(
154156
}
155157

156158
/*
157-
* We use case-insensitive comparison to workaround issues with case-insensitive OSes
158-
* and Gradle behaving slightly different on different platforms.
159-
* We neither know original sensitivity of existing .api files, not
160-
* build ones, because projectName that is part of the path can have any sensitivity.
161-
* To work around that, we replace paths we are looking for the same paths that
162-
* actually exist on FS.
159+
* We use case-insensitive comparison to workaround issues with case-insensitive OSes and Gradle
160+
* behaving slightly different on different platforms. We neither know original sensitivity of
161+
* existing .api files, not build ones, because projectName that is part of the path can have any
162+
* sensitivity. To work around that, we replace paths we are looking for the same paths that
163+
* actually exist on the FS.
163164
*/
164165
private class RelativePaths(
165166
private val map: TreeMap<RelativePath, RelativePath> = caseInsensitiveMap()

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ constructor(
3131
val targets: NamedDomainObjectContainer<BCVTarget> =
3232
extensions.adding("targets") { objects.domainObjectContainer() }
3333

34-
@get:InputFiles
35-
@get:PathSensitive(PathSensitivity.RELATIVE)
34+
@get:Internal
35+
@Deprecated("inputDependencies was unused and can be removed without impact")
36+
@Suppress("unused")
3637
abstract val inputDependencies: ConfigurableFileCollection
3738

3839
@get:Classpath

0 commit comments

Comments
 (0)