diff options
| author | Adam <897017+aSemy@users.noreply.github.com> | 2023-10-20 00:39:12 +1300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-19 13:39:12 +0200 |
| commit | 35d15601f2d129a7d3db67dd9e2f4c41c87ef083 (patch) | |
| tree | f9098cb5b79fc31b4a393347f5cebcf9d87dd139 /dokka-runners/dokkatoo/buildSrc/src | |
| parent | 8016c1face1283952e228aee348487bf0421ab90 (diff) | |
| download | dokka-35d15601f2d129a7d3db67dd9e2f4c41c87ef083.tar.gz dokka-35d15601f2d129a7d3db67dd9e2f4c41c87ef083.tar.bz2 dokka-35d15601f2d129a7d3db67dd9e2f4c41c87ef083.zip | |
Contribute Dokkatoo (#3188)
Diffstat (limited to 'dokka-runners/dokkatoo/buildSrc/src')
20 files changed, 1387 insertions, 0 deletions
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/android-setup.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/android-setup.gradle.kts new file mode 100644 index 00000000..ed22d799 --- /dev/null +++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/android-setup.gradle.kts @@ -0,0 +1,78 @@ +package buildsrc.conventions + +import org.jetbrains.kotlin.util.suffixIfNot + + +/** + * Utilities for preparing Android projects + */ + +plugins { + base + id("buildsrc.conventions.base") +} + + +val androidSdkDirPath: Provider<String> = providers + // first try getting the SDK installed on via GitHub step setup-android + .environmentVariable("ANDROID_SDK_ROOT").map(::File) + // else get the project-local SDK + .orElse(layout.projectDirectory.file("projects/ANDROID_SDK").asFile) + .map { it.invariantSeparatorsPath } + + +val createAndroidLocalPropertiesFile by tasks.registering { + + val localPropertiesFile = temporaryDir.resolve("local.properties") + outputs.file(localPropertiesFile).withPropertyName("localPropertiesFile") + + val androidSdkDirPath = androidSdkDirPath + inputs.property("androidSdkDirPath", androidSdkDirPath) + + doLast { + localPropertiesFile.apply { + parentFile.mkdirs() + createNewFile() + writeText( + """ + |# DO NOT EDIT - Generated by $path + | + |sdk.dir=${androidSdkDirPath.get()} + | + """.trimMargin() + ) + } + } +} + + +val updateAndroidLocalProperties by tasks.registering { + + // find all local.properties files + val localPropertiesFiles = layout.projectDirectory.dir("projects") + .asFileTree + .matching { include("**/local.properties") } + .files + + outputs.files(localPropertiesFiles).withPropertyName("localPropertiesFiles") + + val androidSdkDirPath = androidSdkDirPath + inputs.property("androidSdkDirPath", androidSdkDirPath) + + doLast { + localPropertiesFiles + .filter { it.exists() } + .forEach { file -> + file.writeText( + file.useLines { lines -> + lines.joinToString("\n") { line -> + when { + line.startsWith("sdk.dir=") -> "sdk.dir=${androidSdkDirPath.get()}" + else -> line + } + }.suffixIfNot("\n") + } + ) + } + } +} diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts new file mode 100644 index 00000000..60bfa2fe --- /dev/null +++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts @@ -0,0 +1,155 @@ +package buildsrc.conventions + +import java.time.Duration +import org.gradle.api.tasks.testing.logging.TestLogEvent + +/** + * A convention plugin that sets up common config and sensible defaults for all subprojects. + */ + +plugins { + base +} + +if (project != rootProject) { + project.version = rootProject.version + project.group = rootProject.group +} + +tasks.withType<AbstractArchiveTask>().configureEach { + // https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives + isPreserveFileTimestamps = false + isReproducibleFileOrder = true +} + +tasks.withType<AbstractTestTask>().configureEach { + timeout.set(Duration.ofMinutes(60)) + + testLogging { + showCauses = true + showExceptions = true + showStackTraces = true + showStandardStreams = true + events( + TestLogEvent.PASSED, + TestLogEvent.FAILED, + TestLogEvent.SKIPPED, + TestLogEvent.STARTED, + TestLogEvent.STANDARD_ERROR, + TestLogEvent.STANDARD_OUT, + ) + } +} + +tasks.withType<AbstractCopyTask>().configureEach { + includeEmptyDirs = false +} + +val updateTestReportCss by tasks.registering { + description = "Hack so the Gradle test reports have dark mode" + // the CSS is based on https://github.com/gradle/gradle/pull/12177 + + mustRunAfter(tasks.withType<Test>()) + mustRunAfter(tasks.withType<TestReport>()) + + val cssFiles = layout.buildDirectory.asFileTree.matching { + include("reports/**/css/base-style.css") + include("reports/**/css/style.css") + } + + outputs.files(cssFiles.files) + + doLast { + cssFiles.forEach { cssFile -> + val fileContent = cssFile.readText() + + if ("/* Dark mode */" in fileContent) { + return@forEach + } else { + when (cssFile.name) { + "base-style.css" -> cssFile.writeText( + fileContent + """ + + /* Dark mode */ + @media (prefers-color-scheme: dark) { + html { + background: black; + } + body, a, a:visited { + color: #E7E7E7FF; + } + #footer, #footer a { + color: #cacaca; + } + ul.tabLinks li { + border: solid 1px #cacaca; + background-color: #151515; + } + ul.tabLinks li:hover { + background-color: #383838; + } + ul.tabLinks li.selected { + background-color: #002d32; + border-color: #007987; + } + div.tab th, div.tab table { + border-bottom: solid #d0d0d0 1px; + } + span.code pre { + background-color: #0a0a0a; + border: solid 1px #5f5f5f; + } + } + """.trimIndent() + ) + + "style.css" -> cssFile.writeText( + fileContent + """ + + /* Dark mode */ + @media (prefers-color-scheme: dark) { + .breadcrumbs, .breadcrumbs a { + color: #9b9b9b; + } + #successRate, .summaryGroup { + border: solid 2px #d0d0d0; + } + .success, .success a { + color: #7fff7f; + } + div.success, #successRate.success { + background-color: #001c00; + border-color: #7fff7f; + } + .failures, .failures a { + color: #a30000; + } + .skipped, .skipped a { + color: #a26d13; + } + div.failures, #successRate.failures { + background-color: #170000; + border-color: #a30000; + } + } + """.trimIndent() + ) + } + } + } + } +} + +tasks.withType<Test>().configureEach { + finalizedBy(updateTestReportCss) +} + +tasks.withType<TestReport>().configureEach { + finalizedBy(updateTestReportCss) +} + +tasks.matching { it.name == "validatePlugins" }.configureEach { + // prevent warning + // Task ':validatePlugins' uses this output of task ':updateTestReportCss' without declaring an explicit or implicit dependency. + mustRunAfter(updateTestReportCss) +} diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokka-source-downloader.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokka-source-downloader.gradle.kts new file mode 100644 index 00000000..69e384e1 --- /dev/null +++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokka-source-downloader.gradle.kts @@ -0,0 +1,68 @@ +package buildsrc.conventions + +import buildsrc.settings.DokkaSourceDownloaderSettings +import buildsrc.utils.asConsumer +import buildsrc.utils.asProvider +import buildsrc.utils.dropDirectories +import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE +import org.gradle.kotlin.dsl.support.serviceOf + +plugins { + id("buildsrc.conventions.base") +} + +val dsdExt: DokkaSourceDownloaderSettings = extensions.create<DokkaSourceDownloaderSettings>( + DokkaSourceDownloaderSettings.EXTENSION_NAME +) + +val kotlinDokkaSource by configurations.creating<Configuration> { + asConsumer() + attributes { + attribute(USAGE_ATTRIBUTE, objects.named("externals-dokka-src")) + } +} + +val kotlinDokkaSourceElements by configurations.registering { + asProvider() + attributes { + attribute(USAGE_ATTRIBUTE, objects.named("externals-dokka-src")) + } +} + +dependencies { + kotlinDokkaSource(dsdExt.dokkaVersion.map { "kotlin:dokka:$it@zip" }) +} + +val prepareDokkaSource by tasks.registering(Sync::class) { + group = "dokka setup" + description = "Download & unpack Kotlin Dokka source code" + + inputs.property("dokkaVersion", dsdExt.dokkaVersion).optional(false) + + val archives = serviceOf<ArchiveOperations>() + + from( + kotlinDokkaSource.incoming + .artifacts + .resolvedArtifacts + .map { artifacts -> + artifacts.map { archives.zipTree(it.file) } + } + ) { + // drop the first dir (dokka-$version) + eachFile { + relativePath = relativePath.dropDirectories(1) + } + } + + into(temporaryDir) + + exclude( + "*.github", + "*.gradle", + "**/gradlew", + "**/gradlew.bat", + "**/gradle/wrapper/gradle-wrapper.jar", + "**/gradle/wrapper/gradle-wrapper.properties", + ) +} diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects-base.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects-base.gradle.kts new file mode 100644 index 00000000..5c2c45fa --- /dev/null +++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects-base.gradle.kts @@ -0,0 +1,27 @@ +package buildsrc.conventions + +import buildsrc.utils.asConsumer +import buildsrc.utils.asProvider + +plugins { + id("buildsrc.conventions.base") +} + + +val exampleProjectsAttribute: Attribute<String> = + Attribute.of("example-projects", String::class.java) + +dependencies.attributesSchema { + attribute(exampleProjectsAttribute) +} + + +val exampleProjects by configurations.registering { + asConsumer() + attributes { attribute(exampleProjectsAttribute, "dokka") } +} + +val exampleProjectsElements by configurations.registering { + asProvider() + attributes { attribute(exampleProjectsAttribute, "dokka") } +} diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects.gradle.kts new file mode 100644 index 00000000..c6994a83 --- /dev/null +++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects.gradle.kts @@ -0,0 +1,160 @@ +package buildsrc.conventions + +import buildsrc.settings.* +import buildsrc.tasks.* +import buildsrc.utils.* + +plugins { + id("buildsrc.conventions.base") + id("buildsrc.conventions.dokka-source-downloader") + id("buildsrc.conventions.maven-publish-test") + id("buildsrc.conventions.dokkatoo-example-projects-base") +} + +val mavenPublishTestExtension = extensions.getByType<MavenPublishTestSettings>() +val dokkaTemplateProjectSettings = + extensions.create<DokkaTemplateProjectSettings>( + DokkaTemplateProjectSettings.EXTENSION_NAME, + { project.copySpec() } + ).apply { + this.destinationBaseDir.convention(layout.projectDirectory) + } + +val prepareDokkaSource by tasks.existing(Sync::class) + +dokkaTemplateProjectSettings.dokkaSourceDir.convention( + prepareDokkaSource.flatMap { + layout.dir(providers.provider { + it.destinationDir + }) + } +) + +tasks.withType<SetupDokkaProjects>().configureEach { + dependsOn(prepareDokkaSource) + + dokkaSourceDir.convention(dokkaTemplateProjectSettings.dokkaSourceDir) + destinationBaseDir.convention(dokkaTemplateProjectSettings.destinationBaseDir) + + templateProjects.addAllLater(provider { + dokkaTemplateProjectSettings.templateProjects + }) +} + +val setupDokkaTemplateProjects by tasks.registering(SetupDokkaProjects::class) + +fun createDokkatooExampleProjectsSettings( + projectDir: Directory = project.layout.projectDirectory +): DokkatooExampleProjectsSettings { + return extensions.create<DokkatooExampleProjectsSettings>( + DokkatooExampleProjectsSettings.EXTENSION_NAME + ).apply { + + // find all Gradle settings files + val settingsFiles = projectDir.asFileTree + .matching { + include( + "**/*dokkatoo*/**/settings.gradle.kts", + "**/*dokkatoo*/**/settings.gradle", + ) + }.files + + // for each settings file, create a DokkatooExampleProjectSpec + settingsFiles.forEach { + val destinationDir = it.parentFile + val name = destinationDir.toRelativeString(projectDir.asFile).toAlphaNumericCamelCase() + exampleProjects.register(name) { + this.exampleProjectDir.set(destinationDir) + } + } + + exampleProjects.configureEach { + gradlePropertiesContent.add( + mavenPublishTestExtension.testMavenRepoPath.map { testMavenRepoPath -> + "testMavenRepo=$testMavenRepoPath" + } + ) + } + } +} + +val dokkatooExampleProjectsSettings = createDokkatooExampleProjectsSettings() + +val updateDokkatooExamplesGradleProperties by tasks.registering( + UpdateDokkatooExampleProjects::class +) { + group = DokkatooExampleProjectsSettings.TASK_GROUP + + mustRunAfter(tasks.withType<SetupDokkaProjects>()) + + exampleProjects.addAllLater(providers.provider { + dokkatooExampleProjectsSettings.exampleProjects + }) +} + +val dokkatooVersion = provider { project.version.toString() } + +val updateDokkatooExamplesBuildFiles by tasks.registering { + group = DokkatooExampleProjectsSettings.TASK_GROUP + description = "Update the Gradle build files in the Dokkatoo examples" + + outputs.upToDateWhen { false } + + mustRunAfter(tasks.withType<SetupDokkaProjects>()) + shouldRunAfter(updateDokkatooExamplesGradleProperties) + + val dokkatooVersion = dokkatooVersion + + val dokkatooDependencyVersionMatcher = """ + \"dev\.adamko\.dokkatoo\:dokkatoo\-plugin\:([^"]+?)\" + """.trimIndent().toRegex() + + val dokkatooPluginVersionMatcher = """ + id[^"]+?"dev\.adamko\.dokkatoo".+?version "([^"]+?)" + """.trimIndent().toRegex() + + val gradleBuildFiles = + layout.projectDirectory.asFileTree + .matching { + include( + "**/*dokkatoo*/**/build.gradle.kts", + "**/*dokkatoo*/**/build.gradle", + ) + }.elements + outputs.files(gradleBuildFiles) + + doLast { + gradleBuildFiles.get().forEach { fileLocation -> + val file = fileLocation.asFile + if (file.exists()) { + file.writeText( + file.readText() + .replace(dokkatooPluginVersionMatcher) { + val oldVersion = it.groupValues[1] + it.value.replace(oldVersion, dokkatooVersion.get()) + } + .replace(dokkatooDependencyVersionMatcher) { + val oldVersion = it.groupValues[1] + it.value.replace(oldVersion, dokkatooVersion.get()) + } + ) + } + } + } +} + + +val updateDokkatooExamples by tasks.registering { + group = DokkatooExampleProjectsSettings.TASK_GROUP + description = "lifecycle task for all '${DokkatooExampleProjectsSettings.TASK_GROUP}' tasks" + dependsOn( + setupDokkaTemplateProjects, + updateDokkatooExamplesGradleProperties, + updateDokkatooExamplesBuildFiles, + ) +} + +tasks.assemble { + dependsOn(updateDokkatooExamples) + dependsOn(setupDokkaTemplateProjects) +} diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/gradle-plugin-variants.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/gradle-plugin-variants.gradle.kts new file mode 100644 index 00000000..1d9fc43b --- /dev/null +++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/gradle-plugin-variants.gradle.kts @@ -0,0 +1,44 @@ +package buildsrc.conventions + +import org.gradle.api.attributes.plugin.GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE + +plugins { + id("buildsrc.conventions.base") + `java-gradle-plugin` +} + +fun registerGradleVariant(name: String, gradleVersion: String) { + val variantSources = sourceSets.create(name) + + java { + registerFeature(variantSources.name) { + usingSourceSet(variantSources) + capability("${project.group}", "${project.name}", "${project.version}") + + withJavadocJar() + withSourcesJar() + } + } + + configurations + .matching { it.isCanBeConsumed && it.name.startsWith(variantSources.name) } + .configureEach { + attributes { + attribute(GRADLE_PLUGIN_API_VERSION_ATTRIBUTE, objects.named(gradleVersion)) + } + } + + tasks.named<Copy>(variantSources.processResourcesTaskName) { + val copyPluginDescriptors = rootSpec.addChild() + copyPluginDescriptors.into("META-INF/gradle-plugins") +// copyPluginDescriptors.into(tasks.pluginDescriptors.flatMap { it.outputDirectory }) + copyPluginDescriptors.from(tasks.pluginDescriptors) + } + + dependencies { + add(variantSources.compileOnlyConfigurationName, gradleApi()) + } +} + +registerGradleVariant("gradle7", "7.6") +registerGradleVariant("gradle8", "8.0") diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/java-base.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/java-base.gradle.kts new file mode 100644 index 00000000..203b80f2 --- /dev/null +++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/java-base.gradle.kts @@ -0,0 +1,19 @@ +package buildsrc.conventions + +import org.gradle.api.JavaVersion +import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.`java-base` + +plugins { + id("buildsrc.conventions.base") + `java` +} + +extensions.getByType<JavaPluginExtension>().apply { + toolchain { + languageVersion.set(JavaLanguageVersion.of(11)) + } + withSourcesJar() +} diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/kotlin-gradle-plugin.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/kotlin-gradle-plugin.gradle.kts new file mode 100644 index 00000000..4174088a --- /dev/null +++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/kotlin-gradle-plugin.gradle.kts @@ -0,0 +1,37 @@ +package buildsrc.conventions + +plugins { + id("buildsrc.conventions.base") + id("buildsrc.conventions.java-base") + id("org.gradle.kotlin.kotlin-dsl") + id("com.gradle.plugin-publish") +} + +tasks.validatePlugins { + enableStricterValidation.set(true) +} + +val createJavadocJarReadme by tasks.registering(Sync::class) { + description = "generate a readme.txt for the Javadoc JAR" + from( + resources.text.fromString( + """ + This Javadoc JAR is intentionally empty. + + For documentation, see the sources JAR or https://github.com/adamko-dev/dokkatoo/ + + """.trimIndent() + ) + ) { + rename { "readme.txt" } + } + into(temporaryDir) +} + + +// The Gradle Publish Plugin enables the Javadoc JAR in afterEvaluate, so find it lazily +tasks.withType<Jar>() + .matching { it.name == "javadocJar" } + .configureEach { + from(createJavadocJarReadme) + } diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publish-test.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publish-test.gradle.kts new file mode 100644 index 00000000..38678b5b --- /dev/null +++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publish-test.gradle.kts @@ -0,0 +1,93 @@ +package buildsrc.conventions + +import buildsrc.settings.MavenPublishTestSettings +import buildsrc.utils.* + + +/** Utility for publishing a project to a local Maven directory for use in integration tests. */ + +plugins { + base +} + +val Gradle.rootGradle: Gradle get() = generateSequence(gradle) { it.parent }.last() + +val mavenPublishTestExtension = extensions.create<MavenPublishTestSettings>( + "mavenPublishTest", + gradle.rootGradle.rootProject.layout.buildDirectory.dir("test-maven-repo"), +) + + +val publishToTestMavenRepo by tasks.registering { + group = PublishingPlugin.PUBLISH_TASK_GROUP + description = "Publishes all Maven publications to the test Maven repository." +} + + +plugins.withType<MavenPublishPlugin>().all { + extensions + .getByType<PublishingExtension>() + .publications + .withType<MavenPublication>().all publication@{ + val publicationName = this@publication.name + val installTaskName = "publish${publicationName.uppercaseFirstChar()}PublicationToTestMavenRepo" + + // Register a publication task for each publication. + // Use PublishToMavenLocal, because the PublishToMavenRepository task will *always* create + // a new jar, even if nothing has changed, and append a timestamp, which results in a large + // directory and tasks are never up-to-date. + // PublishToMavenLocal does not append a timestamp, so the target directory is smaller, and + // up-to-date checks work. + val installTask = tasks.register<PublishToMavenLocal>(installTaskName) { + description = "Publishes Maven publication '$publicationName' to the test Maven repository." + group = PublishingPlugin.PUBLISH_TASK_GROUP + outputs.cacheIf { true } + publication = this@publication + val destinationDir = mavenPublishTestExtension.testMavenRepo.get().asFile + inputs.property("testMavenRepoTempDir", destinationDir.invariantSeparatorsPath) + doFirst { + /** + * `maven.repo.local` will set the destination directory for this [PublishToMavenLocal] task. + * + * @see org.gradle.api.internal.artifacts.mvnsettings.DefaultLocalMavenRepositoryLocator.getLocalMavenRepository + */ + System.setProperty("maven.repo.local", destinationDir.absolutePath) + } + } + + publishToTestMavenRepo.configure { + dependsOn(installTask) + } + + tasks.check { + mustRunAfter(installTask) + } + } +} + + +val testMavenPublication by configurations.registering { + asConsumer() + attributes { + attribute(MavenPublishTestSettings.attribute, "testMavenRepo") + } +} + +val testMavenPublicationElements by configurations.registering { + asProvider() + extendsFrom(testMavenPublication.get()) + attributes { + attribute(MavenPublishTestSettings.attribute, "testMavenRepo") + } + outgoing { + artifact(mavenPublishTestExtension.testMavenRepo) { + builtBy(publishToTestMavenRepo) + } + } +} + +dependencies { + attributesSchema { + attribute(MavenPublishTestSettings.attribute) + } +} diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publishing.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publishing.gradle.kts new file mode 100644 index 00000000..7af7b69f --- /dev/null +++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publishing.gradle.kts @@ -0,0 +1,137 @@ +package buildsrc.conventions + +import buildsrc.settings.MavenPublishingSettings + +plugins { + `maven-publish` + signing +} + +val mavenPublishing = + extensions.create<MavenPublishingSettings>(MavenPublishingSettings.EXTENSION_NAME, project) + + +//region POM convention +publishing { + publications.withType<MavenPublication>().configureEach { + pom { + name.convention("Dokkatoo") + description.convention("Dokkatoo is a Gradle plugin that generates documentation for your Kotlin projects") + url.convention("https://github.com/adamko-dev/dokkatoo") + + scm { + connection.convention("scm:git:https://github.com/adamko-dev/dokkatoo") + developerConnection.convention("scm:git:https://github.com/adamko-dev/dokkatoo") + url.convention("https://github.com/adamko-dev/dokkatoo") + } + + licenses { + license { + name.convention("Apache-2.0") + url.convention("https://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + + developers { + developer { + email.set("adam@adamko.dev") + } + } + } + } +} +//endregion + + +//region GitHub branch publishing +publishing { + repositories { + maven(mavenPublishing.githubPublishDir) { + name = "GitHubPublish" + } + } +} +//endregion + + +//region Maven Central publishing/signing +publishing { + repositories { + val mavenCentralUsername = mavenPublishing.mavenCentralUsername.orNull + val mavenCentralPassword = mavenPublishing.mavenCentralPassword.orNull + if (!mavenCentralUsername.isNullOrBlank() && !mavenCentralPassword.isNullOrBlank()) { + maven(mavenPublishing.sonatypeReleaseUrl) { + name = "SonatypeRelease" + credentials { + username = mavenCentralUsername + password = mavenCentralPassword + } + } + } + } + + // com.gradle.plugin-publish automatically adds a Javadoc jar +} + +signing { + logger.info("maven-publishing.gradle.kts enabled signing for ${project.path}") + + val keyId = mavenPublishing.signingKeyId.orNull + val key = mavenPublishing.signingKey.orNull + val password = mavenPublishing.signingPassword.orNull + + if (!keyId.isNullOrBlank() && !key.isNullOrBlank() && !password.isNullOrBlank()) { + useInMemoryPgpKeys(keyId, key, password) + } + + setRequired({ + gradle.taskGraph.allTasks.filterIsInstance<PublishToMavenRepository>().any { + it.repository.name == "SonatypeRelease" + } + }) +} + +//afterEvaluate { +// com.gradle.plugin-publish automatically signs tasks in a weird way, that stops this from working: +// signing { +// sign(publishing.publications) +// } +//} +//endregion + + +//region Fix Gradle warning about signing tasks using publishing task outputs without explicit dependencies +// https://youtrack.jetbrains.com/issue/KT-46466 https://github.com/gradle/gradle/issues/26091 +tasks.withType<AbstractPublishToMaven>().configureEach { + val signingTasks = tasks.withType<Sign>() + mustRunAfter(signingTasks) +} +//endregion + + +//region publishing logging +tasks.withType<AbstractPublishToMaven>().configureEach { + val publicationGAV = provider { publication?.run { "$group:$artifactId:$version" } } + doLast("log publication GAV") { + if (publicationGAV.isPresent) { + logger.lifecycle("[task: ${path}] ${publicationGAV.get()}") + } + } +} +//endregion + + +//region IJ workarounds +// manually define the Kotlin DSL accessors bec |
