diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayout.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayout.kt index e604ed46b8..a5c764d019 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayout.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayout.kt @@ -1,6 +1,10 @@ package org.jetbrains.dokka.gradle +import org.gradle.api.file.Directory +import org.gradle.api.provider.Provider import org.jetbrains.dokka.DokkaException +import org.jetbrains.dokka.gradle.DokkaMultiModuleFileLayout.CompactInParent +import org.jetbrains.dokka.gradle.DokkaMultiModuleFileLayout.NoCopy import java.io.File /** @@ -16,14 +20,16 @@ fun interface DokkaMultiModuleFileLayout { * @return The target output directory of the [child] dokka task referenced by [parent]. This should * be unique for all registered child tasks. */ - fun targetChildOutputDirectory(parent: DokkaMultiModuleTask, child: AbstractDokkaTask): File + fun targetChildOutputDirectory(parent: DokkaMultiModuleTask, child: AbstractDokkaTask): Provider /** * Will link to the original [AbstractDokkaTask.outputDirectory]. This requires no copying of the output files. */ object NoCopy : DokkaMultiModuleFileLayout { - override fun targetChildOutputDirectory(parent: DokkaMultiModuleTask, child: AbstractDokkaTask): File = - child.outputDirectory.get() + override fun targetChildOutputDirectory( + parent: DokkaMultiModuleTask, + child: AbstractDokkaTask + ): Provider = child.outputDirectory } /** @@ -34,18 +40,21 @@ fun interface DokkaMultiModuleFileLayout { * {parent output directory}/firstAncestor/secondAncestor */ object CompactInParent : DokkaMultiModuleFileLayout { - override fun targetChildOutputDirectory(parent: DokkaMultiModuleTask, child: AbstractDokkaTask): File { + override fun targetChildOutputDirectory( + parent: DokkaMultiModuleTask, + child: AbstractDokkaTask + ): Provider { val relativeProjectPath = parent.project.relativeProjectPath(child.project.path) val relativeFilePath = relativeProjectPath.replace(":", File.separator) check(!File(relativeFilePath).isAbsolute) { "Unexpected absolute path $relativeFilePath" } - return parent.outputDirectory.get().resolve(relativeFilePath) + return parent.outputDirectory.dir(relativeFilePath) } } } internal fun DokkaMultiModuleTask.targetChildOutputDirectory( child: AbstractDokkaTask -): File = fileLayout.get().targetChildOutputDirectory(this, child) +): Provider = fileLayout.get().targetChildOutputDirectory(this, child) internal fun DokkaMultiModuleTask.copyChildOutputDirectories() { @@ -56,7 +65,7 @@ internal fun DokkaMultiModuleTask.copyChildOutputDirectories() { internal fun DokkaMultiModuleTask.copyChildOutputDirectory(child: AbstractDokkaTask) { val targetChildOutputDirectory = project.file(fileLayout.get().targetChildOutputDirectory(this, child)) - val sourceChildOutputDirectory = child.outputDirectory.get() + val sourceChildOutputDirectory = child.outputDirectory.asFile.get() /* Pointing to the same directory -> No copy necessary */ if (sourceChildOutputDirectory.absoluteFile == targetChildOutputDirectory.absoluteFile) { diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaPlugin.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaPlugin.kt index c687896351..c30fc18193 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaPlugin.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaPlugin.kt @@ -5,7 +5,9 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.Dependency import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.withType import org.gradle.util.GradleVersion +import org.jetbrains.dokka.DokkaDefaults open class DokkaPlugin : Plugin { override fun apply(project: Project) { @@ -25,15 +27,24 @@ open class DokkaPlugin : Plugin { description = "Generates documentation in 'javadoc' format" } - project.setupDokkaTasks("dokkaGfm", allModulesPageAndTemplateProcessing = project.dokkaArtifacts.gfmTemplateProcessing) { + project.setupDokkaTasks( + "dokkaGfm", + allModulesPageAndTemplateProcessing = project.dokkaArtifacts.gfmTemplateProcessing + ) { plugins.dependencies.add(project.dokkaArtifacts.gfmPlugin) description = "Generates documentation in GitHub flavored markdown format" } - project.setupDokkaTasks("dokkaJekyll", allModulesPageAndTemplateProcessing = project.dokkaArtifacts.jekyllTemplateProcessing) { + project.setupDokkaTasks( + "dokkaJekyll", + allModulesPageAndTemplateProcessing = project.dokkaArtifacts.jekyllTemplateProcessing + ) { plugins.dependencies.add(project.dokkaArtifacts.jekyllPlugin) description = "Generates documentation in Jekyll flavored markdown format" } + + project.configureEachAbstractDokkaTask() + project.configureEachDokkaMultiModuleTask() } /** @@ -92,4 +103,18 @@ open class DokkaPlugin : Plugin { } } } + + private fun Project.configureEachAbstractDokkaTask() { + tasks.withType().configureEach { + val formatClassifier = name.removePrefix("dokka").decapitalize() + outputDirectory.convention(project.layout.buildDirectory.dir("dokka/$formatClassifier")) + cacheRoot.set(DokkaDefaults.cacheRoot) + } + } + + private fun Project.configureEachDokkaMultiModuleTask() { + tasks.withType().configureEach { + sourceChildOutputDirectories.from({ childDokkaTasks.map { it.outputDirectory } }) + } + } } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/AbstractDokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/AbstractDokkaTask.kt index b817e51d88..d4314e37fd 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/AbstractDokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/AbstractDokkaTask.kt @@ -7,6 +7,7 @@ import org.gradle.api.Action import org.gradle.api.DefaultTask import org.gradle.api.Task import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.DirectoryProperty import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.provider.ListProperty import org.gradle.api.provider.MapProperty @@ -19,7 +20,6 @@ import org.gradle.work.DisableCachingByDefault import org.jetbrains.dokka.* import org.jetbrains.dokka.plugability.ConfigurableBlock import org.jetbrains.dokka.plugability.DokkaPlugin -import java.io.File import java.util.function.BiConsumer import kotlin.reflect.full.createInstance @@ -56,9 +56,8 @@ abstract class AbstractDokkaTask : DefaultTask() { * Default is `project/buildDir/taskName.removePrefix("dokka").decapitalize()`, so * for `dokkaHtmlMultiModule` task it will be `project/buildDir/htmlMultiModule` */ - @OutputDirectory - val outputDirectory: Property = project.objects.property() - .convention(project.provider { defaultDokkaOutputDirectory() }) + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty /** * Configuration for Dokka plugins. This property is not expected to be used directly - if possible, use @@ -151,10 +150,10 @@ abstract class AbstractDokkaTask : DefaultTask() { val failOnWarning: Property = project.objects.property() .convention(DokkaDefaults.failOnWarning) - @Optional - @InputDirectory - @PathSensitive(PathSensitivity.RELATIVE) - val cacheRoot: Property = project.objects.property() + @get:Optional + @get:InputDirectory + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val cacheRoot: DirectoryProperty /** * Type-safe configuration for a Dokka plugin. diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaCollectorTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaCollectorTask.kt index 096dace5d4..77a84b3ffb 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaCollectorTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaCollectorTask.kt @@ -16,8 +16,8 @@ abstract class DokkaCollectorTask : AbstractDokkaParentTask() { override fun buildDokkaConfiguration(): DokkaConfigurationImpl { val initialDokkaConfiguration = DokkaConfigurationImpl( moduleName = moduleName.get(), - outputDir = outputDirectory.get(), - cacheRoot = cacheRoot.orNull, + outputDir = outputDirectory.asFile.get(), + cacheRoot = cacheRoot.asFile.orNull, failOnWarning = failOnWarning.get(), offlineMode = offlineMode.get(), pluginsClasspath = plugins.resolve().toList(), diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTask.kt index 1b61d57efe..0a55f13097 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTask.kt @@ -3,8 +3,10 @@ package org.jetbrains.dokka.gradle import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.Directory import org.gradle.api.internal.tasks.TaskDependencyInternal import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider import org.gradle.api.tasks.* import org.gradle.kotlin.dsl.property import org.jetbrains.dokka.DokkaConfigurationImpl @@ -46,10 +48,10 @@ abstract class DokkaMultiModuleTask : AbstractDokkaParentTask() { * Useful stuff in another package. * ``` */ - @InputFiles - @Optional - @PathSensitive(PathSensitivity.RELATIVE) - val includes: ConfigurableFileCollection = project.files() + @get:InputFiles + @get:Optional + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val includes: ConfigurableFileCollection @Internal val fileLayout: Property = project.objects.property() @@ -57,12 +59,12 @@ abstract class DokkaMultiModuleTask : AbstractDokkaParentTask() { @get:InputFiles @get:PathSensitive(PathSensitivity.RELATIVE) - internal val sourceChildOutputDirectories: Iterable - get() = childDokkaTasks.map { task -> task.outputDirectory.get() } + internal abstract val sourceChildOutputDirectories: ConfigurableFileCollection @get:OutputDirectories - internal val targetChildOutputDirectories: Iterable - get() = childDokkaTasks.map { task -> targetChildOutputDirectory(task) } + internal val targetChildOutputDirectories: Provider> = project.provider { + childDokkaTasks.map { task -> targetChildOutputDirectory(task).get() } + } @get:Input internal val childDokkaTaskIncludes: Map> @@ -83,23 +85,27 @@ abstract class DokkaMultiModuleTask : AbstractDokkaParentTask() { super.generateDocumentation() } - override fun buildDokkaConfiguration(): DokkaConfigurationImpl = DokkaConfigurationImpl( - moduleName = moduleName.get(), - moduleVersion = moduleVersion.getValidVersionOrNull(), - outputDir = outputDirectory.get(), - cacheRoot = cacheRoot.orNull, - pluginsConfiguration = buildPluginsConfiguration(), + override fun buildDokkaConfiguration(): DokkaConfigurationImpl { + return DokkaConfigurationImpl( + moduleName = moduleName.get(), + moduleVersion = moduleVersion.getValidVersionOrNull(), + outputDir = outputDirectory.asFile.get(), + cacheRoot = cacheRoot.asFile.orNull, + pluginsConfiguration = buildPluginsConfiguration(), failOnWarning = failOnWarning.get(), offlineMode = offlineMode.get(), - pluginsClasspath = plugins.resolve().toList(), - modules = childDokkaTasks.map { dokkaTask -> - DokkaModuleDescriptionImpl( - name = dokkaTask.moduleName.get(), - relativePathToOutputDirectory = targetChildOutputDirectory(dokkaTask).relativeTo(outputDirectory.get()), - includes = childDokkaTaskIncludes[dokkaTask.path].orEmpty(), - sourceOutputDirectory = dokkaTask.outputDirectory.get() - ) - }, - includes = includes.toSet(), - ) + pluginsClasspath = plugins.resolve().toList(), + modules = childDokkaTasks.map { dokkaTask -> + DokkaModuleDescriptionImpl( + name = dokkaTask.moduleName.get(), + relativePathToOutputDirectory = targetChildOutputDirectory(dokkaTask).get().asFile.relativeTo( + outputDirectory.asFile.get() + ), + includes = childDokkaTaskIncludes[dokkaTask.path].orEmpty(), + sourceOutputDirectory = dokkaTask.outputDirectory.asFile.get(), + ) + }, + includes = includes.toSet(), + ) + } } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTask.kt index 46c59e9564..8c6a376770 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTask.kt @@ -2,9 +2,9 @@ package org.jetbrains.dokka.gradle +import org.gradle.api.tasks.* import org.jetbrains.dokka.DokkaConfigurationImpl import org.jetbrains.dokka.build -import org.gradle.api.tasks.* @CacheableTask abstract class DokkaTask : AbstractDokkaLeafTask() { @@ -12,8 +12,8 @@ abstract class DokkaTask : AbstractDokkaLeafTask() { DokkaConfigurationImpl( moduleName = moduleName.get(), moduleVersion = moduleVersion.getValidVersionOrNull(), - outputDir = outputDirectory.get(), - cacheRoot = cacheRoot.orNull, + outputDir = outputDirectory.asFile.get(), + cacheRoot = cacheRoot.asFile.orNull, offlineMode = offlineMode.get(), failOnWarning = failOnWarning.get(), sourceSets = unsuppressedSourceSets.build(), diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskPartial.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskPartial.kt index 8431f1df32..1b9f264169 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskPartial.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskPartial.kt @@ -2,9 +2,9 @@ package org.jetbrains.dokka.gradle +import org.gradle.api.tasks.* import org.jetbrains.dokka.DokkaConfigurationImpl import org.jetbrains.dokka.build -import org.gradle.api.tasks.* @CacheableTask abstract class DokkaTaskPartial : AbstractDokkaLeafTask() { @@ -13,8 +13,8 @@ abstract class DokkaTaskPartial : AbstractDokkaLeafTask() { return DokkaConfigurationImpl( moduleName = moduleName.get(), moduleVersion = moduleVersion.orNull, - outputDir = outputDirectory.get(), - cacheRoot = cacheRoot.orNull, + outputDir = outputDirectory.asFile.get(), + cacheRoot = cacheRoot.asFile.orNull, offlineMode = offlineMode.get(), failOnWarning = failOnWarning.get(), sourceSets = unsuppressedSourceSets.build(), diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTaskTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTaskTest.kt index 2cac940fb6..c5ea42a565 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTaskTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTaskTest.kt @@ -7,6 +7,7 @@ import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.getByName import org.gradle.testfixtures.ProjectBuilder import org.jetbrains.dokka.DokkaConfigurationImpl +import org.jetbrains.dokka.gradle.utils.subprojects_ import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -19,7 +20,7 @@ class AbstractDokkaParentTaskTest { private val subSubproject0 = ProjectBuilder.builder().withName("subSubproject0").withParent(subproject0).build() init { - rootProject.subprojects { + rootProject.subprojects_ { tasks.create("dokkaTask") } } @@ -190,12 +191,10 @@ class AbstractDokkaParentTaskTest { } } -internal open class TestDokkaParentTask : AbstractDokkaParentTask() { +internal abstract class TestDokkaParentTask : AbstractDokkaParentTask() { override fun buildDokkaConfiguration(): DokkaConfigurationImpl { throw NotImplementedError() } } private val Project.dokkaTask: DokkaTask get() = tasks.getByName("dokkaTask") - - diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt index 108c7fe0af..d01847a083 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt @@ -2,7 +2,13 @@ package org.jetbrains.dokka.gradle import org.gradle.kotlin.dsl.withType import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.* +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.DokkaConfigurationImpl +import org.jetbrains.dokka.PluginConfigurationImpl +import org.jetbrains.dokka.gradle.utils.create_ +import org.jetbrains.dokka.gradle.utils.externalDocumentationLink_ +import org.jetbrains.dokka.gradle.utils.withDependencies_ +import org.jetbrains.dokka.toCompactJsonString import java.io.File import java.net.URL import kotlin.test.Test @@ -15,23 +21,31 @@ class DokkaConfigurationJsonTest { val project = ProjectBuilder.builder().build() project.plugins.apply("org.jetbrains.dokka") val dokkaTask = project.tasks.withType().first() - dokkaTask.plugins.withDependencies { clear() } + dokkaTask.plugins.withDependencies_ { clear() } dokkaTask.apply { this.failOnWarning.set(true) this.offlineMode.set(true) this.outputDirectory.set(File("customOutputDir")) this.cacheRoot.set(File("customCacheRoot")) this.pluginsConfiguration.add( - PluginConfigurationImpl("A", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value1" } """) + PluginConfigurationImpl( + "A", + DokkaConfiguration.SerializationFormat.JSON, + """ { "key" : "value1" } """ + ) ) this.pluginsConfiguration.add( - PluginConfigurationImpl("B", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value2" } """) + PluginConfigurationImpl( + "B", + DokkaConfiguration.SerializationFormat.JSON, + """ { "key" : "value2" } """ + ) ) - this.dokkaSourceSets.create("main") { + this.dokkaSourceSets.create_("main") { displayName.set("customSourceSetDisplayName") reportUndocumented.set(true) - externalDocumentationLink { + externalDocumentationLink_ { packageListUrl.set(URL("http://some.url")) url.set(URL("http://some.other.url")) } diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt index 75e2b63e40..b52301148e 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt @@ -4,6 +4,9 @@ import org.gradle.kotlin.dsl.withType import org.gradle.testfixtures.ProjectBuilder import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.PluginConfigurationImpl +import org.jetbrains.dokka.gradle.utils.create_ +import org.jetbrains.dokka.gradle.utils.externalDocumentationLink_ +import org.jetbrains.dokka.gradle.utils.withDependencies_ import org.junit.Rule import org.junit.rules.TemporaryFolder import java.io.File @@ -24,19 +27,31 @@ class DokkaConfigurationSerializableTest { val project = ProjectBuilder.builder().build() project.plugins.apply("org.jetbrains.dokka") val dokkaTask = project.tasks.withType().first() - dokkaTask.plugins.withDependencies { clear() } + dokkaTask.plugins.withDependencies_ { clear() } dokkaTask.apply { this.failOnWarning.set(true) this.offlineMode.set(true) this.outputDirectory.set(File("customOutputDir")) this.cacheRoot.set(File("customCacheRoot")) - this.pluginsConfiguration.add(PluginConfigurationImpl("A", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value1" } """)) - this.pluginsConfiguration.add(PluginConfigurationImpl("B", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value2" } """)) - this.dokkaSourceSets.create("main") { + this.pluginsConfiguration.add( + PluginConfigurationImpl( + "A", + DokkaConfiguration.SerializationFormat.JSON, + """ { "key" : "value1" } """ + ) + ) + this.pluginsConfiguration.add( + PluginConfigurationImpl( + "B", + DokkaConfiguration.SerializationFormat.JSON, + """ { "key" : "value2" } """ + ) + ) + this.dokkaSourceSets.create_("main") { displayName.set("customSourceSetDisplayName") reportUndocumented.set(true) - externalDocumentationLink { + externalDocumentationLink_ { packageListUrl.set(URL("http://some.url")) url.set(URL("http://some.other.url")) } diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayoutTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayoutTest.kt index d00664b51a..6f0ce8a244 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayoutTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleFileLayoutTest.kt @@ -16,12 +16,15 @@ class DokkaMultiModuleFileLayoutTest { @Test fun `no copy`() { val project = ProjectBuilder.builder().build() + project.plugins.apply("org.jetbrains.dokka") + val child = project.tasks.create("child") val parent = project.tasks.create("parent") child.outputDirectory.set(File("some/path")) assertEquals( - File("some/path"), NoCopy.targetChildOutputDirectory(parent, child), + File("some/path"), + NoCopy.targetChildOutputDirectory(parent, child).get().asFile.relativeTo(project.projectDir), "Expected original file path returned" ) } @@ -29,16 +32,21 @@ class DokkaMultiModuleFileLayoutTest { @Test fun `compact in parent`() { val rootProject = ProjectBuilder.builder().build() + val parentProject = ProjectBuilder.builder().withName("parent").withParent(rootProject).build() + parentProject.plugins.apply("org.jetbrains.dokka") + val intermediateProject = ProjectBuilder.builder().withName("intermediate").withParent(parentProject).build() val childProject = ProjectBuilder.builder().withName("child").withParent(intermediateProject).build() + childProject.plugins.apply("org.jetbrains.dokka") val parentTask = parentProject.tasks.create("parentTask") val childTask = childProject.tasks.create("childTask") val targetOutputDirectory = CompactInParent.targetChildOutputDirectory(parentTask, childTask) assertEquals( - parentTask.outputDirectory.get().resolve("intermediate/child"), targetOutputDirectory, + parentTask.outputDirectory.get().asFile.resolve("intermediate/child"), + targetOutputDirectory.get().asFile, "Expected nested file structure representing project structure" ) } @@ -47,17 +55,21 @@ class DokkaMultiModuleFileLayoutTest { fun copyChildOutputDirectory() { /* Prepare */ val project = ProjectBuilder.builder().build() + project.plugins.apply("org.jetbrains.dokka") + val childTask = project.tasks.create("child") val parentTask = project.tasks.create("parent") - val sourceOutputDirectory = childTask.outputDirectory.get() + val sourceOutputDirectory = childTask.outputDirectory.get().asFile sourceOutputDirectory.mkdirs() sourceOutputDirectory.resolve("some.file").writeText("some text") val subFolder = sourceOutputDirectory.resolve("subFolder") subFolder.mkdirs() subFolder.resolve("other.file").writeText("other text") - parentTask.fileLayout.set(DokkaMultiModuleFileLayout { parent, _ -> parent.project.file("target/output") }) + parentTask.fileLayout.set(DokkaMultiModuleFileLayout { parent, _ -> + parent.project.provider { parent.project.layout.projectDirectory.dir("target/output") } + }) parentTask.copyChildOutputDirectory(childTask) /* Assertions */ @@ -99,10 +111,12 @@ class DokkaMultiModuleFileLayoutTest { @Test fun `copyChildOutputDirectory target output directory within itself throws DokkaException`() { val project = ProjectBuilder.builder().build() + project.plugins.apply("org.jetbrains.dokka") + val childTask = project.tasks.create("child") val parentTask = project.tasks.create("parent") parentTask.fileLayout.set(DokkaMultiModuleFileLayout { _, child -> - child.outputDirectory.get().resolve("subfolder") + child.outputDirectory.dir("subfolder") }) assertFailsWith { parentTask.copyChildOutputDirectory(childTask) } } @@ -110,6 +124,8 @@ class DokkaMultiModuleFileLayoutTest { @Test fun `copyChildOutputDirectory NoCopy`() { val project = ProjectBuilder.builder().build() + project.plugins.apply("org.jetbrains.dokka") + val childTask = project.tasks.create("child") val parentTask = project.tasks.create("parent") parentTask.fileLayout.set(NoCopy) diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt index 52485cdc19..fe6869e91b 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt @@ -2,7 +2,8 @@ package org.jetbrains.dokka.gradle import org.gradle.kotlin.dsl.withType import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.DokkaSourceSetID +import org.jetbrains.dokka.gradle.utils.configureEach_ +import org.jetbrains.dokka.gradle.utils.create_ import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension import java.io.File import kotlin.test.Test @@ -13,12 +14,12 @@ class KotlinDslDokkaTaskConfigurationTest { fun `configure dokka task`() { val project = ProjectBuilder.builder().build() project.plugins.apply("org.jetbrains.dokka") - project.tasks.withType().configureEach { + project.tasks.withType().configureEach_ { outputDirectory.set(File("test")) } project.tasks.withType(DokkaTask::class.java).forEach { dokkaTask -> - assertEquals(File("test"), dokkaTask.outputDirectory.get()) + assertEquals(File("test"), dokkaTask.outputDirectory.get().asFile.relativeTo(project.projectDir)) } } @@ -30,7 +31,7 @@ class KotlinDslDokkaTaskConfigurationTest { project.tasks.withType(DokkaTask::class.java).forEach { dokkaTask -> dokkaTask.dokkaSourceSets.run { val commonMain = create("commonMain") - val jvmMain = create("jvmMain") { + val jvmMain = create_("jvmMain") { dependsOn("commonMain") } diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTaskTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaCollectorTaskTest.kt similarity index 71% rename from runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTaskTest.kt rename to runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaCollectorTaskTest.kt index b9c20dce09..3c7b58a060 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTaskTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaCollectorTaskTest.kt @@ -1,10 +1,17 @@ -package org.jetbrains.dokka.gradle +package org.jetbrains.dokka.gradle.tasks import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.withType import org.gradle.testfixtures.ProjectBuilder import org.jetbrains.dokka.DokkaConfigurationImpl import org.jetbrains.dokka.DokkaException +import org.jetbrains.dokka.gradle.AbstractDokkaTask +import org.jetbrains.dokka.gradle.DokkaCollectorTask +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.gradle.utils.all_ +import org.jetbrains.dokka.gradle.utils.allprojects_ +import org.jetbrains.dokka.gradle.utils.configureEach_ +import org.jetbrains.dokka.gradle.utils.withDependencies_ import java.io.File import kotlin.test.* @@ -16,20 +23,20 @@ class DokkaCollectorTaskTest { val childProject = ProjectBuilder.builder().withParent(rootProject).build() childProject.plugins.apply("org.jetbrains.kotlin.jvm") - rootProject.allprojects { + rootProject.allprojects_ { plugins.apply("org.jetbrains.dokka") - tasks.withType().configureEach { - plugins.withDependencies { clear() } + tasks.withType().configureEach_ { + plugins.withDependencies_ { clear() } } - tasks.withType().configureEach { - dokkaSourceSets.configureEach { + tasks.withType().configureEach_ { + dokkaSourceSets.configureEach_ { classpath.setFrom(emptyList()) } } } val collectorTasks = rootProject.tasks.withType() - collectorTasks.configureEach { + collectorTasks.configureEach_ { moduleName.set("custom Module Name") outputDirectory.set(File("customOutputDirectory")) cacheRoot.set(File("customCacheRoot")) @@ -44,8 +51,8 @@ class DokkaCollectorTaskTest { assertEquals( DokkaConfigurationImpl( moduleName = "custom Module Name", - outputDir = File("customOutputDirectory"), - cacheRoot = File("customCacheRoot"), + outputDir = rootProject.projectDir.resolve("customOutputDirectory"), + cacheRoot = rootProject.projectDir.resolve("customCacheRoot"), failOnWarning = true, offlineMode = true, sourceSets = task.childDokkaTasks @@ -67,20 +74,20 @@ class DokkaCollectorTaskTest { val childProject = ProjectBuilder.builder().withParent(rootProject).build() childProject.plugins.apply("org.jetbrains.kotlin.jvm") - rootProject.allprojects { + rootProject.allprojects_ { plugins.apply("org.jetbrains.dokka") - tasks.withType().configureEach { - plugins.withDependencies { clear() } + tasks.withType().configureEach_ { + plugins.withDependencies_ { clear() } } - tasks.withType().configureEach { - dokkaSourceSets.configureEach { + tasks.withType().configureEach_ { + dokkaSourceSets.configureEach_ { classpath.setFrom(emptyList()) } } } val collectorTasks = rootProject.tasks.withType() - collectorTasks.configureEach { + collectorTasks.configureEach_ { cacheRoot.set(null as File?) } @@ -96,7 +103,7 @@ class DokkaCollectorTaskTest { fun `with no child tasks throws DokkaException`() { val project = ProjectBuilder.builder().build() val collectorTask = project.tasks.create("collector") - project.configurations.all { withDependencies { clear() } } + project.configurations.all_ { withDependencies_ { clear() } } assertFailsWith { collectorTask.generateDocumentation() } } } diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTaskTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTaskTest.kt index ecbe3355b1..6df809ff71 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTaskTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaMultiModuleTaskTest.kt @@ -6,6 +6,10 @@ import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.withType import org.gradle.testfixtures.ProjectBuilder import org.jetbrains.dokka.* +import org.jetbrains.dokka.gradle.utils.allprojects_ +import org.jetbrains.dokka.gradle.utils.configureEach_ +import org.jetbrains.dokka.gradle.utils.create_ +import org.jetbrains.dokka.gradle.utils.withDependencies_ import java.io.File import kotlin.test.* @@ -27,9 +31,11 @@ class DokkaMultiModuleTaskTest { } init { - rootProject.allprojects { - tasks.withType().configureEach { - plugins.withDependencies { clear() } + rootProject.plugins.apply("org.jetbrains.dokka") + childProject.plugins.apply("org.jetbrains.dokka") + rootProject.allprojects_ { + tasks.withType().configureEach_ { + plugins.withDependencies_ { clear() } } } } @@ -56,7 +62,7 @@ class DokkaMultiModuleTaskTest { childDokkaTask.apply { dokkaSourceSets.create("main") dokkaSourceSets.create("test") - dokkaSourceSets.configureEach { + dokkaSourceSets.configureEach_ { includes.from(include1, include2) } } @@ -84,7 +90,7 @@ class DokkaMultiModuleTaskTest { moduleName = "custom Module Name", moduleVersion = "1.5.0", outputDir = multiModuleTask.project.buildDir.resolve("customOutputDirectory"), - cacheRoot = File("customCacheRoot"), + cacheRoot = multiModuleTask.project.projectDir.resolve("customCacheRoot"), pluginsConfiguration = mutableListOf( PluginConfigurationImpl( "pluginA", @@ -101,7 +107,7 @@ class DokkaMultiModuleTaskTest { name = "child", relativePathToOutputDirectory = File("child"), includes = setOf(include1, include2), - sourceOutputDirectory = childDokkaTask.outputDirectory.get() + sourceOutputDirectory = childDokkaTask.outputDirectory.get().asFile ) ) ), @@ -151,7 +157,7 @@ class DokkaMultiModuleTaskTest { fun `multimodule task with no child tasks throws DokkaException`() { val project = ProjectBuilder.builder().build() val multimodule = project.tasks.create("multimodule") - project.configurations.configureEach { withDependencies { clear() } } + project.configurations.configureEach_ { withDependencies_ { clear() } } assertFailsWith { multimodule.generateDocumentation() } } @@ -162,17 +168,17 @@ class DokkaMultiModuleTaskTest { val childDokkaTaskInclude3 = childProject.file("include3") childDokkaTask.apply { - dokkaSourceSets.create("main") { + dokkaSourceSets.create_("main") { includes.from(childDokkaTaskInclude1, childDokkaTaskInclude2) } - dokkaSourceSets.create("main2") { + dokkaSourceSets.create_("main2") { includes.from(childDokkaTaskInclude3) } } val secondChildDokkaTaskInclude = childProject.file("include4") val secondChildDokkaTask = childProject.tasks.create("secondChildDokkaTask") { - dokkaSourceSets.create("main") { + dokkaSourceSets.create_("main") { includes.from(secondChildDokkaTaskInclude) } } @@ -194,7 +200,9 @@ class DokkaMultiModuleTaskTest { @Test fun sourceChildOutputDirectories() { val parent = ProjectBuilder.builder().build() + parent.plugins.apply("org.jetbrains.dokka") val child = ProjectBuilder.builder().withName("child").withParent(parent).build() + child.plugins.apply("org.jetbrains.dokka") val parentTask = parent.tasks.create("parent") val childTask = child.tasks.create("child") @@ -203,7 +211,8 @@ class DokkaMultiModuleTaskTest { childTask.outputDirectory.set(child.file("custom/output")) assertEquals( - listOf(parent.file("child/custom/output")), parentTask.sourceChildOutputDirectories, + listOf(parent.file("child/custom/output")), + parentTask.sourceChildOutputDirectories.files.toList(), "Expected child output directory being present" ) } @@ -219,11 +228,12 @@ class DokkaMultiModuleTaskTest { parentTask.addChildTask(childTask) parentTask.fileLayout.set(DokkaMultiModuleFileLayout { taskParent, taskChild -> - taskParent.project.buildDir.resolve(taskChild.name) + taskParent.project.layout.buildDirectory.dir(taskChild.name) }) assertEquals( - listOf(parent.project.buildDir.resolve("child")), parentTask.targetChildOutputDirectories, + listOf(parent.project.buildDir.resolve("child")), + parentTask.targetChildOutputDirectories.get().map { it.asFile }, "Expected child target output directory being present" ) } diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskTest.kt index 518a01f1d1..79b80fa38e 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/tasks/DokkaTaskTest.kt @@ -4,6 +4,9 @@ package org.jetbrains.dokka.gradle import org.gradle.kotlin.dsl.create import org.gradle.testfixtures.ProjectBuilder +import org.jetbrains.dokka.gradle.utils.all_ +import org.jetbrains.dokka.gradle.utils.register_ +import org.jetbrains.dokka.gradle.utils.withDependencies_ import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNull @@ -12,12 +15,14 @@ class DokkaTaskTest { @Test fun `no suppressed source sets are present after in built configuration`() { val project = ProjectBuilder.builder().build() + project.plugins.apply("org.jetbrains.dokka") + val task = project.tasks.create("dokkaTask") - project.configurations.all { withDependencies { clear() } } + project.configurations.all_ { withDependencies_ { clear() } } task.dokkaSourceSets.register("main") task.dokkaSourceSets.register("jvm") - task.dokkaSourceSets.register("test") { + task.dokkaSourceSets.register_("test") { suppress.set(true) } @@ -29,10 +34,12 @@ class DokkaTaskTest { } @Test - fun `module version is not present if not specified`(){ + fun `module version is not present if not specified`() { val project = ProjectBuilder.builder().build() + project.plugins.apply("org.jetbrains.dokka") + val task = project.tasks.create("dokkaTask") - project.configurations.all { withDependencies { clear() } } + project.configurations.all_ { withDependencies_ { clear() } } task.dokkaSourceSets.register("main") assertNull(task.buildDokkaConfiguration().moduleVersion) diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/utils/samWithReceiverWorkarounds.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/utils/samWithReceiverWorkarounds.kt new file mode 100644 index 0000000000..4738f7d848 --- /dev/null +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/utils/samWithReceiverWorkarounds.kt @@ -0,0 +1,69 @@ +package org.jetbrains.dokka.gradle.utils + +import org.gradle.api.* +import org.gradle.api.artifacts.Configuration +import org.gradle.api.artifacts.DependencySet +import org.jetbrains.dokka.gradle.GradleDokkaSourceSetBuilder +import org.jetbrains.dokka.gradle.GradleExternalDocumentationLinkBuilder + + +/** + * Workarounds because `SamWithReceiver` not working in test sources + * https://youtrack.jetbrains.com/issue/KTIJ-14684 + * + * The `SamWithReceiver` plugin is automatically applied by the `kotlin-dsl` plugin. + * It converts all [org.gradle.api.Action] so the parameter is the receiver: + * + * ``` + * // with SamWithReceiver ✅ + * tasks.configureEach { + * val task: Task = this + * } + * + * // without SamWithReceiver + * tasks.configureEach { it -> + * val task: Task = it + * } + * ``` + * + * This is nice because it means that the Dokka Gradle Plugin more closely matches `build.gradle.kts` files. + * + * However, [IntelliJ is bugged](https://youtrack.jetbrains.com/issue/KTIJ-14684) and doesn't + * acknowledge that `SamWithReceiver` has been applied in test sources. The code works and compiles, + * but IntelliJ shows red errors. + * + * These functions are workarounds, and should be removed ASAP. + */ +@Suppress("unused") +private object Explain + +fun Project.subprojects_(configure: Project.() -> Unit) = + subprojects(configure) + +@Suppress("SpellCheckingInspection") +fun Project.allprojects_(configure: Project.() -> Unit) = + allprojects(configure) + +fun DomainObjectCollection.configureEach_(configure: T.() -> Unit) = + configureEach(configure) + +fun DomainObjectCollection.all_(configure: T.() -> Unit) = + all(configure) + +fun Configuration.withDependencies_(action: DependencySet.() -> Unit): Configuration = + withDependencies(action) + + +fun NamedDomainObjectContainer.create_(name: String, configure: T.() -> Unit): T = + create(name, configure) + +fun NamedDomainObjectContainer.register_( + name: String, + configure: T.() -> Unit +): NamedDomainObjectProvider = + register(name, configure) + + +fun GradleDokkaSourceSetBuilder.externalDocumentationLink_( + action: GradleExternalDocumentationLinkBuilder.() -> Unit +) = externalDocumentationLink(action)