Skip to content

Commit

Permalink
Support specifying custom folder name for older versions for versioni…
Browse files Browse the repository at this point in the history
…ng plugin

* Introduce a new parameter `olderVersionsDirName` in `VersioningConfiguration` to customize the directory name for older versions HTMLs
* Add integration test with different folder names
  • Loading branch information
whyoleg committed Jul 11, 2024
1 parent f414a5f commit 1254b58
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 16,32 @@ subprojects {
apply plugin: 'org.jetbrains.dokka'
}

def olderVersionsDirName = providers.gradleProperty("olderVersionsDirName").orNull

dokkaHtmlMultiModule {
pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.2", "olderVersionsDir": "$projectDir/dokkas" }"""])
if (olderVersionsDirName == null) {
pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.2", "olderVersionsDir": "$projectDir/dokkas" }"""])
} else {
pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.2", "olderVersionsDir": "$projectDir/dokkas", "olderVersionsDirName": "$olderVersionsDirName" }"""])
}
}

tasks.register('dokkaHtmlMultiModuleBaseVersion', DokkaMultiModuleTask) {
outputDirectory.set(file(projectDir.toPath().resolve("dokkas").resolve("1.0")))
pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.0" }"""])
if (olderVersionsDirName == null) {
pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.0" }"""])
} else {
pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.0", "olderVersionsDirName": "$olderVersionsDirName" }"""])
}
addChildTasks([project(":first"), project(":second")], "dokkaHtmlPartial")
}

tasks.register('dokkaHtmlMultiModuleNextVersion', DokkaMultiModuleTask) {
outputDirectory.set(file(projectDir.toPath().resolve("dokkas").resolve("1.1")))
pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.1", "olderVersionsDir": "$projectDir/dokkas" }"""])
if (olderVersionsDirName == null) {
pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.1", "olderVersionsDir": "$projectDir/dokkas" }"""])
} else {
pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.1", "olderVersionsDir": "$projectDir/dokkas", "olderVersionsDirName": "$olderVersionsDirName" }"""])
}
addChildTasks([project(":first"), project(":second")], "dokkaHtmlPartial")
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 74,136 @@ class Versioning0IntegrationTest : AbstractGradleIntegrationTest() {
links.map { it.text() to it.attr("href") }
)
}

@ParameterizedTest(name = "{0}")
@ArgumentsSource(AllSupportedTestedVersionsArgumentsProvider::class)
fun executeWithCustomOlderFolderName(buildVersions: BuildVersions) {
val olderVersionsDirName = "version"

val result = createGradleRunner(
buildVersions,
":dokkaHtmlMultiModuleBaseVersion",
"-i", "-s",
"-PolderVersionsDirName=$olderVersionsDirName"
).buildRelaxed()

assertEquals(TaskOutcome.SUCCESS, assertNotNull(result.task(":dokkaHtmlMultiModuleBaseVersion")).outcome)
val outputDir = File(projectDir, "dokkas/1.0")
assertTrue(outputDir.isDirectory, "Missing dokka output directory")

val result2 = createGradleRunner(
buildVersions,
"clean",
":dokkaHtmlMultiModuleNextVersion",
"-i", "-s",
"-PolderVersionsDirName=$olderVersionsDirName"
).buildRelaxed()

assertEquals(TaskOutcome.SUCCESS, assertNotNull(result2.task(":dokkaHtmlMultiModuleNextVersion")).outcome)
val outputDir2 = File(projectDir, "dokkas/1.1")
assertTrue(outputDir2.isDirectory, "Missing dokka output directory")

val result3 = createGradleRunner(
buildVersions,
"clean",
":dokkaHtmlMultiModule",
"-i", "-s",
"-PolderVersionsDirName=$olderVersionsDirName"
).buildRelaxed()

assertEquals(TaskOutcome.SUCCESS, assertNotNull(result3.task(":dokkaHtmlMultiModule")).outcome)
val outputDirMultiModule = File(projectDir, "build/dokka/htmlMultiModule")
assertTrue(outputDirMultiModule.isDirectory, "Missing dokka output directory")

val version1_0 = outputDirMultiModule.resolve(olderVersionsDirName).resolve("1.0")
val version1_1 = outputDirMultiModule.resolve(olderVersionsDirName).resolve("1.1")

assertTrue(version1_0.isDirectory, "Assumed to have 1.0 version in older dir")
assertTrue(version1_1.isDirectory, "Assumed to have 1.1 version in older dir")

assertFalse(version1_0.resolve(olderVersionsDirName).exists(), "Subversions should not have older directory")
assertFalse(version1_1.resolve(olderVersionsDirName).exists(), "Subversions should not have older directory")

val parsedIndex = Jsoup.parse(outputDirMultiModule.resolve("index.html").readText())
val dropdown = parsedIndex.select("dokka-template-command").firstOrNull()
assertNotNull(dropdown)
val links = dropdown.select("a")
assertEquals(3, links.count(), "Expected 3 versions to be in dropdown: 1.0, 1.1 and 1.2")
assertEquals(
listOf(
"1.2" to "index.html",
"1.1" to "$olderVersionsDirName/1.1/index.html",
"1.0" to "$olderVersionsDirName/1.0/index.html"
),
links.map { it.text() to it.attr("href") }
)
}

