diff options
Diffstat (limited to 'build-logic/src/main/kotlin')
15 files changed, 650 insertions, 0 deletions
diff --git a/build-logic/src/main/kotlin/org/jetbrains/CrossPlatformExec.kt b/build-logic/src/main/kotlin/org/jetbrains/CrossPlatformExec.kt new file mode 100644 index 00000000..715dde2f --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/CrossPlatformExec.kt @@ -0,0 +1,63 @@ +package org.jetbrains + +import org.gradle.api.tasks.AbstractExecTask +import org.gradle.internal.os.OperatingSystem +import java.io.File +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths + +open class CrossPlatformExec : AbstractExecTask<CrossPlatformExec>(CrossPlatformExec::class.java) { + private val windowsExtensions = listOf(".bat", ".cmd", ".exe") + private val unixExtensions = listOf("", ".sh") + + private val isWindows = OperatingSystem.current().isWindows + + override fun exec() { + val commandLine: MutableList<String> = this.commandLine + + if (commandLine.isNotEmpty()) { + commandLine[0] = findCommand(commandLine[0]) + } + + if (isWindows && commandLine.isNotEmpty() && commandLine[0].isNotBlank()) { + this.commandLine = listOf("cmd", "/c") + commandLine + } else { + this.commandLine = commandLine + } + + super.exec() + } + + private fun findCommand(command: String): String { + val normalizedCommand = normalizeCommandPaths(command) + val extensions = if (isWindows) windowsExtensions else unixExtensions + + return extensions.map { extension -> + resolveCommandFromFile(Paths.get("$normalizedCommand$extension")) + }.firstOrNull { it.isNotBlank() } ?: normalizedCommand + } + + private fun resolveCommandFromFile(commandFile: Path) = + if (!Files.isExecutable(commandFile)) { + "" + } else { + commandFile.toAbsolutePath().normalize().toString() + } + + + private fun normalizeCommandPaths(command: String): String { + // need to escape backslash so it works with regex + val backslashSeparator = "\\" + val forwardSlashSeparator = "/" + + // get the actual separator + val separator = if (File.separatorChar == '\\') backslashSeparator else File.separator + + return command + // first replace all of the backslashes with forward slashes + .replace(backslashSeparator, forwardSlashSeparator) + // then replace all forward slashes with whatever the separator actually is + .replace(forwardSlashSeparator, separator) + } +} diff --git a/build-logic/src/main/kotlin/org/jetbrains/DokkaPublicationChannel.kt b/build-logic/src/main/kotlin/org/jetbrains/DokkaPublicationChannel.kt new file mode 100644 index 00000000..03f607e8 --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/DokkaPublicationChannel.kt @@ -0,0 +1,62 @@ +@file:Suppress("LocalVariableName") + +package org.jetbrains + +import org.gradle.api.Project + +enum class DokkaPublicationChannel { + SPACE_DOKKA_DEV, + MAVEN_CENTRAL, + MAVEN_CENTRAL_SNAPSHOT, + GRADLE_PLUGIN_PORTAL; + + val acceptedDokkaVersionTypes: List<DokkaVersionType> + get() = when(this) { + MAVEN_CENTRAL -> listOf(DokkaVersionType.RELEASE, DokkaVersionType.RC) + MAVEN_CENTRAL_SNAPSHOT -> listOf(DokkaVersionType.SNAPSHOT) + SPACE_DOKKA_DEV -> listOf(DokkaVersionType.RELEASE, DokkaVersionType.RC, DokkaVersionType.DEV, DokkaVersionType.SNAPSHOT) + GRADLE_PLUGIN_PORTAL -> listOf(DokkaVersionType.RELEASE, DokkaVersionType.RC) + } + + fun isSpaceRepository() = this == SPACE_DOKKA_DEV + + fun isMavenRepository() = this == MAVEN_CENTRAL || this == MAVEN_CENTRAL_SNAPSHOT + + fun isGradlePluginPortal() = this == GRADLE_PLUGIN_PORTAL + + companion object { + fun fromPropertyString(value: String): DokkaPublicationChannel = when (value) { + "space-dokka-dev" -> SPACE_DOKKA_DEV + "maven-central-release" -> MAVEN_CENTRAL + "maven-central-snapshot" -> MAVEN_CENTRAL_SNAPSHOT + "gradle-plugin-portal" -> GRADLE_PLUGIN_PORTAL + else -> throw IllegalArgumentException("Unknown dokka_publication_channel=$value") + } + } +} + +val Project.publicationChannels: Set<DokkaPublicationChannel> + get() { + val publicationChannel = this.properties["dokka_publication_channel"]?.toString() + val publicationChannels = this.properties["dokka_publication_channels"]?.toString() + if (publicationChannel != null && publicationChannels != null) { + throw IllegalArgumentException( + "Only one of dokka_publication_channel and dokka_publication_channel*s* can be set. Found: \n" + + "dokka_publication_channel=$publicationChannel\n" + + "dokka_publication_channels=$publicationChannels" + ) + } + + if (publicationChannel != null) { + return setOf(DokkaPublicationChannel.fromPropertyString(publicationChannel)) + } + + if (publicationChannels != null) { + return publicationChannels.split("&").map { channel -> + DokkaPublicationChannel.fromPropertyString(channel) + }.toSet() + } + + return emptySet() + } + diff --git a/build-logic/src/main/kotlin/org/jetbrains/DokkaVersion.kt b/build-logic/src/main/kotlin/org/jetbrains/DokkaVersion.kt new file mode 100644 index 00000000..517c7731 --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/DokkaVersion.kt @@ -0,0 +1,19 @@ +package org.jetbrains + +import org.gradle.api.Project +import org.gradle.kotlin.dsl.extra +import org.gradle.kotlin.dsl.provideDelegate + +@Suppress("LocalVariableName") // property name with underscore as taken from gradle.properties +fun Project.configureDokkaVersion(): String { + val dokka_version: String? by this.extra + return checkNotNull(dokka_version) +} + +val Project.dokkaVersion: String + get() = configureDokkaVersion() + +val Project.dokkaVersionType: DokkaVersionType? + get() = DokkaVersionType.values().find { + it.suffix.matches(dokkaVersion.substringAfter("-", "")) + } diff --git a/build-logic/src/main/kotlin/org/jetbrains/DokkaVersionType.kt b/build-logic/src/main/kotlin/org/jetbrains/DokkaVersionType.kt new file mode 100644 index 00000000..077cd854 --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/DokkaVersionType.kt @@ -0,0 +1,8 @@ +package org.jetbrains + +enum class DokkaVersionType(val suffix: Regex) { + RELEASE("^$".toRegex()), + RC("RC\\d?".toRegex()), + SNAPSHOT("SNAPSHOT".toRegex()), + DEV("dev-\\d+".toRegex()); +} diff --git a/build-logic/src/main/kotlin/org/jetbrains/SetupMaven.kt b/build-logic/src/main/kotlin/org/jetbrains/SetupMaven.kt new file mode 100644 index 00000000..a1b59a50 --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/SetupMaven.kt @@ -0,0 +1,45 @@ +package org.jetbrains + +import org.gradle.api.artifacts.Configuration +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.Sync +import org.gradle.kotlin.dsl.creating +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.getValue +import java.io.File + +@Suppress("LeakingThis") +open class SetupMaven : Sync() { + @get:Input + var mavenVersion = "3.5.0" + + @get:Input + var mavenPluginToolsVersion = "3.5.2" + + @get:Internal + val mavenBuildDir = "${project.buildDir}/maven" + + @get:Internal + val mavenBinDir = "${project.buildDir}/maven-bin" + + @get:Internal + val mvn = File(mavenBinDir, "apache-maven-$mavenVersion/bin/mvn") + + private val mavenBinaryConfiguration: Configuration by project.configurations.creating { + project.dependencies { + this@creating.invoke( + group = "org.apache.maven", + name = "apache-maven", + version = mavenVersion, + classifier = "bin", ext = "zip" + ) + } + } + + init { + from(mavenBinaryConfiguration.map { file -> project.zipTree(file) }) + into(mavenBinDir) + } + +} diff --git a/build-logic/src/main/kotlin/org/jetbrains/ValidatePublications.kt b/build-logic/src/main/kotlin/org/jetbrains/ValidatePublications.kt new file mode 100644 index 00000000..af35a847 --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/ValidatePublications.kt @@ -0,0 +1,79 @@ +package org.jetbrains + +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.ProjectDependency +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.findByType + +open class ValidatePublications : DefaultTask() { + + init { + group = "verification" + project.tasks.named("check") { + dependsOn(this@ValidatePublications) + } + } + + @TaskAction + fun validatePublicationConfiguration() { + project.subprojects.forEach { subProject -> + val publishing = subProject.extensions.findByType<PublishingExtension>() ?: return@forEach + publishing.publications + .filterIsInstance<MavenPublication>() + .filter { it.version == project.dokkaVersion } + .forEach { _ -> + checkProjectDependenciesArePublished(subProject) + subProject.assertPublicationVersion() + } + } + } + + private fun checkProjectDependenciesArePublished(project: Project) { + val implementationDependencies = project.findDependenciesByName("implementation") + val apiDependencies = project.findDependenciesByName("api") + + val allDependencies = implementationDependencies + apiDependencies + + allDependencies + .filterIsInstance<ProjectDependency>() + .forEach { projectDependency -> + val publishing = projectDependency.dependencyProject.extensions.findByType<PublishingExtension>() + ?: throw UnpublishedProjectDependencyException( + project = project, dependencyProject = projectDependency.dependencyProject + ) + + val isPublished = publishing.publications.filterIsInstance<MavenPublication>() + .any { it.version == project.dokkaVersion } + + if (!isPublished) { + throw UnpublishedProjectDependencyException(project, projectDependency.dependencyProject) + } + } + } + + private fun Project.findDependenciesByName(name: String): Set<Dependency> { + return configurations.findByName(name)?.allDependencies.orEmpty() + } + + private fun Project.assertPublicationVersion() { + val versionTypeMatchesPublicationChannels = publicationChannels.all { publicationChannel -> + publicationChannel.acceptedDokkaVersionTypes.any { acceptedVersionType -> + acceptedVersionType == dokkaVersionType + } + } + if (!versionTypeMatchesPublicationChannels) { + throw AssertionError("Wrong version $dokkaVersion for configured publication channels $publicationChannels") + } + } + + private class UnpublishedProjectDependencyException( + project: Project, dependencyProject: Project + ): GradleException( + "Published project ${project.path} cannot depend on unpublished project ${dependencyProject.path}" + ) +} diff --git a/build-logic/src/main/kotlin/org/jetbrains/conventions/base-java.gradle.kts b/build-logic/src/main/kotlin/org/jetbrains/conventions/base-java.gradle.kts new file mode 100644 index 00000000..2073f9a2 --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/conventions/base-java.gradle.kts @@ -0,0 +1,22 @@ +package org.jetbrains.conventions + +/** + * Base configuration for Java projects. + * + * This convention plugin contains shared Java config for both the [KotlinJvmPlugin] convention plugin and + * the Gradle Plugin subproject (which cannot have the `kotlin("jvm")` plugin applied). + */ + +plugins { + java +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(8)) + } +} + +java { + withSourcesJar() +} diff --git a/build-logic/src/main/kotlin/org/jetbrains/conventions/base.gradle.kts b/build-logic/src/main/kotlin/org/jetbrains/conventions/base.gradle.kts new file mode 100644 index 00000000..c4352d16 --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/conventions/base.gradle.kts @@ -0,0 +1,12 @@ +package org.jetbrains.conventions + +plugins { + base +} + +// common Gradle configuration that should be applied to all projects + +if (project != rootProject) { + project.group = rootProject.group + project.version = rootProject.version +} diff --git a/build-logic/src/main/kotlin/org/jetbrains/conventions/dokka-integration-test.gradle.kts b/build-logic/src/main/kotlin/org/jetbrains/conventions/dokka-integration-test.gradle.kts new file mode 100644 index 00000000..f9edb68e --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/conventions/dokka-integration-test.gradle.kts @@ -0,0 +1,75 @@ +package org.jetbrains.conventions + +import org.gradle.api.tasks.testing.logging.TestExceptionFormat +import org.gradle.api.tasks.testing.logging.TestLogEvent + +plugins { + id("org.jetbrains.conventions.kotlin-jvm") +} + +val integrationTestSourceSet: SourceSet = sourceSets.create("integrationTest") { + compileClasspath += sourceSets.main.get().output + runtimeClasspath += sourceSets.main.get().output +} + +val integrationTestImplementation: Configuration by configurations.getting { + extendsFrom(configurations.implementation.get()) +} + +val integrationTestRuntimeOnly: Configuration by configurations.getting { + extendsFrom(configurations.runtimeOnly.get()) +} + +/** + * Dokka's integration test task is not cacheable because the HTML outputs + * it produces when running the tests are used for showcasing resulting documentation, + * which does not work well with caching. + * + * At the moment there are two problems that do not allow to make it cacheable: + * + * 1. The task's inputs are such that changes in Dokka's code do not invalidate the cache, + * because it is run with the same version of Dokka (`"DOKKA_VERSION"`) on the same + * test project inputs. + * 2. The tests generate HTML output which is then used to showcase documentation. + * The outputs are usually copied to a location from which it will be served. + * However, if the test is cacheable, it produces no outputs, so no documentation + * to showcase. It needs to be broken into two separate tasks: one cacheable for running + * the tests and producing HTML output, and another non-cacheable for copying the output. + * + * @see [org.jetbrains.dokka.it.TestOutputCopier] for more details on showcasing documentation + */ +@DisableCachingByDefault(because = "Contains incorrect inputs/outputs configuration, see the KDoc for details") +abstract class NonCacheableIntegrationTest : Test() + +val integrationTest by tasks.registering(NonCacheableIntegrationTest::class) { + maxHeapSize = "2G" + description = "Runs integration tests." + group = "verification" + useJUnit() + + testClassesDirs = integrationTestSourceSet.output.classesDirs + classpath = integrationTestSourceSet.runtimeClasspath + + setForkEvery(1) + project.properties["dokka_integration_test_parallelism"]?.toString()?.toIntOrNull()?.let { parallelism -> + maxParallelForks = parallelism + } + environment( + "isExhaustive", + project.properties["dokka_integration_test_is_exhaustive"]?.toString()?.toBoolean() + ?: System.getenv("DOKKA_INTEGRATION_TEST_IS_EXHAUSTIVE")?.toBoolean() + ?: false.toString() + ) + + testLogging { + exceptionFormat = TestExceptionFormat.FULL + events(TestLogEvent.SKIPPED, TestLogEvent.FAILED) + showExceptions = true + showCauses = true + showStackTraces = true + } +} + +tasks.check { + dependsOn(integrationTest) +} diff --git a/build-logic/src/main/kotlin/org/jetbrains/conventions/dokka.gradle.kts b/build-logic/src/main/kotlin/org/jetbrains/conventions/dokka.gradle.kts new file mode 100644 index 00000000..9a193cbb --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/conventions/dokka.gradle.kts @@ -0,0 +1,13 @@ +package org.jetbrains.conventions + +import org.gradle.kotlin.dsl.invoke +import org.jetbrains.isLocalPublication + +plugins { + id("org.jetbrains.dokka") +} + +tasks.dokkaHtml { + onlyIf { !isLocalPublication } + outputDirectory.set(layout.buildDirectory.dir("dokka").map { it.asFile }) +} diff --git a/build-logic/src/main/kotlin/org/jetbrains/conventions/kotlin-jvm.gradle.kts b/build-logic/src/main/kotlin/org/jetbrains/conventions/kotlin-jvm.gradle.kts new file mode 100644 index 00000000..c40ce57c --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/conventions/kotlin-jvm.gradle.kts @@ -0,0 +1,32 @@ +package org.jetbrains.conventions + +import org.jetbrains.configureDokkaVersion +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + id("org.jetbrains.conventions.base") + id("org.jetbrains.conventions.base-java") + kotlin("jvm") +} + +configureDokkaVersion() + +val language_version: String by project + +tasks.withType<KotlinCompile>().configureEach { + compilerOptions { + freeCompilerArgs.addAll( + listOf( + "-opt-in=kotlin.RequiresOptIn", + "-Xjsr305=strict", + "-Xskip-metadata-version-check", + // need 1.4 support, otherwise there might be problems with Gradle 6.x (it's bundling Kotlin 1.4) + "-Xsuppress-version-warnings" + ) + ) + allWarningsAsErrors.set(true) + languageVersion.set(KotlinVersion.fromVersion(language_version)) + apiVersion.set(KotlinVersion.fromVersion(language_version)) + } +} diff --git a/build-logic/src/main/kotlin/org/jetbrains/conventions/maven-publish.gradle.kts b/build-logic/src/main/kotlin/org/jetbrains/conventions/maven-publish.gradle.kts new file mode 100644 index 00000000..7007fd9e --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/conventions/maven-publish.gradle.kts @@ -0,0 +1,30 @@ +package org.jetbrains.conventions + +plugins { + id("org.jetbrains.conventions.base") + `maven-publish` + signing + id("org.jetbrains.conventions.dokka") +} + +val javadocJar by tasks.registering(Jar::class) { + group = JavaBasePlugin.DOCUMENTATION_GROUP + description = "Assembles a Javadoc JAR using Dokka HTML" + archiveClassifier.set("javadoc") + from(tasks.dokkaHtml) +} + +publishing { + repositories { + // Publish to a project-local Maven directory, for verification. To test, run: + // ./gradlew publishAllPublicationsToMavenProjectLocalRepository + // and check $rootDir/build/maven-project-local + maven(rootProject.layout.buildDirectory.dir("maven-project-local")) { + name = "MavenProjectLocal" + } + } + + publications.withType<MavenPublication>().configureEach { + artifact(javadocJar) + } +} diff --git a/build-logic/src/main/kotlin/org/jetbrains/projectUtils.kt b/build-logic/src/main/kotlin/org/jetbrains/projectUtils.kt new file mode 100644 index 00000000..46d803a5 --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/projectUtils.kt @@ -0,0 +1,16 @@ +package org.jetbrains + +import org.gradle.api.Project + +fun Project.whenEvaluated(action: Project.() -> Unit) { + if (state.executed) { + action() + } else { + afterEvaluate { action() } + } +} + +fun Project.invokeWhenEvaluated(action: (project: Project) -> Unit) { + whenEvaluated { action(this) } +} + diff --git a/build-logic/src/main/kotlin/org/jetbrains/publication.kt b/build-logic/src/main/kotlin/org/jetbrains/publication.kt new file mode 100644 index 00000000..60d91c33 --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/publication.kt @@ -0,0 +1,152 @@ +package org.jetbrains + +import com.github.jengelman.gradle.plugins.shadow.ShadowExtension +import org.gradle.api.Project +import org.gradle.api.plugins.JavaBasePlugin +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.publish.maven.tasks.PublishToMavenRepository +import org.gradle.api.tasks.TaskContainer +import org.gradle.api.tasks.TaskProvider +import org.gradle.api.tasks.bundling.Jar +import org.gradle.kotlin.dsl.* +import org.gradle.plugins.signing.SigningExtension +import org.jetbrains.DokkaPublicationChannel.* +import java.net.URI + +class DokkaPublicationBuilder { + enum class Component { + Java, Shadow + } + + var artifactId: String? = null + var component: Component = Component.Java +} + + +fun Project.registerDokkaArtifactPublication(publicationName: String, configure: DokkaPublicationBuilder.() -> Unit) { + configure<PublishingExtension> { + publications { + register<MavenPublication>(publicationName) { + val builder = DokkaPublicationBuilder().apply(configure) + artifactId = builder.artifactId + when (builder.component) { + DokkaPublicationBuilder.Component.Java -> from(components["java"]) + DokkaPublicationBuilder.Component.Shadow -> run { + extensions.getByType(ShadowExtension::class.java).component(this) + artifact(tasks["sourcesJar"]) + } + } + configurePom("Dokka ${project.name}") + } + } + } + + configureSpacePublicationIfNecessary(publicationName) + configureSonatypePublicationIfNecessary(publicationName) + createDokkaPublishTaskIfNecessary() +} + +fun Project.configureSpacePublicationIfNecessary(vararg publications: String) { + if (SPACE_DOKKA_DEV in this.publicationChannels) { + configure<PublishingExtension> { + repositories { + /* already registered */ + findByName(SPACE_DOKKA_DEV.name)?.let { return@repositories } + maven { + name = SPACE_DOKKA_DEV.name + url = URI.create("https://maven.pkg.jetbrains.space/kotlin/p/dokka/dev") + credentials { + username = System.getenv("SPACE_PACKAGES_USER") + password = System.getenv("SPACE_PACKAGES_SECRET") + } + } + } + } + } + + whenEvaluated { + tasks.withType<PublishToMavenRepository> { + if (this.repository.name == SPACE_DOKKA_DEV.name) { + this.isEnabled = this.isEnabled && publication.name in publications + if (!this.isEnabled) { + this.group = "disabled" + } + } + } + } +} + +fun Project.createDokkaPublishTaskIfNecessary() { + tasks.maybeCreate("dokkaPublish").run { + if (publicationChannels.any { it.isSpaceRepository() }) { + dependsOn(tasks.named("publish")) + } + + if (publicationChannels.any { it.isMavenRepository() }) { + dependsOn(tasks.named("publishToSonatype")) + } + + if (publicationChannels.any { it.isGradlePluginPortal() }) { + dependsOn(tasks.named("publishPlugins")) + } + } +} + +fun Project.configureSonatypePublicationIfNecessary(vararg publications: String) { + if (publicationChannels.any { it.isMavenRepository() }) { + signPublicationsIfKeyPresent(*publications) + } +} + +fun MavenPublication.configurePom(projectName: String) { + pom { + name.set(projectName) + description.set("Dokka is an API documentation engine for Kotlin and Java, performing the same function as Javadoc for Java") + url.set("https://github.com/Kotlin/dokka") + + licenses { + license { + name.set("The Apache Software License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + distribution.set("repo") + } + } + + developers { + developer { + id.set("JetBrains") + name.set("JetBrains Team") + organization.set("JetBrains") + organizationUrl.set("http://www.jetbrains.com") + } + } + + scm { + connection.set("scm:git:git://github.com/Kotlin/dokka.git") + url.set("https://github.com/Kotlin/dokka/tree/master") + } + } +} + +@Suppress("UnstableApiUsage") +private fun Project.signPublicationsIfKeyPresent(vararg publications: String) { + val signingKeyId: String? = System.getenv("SIGN_KEY_ID") + val signingKey: String? = System.getenv("SIGN_KEY") + val signingKeyPassphrase: String? = System.getenv("SIGN_KEY_PASSPHRASE") + + if (!signingKey.isNullOrBlank()) { + extensions.configure<SigningExtension>("signing") { + if (signingKeyId?.isNotBlank() == true) { + useInMemoryPgpKeys(signingKeyId, signingKey, signingKeyPassphrase) + } else { + useInMemoryPgpKeys(signingKey, signingKeyPassphrase) + } + publications.forEach { publicationName -> + extensions.findByType(PublishingExtension::class)!!.publications.findByName(publicationName)?.let { + sign(it) + } + } + } + } +} diff --git a/build-logic/src/main/kotlin/org/jetbrains/taskUtils.kt b/build-logic/src/main/kotlin/org/jetbrains/taskUtils.kt new file mode 100644 index 00000000..261d1663 --- /dev/null +++ b/build-logic/src/main/kotlin/org/jetbrains/taskUtils.kt @@ -0,0 +1,22 @@ +package org.jetbrains + +import org.gradle.api.Project +import org.gradle.api.Task + +fun Task.dependsOnMavenLocalPublication() { + project.rootProject.allprojects.forEach { otherProject -> + otherProject.invokeWhenEvaluated { evaluatedProject -> + evaluatedProject.tasks.findByName("publishToMavenLocal")?.let { publishingTask -> + this.dependsOn(publishingTask) + } + } + } +} + +val Project.isLocalPublication: Boolean + get() = gradle.startParameter.taskNames.any { + it.endsWith("publishToMavenLocal", ignoreCase = true) || + it.endsWith("integrationTest", ignoreCase = true) || + it.endsWith("check", ignoreCase = true) || + it.endsWith("test", ignoreCase = true) + } |