diff --git a/buildSrc/src/main/kotlin/JsConfig.kt b/buildSrc/src/main/kotlin/JsConfig.kt index 0cf581fd03c..161e05c452e 100644 --- a/buildSrc/src/main/kotlin/JsConfig.kt +++ b/buildSrc/src/main/kotlin/JsConfig.kt @@ -52,7 +52,6 @@ internal fun Project.configureJsTestTasks(target: String) { val shouldRunJsBrowserTest = !hasProperty("teamcity") || hasProperty("enable-js-tests") if (shouldRunJsBrowserTest) return - val capitalizedTarget = target.replaceFirstChar { it.titlecase() } - tasks.maybeNamed("clean${capitalizedTarget}BrowserTest") { onlyIf { false } } + tasks.maybeNamed("clean${target.capitalized()}BrowserTest") { onlyIf { false } } tasks.maybeNamed("${target}BrowserTest") { onlyIf { false } } } diff --git a/buildSrc/src/main/kotlin/Publication.kt b/buildSrc/src/main/kotlin/Publication.kt index 4020f60ed6c..07de40a7c29 100644 --- a/buildSrc/src/main/kotlin/Publication.kt +++ b/buildSrc/src/main/kotlin/Publication.kt @@ -2,72 +2,73 @@ * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. */ +import internal.* import org.gradle.api.* import org.gradle.api.publish.* import org.gradle.api.publish.maven.* import org.gradle.api.publish.maven.tasks.* +import org.gradle.api.publish.plugins.* import org.gradle.jvm.tasks.* import org.gradle.kotlin.dsl.* import org.gradle.plugins.signing.* import java.util.concurrent.locks.* -fun isAvailableForPublication(publication: Publication): Boolean { - val name = publication.name - if (name == "maven") return true - - var result = false - val jvmAndCommon = setOf( - "jvm", - "androidRelease", - "androidDebug", - "js", - "wasmJs", - "metadata", - "kotlinMultiplatform" - ) - result = result || name in jvmAndCommon - result = result || (HOST_NAME == "linux" && (name == "linuxX64" || name == "linuxArm64")) - result = result || (HOST_NAME == "windows" && name == "mingwX64") - val macPublications = setOf( - "iosX64", - "iosArm64", - "iosSimulatorArm64", - - "watchosX64", - "watchosArm32", - "watchosArm64", - "watchosSimulatorArm64", - "watchosDeviceArm64", - - "tvosX64", - "tvosArm64", - "tvosSimulatorArm64", - - "macosX64", - "macosArm64" - ) - - result = result || (HOST_NAME == "macos" && name in macPublications) - - // can be published from any host - val androidNativePublication = setOf( - "androidNativeArm32", - "androidNativeArm64", - "androidNativeX64", - "androidNativeX86" - ) - - result = result || name in androidNativePublication - - return result -} +private val jvmAndCommonTargets = setOf( + "jvm", + "androidRelease", + "androidDebug", + "metadata", + "kotlinMultiplatform", + "maven", +) + +private val jsTargets = setOf( + "js", + "wasmJs", +) + +private val linuxTargets = setOf( + "linuxX64", + "linuxArm64", +) + +private val windowsTargets = setOf( + "mingwX64", +) + +private val darwinTargets = setOf( + "iosX64", + "iosArm64", + "iosSimulatorArm64", + + "watchosX64", + "watchosArm32", + "watchosArm64", + "watchosSimulatorArm64", + "watchosDeviceArm64", + + "tvosX64", + "tvosArm64", + "tvosSimulatorArm64", + + "macosX64", + "macosArm64", +) + +private val androidNativeTargets = setOf( + "androidNativeArm32", + "androidNativeArm64", + "androidNativeX64", + "androidNativeX86", +) fun Project.configurePublication() { apply(plugin = "maven-publish") tasks.withType().configureEach { - onlyIf { isAvailableForPublication(publication) } + onlyIf { publication.isAvailableForPublication() } } + configureAggregatingTasks() val publishingUser: String? = System.getenv("PUBLISHING_USER") val publishingPassword: String? = System.getenv("PUBLISHING_PASSWORD") @@ -99,7 +100,7 @@ fun Project.configurePublication() { } maven { name = "testLocal" - setUrl("${rootProject.layout.buildDirectory.get().asFile}/m2") + setUrl(rootProject.layout.buildDirectory.dir("m2")) } } @@ -108,7 +109,8 @@ fun Project.configurePublication() { pom { name = project.name - description = project.description?.takeIf { it.isNotEmpty() } ?: "Ktor is a framework for quickly creating web applications in Kotlin with minimal effort." + description = project.description.orEmpty() + .ifEmpty { "Ktor is a framework for quickly creating web applications in Kotlin with minimal effort." } url = "https://github.com/ktorio/ktor" licenses { license { @@ -147,6 +149,36 @@ fun Project.configurePublication() { configureJavadocArtifact() } +private fun Publication.isAvailableForPublication(): Boolean { + val name = name + + var result = name in jvmAndCommonTargets || name in jsTargets || name in androidNativeTargets + result = result || (HOST_NAME == "linux" && name in linuxTargets) + result = result || (HOST_NAME == "windows" && name in windowsTargets) + result = result || (HOST_NAME == "macos" && name in darwinTargets) + + return result +} + +private fun Project.configureAggregatingTasks() { + registerAggregatingTask("JvmAndCommon", jvmAndCommonTargets) + if (hasJs || hasWasmJs) registerAggregatingTask("Js", jsTargets) + if (hasLinux) registerAggregatingTask("Linux", linuxTargets) + if (hasWindows) registerAggregatingTask("Windows", windowsTargets) + if (hasDarwin) registerAggregatingTask("Darwin", darwinTargets) + if (hasAndroidNative) registerAggregatingTask("AndroidNative", androidNativeTargets) +} + +private fun Project.registerAggregatingTask(name: String, targets: Set) { + tasks.register("publish${name}Publications") { + group = PublishingPlugin.PUBLISH_TASK_GROUP + val targetsTasks = targets.mapNotNull { target -> + tasks.maybeNamed("publish${target.capitalized()}PublicationToMavenRepository") + } + dependsOn(targetsTasks) + } +} + private fun Project.configureSigning() { extra["signing.gnupg.keyName"] = (System.getenv("SIGN_KEY_ID") ?: return) extra["signing.gnupg.passphrase"] = (System.getenv("SIGN_KEY_PASSPHRASE") ?: return) diff --git a/buildSrc/src/main/kotlin/TargetsConfig.kt b/buildSrc/src/main/kotlin/TargetsConfig.kt index 2de30a7fa76..d82cb47dfe3 100644 --- a/buildSrc/src/main/kotlin/TargetsConfig.kt +++ b/buildSrc/src/main/kotlin/TargetsConfig.kt @@ -5,13 +5,11 @@ @file:OptIn(ExperimentalKotlinGradlePluginApi::class) import org.gradle.api.* -import org.gradle.api.tasks.testing.* import org.gradle.kotlin.dsl.* import org.jetbrains.kotlin.gradle.* import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.konan.target.* -import org.jetbrains.kotlin.gradle.tasks.* import java.io.* private val Project.files: Array get() = project.projectDir.listFiles() ?: emptyArray() @@ -27,7 +25,7 @@ val Project.hasAndroidNative: Boolean get() = hasPosix || files.any { it.name == val Project.hasWindows: Boolean get() = hasPosix || files.any { it.name == "windows" } val Project.hasJsAndWasmShared: Boolean get() = files.any { it.name == "jsAndWasmShared" } val Project.hasJs: Boolean get() = hasCommon || files.any { it.name == "js" } || hasJsAndWasmShared -val Project.hasWasm: Boolean get() = hasCommon || files.any { it.name == "wasmJs" } || hasJsAndWasmShared +val Project.hasWasmJs: Boolean get() = hasCommon || files.any { it.name == "wasmJs" } || hasJsAndWasmShared val Project.hasJvm: Boolean get() = hasCommon || hasJvmAndNix || hasJvmAndPosix || files.any { it.name == "jvm" } val Project.hasExplicitNative: Boolean @@ -42,7 +40,7 @@ fun Project.configureTargets() { if (hasJvm) configureJvm() if (hasJs) configureJs() - if (hasWasm) configureWasm() + if (hasWasmJs) configureWasm() if (hasPosix) posixTargets() if (hasNix) nixTargets() diff --git a/buildSrc/src/main/kotlin/internal/String.kt b/buildSrc/src/main/kotlin/internal/String.kt new file mode 100644 index 00000000000..8cb2abb155d --- /dev/null +++ b/buildSrc/src/main/kotlin/internal/String.kt @@ -0,0 +1,7 @@ +/* + * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +package internal + +internal fun String.capitalized() = replaceFirstChar { it.uppercase() }