@ParameterizedTest(name = "{0}")
@ArgumentsSource(AllSupportedTestedVersionsArgumentsProvider::class)
fun executeWithEmptyCustomOlderFolderName(buildVersions: BuildVersions) {
// will place versions without a separate dir, but directly inside root
val olderVersionsDirName = ""
val result = createGradleRunner(
buildVersions,
":dokkaHtmlMultiModuleBaseVersion",
"-i", "-s",
"-PolderVersionsDirName=$olderVersionsDirName"
).buildRelaxed()

assertEquals(TaskOutcome.SUCCESS, assertNotNull(result.task(":dokkaHtmlMultiModuleBaseVersion")).outcome)
val outputDir = File(projectDir, "dokkas/1.0")
assertTrue(outputDir.isDirectory, "Missing dokka output directory")

val result2 = createGradleRunner(
buildVersions,
"clean",
":dokkaHtmlMultiModuleNextVersion",
"-i", "-s",
"-PolderVersionsDirName=$olderVersionsDirName"
).buildRelaxed()

assertEquals(TaskOutcome.SUCCESS, assertNotNull(result2.task(":dokkaHtmlMultiModuleNextVersion")).outcome)
val outputDir2 = File(projectDir, "dokkas/1.1")
assertTrue(outputDir2.isDirectory, "Missing dokka output directory")

val result3 = createGradleRunner(
buildVersions,
"clean",
":dokkaHtmlMultiModule",
"-i", "-s",
"-PolderVersionsDirName=$olderVersionsDirName"
).buildRelaxed()

assertEquals(TaskOutcome.SUCCESS, assertNotNull(result3.task(":dokkaHtmlMultiModule")).outcome)
val outputDirMultiModule = File(projectDir, "build/dokka/htmlMultiModule")
assertTrue(outputDirMultiModule.isDirectory, "Missing dokka output directory")

// NO SEPARATE FOLDER HERE
val version1_0 = outputDirMultiModule.resolve("1.0")
val version1_1 = outputDirMultiModule.resolve("1.1")

assertTrue(version1_0.isDirectory, "Assumed to have 1.0 version in older dir")
assertTrue(version1_1.isDirectory, "Assumed to have 1.1 version in older dir")

assertFalse(version1_0.resolve("1.0").exists(), "Subversions should not have older directory")
assertFalse(version1_0.resolve("1.1").exists(), "Subversions should not have older directory")

assertFalse(version1_1.resolve("1.0").exists(), "Subversions should not have older directory")
assertFalse(version1_1.resolve("1.1").exists(), "Subversions should not have older directory")

val parsedIndex = Jsoup.parse(outputDirMultiModule.resolve("index.html").readText())
val dropdown = parsedIndex.select("dokka-template-command").firstOrNull()
assertNotNull(dropdown)
val links = dropdown.select("a")
assertEquals(3, links.count(), "Expected 3 versions to be in dropdown: 1.0, 1.1 and 1.2")
assertEquals(
listOf(
"1.2" to "index.html",
"1.1" to "1.1/index.html",
"1.0" to "1.0/index.html"
),
links.map { it.text() to it.attr("href") }
)
}
}
10 changes: 7 additions & 3 deletions dokka-subprojects/plugin-versioning/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 109,7 @@ The table below contains all the possible configuration options for the versioni
| `olderVersionsDir` | An optional path to a parent folder that contains other documentation versions. It requires a specific directory structure. For more information, see [Directory structure](#directory-structure). |
| `olderVersions` | An optional list of paths to other documentation versions. It must point to Dokka's outputs directly. This is useful if different versions can't all be in the same directory. |
| `renderVersionsNavigationOnAllPages` | An optional boolean value indicating whether to render the navigation dropdown on all pages. Set to true by default. |
| `olderVersionsDirName` | An optional folder name where other documentation versions output will be placed. In case of empty string root folder will be used instead. Set to `older` by default. |

#### Directory structure

Expand Down Expand Up @@ -264,7 265,7 @@ plugin to match versions and generate version navigation. If your previously gen
file, you will need to re-generate documentation for such versions. Just adding the file will not work.

The versioning plugin also bundles all other documentation versions that have been passed through `olderVersionsDir`
and `olderVersions` configuration options by putting them inside the `older` directory.
and `olderVersions` configuration options by putting them inside the directory passed through `olderVersionsDirName`.

## Usage example

Expand All @@ -281,8 282,11 @@ The main idea behind it is the following:
4. Once new documentation has been generated, it needs to be **copied** to somewhere accessible by the user.
For example, GitHub pages or nginx static directories. It needs to be **copied**, not moved because Dokka will still
need this version for future builds, otherwise there will be a gap in the archive.
5. Once it has been safely copied, you can remove the `older` directory from the newly generated and archived version.
This helps reduce the overhead of each version bundling all previous versions, as these files are effectively duplicates.
5. Once it has been safely copied,
you can remove the directory specified in `olderVersionsDirName`(`older` by default)
from the newly generated and archived version.
This helps reduce the overhead of each version bundling all previous versions,
as these files are effectively duplicates.

```kotlin
import org.jetbrains.dokka.versioning.VersioningPlugin
Expand Down
12 changes: 8 additions & 4 deletions dokka-subprojects/plugin-versioning/api/plugin-versioning.api
Original file line number Diff line number Diff line change
Expand Up @@ -86,24 86,27 @@ public final class org/jetbrains/dokka/versioning/VersioningConfiguration : org/
public static final field OLDER_VERSIONS_DIR Ljava/lang/String;
public static final field VERSIONS_FILE Ljava/lang/String;
public fun <init> ()V
public fun <init> (Ljava/io/File;Ljava/util/List;Ljava/util/List;Ljava/lang/String;Ljava/lang/Boolean;)V
public synthetic fun <init> (Ljava/io/File;Ljava/util/List;Ljava/util/List;Ljava/lang/String;Ljava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/io/File;Ljava/util/List;Ljava/util/List;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/io/File;Ljava/util/List;Ljava/util/List;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/io/File;
public final fun component2 ()Ljava/util/List;
public final fun component3 ()Ljava/util/List;
public final fun component4 ()Ljava/lang/String;
public final fun component5 ()Ljava/lang/Boolean;
public final fun copy (Ljava/io/File;Ljava/util/List;Ljava/util/List;Ljava/lang/String;Ljava/lang/Boolean;)Lorg/jetbrains/dokka/versioning/VersioningConfiguration;
public static synthetic fun copy$default (Lorg/jetbrains/dokka/versioning/VersioningConfiguration;Ljava/io/File;Ljava/util/List;Ljava/util/List;Ljava/lang/String;Ljava/lang/Boolean;ILjava/lang/Object;)Lorg/jetbrains/dokka/versioning/VersioningConfiguration;
public final fun component6 ()Ljava/lang/String;
public final fun copy (Ljava/io/File;Ljava/util/List;Ljava/util/List;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;)Lorg/jetbrains/dokka/versioning/VersioningConfiguration;
public static synthetic fun copy$default (Lorg/jetbrains/dokka/versioning/VersioningConfiguration;Ljava/io/File;Ljava/util/List;Ljava/util/List;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;ILjava/lang/Object;)Lorg/jetbrains/dokka/versioning/VersioningConfiguration;
public fun equals (Ljava/lang/Object;)Z
public final fun getOlderVersions ()Ljava/util/List;
public final fun getOlderVersionsDir ()Ljava/io/File;
public final fun getOlderVersionsDirName ()Ljava/lang/String;
public final fun getRenderVersionsNavigationOnAllPages ()Ljava/lang/Boolean;
public final fun getVersion ()Ljava/lang/String;
public final fun getVersionsOrdering ()Ljava/util/List;
public fun hashCode ()I
public final fun setOlderVersions (Ljava/util/List;)V
public final fun setOlderVersionsDir (Ljava/io/File;)V
public final fun setOlderVersionsDirName (Ljava/lang/String;)V
public final fun setRenderVersionsNavigationOnAllPages (Ljava/lang/Boolean;)V
public final fun setVersion (Ljava/lang/String;)V
public final fun setVersionsOrdering (Ljava/util/List;)V
Expand All @@ -113,6 116,7 @@ public final class org/jetbrains/dokka/versioning/VersioningConfiguration : org/
public final class org/jetbrains/dokka/versioning/VersioningConfiguration$Companion {
public final fun getDefaultOlderVersions ()Ljava/util/List;
public final fun getDefaultOlderVersionsDir ()Ljava/io/File;
public final fun getDefaultOlderVersionsDirName ()Ljava/lang/String;
public final fun getDefaultRenderVersionsNavigationOnAllPages ()Z
public final fun getDefaultVersion ()Ljava/lang/String;
public final fun getDefaultVersionsOrdering ()Ljava/util/List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 8,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.query
import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.dokka.plugability.*
import org.jetbrains.dokka.renderers.PostAction
import org.jetbrains.dokka.templates.TemplateProcessingStrategy
import org.jetbrains.dokka.templates.TemplatingPlugin
Expand All @@ -24,18 21,26 @@ public class DefaultPreviousDocumentationCopyPostAction(
private val processingStrategies: List<TemplateProcessingStrategy> =
context.plugin<TemplatingPlugin>().query { templateProcessingStrategy }

private val configuration = configuration<VersioningPlugin, VersioningConfiguration>(context)

override fun invoke() {
versioningStorage.createVersionFile()
versioningStorage.previousVersions.forEach { (_, dirs) -> copyVersion(dirs.src, dirs.dst) }
}

private fun copyVersion(versionRoot: File, targetParent: File) {
targetParent.apply { mkdirs() }
val ignoreDir = versionRoot.resolve(VersioningConfiguration.OLDER_VERSIONS_DIR)
val olderVersionsDirName =
configuration?.olderVersionsDirName ?: VersioningConfiguration.defaultOlderVersionsDirName
val ignoredDirs = when {
olderVersionsDirName.isBlank() -> versioningStorage.previousVersions.keys
else -> setOf(olderVersionsDirName)
}.map { versionRoot.resolve(it).absolutePath }

runBlocking(Dispatchers.Default) {
coroutineScope {
versionRoot.listFiles().orEmpty()
.filter { it.absolutePath != ignoreDir.absolutePath }
.filter { it.absolutePath !in ignoredDirs }
.forEach { versionRootContent ->
launch {
processRecursively(versionRootContent, targetParent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 13,8 @@ public data class VersioningConfiguration(
var olderVersions: List<File>? = defaultOlderVersions,
var versionsOrdering: List<String>? = defaultVersionsOrdering,
var version: String? = defaultVersion,
var renderVersionsNavigationOnAllPages: Boolean? = defaultRenderVersionsNavigationOnAllPages
var renderVersionsNavigationOnAllPages: Boolean? = defaultRenderVersionsNavigationOnAllPages,
var olderVersionsDirName: String = defaultOlderVersionsDirName
) : ConfigurableBlock {
internal fun versionFromConfigurationOrModule(dokkaContext: DokkaContext): String =
version ?: dokkaContext.configuration.moduleVersion ?: "1.0"
Expand All @@ -31,7 32,9 @@ public data class VersioningConfiguration(
public val defaultVersionsOrdering: List<String>? = null
public val defaultVersion: String? = null
public val defaultRenderVersionsNavigationOnAllPages: Boolean = true
public val defaultOlderVersionsDirName: String = "older"

@Deprecated("Replaced with VersioningConfiguration.Companion.defaultOlderVersionsDirName and VersioningConfiguration.olderVersionsDirName")
public const val OLDER_VERSIONS_DIR: String = "older"
public const val VERSIONS_FILE: String = "version.json"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 52,13 @@ public class DefaultVersioningStorage(

private fun getPreviousVersions(olderVersions: List<File>, output: File): Map<String, VersionDirs> =
versionsFrom(olderVersions).associate { (key, srcDir) ->
key to VersionDirs(srcDir, output.resolve(VersioningConfiguration.OLDER_VERSIONS_DIR).resolve(key))
val olderVersionsDirName =
configuration?.olderVersionsDirName ?: VersioningConfiguration.defaultOlderVersionsDirName
val olderVersionsDir = when {
olderVersionsDirName.isBlank() -> output
else -> output.resolve(olderVersionsDirName)
}
key to VersionDirs(srcDir, olderVersionsDir.resolve(key))
}

private fun versionsFrom(olderVersions: List<File>) =
Expand Down

0 comments on commit 1254b58

Please sign in to comment.