Hey guys, I’m trying to set up Dokka in a mono-rep...
# dokka
o
Hey guys, I’m trying to set up Dokka in a mono-repo that contains multiple Kotlin (v1.3.72) libraries and uses Gradle (v6.4.1). I have a top-level 
build.gradle.kts
 script in which I apply the Dokka plugin to all libraries -
Copy code
configure(subprojects.filter { it.parent?.name == "libs" }) {
    apply {
        plugin("org.jetbrains.dokka")
    }
}
I’ve also added the following block that is mentioned in the docs for multi module support -
Copy code
tasks.dokkaHtmlMultiModule.configure {
    outputDirectory.set(buildDir.resolve("dokkaCustomMultiModuleOutput"))
    documentationFileName.set("README.md")
}
I also have a 
README.md
 file under each of my libraries under 
libs
 folder, and I added the following to the 
build.gradle.kts
 script of each of the libraries which I want to include in the generated docs -
Copy code
tasks.withType<org.jetbrains.dokka.gradle.DokkaTask>().configureEach {
    dokkaSourceSets.configureEach {
        includes.from("README.md")
    }
}
After running 
dokkaHtmlMultiModule
, it seems like I get a folder for each library under 
build/dokkaCustomMultiModuleOutput/libs
 (with all generated docs inside), but I can’t seem to find any top-level 
index.html
 file. In addition, none of the libraries are listed in the top level 
-modules.html
 file. Am I missing something, or doing something wrong? Thanks in advance 🙏
