aboutsummaryrefslogtreecommitdiff
path: root/dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooFormatDependencyContainers.kt
blob: 08eece7743257c8b6b648aac79e4f402fc7e087b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package org.jetbrains.dokka.dokkatoo.formats

import org.jetbrains.dokka.dokkatoo.DokkatooBasePlugin
import org.jetbrains.dokka.dokkatoo.distributions.DokkatooConfigurationAttributes
import org.jetbrains.dokka.dokkatoo.distributions.DokkatooConfigurationAttributes.Companion.DOKKATOO_BASE_ATTRIBUTE
import org.jetbrains.dokka.dokkatoo.distributions.DokkatooConfigurationAttributes.Companion.DOKKATOO_CATEGORY_ATTRIBUTE
import org.jetbrains.dokka.dokkatoo.distributions.DokkatooConfigurationAttributes.Companion.DOKKA_FORMAT_ATTRIBUTE
import org.jetbrains.dokka.dokkatoo.internal.DokkatooInternalApi
import org.jetbrains.dokka.dokkatoo.internal.asConsumer
import org.jetbrains.dokka.dokkatoo.internal.asProvider
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.attributes.Bundling.BUNDLING_ATTRIBUTE
import org.gradle.api.attributes.Bundling.EXTERNAL
import org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE
import org.gradle.api.attributes.Category.LIBRARY
import org.gradle.api.attributes.LibraryElements.JAR
import org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE
import org.gradle.api.attributes.Usage.JAVA_RUNTIME
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
import org.gradle.api.attributes.java.TargetJvmEnvironment.STANDARD_JVM
import org.gradle.api.attributes.java.TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE
import org.gradle.api.model.ObjectFactory
import org.gradle.kotlin.dsl.*

/**
 * The Dokka-specific Gradle [Configuration]s used to produce and consume files from external sources
 * (example: Maven Central), or between subprojects.
 *
 * (Be careful of the confusing names: Gradle [Configuration]s are used to transfer files,
 * [DokkaConfiguration][org.jetbrains.dokka.DokkaConfiguration]
 * is used to configure Dokka behaviour.)
 */
@DokkatooInternalApi
class DokkatooFormatDependencyContainers(
  private val formatName: String,
  dokkatooConsumer: NamedDomainObjectProvider<Configuration>,
  project: Project,
) {

  private val objects: ObjectFactory = project.objects

  private val dependencyContainerNames = DokkatooBasePlugin.DependencyContainerNames(formatName)

  private val dokkatooAttributes: DokkatooConfigurationAttributes = objects.newInstance()

  private fun AttributeContainer.dokkaCategory(category: DokkatooConfigurationAttributes.DokkatooCategoryAttribute) {
    attribute(DOKKATOO_BASE_ATTRIBUTE, dokkatooAttributes.dokkatooBaseUsage)
    attribute(DOKKA_FORMAT_ATTRIBUTE, objects.named(formatName))
    attribute(DOKKATOO_CATEGORY_ATTRIBUTE, category)
  }

  private fun AttributeContainer.jvmJar() {
    attribute(USAGE_ATTRIBUTE, objects.named(JAVA_RUNTIME))
    attribute(CATEGORY_ATTRIBUTE, objects.named(LIBRARY))
    attribute(BUNDLING_ATTRIBUTE, objects.named(EXTERNAL))
    attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, objects.named(STANDARD_JVM))
    attribute(LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(JAR))
  }

  //<editor-fold desc="Dokka Module files">
  /** Fetch Dokka Module files from other subprojects */
  val dokkaModuleConsumer: NamedDomainObjectProvider<Configuration> =
    project.configurations.register(dependencyContainerNames.dokkatooModuleFilesConsumer) {
      description = "Fetch Dokka Module files for $formatName from other subprojects"
      asConsumer()
      extendsFrom(dokkatooConsumer.get())
      attributes {
        dokkaCategory(dokkatooAttributes.dokkaModuleFiles)
      }
    }
  /** Provide Dokka Module files to other subprojects */
  val dokkaModuleOutgoing: NamedDomainObjectProvider<Configuration> =
    project.configurations.register(dependencyContainerNames.dokkatooModuleFilesProvider) {
      description = "Provide Dokka Module files for $formatName to other subprojects"
      asProvider()
      // extend from dokkaConfigurationsConsumer, so Dokka Module Configs propagate api() style
      extendsFrom(dokkaModuleConsumer.get())
      attributes {
        dokkaCategory(dokkatooAttributes.dokkaModuleFiles)
      }
    }
  //</editor-fold>

  //<editor-fold desc="Dokka Generator Plugins">
  /**
   * Dokka plugins.
   *
   * Users can add plugins to this dependency.
   *
   * Should not contain runtime dependencies.
   */
  val dokkaPluginsClasspath: NamedDomainObjectProvider<Configuration> =
    project.configurations.register(dependencyContainerNames.dokkaPluginsClasspath) {
      description = "Dokka Plugins classpath for $formatName"
      asConsumer()
      attributes {
        jvmJar()
        dokkaCategory(dokkatooAttributes.dokkaPluginsClasspath)
      }
    }

  /**
   * Dokka Plugins, without transitive dependencies.
   *
   * It extends [dokkaPluginsClasspath], so do not add dependencies to this configuration -
   * the dependencies are computed automatically.
   */
  val dokkaPluginsIntransitiveClasspath: NamedDomainObjectProvider<Configuration> =
    project.configurations.register(dependencyContainerNames.dokkaPluginsIntransitiveClasspath) {
      description =
        "Dokka Plugins classpath for $formatName - for internal use. Fetch only the plugins (no transitive dependencies) for use in the Dokka JSON Configuration."
      asConsumer()
      extendsFrom(dokkaPluginsClasspath.get())
      isTransitive = false
      attributes {
        jvmJar()
        dokkaCategory(dokkatooAttributes.dokkaPluginsClasspath)
      }
    }
  //</editor-fold>

  //<editor-fold desc="Dokka Generator Classpath">
  /**
   * Runtime classpath used to execute Dokka Worker.
   *
   * This configuration is not exposed to other subprojects.
   *
   * Extends [dokkaPluginsClasspath].
   *
   * @see org.jetbrains.dokka.dokkatoo.workers.DokkaGeneratorWorker
   * @see org.jetbrains.dokka.dokkatoo.tasks.DokkatooGenerateTask
   */
  val dokkaGeneratorClasspath: NamedDomainObjectProvider<Configuration> =
    project.configurations.register(dependencyContainerNames.dokkaGeneratorClasspath) {
      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."
      asConsumer()

      // extend from plugins classpath, so Dokka Worker can run the plugins
      extendsFrom(dokkaPluginsClasspath.get())

      isTransitive = true
      attributes {
        jvmJar()
        dokkaCategory(dokkatooAttributes.dokkaGeneratorClasspath)
      }
    }
  //</editor-fold>
}