Skip to content

Commit

Permalink
Updated automatic all-modules-page-plugin (#159)
Browse files Browse the repository at this point in the history
- improved 'missing all-modules-page-plugin' warning message
- added option to disable 'missing all-modules-page-plugin' warning
- all-modules-page-plugin now provided as a transitive dependency
- exclude non-plugin dependencies from generator Dokka Plugins classpath (by checking for Dokka Plugin marker file)
- updated some Configurations to be registered lazily
- tidy up default Dokka dependencies (remove non-plugins from plugins classpath)
  • Loading branch information
aSemy authored Feb 11, 2024
1 parent b43d896 commit 4947743
Show file tree
Hide file tree
Showing 22 changed files with 321 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ class AndroidProjectIntegrationTest : FunSpec({
)
}
}

test("expect configurations are not resolved during configuration time") {
output shouldNotContain Regex("""Configuration '.*' was resolved during configuration time""")
output shouldNotContain "https://github.com/gradle/gradle/issues/2298"
}
}
}

Expand Down
6 changes: 4 additions & 2 deletions modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,12 @@ constructor(
const val TASK_GROUP = "dokkatoo"

/** The names of [Gradle tasks][org.gradle.api.Task] created by Dokkatoo */
val taskNames = TaskNames(null)
val taskNames = TaskNames("")

/** The names of [Configuration]s created by Dokkatoo */
val dependencyContainerNames = DependencyContainerNames(null)
@Deprecated("no longer used")
@Suppress("unused")
val dependencyContainerNames = DependencyContainerNames("null")

/** Name of the [Configuration] used to declare dependencies on other subprojects. */
const val DOKKATOO_CONFIGURATION_NAME = "dokkatoo"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ constructor(
* This is primarily used by Kotlin Multiplatform projects, which can have multiple source sets
* per subproject.
*
* Defaults to [the path of the subproject][org.gradle.api.Project.getPath].
* Defaults to [the Gradle path of the subproject][org.gradle.api.Project.getPath].
*/
abstract val sourceSetScopeDefault: Property<String>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import org.gradle.api.artifacts.Configuration
* - [DokkaConfiguration][org.jetbrains.dokka.DokkaConfiguration] - parameters for executing the Dokka Generator
*/
@DokkatooInternalApi
class DependencyContainerNames(override val formatName: String?) : HasFormatName() {
class DependencyContainerNames(override val formatName: String) : HasFormatName() {

val dokkatoo = DOKKATOO_CONFIGURATION_NAME.appendFormat()
val dokkatooResolver = "${dokkatoo}Resolver"
Expand All @@ -24,7 +24,7 @@ class DependencyContainerNames(override val formatName: String?) : HasFormatName
*
* Includes transitive dependencies, so this can be passed to the Dokka Generator Worker classpath.
*
* Will be used in user's build scripts to declare additional Dokka Plugins.
* Will be used in user's build scripts to declare additional format-specific Dokka Plugins.
*/
val pluginsClasspath = "dokkatooPlugin".appendFormat()

Expand All @@ -51,4 +51,10 @@ class DependencyContainerNames(override val formatName: String?) : HasFormatName

/** Resolver for [generatorClasspath] - internal Dokkatoo usage only. */
val generatorClasspathResolver = "${dokkatoo}GeneratorClasspathResolver"

val publicationPluginClasspath = "${dokkatoo}PublicationPluginClasspath"
val publicationPluginClasspathApiOnly = "${publicationPluginClasspath}ApiOnly"
val publicationPluginClasspathResolver = "${publicationPluginClasspath}Resolver"
val publicationPluginClasspathApiOnlyConsumable =
"${publicationPluginClasspathApiOnly}Consumable"
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dev.adamko.dokkatoo.dependencies
import dev.adamko.dokkatoo.dependencies.DokkatooAttribute.Companion.DokkatooClasspathAttribute
import dev.adamko.dokkatoo.dependencies.DokkatooAttribute.Companion.DokkatooFormatAttribute
import dev.adamko.dokkatoo.internal.DokkatooInternalApi
import dev.adamko.dokkatoo.internal.consumable
import dev.adamko.dokkatoo.internal.declarable
import dev.adamko.dokkatoo.internal.resolvable
import org.gradle.api.NamedDomainObjectProvider
Expand Down Expand Up @@ -79,7 +80,7 @@ class FormatDependenciesManager(
*
* Should not contain runtime dependencies - use [dokkaGeneratorClasspath].
*/
val dokkaPluginsClasspath: NamedDomainObjectProvider<Configuration> =
private val dokkaPluginsClasspath: NamedDomainObjectProvider<Configuration> =
project.configurations.register(configurationNames.pluginsClasspath) {
description = "Dokka Plugins classpath for $formatName."
declarable()
Expand All @@ -90,8 +91,8 @@ class FormatDependenciesManager(
*
* It extends [dokkaPluginsClasspath].
*/
val dokkaPluginsIntransitiveClasspathResolver: Configuration =
project.configurations.create(configurationNames.pluginsClasspathIntransitiveResolver) {
val dokkaPluginsIntransitiveClasspathResolver: NamedDomainObjectProvider<Configuration> =
project.configurations.register(configurationNames.pluginsClasspathIntransitiveResolver) {
description =
"Resolves Dokka Plugins classpath for $formatName - for internal use. Fetch only the plugins (no transitive dependencies) for use in the Dokka JSON Configuration."
resolvable()
Expand All @@ -105,6 +106,51 @@ class FormatDependenciesManager(
}
//endregion

//region Dokka Plugins for Publication Generation
private val dokkaPublicationPluginClasspath: NamedDomainObjectProvider<Configuration> =
project.configurations.register(configurationNames.publicationPluginClasspath) {
description =
"Dokka Plugins classpath for a $formatName Publication (consisting of 1+ Dokka Module)."
declarable()
extendsFrom(baseDependencyManager.declaredDependencies)
}

val dokkaPublicationPluginClasspathResolver: NamedDomainObjectProvider<Configuration> =
project.configurations.register(configurationNames.publicationPluginClasspathResolver) {
description =
"Resolves Dokka Plugins classpath for a $formatName Publication (consisting of 1+ Dokka Module)."
resolvable()
extendsFrom(dokkaPublicationPluginClasspath.get())
attributes {
jvmJar()
attribute(DokkatooFormatAttribute, formatAttributes.format)
attribute(DokkatooClasspathAttribute, baseAttributes.dokkaPublicationPlugins)
}
}

val dokkaPublicationPluginClasspathApiOnly: NamedDomainObjectProvider<Configuration> =
project.configurations.register(configurationNames.publicationPluginClasspathApiOnly) {
description =
"Dokka Plugins for consumers that will assemble a $formatName Publication using the Dokka Module that this project produces"
description = "TODO"
declarable()
}

init {
project.configurations.register(configurationNames.publicationPluginClasspathApiOnlyConsumable) {
description =
"Shared Dokka Plugins for consumers that will assemble a $formatName Publication using the Dokka Module that this project produces"
consumable()
extendsFrom(dokkaPublicationPluginClasspathApiOnly.get())
attributes {
jvmJar()
attribute(DokkatooFormatAttribute, formatAttributes.format)
attribute(DokkatooClasspathAttribute, baseAttributes.dokkaPublicationPlugins)
}
}
}
//endregion

//region Dokka Generator Classpath
/**
* Runtime classpath used to execute Dokka Worker.
Expand Down Expand Up @@ -136,8 +182,8 @@ class FormatDependenciesManager(
* @see dev.adamko.dokkatoo.workers.DokkaGeneratorWorker
* @see dev.adamko.dokkatoo.tasks.DokkatooGenerateTask
*/
val dokkaGeneratorClasspathResolver: Configuration =
project.configurations.create(configurationNames.generatorClasspathResolver) {
val dokkaGeneratorClasspathResolver: NamedDomainObjectProvider<Configuration> =
project.configurations.register(configurationNames.generatorClasspathResolver) {
description =
"Dokka Generator runtime classpath for $formatName - will be used in Dokka Worker. Should contain all transitive dependencies, plugins (and their transitive dependencies), so Dokka Worker can run."
resolvable()
Expand All @@ -153,18 +199,6 @@ class FormatDependenciesManager(
}
//endregion

private fun componentDependencies(
component: DokkatooAttribute.ModuleComponent
): ModuleComponentDependencies =
ModuleComponentDependencies(
project = project,
component = component,
baseAttributes = baseAttributes,
formatAttributes = formatAttributes,
declaredDependencies = baseDependencyManager.declaredDependencies,
baseConfigurationName = configurationNames.dokkatoo,
)

/**
* Output directories of a Dokka Module.
*
Expand All @@ -179,4 +213,16 @@ class FormatDependenciesManager(
*/
val moduleOutputDirectories: ModuleComponentDependencies =
componentDependencies(formatAttributes.moduleOutputDirectories)

private fun componentDependencies(
component: DokkatooAttribute.ModuleComponent,
): ModuleComponentDependencies =
ModuleComponentDependencies(
project = project,
component = component,
baseAttributes = baseAttributes,
formatAttributes = formatAttributes,
declaredDependencies = baseDependencyManager.declaredDependencies,
baseConfigurationName = configurationNames.dokkatoo,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import dev.adamko.dokkatoo.dependencies.DokkatooAttribute.Companion.DokkatooForm
import dev.adamko.dokkatoo.dependencies.DokkatooAttribute.Companion.DokkatooModuleComponentAttribute
import dev.adamko.dokkatoo.internal.*
import java.io.File
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.result.ResolvedArtifactResult
Expand All @@ -25,8 +26,8 @@ class ModuleComponentDependencies(
private val formatName: String get() = formatAttributes.format.name
private val componentName: String get() = component.name

private val resolver: Configuration =
project.configurations.create("${baseConfigurationName}${componentName}Resolver") {
private val resolver: NamedDomainObjectProvider<Configuration> =
project.configurations.register("${baseConfigurationName}${componentName}Resolver") {
description = "Resolves Dokkatoo $formatName $componentName files."
resolvable()
extendsFrom(declaredDependencies)
Expand All @@ -37,11 +38,12 @@ class ModuleComponentDependencies(
}
}

val outgoing: Configuration =
project.configurations.create("${baseConfigurationName}${componentName}Consumable") {
val outgoing: NamedDomainObjectProvider<Configuration> =
project.configurations.register("${baseConfigurationName}${componentName}Consumable") {
description =
"Provides Dokkatoo $formatName $componentName files for consumption by other subprojects."
consumable()
extendsFrom(declaredDependencies)
attributes {
attribute(USAGE_ATTRIBUTE, baseAttributes.dokkatooUsage)
attribute(DokkatooFormatAttribute, formatAttributes.format)
Expand All @@ -62,13 +64,14 @@ class ModuleComponentDependencies(
* enabled, which might obscure errors.
*/
val incomingArtifactFiles: Provider<List<File>> =
resolver.incomingArtifacts().map { it.map(ResolvedArtifactResult::getFile) }
resolver.get().incomingArtifacts().map { it.map(ResolvedArtifactResult::getFile) }

private fun Configuration.incomingArtifacts(): Provider<List<ResolvedArtifactResult>> {

// Redefine variables locally, because Configuration Cache is easily confused
// and produces confusing error messages.
val baseAttributes = baseAttributes
val usage = baseAttributes.dokkatooUsage
val formatAttributes = formatAttributes
val incoming = incoming
val incomingName = incoming.name
Expand All @@ -79,7 +82,7 @@ class ModuleComponentDependencies(
@Suppress("UnstableApiUsage")
withVariantReselection()
attributes {
attribute(USAGE_ATTRIBUTE, baseAttributes.dokkatooUsage)
attribute(USAGE_ATTRIBUTE, usage)
attribute(DokkatooFormatAttribute, formatAttributes.format)
attribute(DokkatooModuleComponentAttribute, component)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.Usage
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Provider
import org.gradle.kotlin.dsl.*


Expand All @@ -17,6 +16,8 @@ class BaseAttributes(
) {
val dokkatooUsage: Usage = objects.named("dev.adamko.dokkatoo")
val dokkaPlugins: DokkatooAttribute.Classpath = objects.named("dokka-plugins")
val dokkaPublicationPlugins: DokkatooAttribute.Classpath =
objects.named("dokka-publication-plugins")
val dokkaGenerator: DokkatooAttribute.Classpath = objects.named("dokka-generator")
}

Expand All @@ -28,5 +29,7 @@ class FormatAttributes(
objects: ObjectFactory,
) {
val format: DokkatooAttribute.Format = objects.named(formatName)
val moduleOutputDirectories: DokkatooAttribute.ModuleComponent = objects.named("ModuleOutputDirectories")

val moduleOutputDirectories: DokkatooAttribute.ModuleComponent =
objects.named("ModuleOutputDirectories")
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import dev.adamko.dokkatoo.DokkatooBasePlugin
import dev.adamko.dokkatoo.dokka.parameters.DokkaGeneratorParametersSpec
import dev.adamko.dokkatoo.dokka.parameters.DokkaModuleDescriptionKxs
import dev.adamko.dokkatoo.dokka.plugins.DokkaPluginParametersBaseSpec
import dev.adamko.dokkatoo.formats.DokkatooHtmlPlugin.Companion.extractDokkaPluginMarkers
import dev.adamko.dokkatoo.internal.DokkatooInternalApi
import java.io.File
import org.gradle.api.Project
import org.gradle.api.file.ArchiveOperations
import org.gradle.api.file.FileCollection
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.jetbrains.dokka.*
Expand All @@ -19,7 +22,9 @@ import org.jetbrains.dokka.*
* leaking into the public API.
*/
@DokkatooInternalApi
internal object DokkaParametersBuilder {
internal class DokkaParametersBuilder(
private val archives: ArchiveOperations,
) {

private val logger: Logger = Logging.getLogger(DokkaParametersBuilder::class.java)

Expand All @@ -40,7 +45,10 @@ internal object DokkaParametersBuilder {
val finalizeCoroutines = spec.finalizeCoroutines.get()
val pluginsConfiguration = spec.pluginsConfiguration.toSet()

val pluginsClasspath = spec.pluginsClasspath.files.toList()
val pluginsClasspath = buildPluginsClasspath(
plugins = spec.pluginsClasspath,
)

val includes = spec.includes.files

return DokkaConfigurationImpl(
Expand All @@ -62,6 +70,18 @@ internal object DokkaParametersBuilder {
)
}

private fun buildPluginsClasspath(
plugins: FileCollection,
): List<File> {
// only include dependencies with Dokka Plugin markers
return plugins
.filter { file ->
val pluginIds = extractDokkaPluginMarkers(archives, file)
pluginIds.isNotEmpty()
}
.toList()
}

private fun buildModuleDescriptors(
moduleDescriptorDirs: Iterable<File>
): List<DokkaModuleDescriptionImpl> {
Expand Down
Loading

0 comments on commit 4947743

Please sign in to comment.