j
I also have trouble understanding where I should apply the dokka plugin for multi-module projects. Should I apply it to every subproject AND the root project? It was my understanding that the dokka plugin made use of the kotlin plugin, but I don’t use the Kotlin plugin on the root project (only on subprojects). Is this the right approach?
s
@Kamil Doległo @Paweł Marks
k
👋 After applying dokka plugin in the toplevel module and running it with
./gradlew :dokkaHtmlMultiModule
, you should see the
dokkaCustomMultiModuleOutput
directory under the toplevel
build
with all documentations collected there. There is no toplevel
index.html
but
-modules.html
instead (note to self: we should probably rename that at some point) and all your submodules should be listed. Can you provide some MRE for the issue?
I also have trouble understanding where I should apply the dokka plugin for multi-module projects. Should I apply it to every subproject AND the root project?
Yes, exactly. Dokka generates documentation in each subproject separately (hence is must be present in each) and can optionally collect all generated documentations (you have to apply dokka in the root project for that)
👍 1
It was my understanding that the dokka plugin made use of the kotlin plugin, but I don’t use the Kotlin plugin on the root project (only on subprojects).
That’s true, but for collecting the subdocumentation from children the
kotlin-plugin
in the root project shouldn’t be necessary IIRC (not applied at least)
👍 1
o
Key @Kamil Doległo, thanks for your response. I do get the
dokkaCustomMultiModuleOutput
and the
-modules.html
file inside, it just doesn’t seem to contain any of my modules to which I’ve configured the
DokkaTask
Anyway I’ll setup a similar, empty project that you could use to reproduce the issue. Thanks!
k
That would be great! ☺️ Strange, it should automatically pick up all dokkaHtml tasks in subprojects
As a workaround you can probably add those subtasks manually, using
addChildTask()
however I’d be very interested why it’s not working properly
o
if I run
./gradlew dokkaHtmlMultiModule --dry-run
it seems like the
dokkaHtml
tasks of my subproject are already added -
Copy code
:libs:core:compileKotlin SKIPPED
:libs:core:compileJava SKIPPED
:libs:core:dokkaHtml SKIPPED
:libs:core-test:dokkaHtml SKIPPED
:dokkaHtmlMultiModule SKIPPED
and I even have a
libs/core
&
/libs/core-test
under
dokkaCustomMultiModuleOutput
they’re just not listed in the
-modules.html
file for some reason.
k
Very strange. Could you please delete the
dokkaCustomMultiModuleOutput
directory entirely and the run the toplevel task explicitly? (I mean with colon:
./gradlew :dokkaHtmlMultiModule
)
o
Same result. Perhaps there are any info logs I can look for written by the collector of the subprojects’ html files? If not, I’ll just create a thin project in which I can reproduce it the issue later today. And anyway thanks a lot for your support!
k
Nothing that would help us I think. Thanks! ☺️
Oh, one more thing - what happens if you remove
documentationFileName.set("README.md")
? I have a feeling that it may just overwrite the
-modules.html
file. Didn’t think of that before as we changed this in newer versions
o
This itself didn’t change the output. Should I remove the corresponding
includes.from("README.md")
of each subproject as well?
k
That’s a bummer. No, those child READMEs were required for creating a short module summary in the
-modules
page
👍 1
o
Obviously I weren’t able to reproduce the issue in a thin project I created :3 But I’m basically trying to set up project in an existing monorepo so it’s kinda hard for me to tell where the issue is exactly. Could you please point me to the html collector code? guess I’ll try to clone it and debug it on my machine 🤷‍♂️
k
Sure. Basically everything happens in the
DokkaMultiModuleTask
(
runners/gradle-plugin
). I think the configuration there should be correct (as you do get subtasks to run and then their documentation collected). The next point to check would be the
MultimodulePageCreator
(
plugins/base
) modules present there and the content node tree generated If everything is ok in those places then I just have no idea what’s going wrong
o
Cool, thanks. As you said the subproject tasks do run and I can also see their outputs, so I’ll take a look at the
MultimodulePageCreator
first. Thanks a lot again!
k
No problem. You could also try to see if one of our nightly builds fixed your issue by accident, if you wanted to:
maven("<https://maven.pkg.jetbrains.space/kotlin/p/dokka/dev>")
and the latest version would be
1.4.10-dev-69
j
@Kamil Doległo thanks for your input! I got this module doc to work when applying the dokka plugin on the root project 🙂 However, I still face the strange ZipException issue I had before for the JS platform: https://github.com/Kotlin/dokka/issues/537 Here is my build with the exception: https://travis-ci.org/github/joffrey-bion/krossbow/builds/725700239#L507
k
Great to hear that ☺️ I’ll take a look at this, but we might need some help from the IntelliJ team
j
Thanks a lot! Why is this related to intelliJ, though? I get the problem via Gradle CLI. It looks like Dokka uses some Kotlin compiler internals to access dependency files (usually jars), but in the context of Kotlin/JS it also tries to open npm dependencies as Zip files. EDIT: my bad, I just noticed it uses some sort of VFS API under IntelliJ’s namespace
Interestingly, I literally just came across the release notes of 1.4.10 and one of the issues that were fixed is: https://youtrack.jetbrains.com/issue/KT-41313 Not sure if the root cause is the same as mine (I’m not using graalVM anywhere), but the symptom is definitely similar.
o
@Kamil Doległo So apparently the issue I had was related to the fact that my README files did not contain any text besides a title. Since I was working in a monorepo I only had a top level README with everything needed inside, so when the Dokka plugin required to add similar files to each module I created files that contained only a title in order to make it work. This would cause the
firstParagraph()
method to return
null
and that’s why I had no modules listed in my
-modules.html
file -
Thanks a lot for your help anyway 🙂 What I would also like to know - is if there’s some way to navigate back from a module page to the “All modules” page, cause apparently when I open the
-modules.html
and then browse into a specific module, I can only go back by hitting “back” on the browser or by editing the url myself
k
@Or Cohen thanks for debugging that! I should fix this bug soon. As for the navigating back to the modules page - it has been fixed in some recent dev build IIRC
@Joffrey We use parts from IntelliJ combined with Kotlin compiler for analysing Kotlin source code. I assume it’s not a bug in the compiler part as the compilation succeeds, it’s not a bug in dokka itself so that leaves the IntelliJ (or maybe we just configure those IntelliJ parts wrongly) In the next week I’ll try to check if the 1.4.10 release fixes it then
j
@Kamil Doległo I get it, thanks a lot for looking into it! In the mean time, what would be the correct way to disable dokka just for the JS platform in a multiplatform build? I used to specify all source sets but the
js
one, but now it’s so nice I don’t even need to configure anything, so I’m wondering what’s the minimal config to disable the JS platform.
k
I believe that
suppress.set(true)
in the dokka source set definition for JS should be enough ☺️
👍 1
j
Thanks, will try that! 🙂
o
Thanks for the update @Kamil Doległo 🙂
j
@Kamil Doległo your suggestion worked. For other people without context, I put the following in the root project’s
build.gradle
at the end of the
allProjects
block:
Copy code
afterEvaluate {
    tasks.withType<DokkaTask>().configureEach {
        dokkaSourceSets.findByName("jsMain")
                      ?.suppress?.set(true)
        dokkaSourceSets.findByName("jsTest")
                      ?.suppress?.set(true)
    }
}
k
@Joffrey Sidenote: I think you don’t have to use the
afterEvaluate
here (I may be wrong though). Properties should correctly retain the state set in the configuration phase
j
@Kamil Doległo to be honest I’m not sure to remember correctly, I might not need it anymore, but I would have to check again. I believe it has something to do with the order of the configuration of the projects. Because this is in the root project in the
allprojects
block, the rest of the configuration of the source sets etc might not be done at that point in every subproject, I think that’s why I had to do this, to ensure it’s done after the configuration of the subprojects.
Properties should correctly retain the state set in the configuration phase
yes, but if the source set
jsMain
doesn’t exist yet in the dokka task at that point,
findByName("jsMain")?.suppress?.set(true)
has no effect