From 16e7f1410fc6145873f3b06ca992045941b1c495 Mon Sep 17 00:00:00 2001 From: aSemy <897017+aSemy@users.noreply.github.com> Date: Fri, 17 Feb 2023 17:03:15 +0100 Subject: [PATCH] refactor examples and integration tests (#7) * refactor examples and integration tests - example and integration test projects are automatically copied from Dokka src - integration tests will use the example and integration tests projects * prep dokkatoo example projects * updating integration tests and test projects * git ignore gradle.properties in dokkatoo examples * add code for includeBuild-ing the example projects * setup dokkatoo gradle-example * a bit of integration-test refactoring * add remoteUrl util function * rm setting null into dokkatooCacheDirectory (it's not necessary) * update a couple of build script comments * implement GradleExampleTest * update .gitignore to be more comprehensive * add options for increasing DokkaGenerator memory, and also increase the memory * increase Gradle memory * fix BasicProjectIntegrationTest * try fixing task updateGradlePropertiesInDokkatooExamples * move the integration tests into separate sourceSets * the integration tests keep running out of memory, so fork on every test * try fixing testMavenRepo on Windows * try fixing testMavenRepo on Windows * try fixing testMavenRepo on Windows * try fixing testMavenRepo on Windows * try increases MaxMetaspace https://github.com/Kotlin/dokka/issues/1405 * try fixing updateTestReportCss task output warnings * more memory increasing --- .gitattributes | 5 +- .gitignore | 68 +++- buildSrc/settings.gradle.kts | 2 +- .../buildsrc/conventions/base.gradle.kts | 18 +- .../dokka-source-downloader.gradle.kts | 54 +++ .../dokkatoo-example-projects-base.gradle.kts | 29 ++ .../dokkatoo-example-projects.gradle.kts | 70 ++++ .../conventions/maven-publish-test.gradle.kts | 64 ++- .../buildsrc/tasks/SetupDokkaProjects.kt | 54 +++ examples/.gitignore | 5 + examples/README.md | 18 + examples/build.gradle.kts | 52 +++ .../custom-format-example/dokka/README.md | 24 ++ .../dokka/build.gradle.kts | 34 ++ .../custom-format-example/dokka/ktor-logo.png | Bin 0 -> 179624 bytes .../dokka/logo-styles.css | 20 + .../dokka/settings.gradle.kts | 1 + .../dokka/src/main/kotlin/demo/HelloWorld.kt | 20 + .../dokkatoo/settings.gradle.kts | 17 + examples/gradle-example/dokka/Module.md | 7 + .../gradle-example/dokka/build.gradle.kts | 32 ++ .../gradle-example/dokka/settings.gradle.kts | 1 + .../dokka/src/main/kotlin/demo/HelloWorld.kt | 20 + examples/gradle-example/dokkatoo/Module.md | 7 + .../gradle-example/dokkatoo/build.gradle.kts | 23 ++ .../dokkatoo/settings.gradle.kts | 17 + .../src/main/kotlin/demo/HelloWorld.kt | 20 + .../dokka/build.gradle.kts | 22 ++ .../dokka/settings.gradle.kts | 1 + .../dokka/src/main/kotlin/demo/HelloWorld.kt | 20 + .../dokkatoo/settings.gradle.kts | 17 + .../dokka/build.gradle.kts | 44 +++ .../dokka/settings.gradle.kts | 1 + .../dokka/src/main/kotlin/demo/HelloWorld.kt | 20 + .../dokkatoo/settings.gradle.kts | 17 + .../dokka/build.gradle.kts | 5 + .../dokka/parentProject/build.gradle.kts | 20 + .../parentProject/childProjectA/Module.md | 5 + .../childProjectA/build.gradle.kts | 18 + .../main/kotlin/demo/ChildProjectAClass.kt | 8 + .../parentProject/childProjectB/Module.md | 5 + .../childProjectB/build.gradle.kts | 18 + .../main/kotlin/demo/ChildProjectBClass.kt | 8 + .../dokka/settings.gradle.kts | 12 + .../dokkatoo/parentProject/build.gradle.kts | 11 + .../parentProject/childProjectA/Module.md | 5 + .../childProjectA/build.gradle.kts | 17 + .../main/kotlin/demo/ChildProjectAClass.kt | 8 + .../parentProject/childProjectB/Module.md | 5 + .../childProjectB/build.gradle.kts | 17 + .../main/kotlin/demo/ChildProjectBClass.kt | 8 + .../dokkatoo/settings.gradle.kts | 24 ++ .../dokka/build.gradle.kts | 44 +++ .../dokka/gradle.properties | 1 + .../dokka/settings.gradle.kts | 2 + .../kotlin/org.kotlintestmpp.common/main.kt | 4 + .../kotlin/org/kotlintestmpp/coroutines.kt | 6 + .../org/kotlintestmpp/getCurrentDate.kt | 8 + .../kotlin/demo/CustomSourceSetFile.kt | 11 + .../org/kotlintestmpp/asyncWithDealy.kt | 8 + .../jsMain/kotlin/org/kotlintestmpp/main.kt | 17 + .../jsMain/kotlin/shouldbesuppressed/supp.kt | 11 + .../kotlin/org/kotlintestmpp/MainCommand.java | 16 + .../org/kotlintestmpp/asyncWithDealy.kt | 8 + .../jvmMain/kotlin/org/kotlintestmpp/main.kt | 30 ++ .../jvmMain/kotlin/shouldbesuppressed/supp.kt | 11 + .../org/kotlintestmpp/asyncWithDealy.kt | 8 + .../kotlin/org/kotlintestmpp/cinterop.kt | 10 + .../org/kotlintestmpp/getCurrentDate.kt | 8 + .../org/kotlintestmpp/asyncWithDealy.kt | 8 + .../org/kotlintestmpp/getCurrentDate.kt | 8 + .../dokkatoo/settings.gradle.kts | 17 + .../dokka/build.gradle.kts | 19 + .../dokka/parentProject/build.gradle.kts | 25 ++ .../childProjectA/build.gradle.kts | 3 + .../main/kotlin/demo/ChildProjectAClass.kt | 8 + .../childProjectB/build.gradle.kts | 3 + .../main/kotlin/demo/ChildProjectBClass.kt | 8 + .../dokka/settings.gradle.kts | 5 + .../dokkatoo/settings.gradle.kts | 17 + externals/.gitignore | 1 - externals/build.gradle.kts | 44 --- gradle.properties | 3 +- .../build.gradle.kts | 212 ++++++++++ .../projects/.gitignore | 5 + .../it-android-0/dokka/build.gradle.kts | 20 + .../it-android-0/dokka/gradle.properties | 3 + .../it-android-0/dokka/settings.gradle.kts | 5 + .../dokka/src/main/AndroidManifest.xml | 1 + .../java/it/android/AndroidSpecificClass.kt | 16 + .../it/android/IntegrationTestActivity.kt | 22 ++ .../dokka/template.root.gradle.kts | 23 ++ .../dokka/template.settings.gradle.kts | 38 ++ .../it-android-0/dokkatoo/settings.gradle.kts | 17 + .../it-basic-groovy/dokka/build.gradle | 54 +++ .../it-basic-groovy/dokka/gradle.properties | 1 + .../it-basic-groovy/dokka/settings.gradle.kts | 5 + .../java/it/basic/java/SampleJavaClass.java | 17 + .../src/main/kotlin/it/basic/PublicClass.kt | 48 +++ .../dokka/template.root.gradle.kts | 23 ++ .../dokka/template.settings.gradle.kts | 38 ++ .../it-basic-groovy/dokkatoo/settings.gradle | 16 + .../projects/it-basic/dokka/build.gradle.kts | 64 +++ .../dokka/customResources/custom-resource.svg | 3 + .../customResources/custom-style-to-add.css | 1 + .../dokka/customResources/logo-styles.css | 3 + .../projects/it-basic/dokka/gradle.properties | 1 + .../it-basic/dokka/settings.gradle.kts | 5 + .../java/it/basic/java/SampleJavaClass.java | 17 + .../dokka/src/main/kotlin/RootPackageClass.kt | 8 + .../src/main/kotlin/it/basic/PublicClass.kt | 69 ++++ .../main/kotlin/it/internal/InternalClass.kt | 7 + .../VisiblePrivateClass.kt | 12 + .../kotlin/it/protected/ProtectedClass.kt | 10 + .../SuppressedByPackage.kt | 7 + .../it/suppressedByPath/SuppressedByPath.kt | 7 + .../src/test/kotlin/it/basic/TestClass.kt | 17 + .../it-basic/dokka/template.root.gradle.kts | 23 ++ .../dokka/template.settings.gradle.kts | 38 ++ .../it-basic/dokkatoo/build.gradle.kts | 69 ++++ .../customResources/custom-resource.svg | 3 + .../customResources/custom-style-to-add.css | 1 + .../dokkatoo/customResources/logo-styles.css | 3 + .../it-basic/dokkatoo/settings.gradle.kts | 17 + .../java/it/basic/java/SampleJavaClass.java | 17 + .../src/main/kotlin/RootPackageClass.kt | 8 + .../src/main/kotlin/it/basic/PublicClass.kt | 69 ++++ .../main/kotlin/it/internal/InternalClass.kt | 7 + .../VisiblePrivateClass.kt | 12 + .../kotlin/it/protected/ProtectedClass.kt | 10 + .../SuppressedByPackage.kt | 7 + .../it/suppressedByPath/SuppressedByPath.kt | 7 + .../src/test/kotlin/it/basic/TestClass.kt | 17 + .../it-collector-0/dokka/build.gradle.kts | 1 + .../it-collector-0/dokka/gradle.properties | 1 + .../dokka/moduleA/build.gradle.kts | 6 + .../dokka/moduleA/moduleB/README.md | 2 + .../dokka/moduleA/moduleB/build.gradle.kts | 8 + .../org/jetbrains/dokka/it/moduleB/ModuleB.kt | 6 + .../dokka/moduleA/moduleC/README.md | 2 + .../dokka/moduleA/moduleC/build.gradle.kts | 8 + .../org/jetbrains/dokka/it/moduleC/ModuleC.kt | 6 + .../it-collector-0/dokka/settings.gradle.kts | 5 + .../dokka/template.root.gradle.kts | 23 ++ .../dokka/template.settings.gradle.kts | 38 ++ .../dokkatoo/settings.gradle.kts | 17 + .../it-js-ir-0/dokka/build.gradle.kts | 22 ++ .../it-js-ir-0/dokka/gradle.properties | 2 + .../it-js-ir-0/dokka/settings.gradle.kts | 5 + .../dokka/src/main/kotlin/RootPackageClass.kt | 26 ++ .../src/main/kotlin/it/basic/PublicClass.kt | 53 +++ .../main/kotlin/it/internal/InternalClass.kt | 7 + .../SuppressedByPackage.kt | 7 + .../it/suppressedByPath/SuppressedByPath.kt | 7 + .../it-js-ir-0/dokka/template.root.gradle.kts | 23 ++ .../dokka/template.settings.gradle.kts | 38 ++ .../it-js-ir-0/dokkatoo/settings.gradle.kts | 17 + .../it-multimodule-0/dokka/build.gradle.kts | 1 + .../it-multimodule-0/dokka/gradle.properties | 1 + .../dokka/moduleA/build.gradle.kts | 6 + .../dokka/moduleA/moduleB/Module.md | 6 + .../dokka/moduleA/moduleB/build.gradle.kts | 17 + .../org/jetbrains/dokka/it/moduleB/ModuleB.kt | 6 + .../dokka/moduleA/moduleC/Module.md | 2 + .../dokka/moduleA/moduleC/build.gradle.kts | 16 + .../org/jetbrains/dokka/it/moduleC/ModuleC.kt | 6 + .../dokka/moduleA/moduleD/build.gradle.kts | 10 + .../org/jetbrains/dokka/it/moduleD/ModuleC.kt | 6 + .../dokka/settings.gradle.kts | 6 + .../dokka/template.root.gradle.kts | 23 ++ .../dokka/template.settings.gradle.kts | 38 ++ .../dokkatoo/settings.gradle.kts | 17 + .../it-multimodule-1/dokka/build.gradle | 18 + .../it-multimodule-1/dokka/first/build.gradle | 0 .../first/src/main/kotlin/foo/FirstClass.kt | 11 + .../src/main/kotlin/foo/FirstSubclass.kt | 12 + .../dokka/first/src/main/kotlin/foo/Main.kt | 8 + .../dokka/first/src/main/kotlin/noPackage.kt | 3 + .../it-multimodule-1/dokka/gradle.properties | 1 + .../dokka/second/build.gradle | 14 + .../second/src/main/kotlin/NoPackageClass.kt | 1 + .../second/src/main/kotlin/bar/SecondClass.kt | 21 + .../second/src/main/kotlin/foo/ThirdClass.kt | 11 + .../dokka/settings.gradle.kts | 4 + .../dokka/template.root.gradle.kts | 23 ++ .../dokka/template.settings.gradle.kts | 38 ++ .../dokkatoo/settings.gradle.kts | 17 + .../dokka/build.gradle | 43 ++ .../dokka/first/build.gradle | 0 .../first/src/main/kotlin/foo/FirstClass.kt | 11 + .../dokka/gradle.properties | 2 + .../dokka/second/build.gradle | 3 + .../second/src/main/kotlin/bar/SecondClass.kt | 21 + .../dokka/settings.gradle.kts | 4 + .../dokka/template.root.gradle.kts | 23 ++ .../dokka/template.settings.gradle.kts | 38 ++ .../dokkatoo/settings.gradle.kts | 17 + .../it-multiplatform-0/dokka/build.gradle.kts | 42 ++ .../dokka/gradle.properties | 5 + .../dokka/settings.gradle.kts | 2 + .../kotlin/it/mpp0/CommonMainClass.kt | 8 + .../kotlin/it/mpp0/ExpectedClass.kt | 5 + .../commonMain/kotlin/it/mpp0/coroutines.kt | 5 + .../kotlin/it/mpp0/CPointerExtension.kt | 11 + .../kotlin/it/mpp0/ExpectedClass.kt | 5 + .../jsMain/kotlin/it/mpp0/ExpectedClass.kt | 5 + .../src/jsMain/kotlin/it/mpp0/runBlocking.kt | 7 + .../jvmMain/kotlin/it/mpp0/ExpectedClass.kt | 11 + .../jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt | 13 + .../src/jvmMain/kotlin/it/mpp0/runBlocking.kt | 7 + .../kotlin/it/mpp0/CPointerExtension.kt | 11 + .../linuxMain/kotlin/it/mpp0/ExpectedClass.kt | 5 + .../linuxMain/kotlin/it/mpp0/runBlocking.kt | 13 + .../macosMain/kotlin/it/mpp0/ExpectedClass.kt | 5 + .../macosMain/kotlin/it/mpp0/runBlocking.kt | 7 + .../dokka/template.root.gradle.kts | 23 ++ .../dokka/template.settings.gradle.kts | 38 ++ .../dokkatoo/settings.gradle.kts | 17 + .../testExamples/kotlin/GradleExampleTest.kt | 149 +++++++ .../kotlin/MultimoduleExampleTest.kt} | 115 +----- .../kotlin/templateProjectUtils.kt | 17 + .../kotlin/BasicProjectIntegrationTest.kt | 155 ++++++++ .../dokka-multi-module/childProjectA.json | 0 .../dokka-multi-module/childProjectB.json | 0 .../dokka-multi-module/parentProject.json | 0 .../it/example/dokka-multi-module/readme.md | 0 modules/dokkatoo-plugin/build.gradle.kts | 24 +- .../src/main/kotlin/DokkatooBasePlugin.kt | 7 +- .../DokkaSourceLinkGradleBuilder.kt | 14 + .../main/kotlin/tasks/DokkatooGenerateTask.kt | 24 +- .../testFixtures/kotlin/GradleTestKitUtils.kt | 35 +- .../kotlin/BasicProjectIntegrationTest.kt | 367 ------------------ settings.gradle.kts | 49 ++- 233 files changed, 3928 insertions(+), 601 deletions(-) create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/dokka-source-downloader.gradle.kts create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects-base.gradle.kts create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects.gradle.kts create mode 100644 buildSrc/src/main/kotlin/buildsrc/tasks/SetupDokkaProjects.kt create mode 100644 examples/.gitignore create mode 100644 examples/README.md create mode 100644 examples/build.gradle.kts create mode 100644 examples/custom-format-example/dokka/README.md create mode 100644 examples/custom-format-example/dokka/build.gradle.kts create mode 100644 examples/custom-format-example/dokka/ktor-logo.png create mode 100644 examples/custom-format-example/dokka/logo-styles.css create mode 100644 examples/custom-format-example/dokka/settings.gradle.kts create mode 100644 examples/custom-format-example/dokka/src/main/kotlin/demo/HelloWorld.kt create mode 100644 examples/custom-format-example/dokkatoo/settings.gradle.kts create mode 100644 examples/gradle-example/dokka/Module.md create mode 100644 examples/gradle-example/dokka/build.gradle.kts create mode 100644 examples/gradle-example/dokka/settings.gradle.kts create mode 100644 examples/gradle-example/dokka/src/main/kotlin/demo/HelloWorld.kt create mode 100644 examples/gradle-example/dokkatoo/Module.md create mode 100644 examples/gradle-example/dokkatoo/build.gradle.kts create mode 100644 examples/gradle-example/dokkatoo/settings.gradle.kts create mode 100644 examples/gradle-example/dokkatoo/src/main/kotlin/demo/HelloWorld.kt create mode 100644 examples/kotlin-as-java-example/dokka/build.gradle.kts create mode 100644 examples/kotlin-as-java-example/dokka/settings.gradle.kts create mode 100644 examples/kotlin-as-java-example/dokka/src/main/kotlin/demo/HelloWorld.kt create mode 100644 examples/kotlin-as-java-example/dokkatoo/settings.gradle.kts create mode 100644 examples/library-publishing-example/dokka/build.gradle.kts create mode 100644 examples/library-publishing-example/dokka/settings.gradle.kts create mode 100644 examples/library-publishing-example/dokka/src/main/kotlin/demo/HelloWorld.kt create mode 100644 examples/library-publishing-example/dokkatoo/settings.gradle.kts create mode 100644 examples/multimodule-example/dokka/build.gradle.kts create mode 100644 examples/multimodule-example/dokka/parentProject/build.gradle.kts create mode 100644 examples/multimodule-example/dokka/parentProject/childProjectA/Module.md create mode 100644 examples/multimodule-example/dokka/parentProject/childProjectA/build.gradle.kts create mode 100644 examples/multimodule-example/dokka/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt create mode 100644 examples/multimodule-example/dokka/parentProject/childProjectB/Module.md create mode 100644 examples/multimodule-example/dokka/parentProject/childProjectB/build.gradle.kts create mode 100644 examples/multimodule-example/dokka/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt create mode 100644 examples/multimodule-example/dokka/settings.gradle.kts create mode 100644 examples/multimodule-example/dokkatoo/parentProject/build.gradle.kts create mode 100644 examples/multimodule-example/dokkatoo/parentProject/childProjectA/Module.md create mode 100644 examples/multimodule-example/dokkatoo/parentProject/childProjectA/build.gradle.kts create mode 100644 examples/multimodule-example/dokkatoo/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt create mode 100644 examples/multimodule-example/dokkatoo/parentProject/childProjectB/Module.md create mode 100644 examples/multimodule-example/dokkatoo/parentProject/childProjectB/build.gradle.kts create mode 100644 examples/multimodule-example/dokkatoo/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt create mode 100644 examples/multimodule-example/dokkatoo/settings.gradle.kts create mode 100644 examples/multiplatform-example/dokka/build.gradle.kts create mode 100644 examples/multiplatform-example/dokka/gradle.properties create mode 100644 examples/multiplatform-example/dokka/settings.gradle.kts create mode 100644 examples/multiplatform-example/dokka/src/commonMain/kotlin/org.kotlintestmpp.common/main.kt create mode 100644 examples/multiplatform-example/dokka/src/commonMain/kotlin/org/kotlintestmpp/coroutines.kt create mode 100644 examples/multiplatform-example/dokka/src/commonMain/kotlin/org/kotlintestmpp/getCurrentDate.kt create mode 100644 examples/multiplatform-example/dokka/src/customJdk9/kotlin/demo/CustomSourceSetFile.kt create mode 100644 examples/multiplatform-example/dokka/src/jsMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt create mode 100644 examples/multiplatform-example/dokka/src/jsMain/kotlin/org/kotlintestmpp/main.kt create mode 100644 examples/multiplatform-example/dokka/src/jsMain/kotlin/shouldbesuppressed/supp.kt create mode 100644 examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/MainCommand.java create mode 100644 examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt create mode 100644 examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/main.kt create mode 100644 examples/multiplatform-example/dokka/src/jvmMain/kotlin/shouldbesuppressed/supp.kt create mode 100644 examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt create mode 100644 examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/cinterop.kt create mode 100644 examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/getCurrentDate.kt create mode 100644 examples/multiplatform-example/dokka/src/macosMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt create mode 100644 examples/multiplatform-example/dokka/src/macosMain/kotlin/org/kotlintestmpp/getCurrentDate.kt create mode 100644 examples/multiplatform-example/dokkatoo/settings.gradle.kts create mode 100644 examples/versioning-multimodule-example/dokka/build.gradle.kts create mode 100644 examples/versioning-multimodule-example/dokka/parentProject/build.gradle.kts create mode 100644 examples/versioning-multimodule-example/dokka/parentProject/childProjectA/build.gradle.kts create mode 100644 examples/versioning-multimodule-example/dokka/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt create mode 100644 examples/versioning-multimodule-example/dokka/parentProject/childProjectB/build.gradle.kts create mode 100644 examples/versioning-multimodule-example/dokka/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt create mode 100644 examples/versioning-multimodule-example/dokka/settings.gradle.kts create mode 100644 examples/versioning-multimodule-example/dokkatoo/settings.gradle.kts delete mode 100644 externals/.gitignore delete mode 100644 externals/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/.gitignore create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/gradle.properties create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/AndroidManifest.xml create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/java/it/android/AndroidSpecificClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/java/it/android/IntegrationTestActivity.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/template.root.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/template.settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokkatoo/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/build.gradle create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/gradle.properties create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/src/main/java/it/basic/java/SampleJavaClass.java create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/src/main/kotlin/it/basic/PublicClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/template.root.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/template.settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokkatoo/settings.gradle create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/custom-resource.svg create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/custom-style-to-add.css create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/logo-styles.css create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/gradle.properties create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/java/it/basic/java/SampleJavaClass.java create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/RootPackageClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/basic/PublicClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/internal/InternalClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/overriddenVisibility/VisiblePrivateClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/protected/ProtectedClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/test/kotlin/it/basic/TestClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/template.root.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/template.settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/custom-resource.svg create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/custom-style-to-add.css create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/logo-styles.css create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/java/it/basic/java/SampleJavaClass.java create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/RootPackageClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/basic/PublicClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/internal/InternalClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/overriddenVisibility/VisiblePrivateClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/protected/ProtectedClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/test/kotlin/it/basic/TestClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/gradle.properties create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/README.md create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/src/main/kotlin/org/jetbrains/dokka/it/moduleB/ModuleB.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/README.md create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/src/main/kotlin/org/jetbrains/dokka/it/moduleC/ModuleC.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/template.root.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/template.settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokkatoo/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/gradle.properties create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/RootPackageClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/basic/PublicClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/internal/InternalClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/template.root.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/template.settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokkatoo/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/gradle.properties create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/Module.md create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/src/main/kotlin/org/jetbrains/dokka/it/moduleB/ModuleB.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/Module.md create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/src/main/kotlin/org/jetbrains/dokka/it/moduleC/ModuleC.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleD/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleD/src/main/kotlin/org/jetbrains/dokka/it/moduleD/ModuleC.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/template.root.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/template.settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokkatoo/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/build.gradle create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/build.gradle create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/FirstClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/FirstSubclass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/Main.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/noPackage.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/gradle.properties create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/build.gradle create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/NoPackageClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/bar/SecondClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/foo/ThirdClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/template.root.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/template.settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokkatoo/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/build.gradle create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/first/build.gradle create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/first/src/main/kotlin/foo/FirstClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/gradle.properties create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/second/build.gradle create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/second/src/main/kotlin/bar/SecondClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/template.root.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/template.settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokkatoo/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/build.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/gradle.properties create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/CommonMainClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/ExpectedClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/coroutines.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/desktopMain/kotlin/it/mpp0/CPointerExtension.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/desktopMain/kotlin/it/mpp0/ExpectedClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jsMain/kotlin/it/mpp0/ExpectedClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jsMain/kotlin/it/mpp0/runBlocking.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/ExpectedClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/runBlocking.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/CPointerExtension.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/ExpectedClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/runBlocking.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/macosMain/kotlin/it/mpp0/ExpectedClass.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/macosMain/kotlin/it/mpp0/runBlocking.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/template.root.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/template.settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokkatoo/settings.gradle.kts create mode 100644 modules/dokkatoo-plugin-integration-tests/src/testExamples/kotlin/GradleExampleTest.kt rename modules/{dokkatoo-plugin/src/testIntegration/kotlin/examples/DokkaMultimoduleExampleTest.kt => dokkatoo-plugin-integration-tests/src/testExamples/kotlin/MultimoduleExampleTest.kt} (64%) create mode 100644 modules/dokkatoo-plugin-integration-tests/src/testFixtures/kotlin/templateProjectUtils.kt create mode 100644 modules/dokkatoo-plugin-integration-tests/src/testIntegration/kotlin/BasicProjectIntegrationTest.kt rename modules/{dokkatoo-plugin => dokkatoo-plugin-integration-tests}/src/testIntegration/resources/it/example/dokka-multi-module/childProjectA.json (100%) rename modules/{dokkatoo-plugin => dokkatoo-plugin-integration-tests}/src/testIntegration/resources/it/example/dokka-multi-module/childProjectB.json (100%) rename modules/{dokkatoo-plugin => dokkatoo-plugin-integration-tests}/src/testIntegration/resources/it/example/dokka-multi-module/parentProject.json (100%) rename modules/{dokkatoo-plugin => dokkatoo-plugin-integration-tests}/src/testIntegration/resources/it/example/dokka-multi-module/readme.md (100%) delete mode 100644 modules/dokkatoo-plugin/src/testIntegration/kotlin/BasicProjectIntegrationTest.kt diff --git a/.gitattributes b/.gitattributes index 5de51604..29e261ec 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,4 +9,7 @@ # Exclude external libs from GitHub language stats https://github.com/github/linguist/blob/v7.24.1/docs/overrides.md -externals/*/** linguist-vendored +examples/** linguist-documentation +examples/*/dokka linguist-vendored +modules/dokkatoo-plugin-integration-tests/projects/**dokka/ linguist-vendored +modules/dokkatoo-plugin-integration-tests/projects/**dokkatoo/ linguist-documentation diff --git a/.gitignore b/.gitignore index 1f93dfcf..75e0257a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,69 @@ -# Ignore Gradle project-specific cache directory +### Gradle ### .gradle +build/ -# Ignore Gradle build output directory -build +!gradle/wrapper/gradle-wrapper.jar +!gradle/wrapper/gradle-wrapper.properties + +### Kotlin/JVM ### +*.class +*.log + +hs_err_pid* +replay_pid* +*.hprof + +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + + +### IntelliJ ### .idea + + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +.settings/ +.loadpath +.recommenders +.classpath + +.apt_generated/ +.apt_generated_test/ +.project + + +### Linux ### +*~ +.fuse_hidden* +.Trash-* +.nfs* + + +### Windows ### +[Dd]esktop.ini +$RECYCLE.BIN/ +*.lnk + + +### macOS ### +.DS_Store +._* + +# Icon must end with two \r +Icon + + +########################### diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index 01564ffa..d17e78f3 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -7,7 +7,7 @@ pluginManagement { } } -@Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature +@Suppress("UnstableApiUsage") dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts index a9b6ff83..23c37955 100644 --- a/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts +++ b/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts @@ -1,7 +1,5 @@ package buildsrc.conventions -import buildsrc.conventions.utils.asConsumer -import buildsrc.conventions.utils.asProvider import java.time.Duration import org.gradle.api.tasks.testing.logging.TestLogEvent @@ -45,20 +43,6 @@ tasks.withType().configureEach { includeEmptyDirs = false } -val kotlinDokkaSource by configurations.registering { - asConsumer() - attributes { - attribute(Usage.USAGE_ATTRIBUTE, objects.named("externals-dokka-src")) - } -} - -val kotlinDokkaSourceElements by configurations.registering { - asProvider() - attributes { - attribute(Usage.USAGE_ATTRIBUTE, objects.named("externals-dokka-src")) - } -} - val updateTestReportCss by tasks.registering { description = "Hack so the Gradle test reports have dark mode" // the CSS is based on https://github.com/gradle/gradle/pull/12177 @@ -71,7 +55,7 @@ val updateTestReportCss by tasks.registering { include("reports/**/css/style.css") } - outputs.files(cssFiles) + outputs.files(cssFiles.files) doLast { cssFiles.forEach { cssFile -> diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/dokka-source-downloader.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/dokka-source-downloader.gradle.kts new file mode 100644 index 00000000..2bd923a5 --- /dev/null +++ b/buildSrc/src/main/kotlin/buildsrc/conventions/dokka-source-downloader.gradle.kts @@ -0,0 +1,54 @@ +package buildsrc.conventions + +import buildsrc.conventions.utils.asConsumer +import buildsrc.conventions.utils.asProvider +import buildsrc.conventions.utils.dropDirectories + +plugins { + id("buildsrc.conventions.base") +} + +val kotlinDokkaSource by configurations.creating { + asConsumer() + attributes { + attribute(Usage.USAGE_ATTRIBUTE, objects.named("externals-dokka-src")) + } +} + +val kotlinDokkaSourceElements by configurations.registering { + asProvider() + attributes { + attribute(Usage.USAGE_ATTRIBUTE, objects.named("externals-dokka-src")) + } +} + +dependencies { + kotlinDokkaSource("kotlin:dokka:1.7.20@zip") +} + +val prepareDokkaSource by tasks.registering(Sync::class) { + group = "dokka setup" + description = "Download & unpack Kotlin Dokka source code" + from( + kotlinDokkaSource.incoming + .artifactView { lenient(true) } + .artifacts + .resolvedArtifacts.map { artifacts -> + artifacts.map { zipTree(it.file) } + } + ) { + // drop the first dir (dokka-$version) + eachFile { + relativePath = relativePath.dropDirectories(1) + } + } + into(temporaryDir) + exclude( + "*.github", + "*.gradle", + "**/gradlew", + "**/gradlew.bat", + "**/gradle/wrapper/gradle-wrapper.jar", + "**/gradle/wrapper/gradle-wrapper.properties", + ) +} diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects-base.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects-base.gradle.kts new file mode 100644 index 00000000..1d5b9e02 --- /dev/null +++ b/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects-base.gradle.kts @@ -0,0 +1,29 @@ +package buildsrc.conventions + +import buildsrc.conventions.Maven_publish_test_gradle.MavenPublishTest +import buildsrc.conventions.utils.asConsumer +import buildsrc.conventions.utils.asProvider +import buildsrc.tasks.SetupDokkaProjects + +plugins { + id("buildsrc.conventions.base") +} + + +val exampleProjectsAttribute = Attribute.of("example-projects", String::class.java) +dependencies.attributesSchema { + attribute(exampleProjectsAttribute) +} + + +val exampleProjects by configurations.registering { + asConsumer() + isVisible = false + attributes { attribute(exampleProjectsAttribute, "dokka") } +} + +val exampleProjectsElements by configurations.registering { + asProvider() + isVisible = true + attributes { attribute(exampleProjectsAttribute, "dokka") } +} diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects.gradle.kts new file mode 100644 index 00000000..d7f6ed99 --- /dev/null +++ b/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects.gradle.kts @@ -0,0 +1,70 @@ +package buildsrc.conventions + +import buildsrc.conventions.Maven_publish_test_gradle.MavenPublishTest +import buildsrc.tasks.SetupDokkaProjects + +plugins { + id("buildsrc.conventions.base") + id("buildsrc.conventions.dokka-source-downloader") + id("buildsrc.conventions.maven-publish-test") + id("buildsrc.conventions.dokkatoo-example-projects-base") +} + + +val prepareDokkaSourceTask = tasks.named("prepareDokkaSource") + +val setupDokkaTemplateProjects by tasks.registering(SetupDokkaProjects::class) { + dependsOn(prepareDokkaSourceTask) + destinationToSources.convention(emptyMap()) + dokkaSourceDir.set( + layout.dir( + prepareDokkaSourceTask.map { it.destinationDir } + ) + ) +} + +val mavenPublishTestExtension = extensions.getByType() + +val updateGradlePropertiesInDokkatooExamples by tasks.registering { + group = "dokkatoo examples" + + mustRunAfter(tasks.withType()) + + val gradlePropertiesFiles = + layout.projectDirectory.asFileTree + .matching { + include( + "**/*dokkatoo*/settings.gradle.kts", + "**/*dokkatoo*/settings.gradle", + ) + }.elements.map { settingsFiles -> + settingsFiles.map { + it.asFile.resolveSibling("gradle.properties") + } + } + + outputs.files(gradlePropertiesFiles) + + val testMavenRepoPath = mavenPublishTestExtension.testMavenRepo.map { + it.asFile.invariantSeparatorsPath + } + inputs.property("testMavenRepoPath", testMavenRepoPath) + + doLast task@{ + gradlePropertiesFiles.get().forEach { + it.writeText( + """ + |# DO NOT EDIT - Generated by ${this@task.path} + | + |testMavenRepo=${testMavenRepoPath.get()} + | + """.trimMargin() + ) + } + } +} + +tasks.assemble { + dependsOn(setupDokkaTemplateProjects) + dependsOn(updateGradlePropertiesInDokkatooExamples) +} diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publish-test.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publish-test.gradle.kts index 885224e8..1f54c9ea 100644 --- a/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publish-test.gradle.kts +++ b/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publish-test.gradle.kts @@ -1,5 +1,8 @@ package buildsrc.conventions +import buildsrc.conventions.utils.asConsumer +import buildsrc.conventions.utils.asProvider + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -9,26 +12,28 @@ Utility for publishing a project to a local Maven directory for use in integrati * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -abstract class MavenPublishTest { - abstract val testMavenRepo: DirectoryProperty - internal abstract val testMavenRepoTemp: DirectoryProperty +abstract class MavenPublishTest( + val testMavenRepo: Provider +) { + companion object { + val attribute = Attribute.of("maven-publish-test", String::class.java) + } } -val mavenPublishTest = extensions.create("mavenPublishTest").apply { - testMavenRepo.convention(layout.buildDirectory.dir("test-maven-repo")) - testMavenRepoTemp.convention(layout.buildDirectory.dir("tmp/test-maven-repo")) -} +val Gradle.rootGradle: Gradle get() = generateSequence(gradle) { it.parent }.last() + +val mavenPublishTestExtension = extensions.create( + "mavenPublishTest", + gradle.rootGradle.rootProject.layout.buildDirectory.dir("test-maven-repo"), +) -val publishToTestMavenRepo by tasks.registering(Sync::class) { +val publishToTestMavenRepo by tasks.registering { group = PublishingPlugin.PUBLISH_TASK_GROUP description = "Publishes all Maven publications to the test Maven repository." - from(mavenPublishTest.testMavenRepoTemp) - into(mavenPublishTest.testMavenRepo) } - plugins.withType().all { extensions .getByType() @@ -46,15 +51,15 @@ plugins.withType().all { group = PublishingPlugin.PUBLISH_TASK_GROUP outputs.cacheIf { true } publication = this@publication - val destinationDir = mavenPublishTest.testMavenRepoTemp.asFile - inputs.property("testMavenRepoTempDir", destinationDir.map { it.invariantSeparatorsPath }) + val destinationDir = mavenPublishTestExtension.testMavenRepo.get().asFile + inputs.property("testMavenRepoTempDir", destinationDir.invariantSeparatorsPath) doFirst { /** - * `maven.repo.local` will set the destination directry + * `maven.repo.local` will set the destination directory for this [PublishToMavenLocal] task. * * @see org.gradle.api.internal.artifacts.mvnsettings.DefaultLocalMavenRepositoryLocator.getLocalMavenRepository */ - System.setProperty("maven.repo.local", destinationDir.get().absolutePath) + System.setProperty("maven.repo.local", destinationDir.absolutePath) } } @@ -63,3 +68,32 @@ plugins.withType().all { } } } + + +val testMavenPublication by configurations.registering { + asConsumer() + isVisible = false + attributes { + attribute(MavenPublishTest.attribute, "testMavenRepo") + } +} + +val testMavenPublicationElements by configurations.registering { + asProvider() + isVisible = true + extendsFrom(testMavenPublication.get()) + attributes { + attribute(MavenPublishTest.attribute, "testMavenRepo") + } + outgoing { + artifact(mavenPublishTestExtension.testMavenRepo) { + builtBy(publishToTestMavenRepo) + } + } +} + +dependencies { + attributesSchema { + attribute(MavenPublishTest.attribute) + } +} diff --git a/buildSrc/src/main/kotlin/buildsrc/tasks/SetupDokkaProjects.kt b/buildSrc/src/main/kotlin/buildsrc/tasks/SetupDokkaProjects.kt new file mode 100644 index 00000000..089d979a --- /dev/null +++ b/buildSrc/src/main/kotlin/buildsrc/tasks/SetupDokkaProjects.kt @@ -0,0 +1,54 @@ +package buildsrc.tasks + +import java.io.File +import javax.inject.Inject +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileCollection +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.file.ProjectLayout +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.MapProperty +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.OutputDirectories +import org.gradle.api.tasks.TaskAction + +abstract class SetupDokkaProjects @Inject constructor( + private val fs: FileSystemOperations, + private val layout: ProjectLayout, + private val objects: ObjectFactory, +) : DefaultTask() { + + @get:Input + abstract val destinationToSources: MapProperty> + + @get:InputDirectory + abstract val dokkaSourceDir: DirectoryProperty + + @get:OutputDirectories + val destinationDirs: FileCollection = layout.files( + destinationToSources.map { it.keys } + ) + + init { + group = "dokka examples" + } + + @TaskAction + fun action() { + val destinationToSources = destinationToSources.get() + val dokkaSourceDir = dokkaSourceDir.get() + + println("destinationToSources: $destinationToSources") + + destinationToSources.forEach { (dest: File, sources: List) -> + fs.sync { + sources.forEach { src -> + from("$dokkaSourceDir/$src") + } + into(dest) + } + } + } +} diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 00000000..72f2d93e --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,5 @@ +.idea +**/gradle/wrapper/** +gradlew.bat +gradlew +gradle.properties diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 00000000..f39abb5b --- /dev/null +++ b/examples/README.md @@ -0,0 +1,18 @@ +# Dokkatoo Examples + +Examples of how to use Dokkatoo. + +The examples are copied from the Dokka project. + +### Set up + +The Dokka examples are synced automatically from the Dokka source code. + +### Tests + +The projects are tested in the +[`:modules:dokkatoo-plugin-integration-tests`](./../modules/dokkatoo-plugin-integration-tests/) +project. + +The Dokka Publications generated by the Dokka examples are compared against the Dokka +Publications generated by the Dokkatoo projects. diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts new file mode 100644 index 00000000..26ef43ab --- /dev/null +++ b/examples/build.gradle.kts @@ -0,0 +1,52 @@ +plugins { + buildsrc.conventions.`maven-publish-test` + buildsrc.conventions.`dokkatoo-example-projects` +} + + +dependencies { +// testMavenPublication(projects.modules.dokkatooPlugin) +} + +tasks.setupDokkaTemplateProjects { + destinationToSources.set( + mapOf( + //@formatter:off + "custom-format-example/dokka" to listOf("examples/gradle/dokka-customFormat-example"), + "gradle-example/dokka" to listOf("examples/gradle/dokka-gradle-example"), + "kotlin-as-java-example/dokka" to listOf("examples/gradle/dokka-kotlinAsJava-example"), + "library-publishing-example/dokka" to listOf("examples/gradle/dokka-library-publishing-example"), + "multimodule-example/dokka" to listOf("examples/gradle/dokka-multimodule-example"), + "multiplatform-example/dokka" to listOf("examples/gradle/dokka-multiplatform-example"), + "versioning-multimodule-example/dokka" to listOf("examples/gradle/dokka-versioning-multimodule-example"), + //@formatter:on + ).mapKeys { (dest, _) -> projectDir.resolve(dest) } + ) +} + +configurations.exampleProjectsElements.configure { + outgoing { + artifact(projectDir) { + builtBy(tasks.setupDokkaTemplateProjects, tasks.updateGradlePropertiesInDokkatooExamples) + type = "directory" + } + } +// outgoing { +// listOf( +// "custom-format-example", +// "gradle-example", +// "kotlin-as-java-example", +// "library-publishing-example", +// "multimodule-example", +// "multiplatform-example", +// "versioning-multimodule-example", +// ).forEach { exampleDir -> +// artifact(layout.projectDirectory.dir("$exampleDir/dokka")) { +// builtBy(tasks.setupDokkaTemplateProjects) +// } +// artifact(layout.projectDirectory.dir("$exampleDir/dokkatoo")) { +// builtBy(tasks.setupDokkaTemplateProjects, tasks.updateGradlePropertiesInDokkatooExamples) +// } +// } +// } +} diff --git a/examples/custom-format-example/dokka/README.md b/examples/custom-format-example/dokka/README.md new file mode 100644 index 00000000..00dd668c --- /dev/null +++ b/examples/custom-format-example/dokka/README.md @@ -0,0 +1,24 @@ +## Dokka custom format example + +This example demonstrates a few things: + +1. How to override css styles and add custom images. +2. How to change logo used in the header. +3. How to register a custom `Dokka` task with its own independent configuration. + +### Running + +`dokkaCustomFormat` task has been created in the buildscript of this example project with a few configuration changes. + +In order to see the full effect of these changes, run `dokkaCustomFormat` task from your IDE or execute +the following command: + +```bash +./gradlew clean dokkaCustomFormat +``` + +--- + +If you run any other `Dokka` task, such as `dokkaHtml`, you'll see vanilla `Dokka` without any alterations. +This is because changes to configuration are applied only within `dokkaCustomFormat` task. This can be useful +if you want to generate multiple versions of documentation with different configuration settings. diff --git a/examples/custom-format-example/dokka/build.gradle.kts b/examples/custom-format-example/dokka/build.gradle.kts new file mode 100644 index 00000000..bea4161a --- /dev/null +++ b/examples/custom-format-example/dokka/build.gradle.kts @@ -0,0 +1,34 @@ +import org.jetbrains.dokka.gradle.DokkaTask + +plugins { + kotlin("jvm") version "1.7.20" + id("org.jetbrains.dokka") version ("1.7.10") +} + +buildscript { + dependencies { + classpath("org.jetbrains.dokka:dokka-base:1.7.10") + } +} + +repositories { + mavenCentral() +} + +/** + * Custom format adds a custom logo + */ +tasks.register("dokkaCustomFormat") { + pluginConfiguration { + // Dokka's stylesheets and assets with conflicting names will be overriden. + // In this particular case, logo-styles.css will be overriden and ktor-logo.png will + // be added as an additional image asset + customStyleSheets = listOf(file("logo-styles.css")) + customAssets = listOf(file("ktor-logo.png")) + } +} + +dependencies { + implementation(kotlin("stdlib")) + testImplementation(kotlin("test-junit")) +} diff --git a/examples/custom-format-example/dokka/ktor-logo.png b/examples/custom-format-example/dokka/ktor-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ef943896522ec6199dec5df5ce370a526e6a534b GIT binary patch literal 179624 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 { + Greeter(args[0]).greet() +} diff --git a/examples/custom-format-example/dokkatoo/settings.gradle.kts b/examples/custom-format-example/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..d3e8b98d --- /dev/null +++ b/examples/custom-format-example/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "custom-format-example" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/examples/gradle-example/dokka/Module.md b/examples/gradle-example/dokka/Module.md new file mode 100644 index 00000000..0d051cb1 --- /dev/null +++ b/examples/gradle-example/dokka/Module.md @@ -0,0 +1,7 @@ +# Module Dokka Gradle Example + +This is an example of how you can write module documentation with Dokka. + +# Package demo + +This package contains a few examples of Dokka usage. diff --git a/examples/gradle-example/dokka/build.gradle.kts b/examples/gradle-example/dokka/build.gradle.kts new file mode 100644 index 00000000..d15b0331 --- /dev/null +++ b/examples/gradle-example/dokka/build.gradle.kts @@ -0,0 +1,32 @@ +import org.jetbrains.dokka.gradle.DokkaTask +import java.net.URL + +plugins { + kotlin("jvm") version "1.7.20" + id("org.jetbrains.dokka") version ("1.7.10") +} + +repositories { + mavenCentral() +} + +dependencies { + implementation(kotlin("stdlib")) + testImplementation(kotlin("test-junit")) +} + +tasks.withType().configureEach { + dokkaSourceSets { + named("main") { + moduleName.set("Dokka Gradle Example") + includes.from("Module.md") + sourceLink { + localDirectory.set(file("src/main/kotlin")) + remoteUrl.set(URL("https://github.com/Kotlin/dokka/tree/master/" + + "examples/gradle/dokka-gradle-example/src/main/kotlin" + )) + remoteLineSuffix.set("#L") + } + } + } +} diff --git a/examples/gradle-example/dokka/settings.gradle.kts b/examples/gradle-example/dokka/settings.gradle.kts new file mode 100644 index 00000000..5b8c3c92 --- /dev/null +++ b/examples/gradle-example/dokka/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "dokka-gradle-example" diff --git a/examples/gradle-example/dokka/src/main/kotlin/demo/HelloWorld.kt b/examples/gradle-example/dokka/src/main/kotlin/demo/HelloWorld.kt new file mode 100644 index 00000000..172e18f7 --- /dev/null +++ b/examples/gradle-example/dokka/src/main/kotlin/demo/HelloWorld.kt @@ -0,0 +1,20 @@ +package demo + +/** + * This class supports greeting people by name. + * + * @property name The name of the person to be greeted. + */ +class Greeter(val name: String) { + + /** + * Prints the greeting to the standard output. + */ + fun greet() { + println("Hello $name!") + } +} + +fun main(args: Array) { + Greeter(args[0]).greet() +} diff --git a/examples/gradle-example/dokkatoo/Module.md b/examples/gradle-example/dokkatoo/Module.md new file mode 100644 index 00000000..0d051cb1 --- /dev/null +++ b/examples/gradle-example/dokkatoo/Module.md @@ -0,0 +1,7 @@ +# Module Dokka Gradle Example + +This is an example of how you can write module documentation with Dokka. + +# Package demo + +This package contains a few examples of Dokka usage. diff --git a/examples/gradle-example/dokkatoo/build.gradle.kts b/examples/gradle-example/dokkatoo/build.gradle.kts new file mode 100644 index 00000000..e9403ea3 --- /dev/null +++ b/examples/gradle-example/dokkatoo/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + kotlin("jvm") version "1.7.20" + id("dev.adamko.dokkatoo") version "0.0.1-SNAPSHOT" +} + +dokkatoo { + moduleName.set("Dokka Gradle Example") + dokkatooSourceSets.named("main") { + includes.from("Module.md") + sourceLink { + localDirectory.set(file("src/main/kotlin")) + remoteUrl("https://github.com/Kotlin/dokka/tree/master/examples/gradle/dokka-gradle-example/src/main/kotlin") +// remoteUrl("https://github.com/adamko-dev/dokkatoo/tree/main/examples/gradle-example/dokkatoo/src/main/kotlin") + remoteLineSuffix.set("#L") + } + } +} + +tasks.withType().configureEach { + dokkaSourceSets.configureEach { + sourceSetScope.set(":dokkaHtml") // only necessary for testing + } +} diff --git a/examples/gradle-example/dokkatoo/settings.gradle.kts b/examples/gradle-example/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..02c75bfb --- /dev/null +++ b/examples/gradle-example/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "gradle-example" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/examples/gradle-example/dokkatoo/src/main/kotlin/demo/HelloWorld.kt b/examples/gradle-example/dokkatoo/src/main/kotlin/demo/HelloWorld.kt new file mode 100644 index 00000000..172e18f7 --- /dev/null +++ b/examples/gradle-example/dokkatoo/src/main/kotlin/demo/HelloWorld.kt @@ -0,0 +1,20 @@ +package demo + +/** + * This class supports greeting people by name. + * + * @property name The name of the person to be greeted. + */ +class Greeter(val name: String) { + + /** + * Prints the greeting to the standard output. + */ + fun greet() { + println("Hello $name!") + } +} + +fun main(args: Array) { + Greeter(args[0]).greet() +} diff --git a/examples/kotlin-as-java-example/dokka/build.gradle.kts b/examples/kotlin-as-java-example/dokka/build.gradle.kts new file mode 100644 index 00000000..febd2819 --- /dev/null +++ b/examples/kotlin-as-java-example/dokka/build.gradle.kts @@ -0,0 +1,22 @@ +plugins { + kotlin("jvm") version "1.7.20" + id("org.jetbrains.dokka") version ("1.7.10") +} + +repositories { + mavenCentral() +} + +dependencies { + implementation(kotlin("stdlib")) + testImplementation(kotlin("test-junit")) + + // Will apply the plugin to all dokka tasks + dokkaPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:1.7.10") + + // Will apply the plugin only to the `:dokkaHtml` task + //dokkaHtmlPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:1.7.10") + + // Will apply the plugin only to the `:dokkaGfm` task + //dokkaGfmPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:1.7.10") +} diff --git a/examples/kotlin-as-java-example/dokka/settings.gradle.kts b/examples/kotlin-as-java-example/dokka/settings.gradle.kts new file mode 100644 index 00000000..0a0b8c0e --- /dev/null +++ b/examples/kotlin-as-java-example/dokka/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "dokka-kotlinAsJava-example" diff --git a/examples/kotlin-as-java-example/dokka/src/main/kotlin/demo/HelloWorld.kt b/examples/kotlin-as-java-example/dokka/src/main/kotlin/demo/HelloWorld.kt new file mode 100644 index 00000000..172e18f7 --- /dev/null +++ b/examples/kotlin-as-java-example/dokka/src/main/kotlin/demo/HelloWorld.kt @@ -0,0 +1,20 @@ +package demo + +/** + * This class supports greeting people by name. + * + * @property name The name of the person to be greeted. + */ +class Greeter(val name: String) { + + /** + * Prints the greeting to the standard output. + */ + fun greet() { + println("Hello $name!") + } +} + +fun main(args: Array) { + Greeter(args[0]).greet() +} diff --git a/examples/kotlin-as-java-example/dokkatoo/settings.gradle.kts b/examples/kotlin-as-java-example/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..019ac938 --- /dev/null +++ b/examples/kotlin-as-java-example/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "kotlin-as-java-example" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/examples/library-publishing-example/dokka/build.gradle.kts b/examples/library-publishing-example/dokka/build.gradle.kts new file mode 100644 index 00000000..ab8a8249 --- /dev/null +++ b/examples/library-publishing-example/dokka/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + kotlin("jvm") version "1.7.20" + id("org.jetbrains.dokka") version ("1.7.10") + `java-library` + `maven-publish` +} + +repositories { + mavenCentral() +} + +dependencies { + implementation(kotlin("stdlib")) + testImplementation(kotlin("test-junit")) +} + +val dokkaJavadocJar by tasks.register("dokkaJavadocJar") { + dependsOn(tasks.dokkaJavadoc) + from(tasks.dokkaJavadoc.flatMap { it.outputDirectory }) + archiveClassifier.set("javadoc") +} + +val dokkaHtmlJar by tasks.register("dokkaHtmlJar") { + dependsOn(tasks.dokkaHtml) + from(tasks.dokkaHtml.flatMap { it.outputDirectory }) + archiveClassifier.set("html-doc") +} + +publishing { + publications { + register("library") { + from(components["java"]) + version = "1.0.0" + groupId = "demo" + artifactId = "dokka-library-publishing-example" + artifact(dokkaJavadocJar) + artifact(dokkaHtmlJar) + } + } +} + + + + diff --git a/examples/library-publishing-example/dokka/settings.gradle.kts b/examples/library-publishing-example/dokka/settings.gradle.kts new file mode 100644 index 00000000..e0847ac9 --- /dev/null +++ b/examples/library-publishing-example/dokka/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "dokka-library-publishing-example" diff --git a/examples/library-publishing-example/dokka/src/main/kotlin/demo/HelloWorld.kt b/examples/library-publishing-example/dokka/src/main/kotlin/demo/HelloWorld.kt new file mode 100644 index 00000000..172e18f7 --- /dev/null +++ b/examples/library-publishing-example/dokka/src/main/kotlin/demo/HelloWorld.kt @@ -0,0 +1,20 @@ +package demo + +/** + * This class supports greeting people by name. + * + * @property name The name of the person to be greeted. + */ +class Greeter(val name: String) { + + /** + * Prints the greeting to the standard output. + */ + fun greet() { + println("Hello $name!") + } +} + +fun main(args: Array) { + Greeter(args[0]).greet() +} diff --git a/examples/library-publishing-example/dokkatoo/settings.gradle.kts b/examples/library-publishing-example/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..198cfbdf --- /dev/null +++ b/examples/library-publishing-example/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "library-publishing-example" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/examples/multimodule-example/dokka/build.gradle.kts b/examples/multimodule-example/dokka/build.gradle.kts new file mode 100644 index 00000000..6b416abc --- /dev/null +++ b/examples/multimodule-example/dokka/build.gradle.kts @@ -0,0 +1,5 @@ +subprojects { + repositories { + mavenCentral() + } +} diff --git a/examples/multimodule-example/dokka/parentProject/build.gradle.kts b/examples/multimodule-example/dokka/parentProject/build.gradle.kts new file mode 100644 index 00000000..397ad22f --- /dev/null +++ b/examples/multimodule-example/dokka/parentProject/build.gradle.kts @@ -0,0 +1,20 @@ +plugins { + /** + * Kotlin plugin necessary because of potential Gradle bug! + * This is not necessary if the kotlin gradle plugin is added as buildscript + * dependency like + * + * buildscript { + * dependencies { + * classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") + * } + * } + */ + kotlin("jvm") + id("org.jetbrains.dokka") +} + +dependencies { + implementation(kotlin("stdlib")) +} + diff --git a/examples/multimodule-example/dokka/parentProject/childProjectA/Module.md b/examples/multimodule-example/dokka/parentProject/childProjectA/Module.md new file mode 100644 index 00000000..e6cf0e04 --- /dev/null +++ b/examples/multimodule-example/dokka/parentProject/childProjectA/Module.md @@ -0,0 +1,5 @@ +# Module childProjectA +This is the child module a + +# Package demo +This package contains a few examples of Dokka usage. diff --git a/examples/multimodule-example/dokka/parentProject/childProjectA/build.gradle.kts b/examples/multimodule-example/dokka/parentProject/childProjectA/build.gradle.kts new file mode 100644 index 00000000..b3c42aba --- /dev/null +++ b/examples/multimodule-example/dokka/parentProject/childProjectA/build.gradle.kts @@ -0,0 +1,18 @@ +import org.jetbrains.dokka.gradle.DokkaTaskPartial + +plugins { + kotlin("jvm") + id("org.jetbrains.dokka") +} + +dependencies { + implementation(kotlin("stdlib")) +} + +tasks.withType().configureEach { + dokkaSourceSets { + configureEach { + includes.from("Module.md") + } + } +} diff --git a/examples/multimodule-example/dokka/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt b/examples/multimodule-example/dokka/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt new file mode 100644 index 00000000..533b305c --- /dev/null +++ b/examples/multimodule-example/dokka/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt @@ -0,0 +1,8 @@ +@file:Suppress("unused") + +package demo + +/** + * Class defined in child project a + */ +class ChildProjectAClass diff --git a/examples/multimodule-example/dokka/parentProject/childProjectB/Module.md b/examples/multimodule-example/dokka/parentProject/childProjectB/Module.md new file mode 100644 index 00000000..27031edf --- /dev/null +++ b/examples/multimodule-example/dokka/parentProject/childProjectB/Module.md @@ -0,0 +1,5 @@ +# Module childProjectB +This is the child module b + +# Package demo +This package contains a few examples of Dokka usage. diff --git a/examples/multimodule-example/dokka/parentProject/childProjectB/build.gradle.kts b/examples/multimodule-example/dokka/parentProject/childProjectB/build.gradle.kts new file mode 100644 index 00000000..b3c42aba --- /dev/null +++ b/examples/multimodule-example/dokka/parentProject/childProjectB/build.gradle.kts @@ -0,0 +1,18 @@ +import org.jetbrains.dokka.gradle.DokkaTaskPartial + +plugins { + kotlin("jvm") + id("org.jetbrains.dokka") +} + +dependencies { + implementation(kotlin("stdlib")) +} + +tasks.withType().configureEach { + dokkaSourceSets { + configureEach { + includes.from("Module.md") + } + } +} diff --git a/examples/multimodule-example/dokka/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt b/examples/multimodule-example/dokka/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt new file mode 100644 index 00000000..6bfd22eb --- /dev/null +++ b/examples/multimodule-example/dokka/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt @@ -0,0 +1,8 @@ +@file:Suppress("unused") + +package demo + +/** + * Class defined in child module b + */ +class ChildProjectBClass diff --git a/examples/multimodule-example/dokka/settings.gradle.kts b/examples/multimodule-example/dokka/settings.gradle.kts new file mode 100644 index 00000000..0631e30f --- /dev/null +++ b/examples/multimodule-example/dokka/settings.gradle.kts @@ -0,0 +1,12 @@ +pluginManagement { + plugins { + kotlin("jvm") version "1.7.20" + id("org.jetbrains.dokka") version ("1.7.10") + } +} + +include(":parentProject") +include(":parentProject:childProjectA") +include(":parentProject:childProjectB") + +rootProject.name = "dokka-multimodule-example" diff --git a/examples/multimodule-example/dokkatoo/parentProject/build.gradle.kts b/examples/multimodule-example/dokkatoo/parentProject/build.gradle.kts new file mode 100644 index 00000000..7facb007 --- /dev/null +++ b/examples/multimodule-example/dokkatoo/parentProject/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + kotlin("jvm") version "1.7.20" apply false + id("dev.adamko.dokkatoo") version "0.0.1-SNAPSHOT" +} + +dependencies { + dokkatoo(project(":parentProject:childProjectA")) + dokkatoo(project(":parentProject:childProjectB")) + dokkatooPluginHtml("org.jetbrains.dokka:all-modules-page-plugin:1.7.20") + dokkatooPluginHtml("org.jetbrains.dokka:templating-plugin:1.7.20") +} diff --git a/examples/multimodule-example/dokkatoo/parentProject/childProjectA/Module.md b/examples/multimodule-example/dokkatoo/parentProject/childProjectA/Module.md new file mode 100644 index 00000000..e6cf0e04 --- /dev/null +++ b/examples/multimodule-example/dokkatoo/parentProject/childProjectA/Module.md @@ -0,0 +1,5 @@ +# Module childProjectA +This is the child module a + +# Package demo +This package contains a few examples of Dokka usage. diff --git a/examples/multimodule-example/dokkatoo/parentProject/childProjectA/build.gradle.kts b/examples/multimodule-example/dokkatoo/parentProject/childProjectA/build.gradle.kts new file mode 100644 index 00000000..5a7750b3 --- /dev/null +++ b/examples/multimodule-example/dokkatoo/parentProject/childProjectA/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + kotlin("jvm") + id("dev.adamko.dokkatoo") version "0.0.1-SNAPSHOT" +} + +dokkatoo { + dokkatooSourceSets.configureEach { + includes.from("Module.md") + } + modulePath.set("childProjectA") // match the original dokka default +} + +tasks.withType().configureEach { + dokkaSourceSets.configureEach { + sourceSetScope.set(":parentProject:childProjectA:dokkaHtmlPartial") + } +} diff --git a/examples/multimodule-example/dokkatoo/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt b/examples/multimodule-example/dokkatoo/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt new file mode 100644 index 00000000..533b305c --- /dev/null +++ b/examples/multimodule-example/dokkatoo/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt @@ -0,0 +1,8 @@ +@file:Suppress("unused") + +package demo + +/** + * Class defined in child project a + */ +class ChildProjectAClass diff --git a/examples/multimodule-example/dokkatoo/parentProject/childProjectB/Module.md b/examples/multimodule-example/dokkatoo/parentProject/childProjectB/Module.md new file mode 100644 index 00000000..27031edf --- /dev/null +++ b/examples/multimodule-example/dokkatoo/parentProject/childProjectB/Module.md @@ -0,0 +1,5 @@ +# Module childProjectB +This is the child module b + +# Package demo +This package contains a few examples of Dokka usage. diff --git a/examples/multimodule-example/dokkatoo/parentProject/childProjectB/build.gradle.kts b/examples/multimodule-example/dokkatoo/parentProject/childProjectB/build.gradle.kts new file mode 100644 index 00000000..f2d7c3ce --- /dev/null +++ b/examples/multimodule-example/dokkatoo/parentProject/childProjectB/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + kotlin("jvm") + id("dev.adamko.dokkatoo") version "0.0.1-SNAPSHOT" +} + +dokkatoo { + dokkatooSourceSets.configureEach { + includes.from("Module.md") + } + modulePath.set("childProjectB") // match the original dokka default +} + +tasks.withType().configureEach { + dokkaSourceSets.configureEach { + sourceSetScope.set(":parentProject:childProjectB:dokkaHtmlPartial") + } +} diff --git a/examples/multimodule-example/dokkatoo/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt b/examples/multimodule-example/dokkatoo/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt new file mode 100644 index 00000000..6bfd22eb --- /dev/null +++ b/examples/multimodule-example/dokkatoo/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt @@ -0,0 +1,8 @@ +@file:Suppress("unused") + +package demo + +/** + * Class defined in child module b + */ +class ChildProjectBClass diff --git a/examples/multimodule-example/dokkatoo/settings.gradle.kts b/examples/multimodule-example/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..fef85372 --- /dev/null +++ b/examples/multimodule-example/dokkatoo/settings.gradle.kts @@ -0,0 +1,24 @@ +rootProject.name = "dokkatoo-multimodule-example" + +pluginManagement { + plugins { + kotlin("jvm") version "1.7.20" + } + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +include(":parentProject") +include(":parentProject:childProjectA") +include(":parentProject:childProjectB") diff --git a/examples/multiplatform-example/dokka/build.gradle.kts b/examples/multiplatform-example/dokka/build.gradle.kts new file mode 100644 index 00000000..e2b7c4f3 --- /dev/null +++ b/examples/multiplatform-example/dokka/build.gradle.kts @@ -0,0 +1,44 @@ +@file:Suppress("UNUSED_VARIABLE") + +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.Platform + +plugins { + kotlin("multiplatform") version "1.7.20" + id("org.jetbrains.dokka") version "1.7.10" +} + +repositories { + mavenCentral() +} + +group = "org.test" +version = "1.0-SNAPSHOT" + +kotlin { + jvm() // Create a JVM target with the default name "jvm" + linuxX64("linux") + macosX64("macos") + js() + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin("stdlib-common")) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1") + } + } + } +} + +tasks.withType().configureEach { + dokkaSourceSets { + /* + Create custom source set (not known to the Kotlin Gradle Plugin) + */ + register("customSourceSet") { + this.jdkVersion.set(9) + this.displayName.set("custom") + this.sourceRoots.from(file("src/customJdk9/kotlin")) + } + } +} diff --git a/examples/multiplatform-example/dokka/gradle.properties b/examples/multiplatform-example/dokka/gradle.properties new file mode 100644 index 00000000..29e08e8c --- /dev/null +++ b/examples/multiplatform-example/dokka/gradle.properties @@ -0,0 +1 @@ +kotlin.code.style=official \ No newline at end of file diff --git a/examples/multiplatform-example/dokka/settings.gradle.kts b/examples/multiplatform-example/dokka/settings.gradle.kts new file mode 100644 index 00000000..e9daf094 --- /dev/null +++ b/examples/multiplatform-example/dokka/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "dokka-multiplatform-example" + diff --git a/examples/multiplatform-example/dokka/src/commonMain/kotlin/org.kotlintestmpp.common/main.kt b/examples/multiplatform-example/dokka/src/commonMain/kotlin/org.kotlintestmpp.common/main.kt new file mode 100644 index 00000000..1746d513 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/commonMain/kotlin/org.kotlintestmpp.common/main.kt @@ -0,0 +1,4 @@ +package org.kotlintestmpp.common + +class Foo {} + diff --git a/examples/multiplatform-example/dokka/src/commonMain/kotlin/org/kotlintestmpp/coroutines.kt b/examples/multiplatform-example/dokka/src/commonMain/kotlin/org/kotlintestmpp/coroutines.kt new file mode 100644 index 00000000..330cd83a --- /dev/null +++ b/examples/multiplatform-example/dokka/src/commonMain/kotlin/org/kotlintestmpp/coroutines.kt @@ -0,0 +1,6 @@ +package org.kotlintestmpp + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Deferred + +expect fun CoroutineScope.asyncWithDealy(delay: Long, block: suspend () -> T): Deferred diff --git a/examples/multiplatform-example/dokka/src/commonMain/kotlin/org/kotlintestmpp/getCurrentDate.kt b/examples/multiplatform-example/dokka/src/commonMain/kotlin/org/kotlintestmpp/getCurrentDate.kt new file mode 100644 index 00000000..46a1dd23 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/commonMain/kotlin/org/kotlintestmpp/getCurrentDate.kt @@ -0,0 +1,8 @@ +package org.kotlintestmpp + +expect fun getCurrentDate(): String + +fun getDate(): String { + return "Today's Date is ${getCurrentDate()}" +} + diff --git a/examples/multiplatform-example/dokka/src/customJdk9/kotlin/demo/CustomSourceSetFile.kt b/examples/multiplatform-example/dokka/src/customJdk9/kotlin/demo/CustomSourceSetFile.kt new file mode 100644 index 00000000..5b642416 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/customJdk9/kotlin/demo/CustomSourceSetFile.kt @@ -0,0 +1,11 @@ +package demo + +/** + * This class demonstrates custom dokka source sets + */ +class CustomSourceSetFile { + /** + * This function will not do anything + */ + fun thisIsAFunction() {} +} diff --git a/examples/multiplatform-example/dokka/src/jsMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt b/examples/multiplatform-example/dokka/src/jsMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt new file mode 100644 index 00000000..7b5fe652 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/jsMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt @@ -0,0 +1,8 @@ +package org.kotlintestmpp + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Deferred + +actual fun CoroutineScope.asyncWithDealy(delay: Long, block: suspend () -> T): Deferred { + TODO("Not yet implemented") +} diff --git a/examples/multiplatform-example/dokka/src/jsMain/kotlin/org/kotlintestmpp/main.kt b/examples/multiplatform-example/dokka/src/jsMain/kotlin/org/kotlintestmpp/main.kt new file mode 100644 index 00000000..8cb66e6d --- /dev/null +++ b/examples/multiplatform-example/dokka/src/jsMain/kotlin/org/kotlintestmpp/main.kt @@ -0,0 +1,17 @@ +package org.kotlintestmpp + +fun main(args : Array) { + console.log("Hello, world!") +} + +fun js(){} +fun shared(){} + +/** + * Actual function for js + */ +actual fun getCurrentDate(): String { + return "test" +} + +fun String.myExtension() = println("test") \ No newline at end of file diff --git a/examples/multiplatform-example/dokka/src/jsMain/kotlin/shouldbesuppressed/supp.kt b/examples/multiplatform-example/dokka/src/jsMain/kotlin/shouldbesuppressed/supp.kt new file mode 100644 index 00000000..21dca566 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/jsMain/kotlin/shouldbesuppressed/supp.kt @@ -0,0 +1,11 @@ +package shouldbesuppressed + +/** + * This function should not be visible + */ +fun thatShouldNotBeVisible(): String = "oops" + +/** + * This class should not be visible + */ +class DontLookAtMe(val stealth: Int = 9001) \ No newline at end of file diff --git a/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/MainCommand.java b/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/MainCommand.java new file mode 100644 index 00000000..16de8ef3 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/MainCommand.java @@ -0,0 +1,16 @@ +package org.kotlintestmpp; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface MainCommand { + String command(); + + String[] aliases(); + + String description(); +} \ No newline at end of file diff --git a/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt b/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt new file mode 100644 index 00000000..7b5fe652 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt @@ -0,0 +1,8 @@ +package org.kotlintestmpp + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Deferred + +actual fun CoroutineScope.asyncWithDealy(delay: Long, block: suspend () -> T): Deferred { + TODO("Not yet implemented") +} diff --git a/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/main.kt b/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/main.kt new file mode 100644 index 00000000..bc5b53de --- /dev/null +++ b/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/main.kt @@ -0,0 +1,30 @@ +package org.kotlintestmpp +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import org.kotlintestmpp.common.Foo + +fun main(args : Array) { + println("Hello, world!") +} + +/** + * also see the [Foo] class + * @see org.kotlintestmpp.common.Foo + */ +fun jvm(){} +fun shared(){} +fun CoroutineScope.startConnectionPipeline( + input: String +): Job = launch { TODO () } + +/** + * Actual function for jvm + */ +actual fun getCurrentDate(): String { + return "test" +} + +fun String.myExtension() = println("test2") + + diff --git a/examples/multiplatform-example/dokka/src/jvmMain/kotlin/shouldbesuppressed/supp.kt b/examples/multiplatform-example/dokka/src/jvmMain/kotlin/shouldbesuppressed/supp.kt new file mode 100644 index 00000000..21dca566 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/jvmMain/kotlin/shouldbesuppressed/supp.kt @@ -0,0 +1,11 @@ +package shouldbesuppressed + +/** + * This function should not be visible + */ +fun thatShouldNotBeVisible(): String = "oops" + +/** + * This class should not be visible + */ +class DontLookAtMe(val stealth: Int = 9001) \ No newline at end of file diff --git a/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt b/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt new file mode 100644 index 00000000..7b5fe652 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt @@ -0,0 +1,8 @@ +package org.kotlintestmpp + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Deferred + +actual fun CoroutineScope.asyncWithDealy(delay: Long, block: suspend () -> T): Deferred { + TODO("Not yet implemented") +} diff --git a/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/cinterop.kt b/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/cinterop.kt new file mode 100644 index 00000000..efc60f23 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/cinterop.kt @@ -0,0 +1,10 @@ +@file:Suppress("unused") + +package org.kotlintestmpp + +import kotlinx.cinterop.CPointed +import kotlinx.cinterop.CPointer + +fun printPointerRawValue(pointer: CPointer) { + println(pointer.rawValue) +} diff --git a/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/getCurrentDate.kt b/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/getCurrentDate.kt new file mode 100644 index 00000000..86f27c15 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/getCurrentDate.kt @@ -0,0 +1,8 @@ +package org.kotlintestmpp + +/** + * Actual function for linux + */ +actual fun getCurrentDate(): String { + TODO("Not yet implemented") +} \ No newline at end of file diff --git a/examples/multiplatform-example/dokka/src/macosMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt b/examples/multiplatform-example/dokka/src/macosMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt new file mode 100644 index 00000000..7b5fe652 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/macosMain/kotlin/org/kotlintestmpp/asyncWithDealy.kt @@ -0,0 +1,8 @@ +package org.kotlintestmpp + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Deferred + +actual fun CoroutineScope.asyncWithDealy(delay: Long, block: suspend () -> T): Deferred { + TODO("Not yet implemented") +} diff --git a/examples/multiplatform-example/dokka/src/macosMain/kotlin/org/kotlintestmpp/getCurrentDate.kt b/examples/multiplatform-example/dokka/src/macosMain/kotlin/org/kotlintestmpp/getCurrentDate.kt new file mode 100644 index 00000000..3e7849b6 --- /dev/null +++ b/examples/multiplatform-example/dokka/src/macosMain/kotlin/org/kotlintestmpp/getCurrentDate.kt @@ -0,0 +1,8 @@ +package org.kotlintestmpp + +/** + * Actual function for mac os + */ +actual fun getCurrentDate(): String { + TODO("Not yet implemented") +} \ No newline at end of file diff --git a/examples/multiplatform-example/dokkatoo/settings.gradle.kts b/examples/multiplatform-example/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..30503c55 --- /dev/null +++ b/examples/multiplatform-example/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "multiplatform-example" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/examples/versioning-multimodule-example/dokka/build.gradle.kts b/examples/versioning-multimodule-example/dokka/build.gradle.kts new file mode 100644 index 00000000..4b874373 --- /dev/null +++ b/examples/versioning-multimodule-example/dokka/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + kotlin("jvm") version "1.7.20" + id("org.jetbrains.dokka") version ("1.7.10") apply false +} + +// The versioning plugin should be applied in all submodules +subprojects { + repositories { + mavenCentral() + } + apply { + plugin("org.jetbrains.kotlin.jvm") + plugin("org.jetbrains.dokka") + } + val dokkaPlugin by configurations + dependencies { + dokkaPlugin("org.jetbrains.dokka:versioning-plugin:1.7.10") + } +} diff --git a/examples/versioning-multimodule-example/dokka/parentProject/build.gradle.kts b/examples/versioning-multimodule-example/dokka/parentProject/build.gradle.kts new file mode 100644 index 00000000..afbc6675 --- /dev/null +++ b/examples/versioning-multimodule-example/dokka/parentProject/build.gradle.kts @@ -0,0 +1,25 @@ +import org.jetbrains.dokka.gradle.DokkaMultiModuleTask + +dependencies { + implementation(kotlin("stdlib")) +} + +val olderVersionsFolder = "olderVersions" + +// The previously documentations should be generated with the versioning plugin +val generatePreviouslyDocTask by tasks.register("dokkaPreviouslyDocumentation") { + dependencies { + dokkaPlugin("org.jetbrains.dokka:all-modules-page-plugin:1.7.10") + dokkaPlugin("org.jetbrains.dokka:versioning-plugin:1.7.10") + } + val configuredVersion = "0.9" + outputDirectory.set(file(projectDir.resolve(olderVersionsFolder).resolve(configuredVersion))) + pluginsMapConfiguration.set(mapOf("org.jetbrains.dokka.versioning.VersioningPlugin" to """{ "version": "$configuredVersion" }""")) + addChildTasks(listOf(project("childProjectA"), project("childProjectB")), "dokkaHtmlPartial") +} + +tasks.dokkaHtmlMultiModule { + dependsOn(generatePreviouslyDocTask) + val configuredVersion = "1.0" + pluginsMapConfiguration.set(mapOf("org.jetbrains.dokka.versioning.VersioningPlugin" to """{ "version": "$configuredVersion", "olderVersionsDir": "${projectDir.resolve(olderVersionsFolder).invariantSeparatorsPath}" }""")) +} diff --git a/examples/versioning-multimodule-example/dokka/parentProject/childProjectA/build.gradle.kts b/examples/versioning-multimodule-example/dokka/parentProject/childProjectA/build.gradle.kts new file mode 100644 index 00000000..dd9f5199 --- /dev/null +++ b/examples/versioning-multimodule-example/dokka/parentProject/childProjectA/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies { + implementation(kotlin("stdlib")) +} \ No newline at end of file diff --git a/examples/versioning-multimodule-example/dokka/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt b/examples/versioning-multimodule-example/dokka/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt new file mode 100644 index 00000000..533b305c --- /dev/null +++ b/examples/versioning-multimodule-example/dokka/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt @@ -0,0 +1,8 @@ +@file:Suppress("unused") + +package demo + +/** + * Class defined in child project a + */ +class ChildProjectAClass diff --git a/examples/versioning-multimodule-example/dokka/parentProject/childProjectB/build.gradle.kts b/examples/versioning-multimodule-example/dokka/parentProject/childProjectB/build.gradle.kts new file mode 100644 index 00000000..fceff829 --- /dev/null +++ b/examples/versioning-multimodule-example/dokka/parentProject/childProjectB/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies { + implementation(kotlin("stdlib")) +} diff --git a/examples/versioning-multimodule-example/dokka/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt b/examples/versioning-multimodule-example/dokka/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt new file mode 100644 index 00000000..6bfd22eb --- /dev/null +++ b/examples/versioning-multimodule-example/dokka/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt @@ -0,0 +1,8 @@ +@file:Suppress("unused") + +package demo + +/** + * Class defined in child module b + */ +class ChildProjectBClass diff --git a/examples/versioning-multimodule-example/dokka/settings.gradle.kts b/examples/versioning-multimodule-example/dokka/settings.gradle.kts new file mode 100644 index 00000000..ec6614f0 --- /dev/null +++ b/examples/versioning-multimodule-example/dokka/settings.gradle.kts @@ -0,0 +1,5 @@ +include(":parentProject") +include(":parentProject:childProjectA") +include(":parentProject:childProjectB") + +rootProject.name = "dokka-versioning-multimodule-example" \ No newline at end of file diff --git a/examples/versioning-multimodule-example/dokkatoo/settings.gradle.kts b/examples/versioning-multimodule-example/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..850a82bf --- /dev/null +++ b/examples/versioning-multimodule-example/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "versioning-multimodule-example" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/externals/.gitignore b/externals/.gitignore deleted file mode 100644 index 7892be13..00000000 --- a/externals/.gitignore +++ /dev/null @@ -1 +0,0 @@ -kotlin-dokka/ diff --git a/externals/build.gradle.kts b/externals/build.gradle.kts deleted file mode 100644 index 37d3347d..00000000 --- a/externals/build.gradle.kts +++ /dev/null @@ -1,44 +0,0 @@ -import buildsrc.conventions.utils.* - -plugins { - buildsrc.conventions.base -} - -dependencies { - kotlinDokkaSource("kotlin:dokka:1.7.20@zip") -} - -val kotlinDokkaPrepareSource by tasks.registering(Sync::class) { - group = "externals" - description = "Download & unpack Kotlin Dokka source code" - from( - @Suppress("UnstableApiUsage") - configurations.kotlinDokkaSource.flatMap { src -> - src.incoming - .artifactView { lenient(true) } - .artifacts - .resolvedArtifacts - .map { artifacts -> artifacts.map { zipTree(it.file) } } - } - ) { - // drop the first dir (dokka-$version) - eachFile { - relativePath = relativePath.dropDirectories(1) - } - } - into(layout.projectDirectory.dir("kotlin-dokka")) - exclude( - "*.github", - "*.gradle", - "**/gradlew", - "**/gradlew.bat", - "**/gradle/wrapper/gradle-wrapper.jar", - "**/gradle/wrapper/gradle-wrapper.properties", - ) -} - -configurations.kotlinDokkaSourceElements.configure { - outgoing { - artifact(kotlinDokkaPrepareSource.map { it.destinationDir }) - } -} diff --git a/gradle.properties b/gradle.properties index dc880ef3..bbf2788f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,5 @@ -org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx2g -XX:MaxMetaspaceSize=1g +# memory is set quite high because the tests launch a lot of processes +org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx4g -XX:MaxMetaspaceSize=2g org.gradle.caching=true # https://github.com/gradle/gradle/issues/20416 diff --git a/modules/dokkatoo-plugin-integration-tests/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/build.gradle.kts new file mode 100644 index 00000000..a7c8205f --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/build.gradle.kts @@ -0,0 +1,212 @@ +@file:Suppress("UnstableApiUsage") // jvm test suites & test report aggregation are incubating + +import org.gradle.api.tasks.testing.logging.TestLogEvent +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") //version embeddedKotlinVersion + kotlin("plugin.serialization") version embeddedKotlinVersion + `java-test-fixtures` + + `jvm-test-suite` + `test-report-aggregation` + + buildsrc.conventions.`dokka-source-downloader` + buildsrc.conventions.`maven-publish-test` + buildsrc.conventions.`dokkatoo-example-projects` +} + +dependencies { + testMavenPublication(projects.modules.dokkatooPlugin) + exampleProjects(projects.examples) + + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1") + + testFixturesApi(testFixtures(projects.modules.dokkatooPlugin)) + testFixturesImplementation(gradleTestKit()) + testFixturesImplementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1") + testFixturesImplementation(platform("io.kotest:kotest-bom:5.5.5")) + testFixturesImplementation("io.kotest:kotest-runner-junit5") + testFixturesImplementation("io.kotest:kotest-assertions-core") + testFixturesImplementation("io.kotest:kotest-assertions-json") + + val jacksonVersion = "2.12.7" + testFixturesImplementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion") + +// kotlinDokkaSource(projects.externals) + + // don't define test dependencies here, instead define them in the testing.suites {} configuration below +} + + +tasks.withType().configureEach { + kotlinOptions { + this.freeCompilerArgs += listOf( + "-opt-in=kotlin.RequiresOptIn", + //"-opt-in=dev.adamko.dokkatoo.internal.DokkatooInternalApi", + ) + } +} + +testing.suites { + + withType().configureEach { + useJUnitJupiter() + + dependencies { + implementation(project.dependencies.gradleTestKit()) + + implementation("org.jetbrains.kotlin:kotlin-test:1.7.20") + + implementation(project.dependencies.platform("io.kotest:kotest-bom:5.5.5")) + implementation("io.kotest:kotest-runner-junit5") + implementation("io.kotest:kotest-assertions-core") + implementation("io.kotest:kotest-assertions-json") + + implementation(project.dependencies.testFixtures(project())) + + implementation("org.jetbrains.dokka:dokka-core:1.7.20") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1") + } + + targets.configureEach { + testTask.configure { + val projectTestTempDirPath = "$buildDir/test-temp-dir" + inputs.property("projectTestTempDir", projectTestTempDirPath) + systemProperty("projectTestTempDir", projectTestTempDirPath) + + // depend on the test-publication configuration, but not the test-maven repo dir + // (otherwise this task will never be up-to-date) + dependsOn(configurations.testMavenPublication) + + // depend on example & integration-test projects setup + dependsOn(configurations.exampleProjects) + dependsOn(tasks.setupDokkaTemplateProjects) + dependsOn(tasks.updateGradlePropertiesInDokkatooExamples) + + val dokkatooExamplesDir = configurations.exampleProjects.map { + it.incoming.artifactView { lenient(true) }.files.singleFile.absolutePath + } + + systemProperty("integrationTestProjectsDir", "$projectDir/projects") + systemProperty("testMavenRepoDir", file(mavenPublishTest.testMavenRepo).canonicalPath) + doFirst { + // workaround for lazy-properties not working https://github.com/gradle/gradle/issues/12247 + systemProperty("exampleProjectsDir", dokkatooExamplesDir.get()) + } + } + } + } + + + /** Examples tests suite */ + val testExamples by registering(JvmTestSuite::class) { +// testType.set(TestSuiteType.FUNCTIONAL_TEST) + + targets.all { + testTask.configure { +// dependsOn(project.configurations.kotlinDokkaSource) + +// inputs.property("dokkaSourceDir", +// project.configurations.kotlinDokkaSource.map { dokkaSrcConf -> +// val files = dokkaSrcConf.incoming.artifactView { lenient(true) }.files +// files.singleOrNull()?.absolutePath +// ?: error("could not get Dokka source code directory from kotlinDokkaSource configuration. Got ${files.count()} files: $files") +// } +// ) +// +// systemProperty("dokkaSourceDir", inputs.properties["dokkaSourceDir"]!!) + } + } + } + + + /** Integration tests suite */ + val testIntegration by registering(JvmTestSuite::class) { +// testType.set(TestSuiteType.INTEGRATION_TEST) + + targets.all { + testTask.configure { +// dependsOn(project.configurations.kotlinDokkaSource) + +// inputs.property("dokkaSourceDir", +// project.configurations.kotlinDokkaSource.map { dokkaSrcConf -> +// val files = dokkaSrcConf.incoming.artifactView { lenient(true) }.files +// files.singleOrNull()?.absolutePath +// ?: error("could not get Dokka source code directory from kotlinDokkaSource configuration. Got ${files.count()} files: $files") +// } +// ) +// +// systemProperty("dokkaSourceDir", inputs.properties["dokkaSourceDir"]!!) + } + } + } + + tasks.check { dependsOn(testExamples, testIntegration) } +} + + +tasks.withType().configureEach { + + mustRunAfter(tasks.withType()) + + testLogging { + events = setOf( + TestLogEvent.STARTED, + TestLogEvent.PASSED, + TestLogEvent.SKIPPED, + TestLogEvent.FAILED, + TestLogEvent.STANDARD_OUT, + TestLogEvent.STANDARD_ERROR, + ) + showStandardStreams = true + showExceptions = true + showCauses = true + showStackTraces = true + } +} + + +// don't publish test fixtures (which causes warnings when publishing) +// https://docs.gradle.org/current/userguide/java_testing.html#publishing_test_fixtures +val javaComponent = components["java"] as AdhocComponentWithVariants +javaComponent.withVariantsFromConfiguration(configurations["testFixturesApiElements"]) { skip() } +javaComponent.withVariantsFromConfiguration(configurations["testFixturesRuntimeElements"]) { skip() } + +tasks.setupDokkaTemplateProjects { + destinationToSources.set( + mapOf( + //@formatter:off + "projects/it-android-0/dokka" to listOf("integration-tests/gradle/projects/it-android-0"), + "projects/it-basic/dokka" to listOf("integration-tests/gradle/projects/it-basic"), + "projects/it-basic-groovy/dokka" to listOf("integration-tests/gradle/projects/it-basic-groovy"), + "projects/it-collector-0/dokka" to listOf("integration-tests/gradle/projects/it-collector-0"), + "projects/it-js-ir-0/dokka" to listOf("integration-tests/gradle/projects/it-js-ir-0"), + "projects/it-multimodule-0/dokka" to listOf("integration-tests/gradle/projects/it-multimodule-0"), + "projects/it-multimodule-1/dokka" to listOf("integration-tests/gradle/projects/it-multimodule-1"), + "projects/it-multimodule-versioning-0/dokka" to listOf("integration-tests/gradle/projects/it-multimodule-versioning-0"), + "projects/it-multiplatform-0/dokka" to listOf("integration-tests/gradle/projects/it-multiplatform-0"), + + //"integration-tests/gradle/projects/coroutines" to "projects/coroutines/dokka", + //"integration-tests/gradle/projects/serialization" to "projects/serialization/dokka", + //"integration-tests/gradle/projects/stdlib" to "projects/stdlib/dokka", + //@formatter:on + ).mapKeys { (dest, _) -> + projectDir.resolve(dest) + }.mapValues { (_, sources) -> + sources + listOf( + "integration-tests/gradle/projects/template.root.gradle.kts", + "integration-tests/gradle/projects/template.settings.gradle.kts", + ) + } + ) +} + +tasks.withType().configureEach { + // this seems to help OOM errors in the Worker Daemons + setForkEvery(1) + jvmArgs( + "-Xmx1g", + "-XX:MaxMetaspaceSize=512m", + ) +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/.gitignore b/modules/dokkatoo-plugin-integration-tests/projects/.gitignore new file mode 100644 index 00000000..72f2d93e --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/.gitignore @@ -0,0 +1,5 @@ +.idea +**/gradle/wrapper/** +gradlew.bat +gradlew +gradle.properties diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/build.gradle.kts new file mode 100644 index 00000000..799ec22d --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/build.gradle.kts @@ -0,0 +1,20 @@ +plugins { + id("com.android.library") + id("org.jetbrains.dokka") + kotlin("android") +} + +apply(from = "../template.root.gradle.kts") + +android { + defaultConfig { + minSdkVersion(21) + setCompileSdkVersion(29) + } +} + +dependencies { + implementation(kotlin("stdlib")) + implementation("androidx.appcompat:appcompat:1.1.0") +} + diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/gradle.properties b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/gradle.properties new file mode 100644 index 00000000..6c0d7406 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/gradle.properties @@ -0,0 +1,3 @@ +dokka_it_kotlin_version=1.7.20 +dokka_it_android_gradle_plugin_version=4.0.0 +android.useAndroidX=true diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/settings.gradle.kts new file mode 100644 index 00000000..664d2cb7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/settings.gradle.kts @@ -0,0 +1,5 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +apply(from = "../template.settings.gradle.kts") +rootProject.name = "it-android-0" + diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/AndroidManifest.xml b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a35f86be --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/java/it/android/AndroidSpecificClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/java/it/android/AndroidSpecificClass.kt new file mode 100644 index 00000000..cb9046b1 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/java/it/android/AndroidSpecificClass.kt @@ -0,0 +1,16 @@ +@file:Suppress("unused") + +package it.android + +import android.content.Context +import android.util.SparseIntArray +import android.view.View + +/** + * This class is specific to android and uses android classes like: + * [Context], [SparseIntArray] or [View] + */ +class AndroidSpecificClass { + fun sparseIntArray() = SparseIntArray() + fun createView(context: Context): View = View(context) +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/java/it/android/IntegrationTestActivity.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/java/it/android/IntegrationTestActivity.kt new file mode 100644 index 00000000..1792818b --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/java/it/android/IntegrationTestActivity.kt @@ -0,0 +1,22 @@ +package it.android + +import android.annotation.SuppressLint +import android.os.Bundle +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity + +/** + * Some Activity implementing [AppCompatActivity] from android x + */ +class IntegrationTestActivity : AppCompatActivity() { + /** + * Will show a small happy text + */ + @SuppressLint("SetTextI18n") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val textView = TextView(this) + textView.text = "I am so happy :)" + setContentView(textView) + } +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/template.root.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/template.root.gradle.kts new file mode 100644 index 00000000..f63c28e7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/template.root.gradle.kts @@ -0,0 +1,23 @@ +allprojects { + repositories { + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenLocal() + mavenCentral() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + content { + includeGroup("org.jetbrains.kotlinx") + } + } + } +} + +afterEvaluate { + logger.quiet("Gradle version: ${gradle.gradleVersion}") + logger.quiet("Kotlin version: ${properties["dokka_it_kotlin_version"]}") + properties["dokka_it_android_gradle_plugin_version"]?.let { androidVersion -> + logger.quiet("Android version: $androidVersion") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/template.settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/template.settings.gradle.kts new file mode 100644 index 00000000..8cb1f2d0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/template.settings.gradle.kts @@ -0,0 +1,38 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +pluginManagement { + val dokka_it_kotlin_version: String by settings + val dokka_it_android_gradle_plugin_version: String? by settings + + plugins { + id("org.jetbrains.kotlin.js") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.jvm") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.android") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.multiplatform") version dokka_it_kotlin_version + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.jetbrains.dokka") { + useModule("org.jetbrains.dokka:dokka-gradle-plugin:for-integration-tests-SNAPSHOT") + } + + if (requested.id.id == "com.android.library") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + + if (requested.id.id == "com.android.application") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + } + } + repositories { + mavenLocal() + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenCentral() + gradlePluginPortal() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokkatoo/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..a9891abc --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "it-android-0" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/build.gradle b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/build.gradle new file mode 100644 index 00000000..f368ed10 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/build.gradle @@ -0,0 +1,54 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' + id("org.jetbrains.dokka") +} + +apply from: '../template.root.gradle.kts' + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib" +} + +dokkaHtml { + outputDirectory = new File(buildDir, "/dokka/customHtml") + failOnWarning = false + dokkaSourceSets { + customSourceSet { + sourceRoot(file("src/main/java")) + sourceRoot(file("src/main/kotlin")) + displayName.set("custom") + reportUndocumented.set(true) + } + + configureEach { + perPackageOption { // testing closures + matchingRegex.set(".*internal.*") + suppress.set(true) + } + + sourceLink { // testing closures + localDirectory.set(file("src/main")) + remoteUrl.set( + new URL( + "https://github.com/Kotlin/dokka/tree/master/" + + "integration-tests/gradle/projects/it-basic-groovy/src/main" + ) + ) + } + } + } + +} + +dokkaJavadoc { + outputDirectory = new File(buildDir, "dokka/customJavadoc") +} + +dokkaGfm { + outputDirectory = new File(buildDir, "dokka/customGfm") +} + +dokkaJekyll { + outputDirectory = new File(buildDir, "dokka/customJekyll") +} + diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/gradle.properties b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/gradle.properties new file mode 100644 index 00000000..fa6c65f6 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/gradle.properties @@ -0,0 +1 @@ +dokka_it_kotlin_version=1.7.20 diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/settings.gradle.kts new file mode 100644 index 00000000..cb6af4e9 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/settings.gradle.kts @@ -0,0 +1,5 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +apply(from = "../template.settings.gradle.kts") +rootProject.name = "it-basic-groovy" + diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/src/main/java/it/basic/java/SampleJavaClass.java b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/src/main/java/it/basic/java/SampleJavaClass.java new file mode 100644 index 00000000..23b0202c --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/src/main/java/it/basic/java/SampleJavaClass.java @@ -0,0 +1,17 @@ +package it.basic.java; + +import it.basic.PublicClass; + +/** + * This class is, unlike {@link PublicClass}, written in Java + */ +@SuppressWarnings("unused") +public class SampleJavaClass { + + /** + * @return Empty instance of {@link PublicClass} + */ + public PublicClass publicDocumentedFunction() { + return new PublicClass(); + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/src/main/kotlin/it/basic/PublicClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/src/main/kotlin/it/basic/PublicClass.kt new file mode 100644 index 00000000..71bc7e63 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/src/main/kotlin/it/basic/PublicClass.kt @@ -0,0 +1,48 @@ +@file:Suppress("unused") + +package it.basic + +class PublicClass { + /** + * This function is public and documented + */ + fun publicDocumentedFunction(): String = "" + + fun publicUndocumentedFunction(): String = "" + + /** + * This function is internal and documented + */ + internal fun internalDocumentedFunction(): String = "" + + internal fun internalUndocumentedFunction(): String = "" + + /** + * This function is private and documented + */ + private fun privateDocumentedFunction(): String = "" + + private fun privateUndocumentedFunction(): String = "" + + + /** + * This property is public and documented + */ + val publicDocumentedProperty: Int = 0 + + val publicUndocumentedProperty: Int = 0 + + /** + * This property internal and documented + */ + val internalDocumentedProperty: Int = 0 + + val internalUndocumentedProperty: Int = 0 + + /** + * This property private and documented + */ + private val privateDocumentedProperty: Int = 0 + + private val privateUndocumentedProperty: Int = 0 +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/template.root.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/template.root.gradle.kts new file mode 100644 index 00000000..f63c28e7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/template.root.gradle.kts @@ -0,0 +1,23 @@ +allprojects { + repositories { + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenLocal() + mavenCentral() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + content { + includeGroup("org.jetbrains.kotlinx") + } + } + } +} + +afterEvaluate { + logger.quiet("Gradle version: ${gradle.gradleVersion}") + logger.quiet("Kotlin version: ${properties["dokka_it_kotlin_version"]}") + properties["dokka_it_android_gradle_plugin_version"]?.let { androidVersion -> + logger.quiet("Android version: $androidVersion") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/template.settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/template.settings.gradle.kts new file mode 100644 index 00000000..8cb1f2d0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/template.settings.gradle.kts @@ -0,0 +1,38 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +pluginManagement { + val dokka_it_kotlin_version: String by settings + val dokka_it_android_gradle_plugin_version: String? by settings + + plugins { + id("org.jetbrains.kotlin.js") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.jvm") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.android") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.multiplatform") version dokka_it_kotlin_version + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.jetbrains.dokka") { + useModule("org.jetbrains.dokka:dokka-gradle-plugin:for-integration-tests-SNAPSHOT") + } + + if (requested.id.id == "com.android.library") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + + if (requested.id.id == "com.android.application") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + } + } + repositories { + mavenLocal() + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenCentral() + gradlePluginPortal() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokkatoo/settings.gradle b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokkatoo/settings.gradle new file mode 100644 index 00000000..fd5763e1 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokkatoo/settings.gradle @@ -0,0 +1,16 @@ +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven { url = providers.gradleProperty("testMavenRepo") } + } +} + +rootProject.name = "it-basic-groovy" + +dependencyResolutionManagement { + repositories { + mavenCentral() + maven { url = providers.gradleProperty("testMavenRepo") } + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/build.gradle.kts new file mode 100644 index 00000000..b1484ac9 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/build.gradle.kts @@ -0,0 +1,64 @@ +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.gradle.kotlinSourceSet +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.base.DokkaBaseConfiguration +import org.jetbrains.dokka.DokkaConfiguration +import java.net.URL + +plugins { + kotlin("jvm") + id("org.jetbrains.dokka") +} + +buildscript { + dependencies { + classpath("org.jetbrains.dokka:dokka-base:${System.getenv("DOKKA_VERSION")}") + } +} + +version = "1.7.20-SNAPSHOT" + +apply(from = "../template.root.gradle.kts") + +dependencies { + implementation(kotlin("stdlib")) + testImplementation(kotlin("test-junit")) +} + +tasks.withType { + moduleName.set("Basic Project") + dokkaSourceSets { + configureEach { + documentedVisibilities.set( + setOf(DokkaConfiguration.Visibility.PUBLIC, DokkaConfiguration.Visibility.PROTECTED) + ) + suppressedFiles.from(file("src/main/kotlin/it/suppressedByPath")) + perPackageOption { + matchingRegex.set("it.suppressedByPackage.*") + suppress.set(true) + } + perPackageOption { + matchingRegex.set("it.overriddenVisibility.*") + documentedVisibilities.set( + setOf(DokkaConfiguration.Visibility.PRIVATE) + ) + } + sourceLink { + localDirectory.set(file("src/main")) + remoteUrl.set( + URL( + "https://github.com/Kotlin/dokka/tree/master/" + + "integration-tests/gradle/projects/it-basic/src/main" + ) + ) + } + } + + register("myTest") { + kotlinSourceSet(kotlin.sourceSets["test"]) + } + } + suppressObviousFunctions.set(false) + + pluginsMapConfiguration.set(mapOf(DokkaBase::class.qualifiedName to """{ "customStyleSheets": ["${file("../customResources/logo-styles.css").invariantSeparatorsPath}", "${file("../customResources/custom-style-to-add.css").invariantSeparatorsPath}"], "customAssets" : ["${file("../customResources/custom-resource.svg").invariantSeparatorsPath}"] }""")) +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/custom-resource.svg b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/custom-resource.svg new file mode 100644 index 00000000..1865f739 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/custom-resource.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/custom-style-to-add.css b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/custom-style-to-add.css new file mode 100644 index 00000000..408c210e --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/custom-style-to-add.css @@ -0,0 +1 @@ +/* custom stylesheet */ \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/logo-styles.css b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/logo-styles.css new file mode 100644 index 00000000..2ac57218 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/logo-styles.css @@ -0,0 +1,3 @@ +#logo { + background-image: url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg'); +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/gradle.properties b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/gradle.properties new file mode 100644 index 00000000..fa6c65f6 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/gradle.properties @@ -0,0 +1 @@ +dokka_it_kotlin_version=1.7.20 diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/settings.gradle.kts new file mode 100644 index 00000000..833995e5 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/settings.gradle.kts @@ -0,0 +1,5 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +apply(from = "../template.settings.gradle.kts") +rootProject.name = "it-basic" + diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/java/it/basic/java/SampleJavaClass.java b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/java/it/basic/java/SampleJavaClass.java new file mode 100644 index 00000000..23b0202c --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/java/it/basic/java/SampleJavaClass.java @@ -0,0 +1,17 @@ +package it.basic.java; + +import it.basic.PublicClass; + +/** + * This class is, unlike {@link PublicClass}, written in Java + */ +@SuppressWarnings("unused") +public class SampleJavaClass { + + /** + * @return Empty instance of {@link PublicClass} + */ + public PublicClass publicDocumentedFunction() { + return new PublicClass(); + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/RootPackageClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/RootPackageClass.kt new file mode 100644 index 00000000..8ff6c750 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/RootPackageClass.kt @@ -0,0 +1,8 @@ +@file:Suppress("unused") + +/** + * A class that lives inside the root package + */ +class RootPackageClass { + val description = "I do live in the root package!" +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/basic/PublicClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/basic/PublicClass.kt new file mode 100644 index 00000000..2958948c --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/basic/PublicClass.kt @@ -0,0 +1,69 @@ +@file:Suppress("unused") + +package it.basic + +import RootPackageClass + +/** + * This class, unlike [RootPackageClass] is located in a sub-package + * + * §PUBLIC§ (marker for asserts) + */ +class PublicClass { + /** + * This function is public and documented + */ + fun publicDocumentedFunction(): String = "" + + fun publicUndocumentedFunction(): String = "" + + /** + * This function is internal and documented + */ + internal fun internalDocumentedFunction(): String = "" + + internal fun internalUndocumentedFunction(): String = "" + + /** + * This function is protected and documented + */ + protected fun protectedDocumentedFunction(): String = "" + + protected fun protectedUndocumentedFunction(): String = "" + + /** + * This function is private and documented + */ + private fun privateDocumentedFunction(): String = "" + + private fun privateUndocumentedFunction(): String = "" + + + /** + * This property is public and documented + */ + val publicDocumentedProperty: Int = 0 + + val publicUndocumentedProperty: Int = 0 + + /** + * This property internal and documented + */ + val internalDocumentedProperty: Int = 0 + + val internalUndocumentedProperty: Int = 0 + + /** + * This property is protected and documented + */ + val protectedDocumentedProperty: Int = 0 + + val protectedUndocumentedProperty: Int = 0 + + /** + * This property private and documented + */ + private val privateDocumentedProperty: Int = 0 + + private val privateUndocumentedProperty: Int = 0 +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/internal/InternalClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/internal/InternalClass.kt new file mode 100644 index 00000000..6173d239 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/internal/InternalClass.kt @@ -0,0 +1,7 @@ +package it.internal + +/** + * §INTERNAL§ (marker for asserts) + * This class is internal and should not be rendered + */ +internal class InternalClass diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/overriddenVisibility/VisiblePrivateClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/overriddenVisibility/VisiblePrivateClass.kt new file mode 100644 index 00000000..230f5e0b --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/overriddenVisibility/VisiblePrivateClass.kt @@ -0,0 +1,12 @@ +package it.overriddenVisibility + +/** + * Private classes and methods generally should not be visible, but [documentedVisibilities] + * are overriden for this specific package to include private code + * + * §PRIVATE§ (marker for asserts) + */ +private class VisiblePrivateClass { + private val privateVal: Int = 0 + private fun privateMethod() {} +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/protected/ProtectedClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/protected/ProtectedClass.kt new file mode 100644 index 00000000..ad19f1a1 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/protected/ProtectedClass.kt @@ -0,0 +1,10 @@ +package it.protected + +/** + * Protected class should be visible because it's included in documentedVisibilities + * + * §PROTECTED§ (marker for asserts) + */ +protected class ProtectedClass { + protected fun protectedFun(): String = "protected" +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt new file mode 100644 index 00000000..d8dc9cff --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt @@ -0,0 +1,7 @@ +package it.suppressedByPackage + +/** + * §SUPPRESSED§ + * This should not be rendered. + */ +class SuppressedByPackage diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt new file mode 100644 index 00000000..4dda9da4 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt @@ -0,0 +1,7 @@ +package it.suppressedByPath + +/** + * §SUPPRESSED§ + * This should not be rendered. + */ +class SuppressedByPath diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/test/kotlin/it/basic/TestClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/test/kotlin/it/basic/TestClass.kt new file mode 100644 index 00000000..3584bdef --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/test/kotlin/it/basic/TestClass.kt @@ -0,0 +1,17 @@ +package it.basic + +import kotlin.test.Test +import kotlin.test.assertTrue + +annotation class OurAnnotation + +class TestClass { + /** + * Asserts something. [PublicClass] + */ + @Test + @OurAnnotation + fun test() { + assertTrue(1 == 1) + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/template.root.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/template.root.gradle.kts new file mode 100644 index 00000000..f63c28e7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/template.root.gradle.kts @@ -0,0 +1,23 @@ +allprojects { + repositories { + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenLocal() + mavenCentral() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + content { + includeGroup("org.jetbrains.kotlinx") + } + } + } +} + +afterEvaluate { + logger.quiet("Gradle version: ${gradle.gradleVersion}") + logger.quiet("Kotlin version: ${properties["dokka_it_kotlin_version"]}") + properties["dokka_it_android_gradle_plugin_version"]?.let { androidVersion -> + logger.quiet("Android version: $androidVersion") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/template.settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/template.settings.gradle.kts new file mode 100644 index 00000000..8cb1f2d0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/template.settings.gradle.kts @@ -0,0 +1,38 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +pluginManagement { + val dokka_it_kotlin_version: String by settings + val dokka_it_android_gradle_plugin_version: String? by settings + + plugins { + id("org.jetbrains.kotlin.js") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.jvm") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.android") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.multiplatform") version dokka_it_kotlin_version + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.jetbrains.dokka") { + useModule("org.jetbrains.dokka:dokka-gradle-plugin:for-integration-tests-SNAPSHOT") + } + + if (requested.id.id == "com.android.library") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + + if (requested.id.id == "com.android.application") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + } + } + repositories { + mavenLocal() + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenCentral() + gradlePluginPortal() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/build.gradle.kts new file mode 100644 index 00000000..2337a83e --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/build.gradle.kts @@ -0,0 +1,69 @@ +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.gradle.kotlinSourceSet + +plugins { + kotlin("jvm") version "1.7.20" + id("dev.adamko.dokkatoo") version "0.0.1-SNAPSHOT" +} + +version = "1.7.20-SNAPSHOT" + +dependencies { + implementation(kotlin("stdlib")) + testImplementation(kotlin("test-junit")) +} + +dokkatoo { + moduleName.set("Basic Project") + dokkatooSourceSets.configureEach { + documentedVisibilities( + DokkaConfiguration.Visibility.PUBLIC, + DokkaConfiguration.Visibility.PROTECTED, + ) + suppressedFiles.from(file("src/main/kotlin/it/suppressedByPath")) + perPackageOption { + matchingRegex.set("it.suppressedByPackage.*") + suppress.set(true) + } + perPackageOption { + matchingRegex.set("it.overriddenVisibility.*") + documentedVisibilities.set( + setOf(DokkaConfiguration.Visibility.PRIVATE) + ) + } + sourceLink { + localDirectory.set(file("src/main")) + remoteUrl.set( + uri( + "https://github.com/Kotlin/dokka/tree/master/integration-tests/gradle/projects/it-basic/src/main" + ).toURL() + ) + } + } + dokkatooPublications.configureEach { + suppressObviousFunctions.set(true) + pluginsConfiguration.create("org.jetbrains.dokka.base.DokkaBase") { + serializationFormat.set(DokkaConfiguration.SerializationFormat.JSON) + values.set( + """ + { + "customStyleSheets": [ + "${file("./customResources/logo-styles.css").invariantSeparatorsPath}", + "${file("./customResources/custom-style-to-add.css").invariantSeparatorsPath}" + ], + "customAssets": [ + "${file("./customResources/custom-resource.svg").invariantSeparatorsPath}" + ] + } + """.trimIndent() + ) + } + suppressObviousFunctions.set(false) + } +} + +tasks.withType().configureEach { + dokkaSourceSets.configureEach { + sourceSetScope.set(":dokkaHtml") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/custom-resource.svg b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/custom-resource.svg new file mode 100644 index 00000000..1865f739 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/custom-resource.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/custom-style-to-add.css b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/custom-style-to-add.css new file mode 100644 index 00000000..408c210e --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/custom-style-to-add.css @@ -0,0 +1 @@ +/* custom stylesheet */ \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/logo-styles.css b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/logo-styles.css new file mode 100644 index 00000000..2ac57218 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/logo-styles.css @@ -0,0 +1,3 @@ +#logo { + background-image: url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg'); +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..a2872f47 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "it-basic" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/java/it/basic/java/SampleJavaClass.java b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/java/it/basic/java/SampleJavaClass.java new file mode 100644 index 00000000..23b0202c --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/java/it/basic/java/SampleJavaClass.java @@ -0,0 +1,17 @@ +package it.basic.java; + +import it.basic.PublicClass; + +/** + * This class is, unlike {@link PublicClass}, written in Java + */ +@SuppressWarnings("unused") +public class SampleJavaClass { + + /** + * @return Empty instance of {@link PublicClass} + */ + public PublicClass publicDocumentedFunction() { + return new PublicClass(); + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/RootPackageClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/RootPackageClass.kt new file mode 100644 index 00000000..8ff6c750 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/RootPackageClass.kt @@ -0,0 +1,8 @@ +@file:Suppress("unused") + +/** + * A class that lives inside the root package + */ +class RootPackageClass { + val description = "I do live in the root package!" +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/basic/PublicClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/basic/PublicClass.kt new file mode 100644 index 00000000..2958948c --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/basic/PublicClass.kt @@ -0,0 +1,69 @@ +@file:Suppress("unused") + +package it.basic + +import RootPackageClass + +/** + * This class, unlike [RootPackageClass] is located in a sub-package + * + * §PUBLIC§ (marker for asserts) + */ +class PublicClass { + /** + * This function is public and documented + */ + fun publicDocumentedFunction(): String = "" + + fun publicUndocumentedFunction(): String = "" + + /** + * This function is internal and documented + */ + internal fun internalDocumentedFunction(): String = "" + + internal fun internalUndocumentedFunction(): String = "" + + /** + * This function is protected and documented + */ + protected fun protectedDocumentedFunction(): String = "" + + protected fun protectedUndocumentedFunction(): String = "" + + /** + * This function is private and documented + */ + private fun privateDocumentedFunction(): String = "" + + private fun privateUndocumentedFunction(): String = "" + + + /** + * This property is public and documented + */ + val publicDocumentedProperty: Int = 0 + + val publicUndocumentedProperty: Int = 0 + + /** + * This property internal and documented + */ + val internalDocumentedProperty: Int = 0 + + val internalUndocumentedProperty: Int = 0 + + /** + * This property is protected and documented + */ + val protectedDocumentedProperty: Int = 0 + + val protectedUndocumentedProperty: Int = 0 + + /** + * This property private and documented + */ + private val privateDocumentedProperty: Int = 0 + + private val privateUndocumentedProperty: Int = 0 +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/internal/InternalClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/internal/InternalClass.kt new file mode 100644 index 00000000..6173d239 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/internal/InternalClass.kt @@ -0,0 +1,7 @@ +package it.internal + +/** + * §INTERNAL§ (marker for asserts) + * This class is internal and should not be rendered + */ +internal class InternalClass diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/overriddenVisibility/VisiblePrivateClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/overriddenVisibility/VisiblePrivateClass.kt new file mode 100644 index 00000000..230f5e0b --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/overriddenVisibility/VisiblePrivateClass.kt @@ -0,0 +1,12 @@ +package it.overriddenVisibility + +/** + * Private classes and methods generally should not be visible, but [documentedVisibilities] + * are overriden for this specific package to include private code + * + * §PRIVATE§ (marker for asserts) + */ +private class VisiblePrivateClass { + private val privateVal: Int = 0 + private fun privateMethod() {} +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/protected/ProtectedClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/protected/ProtectedClass.kt new file mode 100644 index 00000000..ad19f1a1 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/protected/ProtectedClass.kt @@ -0,0 +1,10 @@ +package it.protected + +/** + * Protected class should be visible because it's included in documentedVisibilities + * + * §PROTECTED§ (marker for asserts) + */ +protected class ProtectedClass { + protected fun protectedFun(): String = "protected" +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt new file mode 100644 index 00000000..d8dc9cff --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt @@ -0,0 +1,7 @@ +package it.suppressedByPackage + +/** + * §SUPPRESSED§ + * This should not be rendered. + */ +class SuppressedByPackage diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt new file mode 100644 index 00000000..4dda9da4 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt @@ -0,0 +1,7 @@ +package it.suppressedByPath + +/** + * §SUPPRESSED§ + * This should not be rendered. + */ +class SuppressedByPath diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/test/kotlin/it/basic/TestClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/test/kotlin/it/basic/TestClass.kt new file mode 100644 index 00000000..3584bdef --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/test/kotlin/it/basic/TestClass.kt @@ -0,0 +1,17 @@ +package it.basic + +import kotlin.test.Test +import kotlin.test.assertTrue + +annotation class OurAnnotation + +class TestClass { + /** + * Asserts something. [PublicClass] + */ + @Test + @OurAnnotation + fun test() { + assertTrue(1 == 1) + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/build.gradle.kts new file mode 100644 index 00000000..29b7550c --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/build.gradle.kts @@ -0,0 +1 @@ +apply(from = "../template.root.gradle.kts") diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/gradle.properties b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/gradle.properties new file mode 100644 index 00000000..fa6c65f6 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/gradle.properties @@ -0,0 +1 @@ +dokka_it_kotlin_version=1.7.20 diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/build.gradle.kts new file mode 100644 index 00000000..ab86c333 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/build.gradle.kts @@ -0,0 +1,6 @@ +plugins { + // TODO: File bug report for gradle: :moduleA:moduleB:dokkaHtml is missing kotlin gradle plugin from + // the runtime classpath during execution without this plugin in the parent project + kotlin("jvm") + id("org.jetbrains.dokka") +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/README.md b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/README.md new file mode 100644 index 00000000..f8c52880 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/README.md @@ -0,0 +1,2 @@ +# Module moduleB +Here is some description for module B diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/build.gradle.kts new file mode 100644 index 00000000..9492fdc8 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + kotlin("jvm") + id("org.jetbrains.dokka") +} + +dependencies { + implementation(kotlin("stdlib")) +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/src/main/kotlin/org/jetbrains/dokka/it/moduleB/ModuleB.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/src/main/kotlin/org/jetbrains/dokka/it/moduleB/ModuleB.kt new file mode 100644 index 00000000..430e2234 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/src/main/kotlin/org/jetbrains/dokka/it/moduleB/ModuleB.kt @@ -0,0 +1,6 @@ +package org.jetbrains.dokka.it.moduleB + +@Suppress("unused") +class ModuleB { + fun undocumentedPublicFunction() {} +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/README.md b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/README.md new file mode 100644 index 00000000..4ead5671 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/README.md @@ -0,0 +1,2 @@ +# Module moduleC +Here is some description for module C diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/build.gradle.kts new file mode 100644 index 00000000..9492fdc8 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + kotlin("jvm") + id("org.jetbrains.dokka") +} + +dependencies { + implementation(kotlin("stdlib")) +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/src/main/kotlin/org/jetbrains/dokka/it/moduleC/ModuleC.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/src/main/kotlin/org/jetbrains/dokka/it/moduleC/ModuleC.kt new file mode 100644 index 00000000..e14d68e0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/src/main/kotlin/org/jetbrains/dokka/it/moduleC/ModuleC.kt @@ -0,0 +1,6 @@ +package org.jetbrains.dokka.it.moduleC + +@Suppress("unused") +class ModuleC { + fun undocumentedPublicFunction() {} +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/settings.gradle.kts new file mode 100644 index 00000000..a5c89291 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/settings.gradle.kts @@ -0,0 +1,5 @@ +apply(from = "../template.settings.gradle.kts") +rootProject.name = "it-multimodule-0" +include(":moduleA") +include(":moduleA:moduleB") +include(":moduleA:moduleC") diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/template.root.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/template.root.gradle.kts new file mode 100644 index 00000000..f63c28e7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/template.root.gradle.kts @@ -0,0 +1,23 @@ +allprojects { + repositories { + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenLocal() + mavenCentral() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + content { + includeGroup("org.jetbrains.kotlinx") + } + } + } +} + +afterEvaluate { + logger.quiet("Gradle version: ${gradle.gradleVersion}") + logger.quiet("Kotlin version: ${properties["dokka_it_kotlin_version"]}") + properties["dokka_it_android_gradle_plugin_version"]?.let { androidVersion -> + logger.quiet("Android version: $androidVersion") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/template.settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/template.settings.gradle.kts new file mode 100644 index 00000000..8cb1f2d0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/template.settings.gradle.kts @@ -0,0 +1,38 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +pluginManagement { + val dokka_it_kotlin_version: String by settings + val dokka_it_android_gradle_plugin_version: String? by settings + + plugins { + id("org.jetbrains.kotlin.js") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.jvm") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.android") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.multiplatform") version dokka_it_kotlin_version + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.jetbrains.dokka") { + useModule("org.jetbrains.dokka:dokka-gradle-plugin:for-integration-tests-SNAPSHOT") + } + + if (requested.id.id == "com.android.library") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + + if (requested.id.id == "com.android.application") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + } + } + repositories { + mavenLocal() + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenCentral() + gradlePluginPortal() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokkatoo/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..13811d9a --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "it-collector-0" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/build.gradle.kts new file mode 100644 index 00000000..ec366c9d --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/build.gradle.kts @@ -0,0 +1,22 @@ +plugins { + id("org.jetbrains.dokka") + kotlin("js") +} + +apply(from = "../template.root.gradle.kts") + +kotlin { + js(IR) { + browser() + nodejs() + } +} + +dependencies { + implementation(kotlin("stdlib")) + implementation(npm("is-sorted", "1.0.5")) + + val reactVersion = properties["react_version"] + implementation("org.jetbrains.kotlin-wrappers:kotlin-react:$reactVersion") + implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom:$reactVersion") +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/gradle.properties b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/gradle.properties new file mode 100644 index 00000000..6df9a408 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/gradle.properties @@ -0,0 +1,2 @@ +dokka_it_kotlin_version=1.7.20 +react_version=18.1.0-pre.345 diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/settings.gradle.kts new file mode 100644 index 00000000..ac6f7867 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/settings.gradle.kts @@ -0,0 +1,5 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +apply(from = "../template.settings.gradle.kts") +rootProject.name = "it-js-ir-0" + diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/RootPackageClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/RootPackageClass.kt new file mode 100644 index 00000000..cbe6240e --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/RootPackageClass.kt @@ -0,0 +1,26 @@ +@file:Suppress("unused") + +import org.w3c.dom.url.URLSearchParams +import org.w3c.dom.HTMLAnchorElement +import react.dom.html.AnchorHTMLAttributes +import react.Props +import react.State + +/** + * A class that lives inside the root package + */ +class RootPackageClass { + val description = "I do live in the root package!" +} + +// sample method that uses classes from dom and react, should compile +fun URLSearchParams.react(props: Props, state: State) {} + +fun test(list: MutableList) = "list" + +@JsModule("is-sorted") +@JsNonModule +external fun sorted(a: Array): Boolean + +// this declaration can be used to check deserialization of dynamic type +external interface TextLinkProps: AnchorHTMLAttributes \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/basic/PublicClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/basic/PublicClass.kt new file mode 100644 index 00000000..fc4b36bd --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/basic/PublicClass.kt @@ -0,0 +1,53 @@ +@file:Suppress("unused") + +package it.basic + +import RootPackageClass + +/** + * This class, unlike [RootPackageClass] is located in a sub-package + */ +class PublicClass { + /** + * This function is public and documented + */ + fun publicDocumentedFunction(): String = "" + + fun publicUndocumentedFunction(): String = "" + + /** + * This function is internal and documented + */ + internal fun internalDocumentedFunction(): String = "" + + internal fun internalUndocumentedFunction(): String = "" + + /** + * This function is private and documented + */ + private fun privateDocumentedFunction(): String = "" + + private fun privateUndocumentedFunction(): String = "" + + + /** + * This property is public and documented + */ + val publicDocumentedProperty: Int = 0 + + val publicUndocumentedProperty: Int = 0 + + /** + * This property internal and documented + */ + val internalDocumentedProperty: Int = 0 + + val internalUndocumentedProperty: Int = 0 + + /** + * This property private and documented + */ + private val privateDocumentedProperty: Int = 0 + + private val privateUndocumentedProperty: Int = 0 +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/internal/InternalClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/internal/InternalClass.kt new file mode 100644 index 00000000..7d42b978 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/internal/InternalClass.kt @@ -0,0 +1,7 @@ +package it.internal + +/** + * §INTERNAL§ + * This class is internal and should not be rendered + */ +internal class InternalClass diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt new file mode 100644 index 00000000..d8dc9cff --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt @@ -0,0 +1,7 @@ +package it.suppressedByPackage + +/** + * §SUPPRESSED§ + * This should not be rendered. + */ +class SuppressedByPackage diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt new file mode 100644 index 00000000..4dda9da4 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt @@ -0,0 +1,7 @@ +package it.suppressedByPath + +/** + * §SUPPRESSED§ + * This should not be rendered. + */ +class SuppressedByPath diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/template.root.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/template.root.gradle.kts new file mode 100644 index 00000000..f63c28e7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/template.root.gradle.kts @@ -0,0 +1,23 @@ +allprojects { + repositories { + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenLocal() + mavenCentral() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + content { + includeGroup("org.jetbrains.kotlinx") + } + } + } +} + +afterEvaluate { + logger.quiet("Gradle version: ${gradle.gradleVersion}") + logger.quiet("Kotlin version: ${properties["dokka_it_kotlin_version"]}") + properties["dokka_it_android_gradle_plugin_version"]?.let { androidVersion -> + logger.quiet("Android version: $androidVersion") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/template.settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/template.settings.gradle.kts new file mode 100644 index 00000000..8cb1f2d0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/template.settings.gradle.kts @@ -0,0 +1,38 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +pluginManagement { + val dokka_it_kotlin_version: String by settings + val dokka_it_android_gradle_plugin_version: String? by settings + + plugins { + id("org.jetbrains.kotlin.js") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.jvm") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.android") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.multiplatform") version dokka_it_kotlin_version + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.jetbrains.dokka") { + useModule("org.jetbrains.dokka:dokka-gradle-plugin:for-integration-tests-SNAPSHOT") + } + + if (requested.id.id == "com.android.library") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + + if (requested.id.id == "com.android.application") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + } + } + repositories { + mavenLocal() + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenCentral() + gradlePluginPortal() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokkatoo/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..85b71839 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "it-js-ir-0" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/build.gradle.kts new file mode 100644 index 00000000..29b7550c --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/build.gradle.kts @@ -0,0 +1 @@ +apply(from = "../template.root.gradle.kts") diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/gradle.properties b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/gradle.properties new file mode 100644 index 00000000..fa6c65f6 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/gradle.properties @@ -0,0 +1 @@ +dokka_it_kotlin_version=1.7.20 diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/build.gradle.kts new file mode 100644 index 00000000..ab86c333 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/build.gradle.kts @@ -0,0 +1,6 @@ +plugins { + // TODO: File bug report for gradle: :moduleA:moduleB:dokkaHtml is missing kotlin gradle plugin from + // the runtime classpath during execution without this plugin in the parent project + kotlin("jvm") + id("org.jetbrains.dokka") +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/Module.md b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/Module.md new file mode 100644 index 00000000..0570f467 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/Module.md @@ -0,0 +1,6 @@ +# Module !Module B! +Here is some description for Module B + +Module B: Second paragraph +# Module moduleB +§IGNORED$This documentation shall be ignored, because wrong module name§IGNORED$ diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/build.gradle.kts new file mode 100644 index 00000000..5f0b69c7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/build.gradle.kts @@ -0,0 +1,17 @@ +import org.jetbrains.dokka.gradle.DokkaTask + +plugins { + kotlin("jvm") + id("org.jetbrains.dokka") +} + +dependencies { + implementation(kotlin("stdlib")) +} + +tasks.withType().configureEach { + moduleName.set("!Module B!") + dokkaSourceSets.configureEach { + includes.from("Module.md") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/src/main/kotlin/org/jetbrains/dokka/it/moduleB/ModuleB.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/src/main/kotlin/org/jetbrains/dokka/it/moduleB/ModuleB.kt new file mode 100644 index 00000000..430e2234 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/src/main/kotlin/org/jetbrains/dokka/it/moduleB/ModuleB.kt @@ -0,0 +1,6 @@ +package org.jetbrains.dokka.it.moduleB + +@Suppress("unused") +class ModuleB { + fun undocumentedPublicFunction() {} +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/Module.md b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/Module.md new file mode 100644 index 00000000..4ead5671 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/Module.md @@ -0,0 +1,2 @@ +# Module moduleC +Here is some description for module C diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/build.gradle.kts new file mode 100644 index 00000000..e471d375 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/build.gradle.kts @@ -0,0 +1,16 @@ +import org.jetbrains.dokka.gradle.DokkaTask + +plugins { + kotlin("jvm") + id("org.jetbrains.dokka") +} + +dependencies { + implementation(kotlin("stdlib")) +} + +tasks.withType().configureEach { + dokkaSourceSets.configureEach { + includes.from("Module.md") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/src/main/kotlin/org/jetbrains/dokka/it/moduleC/ModuleC.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/src/main/kotlin/org/jetbrains/dokka/it/moduleC/ModuleC.kt new file mode 100644 index 00000000..e14d68e0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/src/main/kotlin/org/jetbrains/dokka/it/moduleC/ModuleC.kt @@ -0,0 +1,6 @@ +package org.jetbrains.dokka.it.moduleC + +@Suppress("unused") +class ModuleC { + fun undocumentedPublicFunction() {} +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleD/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleD/build.gradle.kts new file mode 100644 index 00000000..a16e038f --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleD/build.gradle.kts @@ -0,0 +1,10 @@ +import org.jetbrains.dokka.gradle.DokkaTask + +plugins { + kotlin("jvm") + id("org.jetbrains.dokka") +} + +dependencies { + implementation(kotlin("stdlib")) +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleD/src/main/kotlin/org/jetbrains/dokka/it/moduleD/ModuleC.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleD/src/main/kotlin/org/jetbrains/dokka/it/moduleD/ModuleC.kt new file mode 100644 index 00000000..88174d53 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleD/src/main/kotlin/org/jetbrains/dokka/it/moduleD/ModuleC.kt @@ -0,0 +1,6 @@ +package org.jetbrains.dokka.it.moduleD + +@Suppress("unused") +class ModuleD { + fun undocumentedPublicFunction() {} +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/settings.gradle.kts new file mode 100644 index 00000000..dda6558f --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/settings.gradle.kts @@ -0,0 +1,6 @@ +apply(from = "../template.settings.gradle.kts") +rootProject.name = "it-multimodule-0" +include(":moduleA") +include(":moduleA:moduleB") +include(":moduleA:moduleC") +include(":moduleA:moduleD") diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/template.root.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/template.root.gradle.kts new file mode 100644 index 00000000..f63c28e7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/template.root.gradle.kts @@ -0,0 +1,23 @@ +allprojects { + repositories { + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenLocal() + mavenCentral() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + content { + includeGroup("org.jetbrains.kotlinx") + } + } + } +} + +afterEvaluate { + logger.quiet("Gradle version: ${gradle.gradleVersion}") + logger.quiet("Kotlin version: ${properties["dokka_it_kotlin_version"]}") + properties["dokka_it_android_gradle_plugin_version"]?.let { androidVersion -> + logger.quiet("Android version: $androidVersion") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/template.settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/template.settings.gradle.kts new file mode 100644 index 00000000..8cb1f2d0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/template.settings.gradle.kts @@ -0,0 +1,38 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +pluginManagement { + val dokka_it_kotlin_version: String by settings + val dokka_it_android_gradle_plugin_version: String? by settings + + plugins { + id("org.jetbrains.kotlin.js") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.jvm") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.android") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.multiplatform") version dokka_it_kotlin_version + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.jetbrains.dokka") { + useModule("org.jetbrains.dokka:dokka-gradle-plugin:for-integration-tests-SNAPSHOT") + } + + if (requested.id.id == "com.android.library") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + + if (requested.id.id == "com.android.application") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + } + } + repositories { + mavenLocal() + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenCentral() + gradlePluginPortal() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokkatoo/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..97712ae9 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "it-multimodule-0" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/build.gradle b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/build.gradle new file mode 100644 index 00000000..57d22b79 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/build.gradle @@ -0,0 +1,18 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' + id("org.jetbrains.dokka") +} + +apply from: '../template.root.gradle.kts' + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib" + implementation project(':first') + implementation project(':second') +} + + +subprojects { + apply plugin: 'org.jetbrains.kotlin.jvm' + apply plugin: 'org.jetbrains.dokka' +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/build.gradle b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/build.gradle new file mode 100644 index 00000000..e69de29b diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/FirstClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/FirstClass.kt new file mode 100644 index 00000000..93f73bf4 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/FirstClass.kt @@ -0,0 +1,11 @@ +package foo + +/** + * First class description + */ +open class FirstClass{ + /** + * PropertyOne description + */ + val propertyOne: Int = 5 +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/FirstSubclass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/FirstSubclass.kt new file mode 100644 index 00000000..0deb65c0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/FirstSubclass.kt @@ -0,0 +1,12 @@ +package foo + +/** + * Subclass description + * @property surname Surname description + */ +class FirstSubclass(var surname: String) : FirstClass() { + /** + * printNewLine description + */ + fun printNewline() = print("\r\n") +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/Main.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/Main.kt new file mode 100644 index 00000000..8c7f58a7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/Main.kt @@ -0,0 +1,8 @@ +package foo + +/** + * Main function + */ +fun main(args : Array) { + println("Hello, world!") +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/noPackage.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/noPackage.kt new file mode 100644 index 00000000..c41e218f --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/noPackage.kt @@ -0,0 +1,3 @@ +fun noPackage(): String = "Hello there" + +open class NoPackage diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/gradle.properties b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/gradle.properties new file mode 100644 index 00000000..fa6c65f6 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/gradle.properties @@ -0,0 +1 @@ +dokka_it_kotlin_version=1.7.20 diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/build.gradle b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/build.gradle new file mode 100644 index 00000000..2b62f963 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/build.gradle @@ -0,0 +1,14 @@ +dependencies { + implementation project(":first") +} +dokkaHtml { + dependsOn(":first:dokkaHtml") + dokkaSourceSets { + "main" { + externalDocumentationLink { + url.set(new URL("file://" + rootProject.rootDir.toPath().toAbsolutePath().resolve("first/build/dokka/html/"))) + packageListUrl.set(new URL("file://" + rootProject.rootDir.toPath().toAbsolutePath().resolve("first/build/dokka/html/first/package-list"))) + } + } + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/NoPackageClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/NoPackageClass.kt new file mode 100644 index 00000000..d2f30ef7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/NoPackageClass.kt @@ -0,0 +1 @@ +class NoPackageClass : NoPackage() diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/bar/SecondClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/bar/SecondClass.kt new file mode 100644 index 00000000..6a0c935e --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/bar/SecondClass.kt @@ -0,0 +1,21 @@ +package bar +/** + * Second class in second module description [foo.FirstClass] + * @author John Doe + * @version 0.1.3 + * @param name Name description text text text. +*/ +class SecondClass(val name: String) { + val firstProperty = "propertystring" + /** + * Second property in second module description [foo.FirstSubclass] + */ + var secondProperty: String = "" + set(value) { + println("Second property not set") + } + + init { + println("InitializerBlock") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/foo/ThirdClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/foo/ThirdClass.kt new file mode 100644 index 00000000..cc24a6b7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/foo/ThirdClass.kt @@ -0,0 +1,11 @@ +package foo + +/** + * Third class description + */ +open class ThirdClass{ + /** + * PropertyOne description + */ + val propertyOne: Int = 5 +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/settings.gradle.kts new file mode 100644 index 00000000..c549ccb7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/settings.gradle.kts @@ -0,0 +1,4 @@ +apply(from = "../template.settings.gradle.kts") +rootProject.name = "it-multimodule-1" +include(":first") +include(":second") diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/template.root.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/template.root.gradle.kts new file mode 100644 index 00000000..f63c28e7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/template.root.gradle.kts @@ -0,0 +1,23 @@ +allprojects { + repositories { + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenLocal() + mavenCentral() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + content { + includeGroup("org.jetbrains.kotlinx") + } + } + } +} + +afterEvaluate { + logger.quiet("Gradle version: ${gradle.gradleVersion}") + logger.quiet("Kotlin version: ${properties["dokka_it_kotlin_version"]}") + properties["dokka_it_android_gradle_plugin_version"]?.let { androidVersion -> + logger.quiet("Android version: $androidVersion") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/template.settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/template.settings.gradle.kts new file mode 100644 index 00000000..8cb1f2d0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/template.settings.gradle.kts @@ -0,0 +1,38 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +pluginManagement { + val dokka_it_kotlin_version: String by settings + val dokka_it_android_gradle_plugin_version: String? by settings + + plugins { + id("org.jetbrains.kotlin.js") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.jvm") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.android") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.multiplatform") version dokka_it_kotlin_version + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.jetbrains.dokka") { + useModule("org.jetbrains.dokka:dokka-gradle-plugin:for-integration-tests-SNAPSHOT") + } + + if (requested.id.id == "com.android.library") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + + if (requested.id.id == "com.android.application") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + } + } + repositories { + mavenLocal() + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenCentral() + gradlePluginPortal() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokkatoo/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..6ce1808e --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "it-multimodule-1" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/build.gradle b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/build.gradle new file mode 100644 index 00000000..e04e412b --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/build.gradle @@ -0,0 +1,43 @@ +import org.jetbrains.dokka.gradle.DokkaMultiModuleTask + +plugins { + id 'org.jetbrains.kotlin.jvm' + id("org.jetbrains.dokka") +} + +apply from: '../template.root.gradle.kts' + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib" + dokkaPlugin "org.jetbrains.dokka:versioning-plugin:${System.getenv("DOKKA_VERSION")}" +} + + +subprojects { + apply plugin: 'org.jetbrains.kotlin.jvm' + apply plugin: 'org.jetbrains.dokka' +} + +dokkaHtmlMultiModule { + pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.2", "olderVersionsDir": "$projectDir/dokkas" }"""]) +} + +tasks.register('dokkaHtmlMultiModuleBaseVersion', DokkaMultiModuleTask){ + dependencies { + dokkaPlugin("org.jetbrains.dokka:all-modules-page-plugin:${System.getenv("DOKKA_VERSION")}") + dokkaPlugin("org.jetbrains.dokka:versioning-plugin:${System.getenv("DOKKA_VERSION")}") + } + outputDirectory.set(file(projectDir.toPath().resolve("dokkas").resolve("1.0"))) + pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.0" }"""]) + addChildTasks([project(":first"), project(":second")], "dokkaHtmlPartial") +} + +tasks.register('dokkaHtmlMultiModuleNextVersion', DokkaMultiModuleTask){ + dependencies { + dokkaPlugin("org.jetbrains.dokka:all-modules-page-plugin:${System.getenv("DOKKA_VERSION")}") + dokkaPlugin("org.jetbrains.dokka:versioning-plugin:${System.getenv("DOKKA_VERSION")}") + } + outputDirectory.set(file(projectDir.toPath().resolve("dokkas").resolve("1.1"))) + pluginsMapConfiguration.set(["org.jetbrains.dokka.versioning.VersioningPlugin": """{ "version": "1.1", "olderVersionsDir": "$projectDir/dokkas" }"""]) + addChildTasks([project(":first"), project(":second")], "dokkaHtmlPartial") +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/first/build.gradle b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/first/build.gradle new file mode 100644 index 00000000..e69de29b diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/first/src/main/kotlin/foo/FirstClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/first/src/main/kotlin/foo/FirstClass.kt new file mode 100644 index 00000000..93f73bf4 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/first/src/main/kotlin/foo/FirstClass.kt @@ -0,0 +1,11 @@ +package foo + +/** + * First class description + */ +open class FirstClass{ + /** + * PropertyOne description + */ + val propertyOne: Int = 5 +} \ No newline at end of file diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/gradle.properties b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/gradle.properties new file mode 100644 index 00000000..731bcb72 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/gradle.properties @@ -0,0 +1,2 @@ +dokka_it_kotlin_version=1.7.20 + diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/second/build.gradle b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/second/build.gradle new file mode 100644 index 00000000..cf1d1f21 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/second/build.gradle @@ -0,0 +1,3 @@ +dependencies { + implementation project(":first") +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/second/src/main/kotlin/bar/SecondClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/second/src/main/kotlin/bar/SecondClass.kt new file mode 100644 index 00000000..6a0c935e --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/second/src/main/kotlin/bar/SecondClass.kt @@ -0,0 +1,21 @@ +package bar +/** + * Second class in second module description [foo.FirstClass] + * @author John Doe + * @version 0.1.3 + * @param name Name description text text text. +*/ +class SecondClass(val name: String) { + val firstProperty = "propertystring" + /** + * Second property in second module description [foo.FirstSubclass] + */ + var secondProperty: String = "" + set(value) { + println("Second property not set") + } + + init { + println("InitializerBlock") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/settings.gradle.kts new file mode 100644 index 00000000..123b9af3 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/settings.gradle.kts @@ -0,0 +1,4 @@ +apply(from = "../template.settings.gradle.kts") +rootProject.name = "it-multimodule-versioning-0" +include(":first") +include(":second") diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/template.root.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/template.root.gradle.kts new file mode 100644 index 00000000..f63c28e7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/template.root.gradle.kts @@ -0,0 +1,23 @@ +allprojects { + repositories { + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenLocal() + mavenCentral() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + content { + includeGroup("org.jetbrains.kotlinx") + } + } + } +} + +afterEvaluate { + logger.quiet("Gradle version: ${gradle.gradleVersion}") + logger.quiet("Kotlin version: ${properties["dokka_it_kotlin_version"]}") + properties["dokka_it_android_gradle_plugin_version"]?.let { androidVersion -> + logger.quiet("Android version: $androidVersion") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/template.settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/template.settings.gradle.kts new file mode 100644 index 00000000..8cb1f2d0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/template.settings.gradle.kts @@ -0,0 +1,38 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +pluginManagement { + val dokka_it_kotlin_version: String by settings + val dokka_it_android_gradle_plugin_version: String? by settings + + plugins { + id("org.jetbrains.kotlin.js") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.jvm") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.android") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.multiplatform") version dokka_it_kotlin_version + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.jetbrains.dokka") { + useModule("org.jetbrains.dokka:dokka-gradle-plugin:for-integration-tests-SNAPSHOT") + } + + if (requested.id.id == "com.android.library") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + + if (requested.id.id == "com.android.application") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + } + } + repositories { + mavenLocal() + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenCentral() + gradlePluginPortal() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokkatoo/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..dbd0ee03 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "it-multimodule-versioning-0" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/build.gradle.kts new file mode 100644 index 00000000..2cea2076 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/build.gradle.kts @@ -0,0 +1,42 @@ +import org.jetbrains.dokka.gradle.DokkaTask +import java.net.URL + +plugins { + kotlin("multiplatform") + id("org.jetbrains.dokka") +} + +apply(from = "../template.root.gradle.kts") + +kotlin { + jvm() + linuxX64("linux") + macosX64("macos") + js() + sourceSets { + val commonMain by sourceSets.getting + val linuxMain by sourceSets.getting + val macosMain by sourceSets.getting + val desktopMain by sourceSets.creating { + dependsOn(commonMain) + linuxMain.dependsOn(this) + macosMain.dependsOn(this) + } + named("commonMain") { + dependencies { + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9") + } + } + } +} + +tasks.withType().configureEach { + dokkaSourceSets { + configureEach { + externalDocumentationLink { + url.set(URL("https://kotlinlang.org/api/kotlinx.coroutines/")) + //packageListUrl.set(URL("https://kotlinlang.org/api/kotlinx.coroutines/package-list")) + } + } + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/gradle.properties b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/gradle.properties new file mode 100644 index 00000000..9d87e55a --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/gradle.properties @@ -0,0 +1,5 @@ +dokka_it_kotlin_version=1.7.20 +#these flags are enabled by default since 1.6.20. +#remove when this test is executed with Kotlin >= 1.6.20 +kotlin.mpp.enableGranularSourceSetsMetadata=true +kotlin.native.enableDependencyPropagation=false diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/settings.gradle.kts new file mode 100644 index 00000000..1894bed8 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/settings.gradle.kts @@ -0,0 +1,2 @@ +apply(from = "../template.settings.gradle.kts") +rootProject.name = "it-multiplatform-0" diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/CommonMainClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/CommonMainClass.kt new file mode 100644 index 00000000..499a4f1e --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/CommonMainClass.kt @@ -0,0 +1,8 @@ +package it.mpp0 + +/** + * This class is defined in commonMain + */ +class CommonMainClass { + fun publicFunction(): String = "public" +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/ExpectedClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/ExpectedClass.kt new file mode 100644 index 00000000..e610b09a --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/ExpectedClass.kt @@ -0,0 +1,5 @@ +package it.mpp0 + +expect class ExpectedClass { + val platform: String +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/coroutines.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/coroutines.kt new file mode 100644 index 00000000..8eee326f --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/coroutines.kt @@ -0,0 +1,5 @@ +package it.mpp0 + +import kotlinx.coroutines.CoroutineScope + +expect fun CoroutineScope.runBlocking(block: suspend () -> T) : T diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/desktopMain/kotlin/it/mpp0/CPointerExtension.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/desktopMain/kotlin/it/mpp0/CPointerExtension.kt new file mode 100644 index 00000000..342a749e --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/desktopMain/kotlin/it/mpp0/CPointerExtension.kt @@ -0,0 +1,11 @@ +package it.mpp0 + +import kotlinx.cinterop.CPointed +import kotlinx.cinterop.CPointer + +/** + * Will print the raw value + */ +fun CPointer.customExtension() { + println(this.rawValue) +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/desktopMain/kotlin/it/mpp0/ExpectedClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/desktopMain/kotlin/it/mpp0/ExpectedClass.kt new file mode 100644 index 00000000..19070a96 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/desktopMain/kotlin/it/mpp0/ExpectedClass.kt @@ -0,0 +1,5 @@ +package it.mpp0 + +actual class ExpectedClass { + actual val platform: String = "linux" +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jsMain/kotlin/it/mpp0/ExpectedClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jsMain/kotlin/it/mpp0/ExpectedClass.kt new file mode 100644 index 00000000..1e4a6d22 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jsMain/kotlin/it/mpp0/ExpectedClass.kt @@ -0,0 +1,5 @@ +package it.mpp0 + +actual class ExpectedClass { + actual val platform: String = "js" +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jsMain/kotlin/it/mpp0/runBlocking.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jsMain/kotlin/it/mpp0/runBlocking.kt new file mode 100644 index 00000000..03b3b0ea --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jsMain/kotlin/it/mpp0/runBlocking.kt @@ -0,0 +1,7 @@ +package it.mpp0 + +import kotlinx.coroutines.CoroutineScope + +actual fun CoroutineScope.runBlocking(block: suspend () -> T): T { + TODO("Not yet implemented") +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/ExpectedClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/ExpectedClass.kt new file mode 100644 index 00000000..6de30de6 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/ExpectedClass.kt @@ -0,0 +1,11 @@ +package it.mpp0 + +actual class ExpectedClass { + actual val platform: String = "jvm" + + /** + * This function can only be used by JVM consumers + */ + fun jvmOnlyFunction() = Unit + +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt new file mode 100644 index 00000000..21101a89 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt @@ -0,0 +1,13 @@ +@file:Suppress("unused") + +package it.mpp0 + +/** + * This class can only be used by JVM consumers + */ +class JvmOnlyClass { + /** + * This function can only be used by JVM consumers + */ + fun myJvm() = println("HI") +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/runBlocking.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/runBlocking.kt new file mode 100644 index 00000000..03b3b0ea --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/runBlocking.kt @@ -0,0 +1,7 @@ +package it.mpp0 + +import kotlinx.coroutines.CoroutineScope + +actual fun CoroutineScope.runBlocking(block: suspend () -> T): T { + TODO("Not yet implemented") +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/CPointerExtension.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/CPointerExtension.kt new file mode 100644 index 00000000..342a749e --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/CPointerExtension.kt @@ -0,0 +1,11 @@ +package it.mpp0 + +import kotlinx.cinterop.CPointed +import kotlinx.cinterop.CPointer + +/** + * Will print the raw value + */ +fun CPointer.customExtension() { + println(this.rawValue) +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/ExpectedClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/ExpectedClass.kt new file mode 100644 index 00000000..19070a96 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/ExpectedClass.kt @@ -0,0 +1,5 @@ +package it.mpp0 + +actual class ExpectedClass { + actual val platform: String = "linux" +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/runBlocking.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/runBlocking.kt new file mode 100644 index 00000000..b56fb80a --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/runBlocking.kt @@ -0,0 +1,13 @@ +package it.mpp0 + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.async + +actual fun CoroutineScope.runBlocking(block: suspend () -> T): T { + TODO("Not yet implemented") +} + +fun CoroutineScope.customAsync(block: suspend () -> T): Deferred { + return async { block() } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/macosMain/kotlin/it/mpp0/ExpectedClass.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/macosMain/kotlin/it/mpp0/ExpectedClass.kt new file mode 100644 index 00000000..7a4a8f75 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/macosMain/kotlin/it/mpp0/ExpectedClass.kt @@ -0,0 +1,5 @@ +package it.mpp0 + +actual class ExpectedClass { + actual val platform: String = "macos" +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/macosMain/kotlin/it/mpp0/runBlocking.kt b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/macosMain/kotlin/it/mpp0/runBlocking.kt new file mode 100644 index 00000000..03b3b0ea --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/macosMain/kotlin/it/mpp0/runBlocking.kt @@ -0,0 +1,7 @@ +package it.mpp0 + +import kotlinx.coroutines.CoroutineScope + +actual fun CoroutineScope.runBlocking(block: suspend () -> T): T { + TODO("Not yet implemented") +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/template.root.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/template.root.gradle.kts new file mode 100644 index 00000000..f63c28e7 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/template.root.gradle.kts @@ -0,0 +1,23 @@ +allprojects { + repositories { + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenLocal() + mavenCentral() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + content { + includeGroup("org.jetbrains.kotlinx") + } + } + } +} + +afterEvaluate { + logger.quiet("Gradle version: ${gradle.gradleVersion}") + logger.quiet("Kotlin version: ${properties["dokka_it_kotlin_version"]}") + properties["dokka_it_android_gradle_plugin_version"]?.let { androidVersion -> + logger.quiet("Android version: $androidVersion") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/template.settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/template.settings.gradle.kts new file mode 100644 index 00000000..8cb1f2d0 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/template.settings.gradle.kts @@ -0,0 +1,38 @@ +@file:Suppress("LocalVariableName", "UnstableApiUsage") + +pluginManagement { + val dokka_it_kotlin_version: String by settings + val dokka_it_android_gradle_plugin_version: String? by settings + + plugins { + id("org.jetbrains.kotlin.js") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.jvm") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.android") version dokka_it_kotlin_version + id("org.jetbrains.kotlin.multiplatform") version dokka_it_kotlin_version + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "org.jetbrains.dokka") { + useModule("org.jetbrains.dokka:dokka-gradle-plugin:for-integration-tests-SNAPSHOT") + } + + if (requested.id.id == "com.android.library") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + + if (requested.id.id == "com.android.application") { + useModule("com.android.tools.build:gradle:$dokka_it_android_gradle_plugin_version") + } + } + } + repositories { + mavenLocal() + maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com") + mavenCentral() + gradlePluginPortal() + google() + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-eap") + maven("https://cache-redirector.jetbrains.com/dl.bintray.com/kotlin/kotlin-dev") + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokkatoo/settings.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokkatoo/settings.gradle.kts new file mode 100644 index 00000000..3e4d074a --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokkatoo/settings.gradle.kts @@ -0,0 +1,17 @@ +rootProject.name = "it-multiplatform-0" + +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + repositories { + mavenCentral() + maven(providers.gradleProperty("testMavenRepo")) + } +} diff --git a/modules/dokkatoo-plugin-integration-tests/src/testExamples/kotlin/GradleExampleTest.kt b/modules/dokkatoo-plugin-integration-tests/src/testExamples/kotlin/GradleExampleTest.kt new file mode 100644 index 00000000..85d4ead3 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/src/testExamples/kotlin/GradleExampleTest.kt @@ -0,0 +1,149 @@ +package dev.adamko.dokkatoo.tests.examples + +import dev.adamko.dokkatoo.utils.* +import dev.adamko.dokkatoo.utils.GradleProjectTest.Companion.projectTestTempDir +import io.kotest.assertions.withClue +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.file.shouldHaveSameStructureAndContentAs +import io.kotest.matchers.file.shouldHaveSameStructureAs +import io.kotest.matchers.should +import io.kotest.matchers.shouldBe +import io.kotest.matchers.string.shouldContain +import io.kotest.matchers.string.shouldNotContain +import java.io.File +import kotlin.text.Regex.Companion.escapeReplacement + +class GradleExampleTest : FunSpec({ + + val dokkaProject = initDokkaProject( + projectTestTempDir.resolve("it/examples/gradle-example/dokka").toFile() + ) + + val dokkatooProject = initDokkatooProject( + projectTestTempDir.resolve("it/examples/gradle-example/dokkatoo").toFile() + ) + + context("compare dokka and dokkatoo HTML generators") { + test("expect dokka can generate HTML") { + val dokkaBuild = dokkaProject.runner + .withArguments( + "clean", + "dokkaHtml", + "--stacktrace", + "--info", + ) + .forwardOutput() + .build() + + dokkaBuild.output shouldContain "BUILD SUCCESSFUL" + dokkaBuild.output shouldContain "Generation completed successfully" + } + + test("expect dokkatoo can generate HTML") { + val dokkatooBuild = dokkatooProject.runner + .withArguments( + "clean", + ":dokkatooGeneratePublicationHtml", + "--stacktrace", + "--info", + ) + .forwardOutput() + .build() + + dokkatooBuild.output shouldContain "BUILD SUCCESSFUL" + dokkatooBuild.output shouldContain "Generation completed successfully" + } + + context("expect dokka and dokkatoo HTML is the same") { + val dokkaHtmlDir = dokkaProject.projectDir.resolve("build/dokka/html") + val dokkatooHtmlDir = dokkatooProject.projectDir.resolve("build/dokka/html") + + test("expect file trees are the same") { + val expectedFileTree = dokkaHtmlDir.toTreeString() + val actualFileTree = dokkatooHtmlDir.toTreeString() + println((actualFileTree to expectedFileTree).sideBySide()) + expectedFileTree shouldBe actualFileTree + } + + test("expect directories are the same") { + dokkatooHtmlDir.toFile().shouldHaveSameStructureAs(dokkaHtmlDir.toFile()) + dokkatooHtmlDir.toFile().shouldHaveSameStructureAndContentAs(dokkaHtmlDir.toFile()) + } + } + } + context("Gradle caching") { + test("expect Dokkatoo is compatible with Gradle Build Cache") { + val dokkatooBuild = dokkatooProject.runner + .withArguments( + "clean", + ":dokkatooGeneratePublicationHtml", + "--info", + "--stacktrace", + ) + .forwardOutput() + .build() + + dokkatooBuild.output shouldContain "BUILD SUCCESSFUL" + dokkatooBuild.output shouldContain "Generation completed successfully" + + dokkatooProject.runner.withArguments( + ":dokkatooGeneratePublicationHtml", + "--stacktrace", + "--info", + "--build-cache", + ).forwardOutput() + .build().should { dokkatooBuildCache -> + + dokkatooBuildCache.output shouldContainAll listOf( + "> Task :prepareDokkatooParametersHtml UP-TO-DATE", + "> Task :dokkatooGeneratePublicationHtml UP-TO-DATE", + "BUILD SUCCESSFUL", + "2 actionable tasks: 2 up-to-date", + ) + withClue("Dokka Generator should not be triggered, so check it doesn't log anything") { + dokkatooBuildCache.output shouldNotContain "Generation completed successfully" + } + } + } + + xtest("expect Dokkatoo is compatible with Gradle Configuration Cache") { + val dokkatooBuild = dokkatooProject.runner + .withArguments( + "clean", + ":dokkatooGeneratePublicationHtml", + "--stacktrace", + "--info", + "--no-build-cache", + "--configuration-cache", + ) + .forwardOutput() + .build() + + dokkatooBuild.output shouldContain "BUILD SUCCESSFUL" + } + } +}) + + +private fun initDokkaProject( + destinationDir: File, +): GradleProjectTest { + return GradleProjectTest(destinationDir.toPath()).apply { + copyExampleProject("gradle-example/dokka") + + val dokkaVersion = "1.7.20" + buildGradleKts = buildGradleKts + .replace( + Regex("""id\("org\.jetbrains\.dokka"\) version \("[\d.]+"\)"""), + escapeReplacement("""id("org.jetbrains.dokka") version "$dokkaVersion""""), + ) + } +} + +private fun initDokkatooProject( + destinationDir: File, +): GradleProjectTest { + return GradleProjectTest(destinationDir.toPath()).apply { + copyExampleProject("gradle-example/dokkatoo") + } +} diff --git a/modules/dokkatoo-plugin/src/testIntegration/kotlin/examples/DokkaMultimoduleExampleTest.kt b/modules/dokkatoo-plugin-integration-tests/src/testExamples/kotlin/MultimoduleExampleTest.kt similarity index 64% rename from modules/dokkatoo-plugin/src/testIntegration/kotlin/examples/DokkaMultimoduleExampleTest.kt rename to modules/dokkatoo-plugin-integration-tests/src/testExamples/kotlin/MultimoduleExampleTest.kt index 5a72b496..c04108cd 100644 --- a/modules/dokkatoo-plugin/src/testIntegration/kotlin/examples/DokkaMultimoduleExampleTest.kt +++ b/modules/dokkatoo-plugin-integration-tests/src/testExamples/kotlin/MultimoduleExampleTest.kt @@ -1,7 +1,6 @@ -package dev.adamko.dokkatoo.it.examples +package dev.adamko.dokkatoo.tests.examples import dev.adamko.dokkatoo.utils.* -import dev.adamko.dokkatoo.utils.GradleProjectTest.Companion.dokkaSrcExampleProjectsDir import dev.adamko.dokkatoo.utils.GradleProjectTest.Companion.projectTestTempDir import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec @@ -14,14 +13,14 @@ import io.kotest.matchers.string.shouldNotContain import java.io.File import kotlin.text.Regex.Companion.escapeReplacement -class DokkaMultimoduleExampleTest : FunSpec({ +class MultimoduleExampleTest : FunSpec({ val dokkaProject = initDokkaProject( - projectTestTempDir.resolve("it/examples/dokka-multimodule-example").toFile() + projectTestTempDir.resolve("it/examples/multimodule-example/dokka").toFile() ) val dokkatooProject = initDokkatooProject( - projectTestTempDir.resolve("it/examples/dokkatoo-multimodule-example").toFile() + projectTestTempDir.resolve("it/examples/multimodule-example/dokkatoo").toFile() ) context("compare dokka and dokkatoo HTML generators") { @@ -126,19 +125,11 @@ class DokkaMultimoduleExampleTest : FunSpec({ } }) - -private fun GradleProjectTest.copyExampleProject() { - dokkaSrcExampleProjectsDir - .resolve("dokka-multimodule-example") - .toFile() - .copyRecursively(projectDir.toFile(), overwrite = true) { _, _ -> OnErrorAction.SKIP } -} - private fun initDokkaProject( destinationDir: File, ): GradleProjectTest { return GradleProjectTest(destinationDir.toPath()).apply { - copyExampleProject() + copyExampleProject("multimodule-example/dokka") val dokkaVersion = "1.7.20" settingsGradleKts = settingsGradleKts @@ -201,100 +192,6 @@ private fun initDokkatooProject( destinationDir: File, ): GradleProjectTest { return GradleProjectTest(destinationDir.toPath()).apply { - copyExampleProject() - - settingsGradleKts = """ - |rootProject.name = "dokkatoo-multimodule-example" - | - |pluginManagement { - | plugins { - | kotlin("jvm") version "1.7.20" - | } - | repositories { - | gradlePluginPortal() - | mavenCentral() - | maven(file("$testMavenRepoRelativePath")) - | } - |} - | - |@Suppress("UnstableApiUsage") - |dependencyResolutionManagement { - | repositories { - | mavenCentral() - | maven(file("$testMavenRepoRelativePath")) - | } - |} - | - |include(":parentProject") - |include(":parentProject:childProjectA") - |include(":parentProject:childProjectB") - | - """.trimMargin() - - - file("build.gradle.kts").toFile().delete() - - dir("parentProject") { - - buildGradleKts = """ - |plugins { - | kotlin("jvm") version "1.7.20" apply false - | id("dev.adamko.dokkatoo") version "0.0.1-SNAPSHOT" - |} - | - |dependencies { - | dokkatoo(project(":parentProject:childProjectA")) - | dokkatoo(project(":parentProject:childProjectB")) - | dokkatooPluginHtml("org.jetbrains.dokka:all-modules-page-plugin:1.7.20") - | dokkatooPluginHtml("org.jetbrains.dokka:templating-plugin:1.7.20") - |} - | - """.trimMargin() - - dir("childProjectA") { - buildGradleKts = """ - |plugins { - | kotlin("jvm") - | id("dev.adamko.dokkatoo") version "0.0.1-SNAPSHOT" - |} - | - |dokkatoo { - | dokkatooSourceSets.configureEach { - | includes.from("Module.md") - | } - | modulePath.set("childProjectA") // match the original dokka default - |} - | - |tasks.withType().configureEach { - | dokkaSourceSets.configureEach { - | sourceSetScope.set(":parentProject:childProjectA:dokkaHtmlPartial") - | } - |} - | - """.trimMargin() - } - dir("childProjectB") { - buildGradleKts = """ - |plugins { - | kotlin("jvm") - | id("dev.adamko.dokkatoo") version "0.0.1-SNAPSHOT" - |} - | - |dokkatoo { - | dokkatooSourceSets.configureEach { - | includes.from("Module.md") - | } - | modulePath.set("childProjectB") // match the original dokka default - |} - | - |tasks.withType().configureEach { - | dokkaSourceSets.configureEach { - | sourceSetScope.set(":parentProject:childProjectB:dokkaHtmlPartial") - | } - |} - | - """.trimMargin() - } - } + copyExampleProject("multimodule-example/dokkatoo") } } diff --git a/modules/dokkatoo-plugin-integration-tests/src/testFixtures/kotlin/templateProjectUtils.kt b/modules/dokkatoo-plugin-integration-tests/src/testFixtures/kotlin/templateProjectUtils.kt new file mode 100644 index 00000000..9b9a3a73 --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/src/testFixtures/kotlin/templateProjectUtils.kt @@ -0,0 +1,17 @@ +package dev.adamko.dokkatoo.utils + + +fun GradleProjectTest.copyExampleProject(path: String) { + GradleProjectTest.exampleProjectsDir + .resolve(path) + .toFile() + .copyRecursively(projectDir.toFile(), overwrite = true) { _, _ -> OnErrorAction.SKIP } +} + + +fun GradleProjectTest.copyIntegrationTestProject(path: String) { + GradleProjectTest.integrationTestProjectsDir + .resolve(path) + .toFile() + .copyRecursively(projectDir.toFile(), overwrite = true) { _, _ -> OnErrorAction.SKIP } +} diff --git a/modules/dokkatoo-plugin-integration-tests/src/testIntegration/kotlin/BasicProjectIntegrationTest.kt b/modules/dokkatoo-plugin-integration-tests/src/testIntegration/kotlin/BasicProjectIntegrationTest.kt new file mode 100644 index 00000000..e77e9fac --- /dev/null +++ b/modules/dokkatoo-plugin-integration-tests/src/testIntegration/kotlin/BasicProjectIntegrationTest.kt @@ -0,0 +1,155 @@ +package dev.adamko.dokkatoo.tests.integration + +import dev.adamko.dokkatoo.utils.* +import dev.adamko.dokkatoo.utils.GradleProjectTest.Companion.integrationTestProjectsDir +import dev.adamko.dokkatoo.utils.GradleProjectTest.Companion.projectTestTempDir +import io.kotest.assertions.withClue +import io.kotest.matchers.file.shouldHaveSameStructureAndContentAs +import io.kotest.matchers.file.shouldHaveSameStructureAs +import io.kotest.matchers.should +import io.kotest.matchers.shouldBe +import io.kotest.matchers.string.shouldContain +import io.kotest.matchers.string.shouldNotContain +import java.io.File +import org.junit.jupiter.api.Test + +/** + * Integration test for the `it-basic` project in Dokka + * + * Runs Dokka & Dokkatoo, and compares the resulting HTML site. + */ +class BasicProjectIntegrationTest { + + @Test + fun `test basic project`() { + + val basicProjectSrcDir = integrationTestProjectsDir.resolve("it-basic/dokka") + + val tempDir = projectTestTempDir.resolve("it/it-basic").toFile() + + val dokkaDir = tempDir.resolve("dokka") + basicProjectSrcDir.toFile().copyRecursively(dokkaDir, overwrite = true) { _, _ -> OnErrorAction.SKIP } + + val dokkaProject = initDokkaProject(dokkaDir) + + val dokkaBuild = dokkaProject.runner + .withArguments( + "clean", + "dokkaHtml", + "--stacktrace", + "--info", + ) + .forwardOutput() + .withEnvironment( + "DOKKA_VERSION" to "1.7.20", + ) + .build() + + dokkaBuild.output shouldContain "BUILD SUCCESSFUL" + dokkaBuild.output shouldContain "Generation completed successfully" + + val dokkatooDir = tempDir.resolve("dokkatoo") + + val dokkatooProject = initDokkatooProject(dokkatooDir) + + val dokkatooBuild = dokkatooProject.runner + .withArguments( + "clean", + "dokkatooGeneratePublicationHtml", + "--stacktrace", + "--info", + ) + .forwardOutput() + .build() + + dokkatooBuild.output shouldContain "BUILD SUCCESSFUL" + dokkatooBuild.output shouldContain "Generation completed successfully" + + val dokkaHtmlDir = dokkaProject.projectDir.resolve("build/dokka/html") + val dokkatooHtmlDir = dokkatooProject.projectDir.resolve("build/dokka/html") + + val expectedFileTree = dokkaHtmlDir.toTreeString() + val actualFileTree = dokkatooHtmlDir.toTreeString() + println((actualFileTree to expectedFileTree).sideBySide()) + expectedFileTree shouldBe actualFileTree + + dokkatooHtmlDir.toFile().shouldHaveSameStructureAs(dokkaHtmlDir.toFile()) + dokkatooHtmlDir.toFile().shouldHaveSameStructureAndContentAs(dokkaHtmlDir.toFile()) + + withClue("Dokkatoo tasks should be cacheable") { + dokkatooProject.runner.withArguments( + "dokkatooGeneratePublicationHtml", + "--stacktrace", + "--info", + "--build-cache", + ).forwardOutput() + .build().should { buildResult -> + buildResult.output shouldContainAll listOf( + "Task :prepareDokkatooParametersHtml UP-TO-DATE", + "Task :dokkatooGeneratePublicationHtml UP-TO-DATE", + ) + withClue("Dokka Generator should not be triggered, so check it doesn't log anything") { + buildResult.output shouldNotContain "Generation completed successfully" + } + } + } + + // TODO test configuration cache +// withClue("Dokkatoo tasks should be configuration-cache compatible") { +// val dokkatooBuildCache = +// dokkatooProject.runner.withArguments( +// "clean", +// "dokkatooGenerate", +// "--stacktrace", +// "--info", +// "--no-build-cache", +// "--configuration-cache", +// ).forwardOutput() +// .build() +// +// dokkatooBuildCache.output.shouldContainAll( +// "Task :prepareDokkatooParametersHtml UP-TO-DATE", +// "Task :dokkatooGeneratePublicationHtml UP-TO-DATE", +// ) +// } + } +} + + +private fun initDokkaProject( + destinationDir: File, +): GradleProjectTest { + return GradleProjectTest(destinationDir.toPath()).apply { + copyIntegrationTestProject("it-basic/dokka") + + buildGradleKts = buildGradleKts + .replace( + // no idea why this needs to be changed + """file("../customResources/""", + """file("./customResources/""", + ) + + // update relative paths to the template files - they're now in the same directory + settingsGradleKts = settingsGradleKts + .replace( + """../template.settings.gradle.kts""", + """./template.settings.gradle.kts""", + ) + buildGradleKts = buildGradleKts + .replace( + """../template.root.gradle.kts""", + """./template.root.gradle.kts""", + ) + var templateGradleSettings: String by projectFile("template.settings.gradle.kts") + templateGradleSettings = templateGradleSettings + .replace("for-integration-tests-SNAPSHOT", "1.7.20") + } +} + +private fun initDokkatooProject( + destinationDir: File, +): GradleProjectTest { + return GradleProjectTest(destinationDir.toPath()).apply { + copyIntegrationTestProject("it-basic/dokkatoo") + } +} diff --git a/modules/dokkatoo-plugin/src/testIntegration/resources/it/example/dokka-multi-module/childProjectA.json b/modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/childProjectA.json similarity index 100% rename from modules/dokkatoo-plugin/src/testIntegration/resources/it/example/dokka-multi-module/childProjectA.json rename to modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/childProjectA.json diff --git a/modules/dokkatoo-plugin/src/testIntegration/resources/it/example/dokka-multi-module/childProjectB.json b/modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/childProjectB.json similarity index 100% rename from modules/dokkatoo-plugin/src/testIntegration/resources/it/example/dokka-multi-module/childProjectB.json rename to modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/childProjectB.json diff --git a/modules/dokkatoo-plugin/src/testIntegration/resources/it/example/dokka-multi-module/parentProject.json b/modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/parentProject.json similarity index 100% rename from modules/dokkatoo-plugin/src/testIntegration/resources/it/example/dokka-multi-module/parentProject.json rename to modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/parentProject.json diff --git a/modules/dokkatoo-plugin/src/testIntegration/resources/it/example/dokka-multi-module/readme.md b/modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/readme.md similarity index 100% rename from modules/dokkatoo-plugin/src/testIntegration/resources/it/example/dokka-multi-module/readme.md rename to modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/readme.md diff --git a/modules/dokkatoo-plugin/build.gradle.kts b/modules/dokkatoo-plugin/build.gradle.kts index b2cd1e78..c061c79a 100644 --- a/modules/dokkatoo-plugin/build.gradle.kts +++ b/modules/dokkatoo-plugin/build.gradle.kts @@ -36,7 +36,7 @@ dependencies { val jacksonVersion = "2.12.7" testFixturesImplementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion") - kotlinDokkaSource(projects.externals) +// kotlinDokkaSource(projects.externals) // don't define test dependencies here, instead define them in the testing.suites {} configuration below } @@ -167,17 +167,17 @@ testing.suites { testTask.configure { shouldRunAfter(test, testFunctional) - dependsOn(project.configurations.kotlinDokkaSource) - - inputs.property("dokkaSourceDir", - project.configurations.kotlinDokkaSource.map { dokkaSrcConf -> - val files = dokkaSrcConf.incoming.artifactView { lenient(true) }.files - files.singleOrNull()?.absolutePath - ?: error("could not get Dokka source code directory from kotlinDokkaSource configuration. Got ${files.count()} files: $files") - } - ) - - systemProperty("dokkaSourceDir", inputs.properties["dokkaSourceDir"]!!) +// dependsOn(project.configurations.kotlinDokkaSource) + +// inputs.property("dokkaSourceDir", +// project.configurations.kotlinDokkaSource.map { dokkaSrcConf -> +// val files = dokkaSrcConf.incoming.artifactView { lenient(true) }.files +// files.singleOrNull()?.absolutePath +// ?: error("could not get Dokka source code directory from kotlinDokkaSource configuration. Got ${files.count()} files: $files") +// } +// ) +// +// systemProperty("dokkaSourceDir", inputs.properties["dokkaSourceDir"]!!) } } } diff --git a/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt b/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt index 5b44442a..81fe8313 100644 --- a/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt +++ b/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt @@ -92,7 +92,11 @@ abstract class DokkatooBasePlugin @Inject constructor( target.tasks.withType().configureEach { cacheDirectory.convention(dokkatooExtension.dokkatooCacheDirectory) - enableWorkerDebug.convention(false) + workerDebugEnabled.convention(false) + // increase memory - DokkaGenerator is hungry https://github.com/Kotlin/dokka/issues/1405 + workerMinHeapSize.convention("256m") + workerMaxHeapSize.convention("1g") + workerJvmArgs.set(listOf("-XX:MaxMetaspaceSize=512m")) } target.tasks.withType().all task@{ @@ -111,7 +115,6 @@ abstract class DokkatooBasePlugin @Inject constructor( moduleVersion.convention(providers.provider { project.version.toString() }) modulePath.convention(project.pathAsFilePath()) - dokkatooCacheDirectory.convention(null) sourceSetScopeDefault.convention(project.path) dokkatooPublicationDirectory.convention(layout.buildDirectory.dir("dokka")) dokkatooModuleDirectory.convention(layout.buildDirectory.dir("dokka-module")) diff --git a/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaSourceLinkGradleBuilder.kt b/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaSourceLinkGradleBuilder.kt index 784cdb87..c46b64da 100644 --- a/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaSourceLinkGradleBuilder.kt +++ b/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaSourceLinkGradleBuilder.kt @@ -68,6 +68,20 @@ abstract class DokkaSourceLinkGradleBuilder : @get:Input abstract val remoteUrl: Property + /** + * Set the value of [remoteUrl]. + * + * @param[value] will be converted to a [URL] + */ + fun remoteUrl(value: String) = remoteUrl.set(URL(value)) + + /** + * Set the value of [remoteUrl]. + * + * @param[value] will be converted to a [URL] + */ + fun remoteUrl(value: Provider) = remoteUrl.set(value.map(::URL)) + /** * Suffix used to append source code line number to the URL. This will help readers navigate * not only to the file, but to the specific line number of the declaration. diff --git a/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooGenerateTask.kt b/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooGenerateTask.kt index c71de9c0..7288b301 100644 --- a/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooGenerateTask.kt +++ b/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooGenerateTask.kt @@ -9,11 +9,13 @@ import kotlinx.serialization.json.decodeFromStream import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property import org.gradle.api.tasks.* import org.gradle.api.tasks.PathSensitivity.NAME_ONLY import org.gradle.api.tasks.PathSensitivity.RELATIVE import org.gradle.kotlin.dsl.submit +import org.gradle.process.JavaForkOptions import org.gradle.workers.WorkerExecutor /** @@ -55,9 +57,18 @@ abstract class DokkatooGenerateTask @Inject constructor( @get:PathSensitive(RELATIVE) abstract val dokkaModuleFiles: ConfigurableFileCollection + /** @see JavaForkOptions.getDebug */ @get:Input - @get:Optional - abstract val enableWorkerDebug: Property + abstract val workerDebugEnabled: Property + /** @see JavaForkOptions.getMinHeapSize */ + @get:Input + abstract val workerMinHeapSize: Property + /** @see JavaForkOptions.getMaxHeapSize */ + @get:Input + abstract val workerMaxHeapSize: Property + /** @see JavaForkOptions.jvmArgs */ + @get:Input + abstract val workerJvmArgs: ListProperty enum class GenerationType { MODULE, @@ -68,8 +79,7 @@ abstract class DokkatooGenerateTask @Inject constructor( @OptIn(ExperimentalSerializationApi::class) // jsonMapper.decodeFromStream fun generateDocumentation() { val dokkaParametersJsonFile = dokkaParametersJson.get().asFile - val generationType = - generationType.orNull ?: error("GenerationType is required, but no value was provided") + val generationType: GenerationType = generationType.get() val dokkaParameters = jsonMapper.decodeFromStream( DokkaParametersKxs.serializer(), @@ -95,7 +105,11 @@ abstract class DokkatooGenerateTask @Inject constructor( classpath.from(runtimeClasspath) forkOptions { defaultCharacterEncoding = "UTF-8" - debug = enableWorkerDebug.getOrElse(false) + minHeapSize = workerMinHeapSize.get() + maxHeapSize = workerMinHeapSize.get() + enableAssertions = true + debug = workerDebugEnabled.get() + jvmArgs = workerJvmArgs.get() } } diff --git a/modules/dokkatoo-plugin/src/testFixtures/kotlin/GradleTestKitUtils.kt b/modules/dokkatoo-plugin/src/testFixtures/kotlin/GradleTestKitUtils.kt index be2bd799..191f985b 100644 --- a/modules/dokkatoo-plugin/src/testFixtures/kotlin/GradleTestKitUtils.kt +++ b/modules/dokkatoo-plugin/src/testFixtures/kotlin/GradleTestKitUtils.kt @@ -17,12 +17,11 @@ import org.intellij.lang.annotations.Language class GradleProjectTest( override val projectDir: Path, ) : ProjectDirectoryScope { + constructor( testProjectName: String, baseDir: Path = funcTestTempDir, - ) : this( - projectDir = baseDir.resolve(testProjectName), - ) + ) : this(projectDir = baseDir.resolve(testProjectName)) val runner: GradleRunner = GradleRunner.create().withProjectDir(projectDir.toFile()) @@ -44,13 +43,9 @@ class GradleProjectTest( private val dokkaSourceDir: Path by systemProperty(Paths::get) /** Dokka Source directory that contains Gradle projects used for integration tests */ - val dokkaSrcIntegrationTestProjectsDir: Path by lazy { - dokkaSourceDir.resolve("integration-tests/gradle/projects") - } + val integrationTestProjectsDir: Path by systemProperty(Paths::get) /** Dokka Source directory that contains example Gradle projects */ - val dokkaSrcExampleProjectsDir: Path by lazy { - dokkaSourceDir.resolve("examples/gradle") - } + val exampleProjectsDir: Path by systemProperty(Paths::get) private fun systemProperty( convert: (String) -> T, @@ -64,17 +59,17 @@ class GradleProjectTest( } -/** - * Load a project from the [GradleProjectTest.dokkaSrcIntegrationTestProjectsDir] - */ -fun gradleKtsProjectIntegrationTest( - testProjectName: String, - build: GradleProjectTest.() -> Unit, -): GradleProjectTest = - GradleProjectTest( - baseDir = GradleProjectTest.dokkaSrcIntegrationTestProjectsDir, - testProjectName = testProjectName, - ).apply(build) +///** +// * Load a project from the [GradleProjectTest.dokkaSrcIntegrationTestProjectsDir] +// */ +//fun gradleKtsProjectIntegrationTest( +// testProjectName: String, +// build: GradleProjectTest.() -> Unit, +//): GradleProjectTest = +// GradleProjectTest( +// baseDir = GradleProjectTest.dokkaSrcIntegrationTestProjectsDir, +// testProjectName = testProjectName, +// ).apply(build) /** diff --git a/modules/dokkatoo-plugin/src/testIntegration/kotlin/BasicProjectIntegrationTest.kt b/modules/dokkatoo-plugin/src/testIntegration/kotlin/BasicProjectIntegrationTest.kt deleted file mode 100644 index efaa3a39..00000000 --- a/modules/dokkatoo-plugin/src/testIntegration/kotlin/BasicProjectIntegrationTest.kt +++ /dev/null @@ -1,367 +0,0 @@ -package dev.adamko.dokkatoo.it - -import dev.adamko.dokkatoo.utils.* -import dev.adamko.dokkatoo.utils.GradleProjectTest.Companion.dokkaSrcIntegrationTestProjectsDir -import dev.adamko.dokkatoo.utils.GradleProjectTest.Companion.projectTestTempDir -import io.kotest.assertions.withClue -import io.kotest.matchers.file.shouldHaveSameStructureAndContentAs -import io.kotest.matchers.file.shouldHaveSameStructureAs -import io.kotest.matchers.should -import io.kotest.matchers.shouldBe -import io.kotest.matchers.string.shouldContain -import io.kotest.matchers.string.shouldNotContain -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.DokkaConfigurationImpl -import org.junit.jupiter.api.Test - -/** - * Integration test for the `it-basic` project in Dokka - * - * Runs Dokka & Dokkatoo, and compares the resulting HTML site. - */ -class BasicProjectIntegrationTest { - - @Test - fun `test basic project`() { - - val basicProjectSrcDir = - dokkaSrcIntegrationTestProjectsDir.resolve("it-basic").toFile() - val templateRootGradleKts = - dokkaSrcIntegrationTestProjectsDir.resolve("template.root.gradle.kts").toFile() - val templateSettingsGradleKts = - dokkaSrcIntegrationTestProjectsDir.resolve("template.settings.gradle.kts").toFile() - - val tempDir = projectTestTempDir.resolve("it/it-basic").toFile() - - val dokkaDir = tempDir.resolve("dokka") - basicProjectSrcDir.copyRecursively(dokkaDir, overwrite = true) { _, _ -> OnErrorAction.SKIP } - templateRootGradleKts.copyInto(directory = dokkaDir, overwrite = true) - templateSettingsGradleKts.copyInto(directory = dokkaDir, overwrite = true) - - val dokkaProject = GradleProjectTest(dokkaDir.toPath()).apply { - buildGradleKts = buildGradleKts - .replace( - // no idea why this needs to be changed - """file("../customResources/""", - """file("./customResources/""", - ) - - // update relative paths to the template files - they're now in the same directory - settingsGradleKts = settingsGradleKts - .replace( - """../template.settings.gradle.kts""", - """./template.settings.gradle.kts""", - ) - buildGradleKts = buildGradleKts - .replace( - """../template.root.gradle.kts""", - """./template.root.gradle.kts""", - ) - var templateGradleSettings: String by projectFile("template.settings.gradle.kts") - templateGradleSettings = templateGradleSettings - .replace("for-integration-tests-SNAPSHOT", "1.7.20") - - } - - val dokkaBuild = dokkaProject.runner - .withArguments( - "clean", - "dokkaHtml", - "--stacktrace", - "--info", - ) - .forwardOutput() - .withEnvironment( - "DOKKA_VERSION" to "1.7.20", - ) - .build() - - dokkaBuild.output shouldContain "BUILD SUCCESSFUL" - dokkaBuild.output shouldContain "Generation completed successfully" - - val dokkatooDir = tempDir.resolve("dokkatoo") - basicProjectSrcDir.copyRecursively(dokkatooDir, overwrite = true) { _, _ -> OnErrorAction.SKIP } - - val dokkatooProject = GradleProjectTest(dokkatooDir.toPath()).apply { - buildGradleKts = """ -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.gradle.kotlinSourceSet - -plugins { - kotlin("jvm") version "1.7.20" - id("dev.adamko.dokkatoo") version "0.0.1-SNAPSHOT" -} - -version = "1.7.20-SNAPSHOT" - -dependencies { - implementation(kotlin("stdlib")) - testImplementation(kotlin("test-junit")) -} - -dokkatoo { - moduleName.set("Basic Project") - dokkatooSourceSets.configureEach { - documentedVisibilities( - DokkaConfiguration.Visibility.PUBLIC, - DokkaConfiguration.Visibility.PROTECTED, - ) - suppressedFiles.from(file("src/main/kotlin/it/suppressedByPath")) - perPackageOption { - matchingRegex.set("it.suppressedByPackage.*") - suppress.set(true) - } - perPackageOption { - matchingRegex.set("it.overriddenVisibility.*") - documentedVisibilities.set( - setOf(DokkaConfiguration.Visibility.PRIVATE) - ) - } - sourceLink { - localDirectory.set(file("src/main")) - remoteUrl.set( - uri( - "https://github.com/Kotlin/dokka/tree/master/integration-tests/gradle/projects/it-basic/src/main" - ).toURL() - ) - } - } - dokkatooPublications.configureEach { - suppressObviousFunctions.set(true) - pluginsConfiguration.create("org.jetbrains.dokka.base.DokkaBase") { - serializationFormat.set(DokkaConfiguration.SerializationFormat.JSON) - values.set( - ${"\"\"\""} - { - "customStyleSheets": [ - "${'$'}{file("./customResources/logo-styles.css").invariantSeparatorsPath}", - "${'$'}{file("./customResources/custom-style-to-add.css").invariantSeparatorsPath}" - ], - "customAssets": [ - "${'$'}{file("./customResources/custom-resource.svg").invariantSeparatorsPath}" - ] - } - ${"\"\"\""}.trimIndent() - ) - } - suppressObviousFunctions.set(false) - } -} - -tasks.withType().configureEach { - dokkaSourceSets.configureEach { - sourceSetScope.set(":dokkaHtml") - } -} - -""".trimIndent() - - settingsGradleKts = """ -rootProject.name = "dokkatoo-it-basic" - -pluginManagement { - repositories { - gradlePluginPortal() - mavenCentral() - maven(file("$testMavenRepoRelativePath")) - } -} - -@Suppress("UnstableApiUsage") -dependencyResolutionManagement { - repositories { - mavenCentral() - maven(file("$testMavenRepoRelativePath")) - } -} - -""".trimIndent() - } - - val dokkatooBuild = dokkatooProject.runner - .withArguments( - "clean", - "dokkatooGeneratePublicationHtml", - "--stacktrace", - "--info", - ) - .forwardOutput() - .build() - - dokkatooBuild.output shouldContain "BUILD SUCCESSFUL" - dokkatooBuild.output shouldContain "Generation completed successfully" - - val dokkaHtmlDir = dokkaProject.projectDir.resolve("build/dokka/html") - val dokkatooHtmlDir = dokkatooProject.projectDir.resolve("build/dokka/html") - - val expectedFileTree = dokkaHtmlDir.toTreeString() - val actualFileTree = dokkatooHtmlDir.toTreeString() - println((actualFileTree to expectedFileTree).sideBySide()) - expectedFileTree shouldBe actualFileTree - - dokkatooHtmlDir.toFile().shouldHaveSameStructureAs(dokkaHtmlDir.toFile()) - dokkatooHtmlDir.toFile().shouldHaveSameStructureAndContentAs(dokkaHtmlDir.toFile()) - - withClue("Dokkatoo tasks should be cacheable") { - dokkatooProject.runner.withArguments( - "dokkatooGeneratePublicationHtml", - "--stacktrace", - "--info", - "--build-cache", - ).forwardOutput() - .build().should { buildResult -> - buildResult.output shouldContainAll listOf( - "Task :prepareDokkatooParametersHtml UP-TO-DATE", - "Task :dokkatooGeneratePublicationHtml UP-TO-DATE", - ) - withClue("Dokka Generator should not be triggered, so check it doesn't log anything") { - buildResult.output shouldNotContain "Generation completed successfully" - } - } - } - - // TODO test configuration cache -// withClue("Dokkatoo tasks should be configuration-cache compatible") { -// val dokkatooBuildCache = -// dokkatooProject.runner.withArguments( -// "clean", -// "dokkatooGenerate", -// "--stacktrace", -// "--info", -// "--no-build-cache", -// "--configuration-cache", -// ).forwardOutput() -// .build() -// -// dokkatooBuildCache.output.shouldContainAll( -// "Task :prepareDokkatooParametersHtml UP-TO-DATE", -// "Task :dokkatooGeneratePublicationHtml UP-TO-DATE", -// ) -// } - } -} - - -private val expectedDokkaConf: DokkaConfiguration = parseJson( -// language=json - """ -{ - "moduleName": "Basic Project", - "moduleVersion": "1.7.20-SNAPSHOT", - "outputDir": ".../build/dokka/html", - "cacheRoot": null, - "offlineMode": false, - "sourceSets": [ - { - "displayName": "jvm", - "sourceSetID": { - "scopeId": ":dokkaHtml", - "sourceSetName": "main" - }, - "classpath": [ - ".../kotlin-stdlib-1.7.20.jar", - ".../kotlin-stdlib-common-1.7.20.jar", - ".../annotations-13.0.jar" - ], - "sourceRoots": [ - ".../src/main/kotlin", - ".../src/main/java" - ], - "dependentSourceSets": [], - "samples": [], - "includes": [], - "includeNonPublic": false, - "reportUndocumented": false, - "skipEmptyPackages": true, - "skipDeprecated": false, - "jdkVersion": 8, - "sourceLinks": [ - { - "localDirectory": ".../src/main", - "remoteUrl": "https://github.com/Kotlin/dokka/tree/master/integration-tests/gradle/projects/it-basic/src/main", - "remoteLineSuffix": "#L" - } - ], - "perPackageOptions": [ - { - "matchingRegex": "it.suppressedByPackage.*", - "includeNonPublic": false, - "reportUndocumented": false, - "skipDeprecated": false, - "suppress": true, - "documentedVisibilities": [ - "PUBLIC" - ] - }, - { - "matchingRegex": "it.overriddenVisibility.*", - "includeNonPublic": false, - "reportUndocumented": false, - "skipDeprecated": false, - "suppress": false, - "documentedVisibilities": [ - "PRIVATE" - ] - } - ], - "externalDocumentationLinks": [ - { - "url": "https://docs.oracle.com/javase/8/docs/api/", - "packageListUrl": "https://docs.oracle.com/javase/8/docs/api/package-list" - }, - { - "url": "https://kotlinlang.org/api/latest/jvm/stdlib/", - "packageListUrl": "https://kotlinlang.org/api/latest/jvm/stdlib/package-list" - } - ], - "languageVersion": null, - "apiVersion": null, - "noStdlibLink": false, - "noJdkLink": false, - "suppressedFiles": [ - ".../src/main/kotlin/it/suppressedByPath" - ], - "analysisPlatform": "jvm", - "documentedVisibilities": [ - "PUBLIC", - "PROTECTED" - ] - } - ], - "pluginsClasspath": [ - ".../dokka-analysis-1.8.0-SNAPSHOT.jar", - ".../dokka-base-1.8.0-SNAPSHOT.jar", - ".../kotlin-analysis-intellij-1.8.0-SNAPSHOT.jar", - ".../kotlin-analysis-compiler-1.8.0-SNAPSHOT.jar", - ".../kotlinx-html-jvm-0.7.5.jar", - ".../kotlinx-coroutines-core-jvm-1.6.3.jar", - ".../kotlin-stdlib-jdk8-1.7.20.jar", - ".../jackson-databind-2.12.7.1.jar", - ".../jackson-annotations-2.12.7.jar", - ".../jackson-core-2.12.7.jar", - ".../jackson-module-kotlin-2.12.7.jar", - ".../kotlin-reflect-1.7.20.jar", - ".../kotlin-stdlib-jdk7-1.7.20.jar", - ".../kotlin-stdlib-1.7.20.jar", - ".../jsoup-1.15.3.jar", - ".../freemarker-2.3.31.jar", - ".../kotlin-stdlib-common-1.7.20.jar", - ".../annotations-13.0.jar" - ], - "pluginsConfiguration": [ - { - "fqPluginName": "org.jetbrains.dokka.base.DokkaBase", - "serializationFormat": "JSON", - "values": "{ \"customStyleSheets\": [\".../customResources/logo-styles.css\", \".../customResources/custom-style-to-add.css\"], \"customAssets\" : [\".../customResources/custom-resource.svg\"] }" - } - ], - "modules": [], - "failOnWarning": false, - "delayTemplateSubstitution": false, - "suppressObviousFunctions": false, - "includes": [], - "suppressInheritedMembers": false, - "finalizeCoroutines": true -} -""".trimIndent() -) diff --git a/settings.gradle.kts b/settings.gradle.kts index 96b5a00e..6ee766d9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -37,14 +37,57 @@ dependencyResolutionManagement { include( ":modules:dokkatoo-plugin", + ":modules:dokkatoo-plugin-integration-tests", - ":externals", + ":examples", ) enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("STABLE_CONFIGURATION_CACHE") -//if (file("./externals/kotlin-dokka").exists()) { -// includeBuild("./externals/kotlin-dokka") +//if (file("./examples/build/tmp/prepareDokkaSource").exists()) { +// includeBuild("./examples/build/tmp/prepareDokkaSource") +//} + +// can only include one example project at a time https://github.com/gradle/gradle/issues/23939 +//@formatter:off +//includeBuild(file("./examples/multiplatform-example/dokkatoo" )) { name = "multiplatform-example" } +//includeBuild(file("./examples/kotlin-as-java-example/dokkatoo" )) { name = "kotlin-as-java-example" } +//includeBuild(file("./examples/versioning-multimodule-example/dokkatoo" )) { name = "versioning-multimodule-example" } +//includeBuild(file("./examples/custom-format-example/dokkatoo" )) { name = "custom-format-example" } +//includeBuild(file("./examples/gradle-example/dokkatoo" )) { name = "gradle-example" } +//includeBuild(file("./examples/library-publishing-example/dokkatoo" )) { name = "library-publishing-example" } +//includeBuild(file("./examples/multimodule-example/dokkatoo" )) { name = "multimodule-example" } +//includeBuild(file("./modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokkatoo" )) { name = "it-multimodule-1" } +//includeBuild(file("./modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokkatoo" )) { name = "it-multimodule-0" } +//includeBuild(file("./modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokkatoo" )) { name = "it-collector-0" } +//includeBuild(file("./modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokkatoo" )) { name = "it-multimodule-versioning-0" } +//includeBuild(file("./modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokkatoo" )) { name = "it-android-0" } +//includeBuild(file("./modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo" )) { name = "it-basic" } +//includeBuild(file("./modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokkatoo" )) { name = "it-multiplatform-0" } +//includeBuild(file("./modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokkatoo" )) { name = "it-js-ir-0" } +//includeBuild(file("./modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokkatoo" )) { name = "it-basic-groovy" } +//@formatter:on + +//listOf( +// "examples", +// "modules/dokkatoo-plugin-integration-tests/projects", +//).forEach { exampleProjectDir -> +// file(exampleProjectDir) +// .walk() +// .filter { +// it.isDirectory +// && it.name == "dokkatoo" +// && ( +// it.resolve("settings.gradle.kts").exists() +// || +// it.resolve("settings.gradle").exists() +// ) +// }.forEach { file -> +// includeBuild(file) { +// name = file.parentFile.name +// println("$file $name") +// } +// } //}