From 1ba220d7aa3b03a39059bf7419faf9f1063196c3 Mon Sep 17 00:00:00 2001 From: Oleg Yukhnevich Date: Mon, 30 Sep 2024 15:09:05 +0300 Subject: [PATCH] Refactor `build-settings-logic` to expose single plugin (#3834) * `dokkasettings` plugin should be applied to all projects in `settings.gradle.kts` * content of `dokkasettings` is copied to `build-settings-logic` itself * remove usage of user/password for build cache and use `develocity` extension * move foojay toolchains there to share it --- build-logic/settings.gradle.kts | 3 +- build-settings-logic/build.gradle.kts | 1 + build-settings-logic/settings.gradle.kts | 108 ++++++++++++++++- .../kotlin/DokkaBuildSettingsProperties.kt | 53 --------- ...kasettings.build-cache.settings.gradle.kts | 64 ---------- ...ings.gradle-enterprise.settings.gradle.kts | 68 ----------- .../kotlin/dokkasettings.settings.gradle.kts | 109 ++++++++++++++++++ dokka-integration-tests/settings.gradle.kts | 3 +- .../dokka-gradle-plugin/settings.gradle.kts | 3 +- dokka-runners/runner-cli/settings.gradle.kts | 3 +- .../runner-maven-plugin/settings.gradle.kts | 3 +- gradle/libs.versions.toml | 3 + settings.gradle.kts | 4 +- 13 files changed, 221 insertions(+), 204 deletions(-) delete mode 100644 build-settings-logic/src/main/kotlin/DokkaBuildSettingsProperties.kt delete mode 100644 build-settings-logic/src/main/kotlin/dokkasettings.build-cache.settings.gradle.kts delete mode 100644 build-settings-logic/src/main/kotlin/dokkasettings.gradle-enterprise.settings.gradle.kts create mode 100644 build-settings-logic/src/main/kotlin/dokkasettings.settings.gradle.kts diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts index 6539578d00..44f02ba476 100644 --- a/build-logic/settings.gradle.kts +++ b/build-logic/settings.gradle.kts @@ -38,6 +38,5 @@ dependencyResolutionManagement { } plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" - id("dokkasettings.build-cache") + id("dokkasettings") } diff --git a/build-settings-logic/build.gradle.kts b/build-settings-logic/build.gradle.kts index 08c8658973..78114e59b1 100644 --- a/build-settings-logic/build.gradle.kts +++ b/build-settings-logic/build.gradle.kts @@ -15,4 +15,5 @@ kotlin { dependencies { implementation(libs.gradlePlugin.gradle.develocity) implementation(libs.gradlePlugin.gradle.customUserData) + implementation(libs.gradlePlugin.gradle.foojayToolchains) } diff --git a/build-settings-logic/settings.gradle.kts b/build-settings-logic/settings.gradle.kts index 73cea3689b..a13d17ea4b 100644 --- a/build-settings-logic/settings.gradle.kts +++ b/build-settings-logic/settings.gradle.kts @@ -36,13 +36,109 @@ dependencyResolutionManagement { } } +// We have to make sure the build-cache config is consistent in the settings.gradle.kts +// files of all projects. The natural way to share logic is with a convention plugin, +// but we can't apply a convention plugin in build-settings-logic to itself, so we just copy it. +// We could publish build-settings-logic to a Maven repo? But this is quicker and easier. +// The following content should be kept in sync with the content of: +// `src/main/kotlin/dokkasettings.settings.gradle.kts` +// The only difference with the script above is explicitly specified versions + +//region copy of src/main/kotlin/dokkasettings.settings.gradle.kts + +// version should be kept in sync with `gradle/libs.versions.toml` plugins { + id("com.gradle.develocity") version "3.17.6" + id("com.gradle.common-custom-user-data-gradle-plugin") version "2.0.2" apply false id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" } -// We have to make sure the build-cache config is consistent in the settings.gradle.kts -// files of all projects. The natural way to share logic is with a convention plugin, -// but we can't apply a convention plugin in build-settings-logic to itself, unless we -// do it with a dumb hack: -apply(from = "src/main/kotlin/dokkasettings.build-cache.settings.gradle.kts") -// We could publish build-settings-logic to a Maven repo? But this is quicker and easier. +//region properties +val buildingOnTeamCity: Boolean = System.getenv("TEAMCITY_VERSION") != null +val buildingOnGitHub: Boolean = System.getenv("GITHUB_ACTION") != null +val buildingOnCi: Boolean = System.getenv("CI") != null || buildingOnTeamCity || buildingOnGitHub + +fun dokkaProperty(name: String): Provider = + providers.gradleProperty("org.jetbrains.dokka.$name") + +fun dokkaProperty(name: String, convert: (String) -> T): Provider = + dokkaProperty(name).map(convert) +//endregion + +//region Gradle Build Scan +// NOTE: build scan properties are documented in CONTRIBUTING.md +val buildScanEnabled: Provider = + dokkaProperty("build.scan.enabled", String::toBoolean) + .orElse(buildingOnCi) + +val BUILD_SCAN_USERNAME_DEFAULT = "" + +/** Optionally override the default name attached to a Build Scan. */ +val buildScanUsername: Provider = + dokkaProperty("build.scan.username") + .orElse(BUILD_SCAN_USERNAME_DEFAULT) + .map(String::trim) + +develocity { + val buildScanEnabled = buildScanEnabled.get() + + if (buildScanEnabled) { + plugins.apply("com.gradle.common-custom-user-data-gradle-plugin") + } + + server = "https://ge.jetbrains.com/" + + buildScan { + publishing { + onlyIf { buildScanEnabled } + } + + capture { + buildLogging = buildScanEnabled + fileFingerprints = buildScanEnabled + testLogging = buildScanEnabled + } + + val overriddenName = buildScanUsername.orNull + obfuscation { + ipAddresses { _ -> listOf("0.0.0.0") } + hostname { _ -> "concealed" } + username { originalUsername -> + when { + buildingOnTeamCity -> "TeamCity" + buildingOnGitHub -> "GitHub" + buildingOnCi -> "CI" + !overriddenName.isNullOrBlank() -> overriddenName + overriddenName == BUILD_SCAN_USERNAME_DEFAULT -> originalUsername + else -> "unknown" + } + } + } + } +} +//endregion + +//region Gradle Build Cache +val buildCacheLocalEnabled: Provider = + dokkaProperty("build.cache.local.enabled", String::toBoolean) + .orElse(!buildingOnCi) +val buildCacheLocalDirectory: Provider = + dokkaProperty("build.cache.local.directory") +val buildCachePushEnabled: Provider = + dokkaProperty("build.cache.push", String::toBoolean) + .orElse(buildingOnTeamCity) + +buildCache { + local { + isEnabled = buildCacheLocalEnabled.get() + if (buildCacheLocalDirectory.orNull != null) { + directory = buildCacheLocalDirectory.get() + } + } + remote(develocity.buildCache) { + isPush = buildCachePushEnabled.get() + } +} +//endregion + +//endregion diff --git a/build-settings-logic/src/main/kotlin/DokkaBuildSettingsProperties.kt b/build-settings-logic/src/main/kotlin/DokkaBuildSettingsProperties.kt deleted file mode 100644 index aa3cc20104..0000000000 --- a/build-settings-logic/src/main/kotlin/DokkaBuildSettingsProperties.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ -import org.gradle.api.initialization.Settings -import org.gradle.api.provider.Provider -import org.gradle.api.provider.ProviderFactory -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.findByType -import javax.inject.Inject - -/** - * Shared properties in `settings.gradle.kts` files. - * - * Fetch an instance using [DokkaBuildSettingsProperties.Companion.dokkaBuildSettingsProperties]. - */ -abstract class DokkaBuildSettingsProperties @Inject constructor( - private val providers: ProviderFactory -) { - val buildingOnTeamCity: Boolean = System.getenv("TEAMCITY_VERSION") != null - val buildingOnGitHub: Boolean = System.getenv("GITHUB_ACTION") != null - val buildingOnCi: Boolean = System.getenv("CI") != null || buildingOnTeamCity || buildingOnGitHub - - - //region Gradle Build Scan - // NOTE: build scan properties are documented in CONTRIBUTING.md - val buildScanEnabled: Provider = - dokkaProperty("build.scan.enabled", String::toBoolean) - .orElse(buildingOnCi) - - /** Optionally override the default name attached to a Build Scan. */ - val buildScanUsername: Provider = - dokkaProperty("build.scan.username") - .orElse(BUILD_SCAN_USERNAME_DEFAULT) - .map(String::trim) - //endregion - - - private fun dokkaProperty(name: String): Provider = - providers.gradleProperty("org.jetbrains.dokka.$name") - - private fun dokkaProperty(name: String, convert: (String) -> T): Provider = - dokkaProperty(name).map(convert) - - companion object { - const val BUILD_SCAN_USERNAME_DEFAULT = "" - - val Settings.dokkaBuildSettingsProperties: DokkaBuildSettingsProperties - get() { - return extensions.findByType() - ?: extensions.create("dokkaBuildSettingsProperties") - } - } -} diff --git a/build-settings-logic/src/main/kotlin/dokkasettings.build-cache.settings.gradle.kts b/build-settings-logic/src/main/kotlin/dokkasettings.build-cache.settings.gradle.kts deleted file mode 100644 index 31738d6308..0000000000 --- a/build-settings-logic/src/main/kotlin/dokkasettings.build-cache.settings.gradle.kts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -/** - * Gradle Build Cache conventions. - * - * Because Dokka uses Composite Builds, Build Cache must be configured consistently on - * - the root settings.gradle.kts, - * - and the settings.gradle.kts of any projects added with `pluginManagement { includedBuild("...") }` - * - * See https://docs.gradle.org/8.4/userguide/build_cache.html#sec:build_cache_composite. - * - * ⚠️ This file _must_ be applicable as a script plugin and so _must not_ depend on other source files. - * - * Based on https://github.com/JetBrains/kotlin/blob/2675531624d42851af502a993bbefd65ee3e38ef/repo/gradle-settings-conventions/build-cache/src/main/kotlin/build-cache.settings.gradle.kts - */ - -val buildingOnTeamCity: Boolean = System.getenv("TEAMCITY_VERSION") != null -val buildingOnGitHub: Boolean = System.getenv("GITHUB_ACTION") != null -val buildingOnCi: Boolean = System.getenv("CI") != null || buildingOnTeamCity || buildingOnGitHub - -fun dokkaProperty(name: String): Provider = - providers.gradleProperty("org.jetbrains.dokka.$name") - -fun dokkaProperty(name: String, convert: (String) -> T): Provider = - dokkaProperty(name).map(convert) - -//region Gradle Build Cache -val buildCacheLocalEnabled: Provider = - dokkaProperty("build.cache.local.enabled", String::toBoolean) - .orElse(!buildingOnCi) -val buildCacheLocalDirectory: Provider = - dokkaProperty("build.cache.local.directory") -val buildCacheUrl: Provider = - dokkaProperty("build.cache.url").map(String::trim) -val buildCachePushEnabled: Provider = - dokkaProperty("build.cache.push", String::toBoolean) - .orElse(buildingOnTeamCity) -val buildCacheUser: Provider = - dokkaProperty("build.cache.user") -val buildCachePassword: Provider = - dokkaProperty("build.cache.password") -//endregion - -buildCache { - local { - isEnabled = buildCacheLocalEnabled.get() - if (buildCacheLocalDirectory.orNull != null) { - directory = buildCacheLocalDirectory.get() - } - } - remote { - url = uri("https://ge.jetbrains.com/cache/") - isPush = buildCachePushEnabled.get() - - if (buildCacheUser.isPresent && - buildCachePassword.isPresent - ) { - credentials.username = buildCacheUser.get() - credentials.password = buildCachePassword.get() - } - } -} diff --git a/build-settings-logic/src/main/kotlin/dokkasettings.gradle-enterprise.settings.gradle.kts b/build-settings-logic/src/main/kotlin/dokkasettings.gradle-enterprise.settings.gradle.kts deleted file mode 100644 index a6a00ed97e..0000000000 --- a/build-settings-logic/src/main/kotlin/dokkasettings.gradle-enterprise.settings.gradle.kts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ -import DokkaBuildSettingsProperties.Companion.BUILD_SCAN_USERNAME_DEFAULT -import DokkaBuildSettingsProperties.Companion.dokkaBuildSettingsProperties - -/** - * [Gradle Develocity](https://docs.gradle.com/develocity/gradle-plugin/) conventions. - * - * See [DokkaBuildSettingsProperties] for properties. - * - * To use JetBrain's Gradle Develocity set the URL - * https://ge.jetbrains.com/ - * in `$GRADLE_USER_HOME/gradle.properties`† - * - * ```properties - * org.jetbrains.dokka.build.scan.url=https\://ge.jetbrains.com/ - * ``` - * - * Based on https://github.com/JetBrains/kotlin/blob/19073b96a7ed53dbda61337465ca898c1482e090/repo/gradle-settings-conventions/gradle-enterprise/src/main/kotlin/gradle-enterprise.settings.gradle.kts - * - * † _See [`GRADLE_USER_HOME`](https://docs.gradle.org/8.5/userguide/directory_layout.html#dir:gradle_user_home)_ - */ - -plugins { - id("com.gradle.develocity") - id("com.gradle.common-custom-user-data-gradle-plugin") apply false -} - -develocity { - val buildSettingsProps = dokkaBuildSettingsProperties - - val buildScanEnabled = buildSettingsProps.buildScanEnabled.get() - - if (buildScanEnabled) { - plugins.apply("com.gradle.common-custom-user-data-gradle-plugin") - } - - server = "https://ge.jetbrains.com/" - - buildScan { - publishing { - onlyIf { buildScanEnabled } - } - - capture { - buildLogging = buildScanEnabled - fileFingerprints = buildScanEnabled - testLogging = buildScanEnabled - } - - val overriddenName = buildSettingsProps.buildScanUsername.orNull - obfuscation { - ipAddresses { _ -> listOf("0.0.0.0") } - hostname { _ -> "concealed" } - username { originalUsername -> - when { - buildSettingsProps.buildingOnTeamCity -> "TeamCity" - buildSettingsProps.buildingOnGitHub -> "GitHub" - buildSettingsProps.buildingOnCi -> "CI" - !overriddenName.isNullOrBlank() -> overriddenName - overriddenName == BUILD_SCAN_USERNAME_DEFAULT -> originalUsername - else -> "unknown" - } - } - } - } -} diff --git a/build-settings-logic/src/main/kotlin/dokkasettings.settings.gradle.kts b/build-settings-logic/src/main/kotlin/dokkasettings.settings.gradle.kts new file mode 100644 index 0000000000..8f7884f3ae --- /dev/null +++ b/build-settings-logic/src/main/kotlin/dokkasettings.settings.gradle.kts @@ -0,0 +1,109 @@ +/* + * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +// Based on https://github.com/JetBrains/kotlin/blob/c20f644ee4cd8d28b39b12ea5304b68c5639e531/repo/gradle-settings-conventions/develocity/src/main/kotlin/develocity.settings.gradle.kts +// Because Dokka uses Composite Builds, Build Cache must be configured consistently on: +// - the root settings.gradle.kts, +// - and the settings.gradle.kts of any projects added with `pluginManagement { includedBuild("...") }` +// The Content of this file should be kept in sync with the content at the end of: +// `build-settings-logic/settings.gradle.kts` +// useful links: +// - develocity: https://docs.gradle.com/develocity/gradle-plugin/ +// - build cache: https://docs.gradle.org/8.4/userguide/build_cache.html#sec:build_cache_composite + +plugins { + id("com.gradle.develocity") + id("com.gradle.common-custom-user-data-gradle-plugin") apply false + id("org.gradle.toolchains.foojay-resolver-convention") +} + +//region properties +val buildingOnTeamCity: Boolean = System.getenv("TEAMCITY_VERSION") != null +val buildingOnGitHub: Boolean = System.getenv("GITHUB_ACTION") != null +val buildingOnCi: Boolean = System.getenv("CI") != null || buildingOnTeamCity || buildingOnGitHub + +fun dokkaProperty(name: String): Provider = + providers.gradleProperty("org.jetbrains.dokka.$name") + +fun dokkaProperty(name: String, convert: (String) -> T): Provider = + dokkaProperty(name).map(convert) +//endregion + +//region Gradle Build Scan +// NOTE: build scan properties are documented in CONTRIBUTING.md +val buildScanEnabled: Provider = + dokkaProperty("build.scan.enabled", String::toBoolean) + .orElse(buildingOnCi) + +/** Optionally override the default name attached to a Build Scan. */ +val buildScanUsername: Provider = + dokkaProperty("build.scan.username") + .map(String::trim) + +develocity { + val buildScanEnabled = buildScanEnabled.get() + + if (buildScanEnabled) { + plugins.apply("com.gradle.common-custom-user-data-gradle-plugin") + } + + server = "https://ge.jetbrains.com/" + + buildScan { + publishing { + onlyIf { buildScanEnabled } + } + + capture { + buildLogging = buildScanEnabled + fileFingerprints = buildScanEnabled + testLogging = buildScanEnabled + } + + val overriddenName = buildScanUsername.orNull + // we need to assign properties' values to local variables to avoid issues with Gradle Configuration Cache. + // if we don't do it, by using those properties in `username { ... }` we catch `this` in closure + // and Gradle Configuration Cache doesn't allow to catch implicit `this` object + val buildingOnTeamCity = buildingOnTeamCity + val buildingOnGitHub = buildingOnGitHub + val buildingOnCi = buildingOnCi + obfuscation { + ipAddresses { _ -> listOf("0.0.0.0") } + hostname { _ -> "concealed" } + username { originalUsername -> + when { + buildingOnTeamCity -> "TeamCity" + buildingOnGitHub -> "GitHub" + buildingOnCi -> "CI" + !overriddenName.isNullOrBlank() -> overriddenName + else -> originalUsername + } + } + } + } +} +//endregion + +//region Gradle Build Cache +val buildCacheLocalEnabled: Provider = + dokkaProperty("build.cache.local.enabled", String::toBoolean) + .orElse(!buildingOnCi) +val buildCacheLocalDirectory: Provider = + dokkaProperty("build.cache.local.directory") +val buildCachePushEnabled: Provider = + dokkaProperty("build.cache.push", String::toBoolean) + .orElse(buildingOnTeamCity) + +buildCache { + local { + isEnabled = buildCacheLocalEnabled.get() + if (buildCacheLocalDirectory.orNull != null) { + directory = buildCacheLocalDirectory.get() + } + } + remote(develocity.buildCache) { + isPush = buildCachePushEnabled.get() + } +} +//endregion diff --git a/dokka-integration-tests/settings.gradle.kts b/dokka-integration-tests/settings.gradle.kts index e992a875bf..bdd4fdeda0 100644 --- a/dokka-integration-tests/settings.gradle.kts +++ b/dokka-integration-tests/settings.gradle.kts @@ -15,8 +15,7 @@ pluginManagement { } plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" - id("dokkasettings.gradle-enterprise") + id("dokkasettings") } dependencyResolutionManagement { diff --git a/dokka-runners/dokka-gradle-plugin/settings.gradle.kts b/dokka-runners/dokka-gradle-plugin/settings.gradle.kts index 5f58e239d3..f368a70b31 100644 --- a/dokka-runners/dokka-gradle-plugin/settings.gradle.kts +++ b/dokka-runners/dokka-gradle-plugin/settings.gradle.kts @@ -15,8 +15,7 @@ pluginManagement { } plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" - id("dokkasettings.gradle-enterprise") + id("dokkasettings") } dependencyResolutionManagement { diff --git a/dokka-runners/runner-cli/settings.gradle.kts b/dokka-runners/runner-cli/settings.gradle.kts index 83f87117ca..7ea3f28b35 100644 --- a/dokka-runners/runner-cli/settings.gradle.kts +++ b/dokka-runners/runner-cli/settings.gradle.kts @@ -15,8 +15,7 @@ pluginManagement { } plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" - id("dokkasettings.gradle-enterprise") + id("dokkasettings") } dependencyResolutionManagement { diff --git a/dokka-runners/runner-maven-plugin/settings.gradle.kts b/dokka-runners/runner-maven-plugin/settings.gradle.kts index e88d695ed9..adfc383b03 100644 --- a/dokka-runners/runner-maven-plugin/settings.gradle.kts +++ b/dokka-runners/runner-maven-plugin/settings.gradle.kts @@ -15,8 +15,7 @@ pluginManagement { } plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" - id("dokkasettings.gradle-enterprise") + id("dokkasettings") } dependencyResolutionManagement { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9d2bd96e3d..b5608a6b88 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -53,8 +53,10 @@ gradlePlugin-gradlePluginPublish = "1.2.1" gradlePlugin-gradleNode = "7.0.1" ## Gradle Develocity +# versions should be kept in sync with `build-settings-logic/settings.gradle.kts` gradlePlugin-gradle-customUserData = "2.0.2" gradlePlugin-gradle-develocity = "3.17.6" +gradlePlugin-gradle-foojayToolchains = "0.7.0" ## Test junit = "5.9.3" @@ -84,6 +86,7 @@ gradlePlugin-shadow = { module = "com.gradleup.shadow:shadow-gradle-plugin", ver gradlePlugin-gradlePublish = { module = "com.gradle.publish:plugin-publish-plugin", version.ref = "gradlePlugin-gradlePluginPublish" } gradlePlugin-gradle-customUserData = { module = "com.gradle:common-custom-user-data-gradle-plugin", version.ref = "gradlePlugin-gradle-customUserData" } gradlePlugin-gradle-develocity = { module = "com.gradle:develocity-gradle-plugin", version.ref = "gradlePlugin-gradle-develocity" } +gradlePlugin-gradle-foojayToolchains = { module = "org.gradle.toolchains:foojay-resolver", version.ref = "gradlePlugin-gradle-foojayToolchains" } gradlePlugin-androidApi = { module = "com.android.tools.build:gradle-api", version.ref = "gradlePlugin-android" } diff --git a/settings.gradle.kts b/settings.gradle.kts index a09ed58dbd..3ea9144972 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -72,9 +72,7 @@ dependencyResolutionManagement { } plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" - id("dokkasettings.gradle-enterprise") - id("dokkasettings.build-cache") + id("dokkasettings") } includeBuild("dokka-integration-tests")