Skip to content

Commit

Permalink
minor fixes (#209)
Browse files Browse the repository at this point in the history
* minor fixes

- use new doc site in Maven POM
- update project logo to avoid doing work during configuration
- update IDEA exclusions dirs via a value source (otherwise Gradle will then add all files as CC input, for no reason
- replace enum `entries` with `values` (awaiting Gradle bumping the minimum Kotlin version to 1.9...)

* tidy up docs for examples

* add build service to prevent parallel Maven Publishing

* wrap test report hack with region

* cool background animation for homepage banner

* useClasspathSnapshot=false
  • Loading branch information
aSemy authored Apr 8, 2024
1 parent b9af4a8 commit abbfbfa
Show file tree
Hide file tree
Showing 11 changed files with 172 additions and 82 deletions.
6 changes: 0 additions & 6 deletions .github/workflows/run_publish_maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ jobs:
gradle-task: >-
publishAllPublicationsToSonatypeReleaseRepository
--stacktrace
--no-configuration-cache
--no-parallel
checkout-ref: ${{ inputs.checkout-ref }}


Expand All @@ -60,8 +58,6 @@ jobs:
gradle-task: >-
publishAllPublicationsToJetBrainsSpaceRepository
--stacktrace
--no-configuration-cache
--no-parallel
checkout-ref: ${{ inputs.checkout-ref }}


Expand All @@ -78,6 +74,4 @@ jobs:
gradle-task: >-
publishAllPublicationsToAdamkoDevRepository
--stacktrace
--no-configuration-cache
--no-parallel
checkout-ref: ${{ inputs.checkout-ref }}
36 changes: 5 additions & 31 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import buildsrc.utils.excludeGeneratedGradleDsl
import buildsrc.utils.excludeProjectConfigurationDirs
import buildsrc.utils.initIdeProjectLogo
import org.gradle.language.base.plugins.LifecycleBasePlugin.VERIFICATION_GROUP

Expand All @@ -10,47 +10,21 @@ plugins {
group = "dev.adamko.dokkatoo"
version = "2.4.0-SNAPSHOT"

excludeProjectConfigurationDirs(idea)

idea {
module {
excludeGeneratedGradleDsl(layout)

excludeDirs.apply {
// exclude .gradle, IDE dirs from nested projects (e.g. example & template projects)
// so IntelliJ project-wide search isn't cluttered with irrelevant files
val excludedDirs = setOf(
".idea",
".gradle",
"build",
"gradle/wrapper",
"ANDROID_SDK",
"examples/versioning-multimodule-example/dokkatoo/previousDocVersions",
"examples/versioning-multimodule-example/dokka/previousDocVersions",
"modules/dokkatoo-plugin-integration-tests/example-project-data",
)
addAll(
projectDir.walk().filter { file ->
excludedDirs.any {
file.invariantSeparatorsPath.endsWith("/$it")
}
}
)
}
}
tasks.prepareKotlinBuildScriptModel {
initIdeProjectLogo("documentation/media/kayray-logo.svg")
}

initIdeProjectLogo("modules/docs/images/logo-icon.svg")

val dokkatooVersion by tasks.registering {
description = "prints the Dokkatoo project version (used during release to verify the version)"
group = "help"
val version = providers.provider { project.version }
val version = providers.provider { project.version.toString() }
doLast {
logger.quiet("${version.orNull}")
}
}


val verifyVersionCatalogKotlinVersion by tasks.registering {
description = "Verify the Version Catalog Kotlin version matches Gradle's embedded Kotlin version"
// https://docs.gradle.org/current/userguide/compatibility.html#kotlin
Expand Down
3 changes: 3 additions & 0 deletions buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ tasks.withType<AbstractCopyTask>().configureEach {
includeEmptyDirs = false
}


//region Gradle test report dark mode
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
Expand Down Expand Up @@ -153,3 +155,4 @@ tasks.matching { it.name == "validatePlugins" }.configureEach {
// Task ':validatePlugins' uses this output of task ':updateTestReportCss' without declaring an explicit or implicit dependency.
mustRunAfter(updateTestReportCss)
}
//endregion
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ publishing {
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")
url.convention("https://adamko-dev.github.io/dokkatoo/")

scm {
connection.convention("scm:git:https://github.com/adamko-dev/dokkatoo")
Expand Down Expand Up @@ -151,6 +151,20 @@ tasks.withType<AbstractPublishToMaven>().configureEach {
//endregion


//region Maven Central can't handle parallel uploads, so limit parallel uploads with a service.
abstract class MavenPublishLimiter : BuildService<BuildServiceParameters.None>

val mavenPublishLimiter =
gradle.sharedServices.registerIfAbsent("mavenPublishLimiter", MavenPublishLimiter::class) {
maxParallelUsages = 1
}

tasks.withType<PublishToMavenRepository>().configureEach {
usesService(mavenPublishLimiter)
}
//endregion


//region IJ workarounds
// manually define the Kotlin DSL accessors because IntelliJ _still_ doesn't load them properly
fun Project.publishing(configure: PublishingExtension.() -> Unit): Unit =
Expand Down
139 changes: 112 additions & 27 deletions buildSrc/src/main/kotlin/buildsrc/utils/intellij.kt
Original file line number Diff line number Diff line change
@@ -1,45 +1,130 @@
package buildsrc.utils

import java.io.File
import javax.inject.Inject
import org.gradle.api.Project
import org.gradle.api.file.ProjectLayout
import org.gradle.plugins.ide.idea.model.IdeaModule
import org.gradle.api.Task
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ValueSource
import org.gradle.api.provider.ValueSourceParameters
import org.gradle.configurationcache.extensions.serviceOf
import org.gradle.kotlin.dsl.*
import org.gradle.plugins.ide.idea.model.IdeaModel


/** exclude generated Gradle code, so it doesn't clog up search results */
fun IdeaModule.excludeGeneratedGradleDsl(layout: ProjectLayout) {
/**
* Exclude directories containing
*
* - generated Gradle code,
* - IDE files,
* - Gradle config,
*
* so they don't clog up search results.
*/
fun Project.excludeProjectConfigurationDirs(
idea: IdeaModel
) {
val excludedDirs = providers.of(IdeaExcludedDirectoriesSource::class) {
parameters.projectDir.set(layout.projectDirectory)
}.get()

idea.module.excludeDirs.addAll(excludedDirs)
}

val generatedSrcDirs = listOf(
"kotlin-dsl-accessors",
"kotlin-dsl-external-plugin-spec-builders",
"kotlin-dsl-plugins",
)
// Have to use a ValueSource to find the files, otherwise Gradle
// considers _all files_ an input for configuration cache 🙄
internal abstract class IdeaExcludedDirectoriesSource :
ValueSource<Set<File>, IdeaExcludedDirectoriesSource.Parameters> {

interface Parameters : ValueSourceParameters {
val projectDir: DirectoryProperty
}

excludeDirs.addAll(
layout.projectDirectory.asFile.walk()
.filter { it.isDirectory && it.parentFile.name in generatedSrcDirs }
override fun obtain(): Set<File> {
val projectDir = parameters.projectDir.get().asFile

val doNotWalkDirs = setOf(
".git",
".kotlin",
)

val generatedSrcDirs = listOf(
"kotlin-dsl-accessors",
"kotlin-dsl-external-plugin-spec-builders",
"kotlin-dsl-plugins",
)

val generatedDirs = projectDir
.walk()
.onEnter { it.name !in doNotWalkDirs && it.parentFile.name !in generatedSrcDirs }
.filter { it.isDirectory }
.filter { it.parentFile.name in generatedSrcDirs }
.flatMap { file ->
file.walk().maxDepth(1).filter { it.isDirectory }.toList()
}
)
.toSet()

// exclude .gradle, IDE dirs from nested projects (e.g. example & template projects)
// so IntelliJ project-wide search isn't cluttered with irrelevant files
val projectDirsToExclude = setOf(
".idea",
".gradle",
"build",
"gradle/wrapper",
"ANDROID_SDK",
"examples/versioning-multimodule-example/dokkatoo/previousDocVersions",
"examples/versioning-multimodule-example/dokka/previousDocVersions",
"modules/dokkatoo-plugin-integration-tests/example-project-data",
)

val excludedProjectDirs = projectDir
.walk()
.onEnter { it.name !in doNotWalkDirs }
// .filter { it.isDirectory }
.filter { dir ->
projectDirsToExclude.any {
dir.invariantSeparatorsPath.endsWith("/$it")
}
}
.toSet()

// can't use buildSet {} https://github.com/gradle/gradle/issues/28325
return mutableSetOf<File>().apply {
addAll(generatedDirs)
addAll(excludedProjectDirs)
}
}
}


/** Sets a logo for project IDEs */
fun Project.initIdeProjectLogo(
/**
* Sets a logo for project IDEs.
*
* (Avoid updating the logo during project configuration,
* instead piggyback off a random task that runs on IJ import.)
*/
fun Task.initIdeProjectLogo(
svgLogoPath: String
) {
val logoSvg = rootProject.layout.projectDirectory.file(svgLogoPath)
val ideaDir = rootProject.layout.projectDirectory.dir(".idea")

if (
logoSvg.asFile.exists()
&& ideaDir.asFile.exists()
&& !ideaDir.file("icon.png").asFile.exists()
&& !ideaDir.file("icon.svg").asFile.exists()
) {
copy {
from(logoSvg) { rename { "icon.svg" } }
into(ideaDir)
val fs = project.serviceOf<FileSystemOperations>()

val logoSvg = project.layout.projectDirectory.file(svgLogoPath)
val ideaDir = project.layout.projectDirectory.dir(".idea")
// don't register task inputs, we don't really care about up-to-date checks

doLast("initIdeProjectLogo") {
if (
logoSvg.asFile.exists()
&& ideaDir.asFile.exists()
&& !ideaDir.file("icon.png").asFile.exists()
&& !ideaDir.file("icon.svg").asFile.exists()
) {
fs.copy {
from(logoSvg) { rename { "icon.svg" } }
into(ideaDir)
}
}
}
}
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The Dokka examples are synced automatically from the Dokka source code.

### Run locally

To run locally the examples locally you must first run `./gradlew assemble`
To run locally the examples locally you must first run `./gradlew assemble publishToTestMavenRepo`
in the root Dokkatoo repository project directory.

### Tests
Expand Down
21 changes: 14 additions & 7 deletions examples/composite-build-example/dokkatoo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This project demonstrates how to use Dokkatoo to aggregate modules across a
[composite build projects](https://docs.gradle.org/current/userguide/composite_builds.html).

> [!WARN]
> [!WARNING]
> HTML is the only format that correctly supports multimodule aggregation.
> This is a limitation of Dokka.
Expand All @@ -21,18 +21,25 @@ There are 4 included builds.

To run locally, follow these steps.

1. In the root Dokkatoo project directory, run `./gradlew assemble`.
1. In the root Dokkatoo project directory, run `./gradlew assemble publishToTestMavenRepo`.
2. Either open the example project in an IDE, or `cd` into it.
3. In the example project, run `gradle build`.

The docs will be generated into [`./docs/build/dokka/`](./docs/build/dokka/).

## Distinct module paths

> [!IMPORTANT]
> When Dokkatoo aggregates modules, each module **must** have a distinct `modulePath`.
> By default, this path is set to be the project path. With composite builds these
> paths may not be distinct, causing Dokkatoo to overwrite modules.
>
> When using composite builds, project paths may clash, so make sure to set a distinct `modulePath`.
>
> This can be achieved in a convention plugin.
> [build-logic/src/main/kotlin/dokka-convention.gradle.kts](./build-logic/src/main/kotlin/dokka-convention.gradle.kts).
The module path determines where each Dokka Module will be located within an aggregated
Dokka Publication.

By default, the module path is set to be the project path, which are distinct for a single
Gradle build. With composite builds the project paths may not be distinct, causing Dokkatoo
to overwrite modules.

This can be achieved in a convention plugin.
[build-logic/src/main/kotlin/dokka-convention.gradle.kts](./build-logic/src/main/kotlin/dokka-convention.gradle.kts).
4 changes: 4 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ org.gradle.parallel=true
org.gradle.welcome=never

kotlin.mpp.import.enableKgpDependencyResolution=true

# remove in Gradle 9.0
# https://docs.gradle.org/current/userguide/upgrading_version_8.html#kotlin_1_8.20
kotlin.incremental.useClasspathSnapshot=false
22 changes: 15 additions & 7 deletions modules/docs/site/src/pages/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@
text-align: center;
position: relative;
overflow: hidden;
background-image: linear-gradient(
-120deg,
#0095D5,
#3C83DC,
#6D74E1,
#806EE3
);
background: linear-gradient(-113deg, #0095D5, #3C83DC, #6D74E1, #806EE3);
animation: gradient 17s linear infinite;
background-size: 400% 400%;
}

@keyframes gradient {
0% {
background-position: 0 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0 50%;
}
}

@media screen and (max-width: 996px) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ enum class VisibilityModifier {
;

companion object {
internal val entries: Set<VisibilityModifier> = values().toSet()
// replace with `entries` when Kotlin lang level is 1.9
internal val values: Set<VisibilityModifier> = values().toSet()

// Not defined as a property to try and minimize the dependency on Dokka Core types
internal val VisibilityModifier.dokkaType: DokkaConfiguration.Visibility
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class VisibilityModifierTest : FunSpec({

test("DokkaConfiguration.Visibility should have equivalent VisibilityModifier") {
DokkaConfiguration.Visibility.values().shouldForAll { dokkaVisibility ->
VisibilityModifier.entries.map { it.dokkaType }.shouldForOne { it shouldBe dokkaVisibility }
VisibilityModifier.values.map { it.dokkaType }.shouldForOne { it shouldBe dokkaVisibility }
}
}
})

0 comments on commit abbfbfa

Please sign in to comment.