diff options
author | Ignat Beresnev <ignat.beresnev@jetbrains.com> | 2023-11-10 11:46:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-10 11:46:54 +0100 |
commit | 8e5c63d035ef44a269b8c43430f43f5c8eebfb63 (patch) | |
tree | 1b915207b2b9f61951ddbf0ff2e687efd053d555 /core/test-api/src/main/kotlin | |
parent | a44efd4ba0c2e4ab921ff75e0f53fc9335aa79db (diff) | |
download | dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.gz dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.bz2 dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.zip |
Restructure the project to utilize included builds (#3174)
* Refactor and simplify artifact publishing
* Update Gradle to 8.4
* Refactor and simplify convention plugins and build scripts
Fixes #3132
---------
Co-authored-by: Adam <897017+aSemy@users.noreply.github.com>
Co-authored-by: Oleg Yukhnevich <whyoleg@gmail.com>
Diffstat (limited to 'core/test-api/src/main/kotlin')
4 files changed, 0 insertions, 565 deletions
diff --git a/core/test-api/src/main/kotlin/testApi/context/MockContext.kt b/core/test-api/src/main/kotlin/testApi/context/MockContext.kt deleted file mode 100644 index 06ea2dad..00000000 --- a/core/test-api/src/main/kotlin/testApi/context/MockContext.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.testApi.context - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.DokkaPlugin -import org.jetbrains.dokka.plugability.ExtensionPoint -import org.jetbrains.dokka.utilities.DokkaConsoleLogger -import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.dokka.utilities.LoggingLevel -import kotlin.reflect.KClass -import kotlin.reflect.KMutableProperty -import kotlin.reflect.full.memberProperties - -@Suppress("UNCHECKED_CAST") // It is only usable from tests so we do not care about safety -public class MockContext( - vararg extensions: Pair<ExtensionPoint<*>, (DokkaContext) -> Any>, - private val testConfiguration: DokkaConfiguration? = null, - private val unusedExtensionPoints: List<ExtensionPoint<*>>? = null -) : DokkaContext { - private val extensionMap by lazy { - extensions.groupBy(Pair<ExtensionPoint<*>, (DokkaContext) -> Any>::first) { - it.second(this) - } - } - - private val plugins = mutableMapOf<KClass<out DokkaPlugin>, DokkaPlugin>() - - override fun <T : DokkaPlugin> plugin(kclass: KClass<T>): T = plugins.getOrPut(kclass) { - kclass.constructors.single { it.parameters.isEmpty() }.call().also { it.injectContext(this) } - } as T - - override fun <T : Any, E : ExtensionPoint<T>> get(point: E): List<T> = extensionMap[point].orEmpty() as List<T> - - override fun <T : Any, E : ExtensionPoint<T>> single(point: E): T = get(point).single() - - override val logger: DokkaLogger = DokkaConsoleLogger(LoggingLevel.DEBUG) - - override val configuration: DokkaConfiguration - get() = testConfiguration ?: throw IllegalStateException("This mock context doesn't provide configuration") - - override val unusedPoints: Collection<ExtensionPoint<*>> - get() = unusedExtensionPoints - ?: throw IllegalStateException("This mock context doesn't provide unused extension points") -} - -private fun DokkaPlugin.injectContext(context: DokkaContext) { - (DokkaPlugin::class.memberProperties.single { it.name == "context" } as KMutableProperty<*>) - .setter.call(this, context) -} diff --git a/core/test-api/src/main/kotlin/testApi/logger/TestLogger.kt b/core/test-api/src/main/kotlin/testApi/logger/TestLogger.kt deleted file mode 100644 index c285a663..00000000 --- a/core/test-api/src/main/kotlin/testApi/logger/TestLogger.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.testApi.logger - -import org.jetbrains.dokka.utilities.DokkaLogger -import java.util.* - -/* - * Even in tests it be used in a concurrent environment, so needs to be thread safe - */ -public class TestLogger(private val logger: DokkaLogger) : DokkaLogger { - override var warningsCount: Int by logger::warningsCount - override var errorsCount: Int by logger::errorsCount - - private var _debugMessages = synchronizedMutableListOf<String>() - public val debugMessages: List<String> get() = _debugMessages.toList() - - private var _infoMessages = synchronizedMutableListOf<String>() - public val infoMessages: List<String> get() = _infoMessages.toList() - - private var _progressMessages = synchronizedMutableListOf<String>() - public val progressMessages: List<String> get() = _progressMessages.toList() - - private var _warnMessages = synchronizedMutableListOf<String>() - public val warnMessages: List<String> get() = _warnMessages.toList() - - private var _errorMessages = synchronizedMutableListOf<String>() - public val errorMessages: List<String> get() = _errorMessages.toList() - - override fun debug(message: String) { - _debugMessages.add(message) - logger.debug(message) - } - - override fun info(message: String) { - _infoMessages.add(message) - logger.info(message) - } - - override fun progress(message: String) { - _progressMessages.add(message) - logger.progress(message) - } - - override fun warn(message: String) { - _warnMessages.add(message) - logger.warn(message) - } - - override fun error(message: String) { - _errorMessages.add(message) - logger.error(message) - } - - private fun <T> synchronizedMutableListOf(): MutableList<T> = Collections.synchronizedList(mutableListOf()) -} diff --git a/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt b/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt deleted file mode 100644 index 4c451fed..00000000 --- a/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package testApi.testRunner - -import org.jetbrains.dokka.* -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.model.doc.CustomDocTag -import org.jetbrains.dokka.model.doc.Description -import org.jetbrains.dokka.model.doc.DocumentationNode -import org.jetbrains.dokka.model.doc.Text -import org.jetbrains.dokka.model.properties.PropertyContainer -import java.io.File - -public fun dokkaConfiguration(block: TestDokkaConfigurationBuilder.() -> Unit): DokkaConfigurationImpl = - TestDokkaConfigurationBuilder().apply(block).build() - -@DslMarker -public annotation class DokkaConfigurationDsl - -// TODO this class heavily relies on `DokkaSourceSetImpl`, should be refactored to `DokkaSourceSet` -@DokkaConfigurationDsl -public class TestDokkaConfigurationBuilder { - - public var moduleName: String = "root" - set(value) { - check(lazySourceSets.isEmpty()) { "Cannot set moduleName after adding source sets" } - field = value - } - public var moduleVersion: String = "1.0-SNAPSHOT" - public var outputDir: File = File("out") - public var format: String = "html" - public var offlineMode: Boolean = false - public var cacheRoot: String? = null - public var pluginsClasspath: List<File> = emptyList() - public var pluginsConfigurations: MutableList<PluginConfigurationImpl> = mutableListOf() - public var failOnWarning: Boolean = false - public var modules: List<DokkaModuleDescriptionImpl> = emptyList() - public var suppressObviousFunctions: Boolean = DokkaDefaults.suppressObviousFunctions - public var includes: List<File> = emptyList() - public var suppressInheritedMembers: Boolean = DokkaDefaults.suppressInheritedMembers - public var delayTemplateSubstitution: Boolean = DokkaDefaults.delayTemplateSubstitution - private val lazySourceSets = mutableListOf<Lazy<DokkaSourceSetImpl>>() - - public fun build(): DokkaConfigurationImpl = DokkaConfigurationImpl( - moduleName = moduleName, - moduleVersion = moduleVersion, - outputDir = outputDir, - cacheRoot = cacheRoot?.let(::File), - offlineMode = offlineMode, - sourceSets = lazySourceSets.map { it.value }.toList(), - pluginsClasspath = pluginsClasspath, - pluginsConfiguration = pluginsConfigurations, - modules = modules, - failOnWarning = failOnWarning, - suppressObviousFunctions = suppressObviousFunctions, - includes = includes.toSet(), - suppressInheritedMembers = suppressInheritedMembers, - delayTemplateSubstitution = delayTemplateSubstitution, - finalizeCoroutines = false - ) - - public fun sourceSets(block: SourceSetsBuilder.() -> Unit) { - lazySourceSets.addAll(SourceSetsBuilder(moduleName).apply(block)) - } - - public fun sourceSet(block: DokkaSourceSetBuilder.() -> Unit): Lazy<DokkaSourceSetImpl> { - val lazySourceSet = lazy { DokkaSourceSetBuilder(moduleName).apply(block).build() } - lazySourceSets.add(lazySourceSet) - return lazySourceSet - } - - public fun unattachedSourceSet(block: DokkaSourceSetBuilder.() -> Unit): DokkaSourceSetImpl { - return DokkaSourceSetBuilder(moduleName).apply(block).build() - } -} - -@DokkaConfigurationDsl -public class SourceSetsBuilder( - public val moduleName: String -) : ArrayList<Lazy<DokkaSourceSetImpl>>() { - public fun sourceSet(block: DokkaSourceSetBuilder.() -> Unit): Lazy<DokkaConfiguration.DokkaSourceSet> { - return lazy { DokkaSourceSetBuilder(moduleName).apply(block).build() }.apply(::add) - } -} - -@DokkaConfigurationDsl -public class DokkaSourceSetBuilder( - private val moduleName: String, - public var name: String = "main", - public var displayName: String = "JVM", - public var classpath: List<String> = emptyList(), - public var sourceRoots: List<String> = emptyList(), - public var dependentSourceSets: Set<DokkaSourceSetID> = emptySet(), - public var samples: List<String> = emptyList(), - public var includes: List<String> = emptyList(), - @Deprecated(message = "Use [documentedVisibilities] property for a more flexible control over documented visibilities") - public var includeNonPublic: Boolean = false, - public var documentedVisibilities: Set<DokkaConfiguration.Visibility> = DokkaDefaults.documentedVisibilities, - public var reportUndocumented: Boolean = false, - public var skipEmptyPackages: Boolean = false, - public var skipDeprecated: Boolean = false, - public var jdkVersion: Int = 8, - public var languageVersion: String? = null, - public var apiVersion: String? = null, - public var noStdlibLink: Boolean = false, - public var noJdkLink: Boolean = false, - public var suppressedFiles: List<String> = emptyList(), - public var analysisPlatform: String = "jvm", - public var perPackageOptions: List<PackageOptionsImpl> = emptyList(), - public var externalDocumentationLinks: List<ExternalDocumentationLinkImpl> = emptyList(), - public var sourceLinks: List<SourceLinkDefinitionImpl> = emptyList() -) { - @Suppress("DEPRECATION") - public fun build(): DokkaSourceSetImpl { - return DokkaSourceSetImpl( - displayName = displayName, - sourceSetID = DokkaSourceSetID(moduleName, name), - classpath = classpath.map(::File), - sourceRoots = sourceRoots.map(::File).toSet(), - dependentSourceSets = dependentSourceSets, - samples = samples.map(::File).toSet(), - includes = includes.map(::File).toSet(), - includeNonPublic = includeNonPublic, - documentedVisibilities = documentedVisibilities, - reportUndocumented = reportUndocumented, - skipEmptyPackages = skipEmptyPackages, - skipDeprecated = skipDeprecated, - jdkVersion = jdkVersion, - sourceLinks = sourceLinks.toSet(), - perPackageOptions = perPackageOptions.toList(), - externalDocumentationLinks = externalDocumentationLinks.toSet(), - languageVersion = languageVersion, - apiVersion = apiVersion, - noStdlibLink = noStdlibLink, - noJdkLink = noJdkLink, - suppressedFiles = suppressedFiles.map(::File).toSet(), - analysisPlatform = Platform.fromString(analysisPlatform) - ) - } -} - -public val defaultSourceSet: DokkaSourceSetImpl = DokkaSourceSetImpl( - displayName = "DEFAULT", - sourceSetID = DokkaSourceSetID("DEFAULT", "DEFAULT"), - classpath = emptyList(), - sourceRoots = emptySet(), - dependentSourceSets = emptySet(), - samples = emptySet(), - includes = emptySet(), - includeNonPublic = false, - documentedVisibilities = DokkaDefaults.documentedVisibilities, - reportUndocumented = false, - skipEmptyPackages = true, - skipDeprecated = false, - jdkVersion = 8, - sourceLinks = emptySet(), - perPackageOptions = emptyList(), - externalDocumentationLinks = emptySet(), - languageVersion = null, - apiVersion = null, - noStdlibLink = false, - noJdkLink = false, - suppressedFiles = emptySet(), - analysisPlatform = Platform.DEFAULT -) - -public fun sourceSet(name: String): DokkaConfiguration.DokkaSourceSet { - return defaultSourceSet.copy( - displayName = name, - sourceSetID = defaultSourceSet.sourceSetID.copy(sourceSetName = name) - ) -} - -public fun dModule( - name: String, - packages: List<DPackage> = emptyList(), - documentation: SourceSetDependent<DocumentationNode> = emptyMap(), - expectPresentInSet: DokkaConfiguration.DokkaSourceSet? = null, - sourceSets: Set<DokkaConfiguration.DokkaSourceSet> = emptySet(), - extra: PropertyContainer<DModule> = PropertyContainer.empty() -): DModule = DModule( - name = name, - packages = packages, - documentation = documentation, - expectPresentInSet = expectPresentInSet, - sourceSets = sourceSets, - extra = extra -) - -public fun dPackage( - dri: DRI, - functions: List<DFunction> = emptyList(), - properties: List<DProperty> = emptyList(), - classlikes: List<DClasslike> = emptyList(), - typealiases: List<DTypeAlias> = emptyList(), - documentation: SourceSetDependent<DocumentationNode> = emptyMap(), - expectPresentInSet: DokkaConfiguration.DokkaSourceSet? = null, - sourceSets: Set<DokkaConfiguration.DokkaSourceSet> = emptySet(), - extra: PropertyContainer<DPackage> = PropertyContainer.empty() -): DPackage = DPackage( - dri = dri, - functions = functions, - properties = properties, - classlikes = classlikes, - typealiases = typealiases, - documentation = documentation, - expectPresentInSet = expectPresentInSet, - sourceSets = sourceSets, - extra = extra -) - -public fun documentationNode(vararg texts: String): DocumentationNode { - return DocumentationNode( - texts.toList() - .map { Description(CustomDocTag(listOf(Text(it)), name = "MARKDOWN_FILE")) }) -} diff --git a/core/test-api/src/main/kotlin/testApi/testRunner/TestRunner.kt b/core/test-api/src/main/kotlin/testApi/testRunner/TestRunner.kt deleted file mode 100644 index 1f7ee060..00000000 --- a/core/test-api/src/main/kotlin/testApi/testRunner/TestRunner.kt +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.testApi.testRunner - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.DokkaConfigurationImpl -import org.jetbrains.dokka.ExternalDocumentationLinkImpl -import org.jetbrains.dokka.model.DModule -import org.jetbrains.dokka.pages.RootPageNode -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.DokkaPlugin -import org.jetbrains.dokka.testApi.logger.TestLogger -import org.jetbrains.dokka.utilities.DokkaLogger -import testApi.testRunner.TestDokkaConfigurationBuilder -import java.io.File -import java.net.URL -import java.nio.charset.Charset -import java.nio.file.Files -import java.nio.file.InvalidPathException -import java.nio.file.Path -import java.nio.file.Paths - -// TODO: take dokka configuration from file -public abstract class AbstractTest<M : TestMethods, T : TestBuilder<M>, D : DokkaTestGenerator<M>>( - protected val testBuilder: () -> T, - protected val dokkaTestGenerator: (DokkaConfiguration, DokkaLogger, M, List<DokkaPlugin>) -> D, - protected val logger: TestLogger, -) { - protected fun getTestDataDir(name: String): Path { - return File("src/test/resources/$name").takeIf { it.exists() }?.toPath() - ?: throw InvalidPathException(name, "Cannot be found") - } - - /** - * @param cleanupOutput if set to true, any temporary files will be cleaned up after execution. If set to false, - * it will be left to the user or the OS to delete it. Has no effect if [useOutputLocationFromConfig] - * is also set to true. - * @param useOutputLocationFromConfig if set to true, output location specified in [DokkaConfigurationImpl.outputDir] - * will be used. If set to false, a temporary folder will be used instead. - */ - protected fun testFromData( - configuration: DokkaConfigurationImpl, - cleanupOutput: Boolean = true, - useOutputLocationFromConfig: Boolean = false, - pluginOverrides: List<DokkaPlugin> = emptyList(), - block: T.() -> Unit, - ) { - if (useOutputLocationFromConfig) { - runTests( - configuration = configuration, - pluginOverrides = pluginOverrides, - testLogger = logger, - block = block - ) - } else { - withTempDirectory(cleanUpAfterUse = cleanupOutput) { tempDir -> - if (!cleanupOutput) { - logger.info("Output will be generated under: ${tempDir.absolutePath}") - } - runTests( - configuration = configuration.copy(outputDir = tempDir), - pluginOverrides = pluginOverrides, - testLogger = logger, - block = block - ) - } - } - } - - protected fun testInline( - query: String, - configuration: DokkaConfigurationImpl, - cleanupOutput: Boolean = true, - pluginOverrides: List<DokkaPlugin> = emptyList(), - loggerForTest: DokkaLogger = logger, - block: T.() -> Unit, - ) { - withTempDirectory(cleanUpAfterUse = cleanupOutput) { tempDir -> - if (!cleanupOutput) { - loggerForTest.info("Output will be generated under: ${tempDir.absolutePath}") - } - - val fileMap = query.toFileMap() - fileMap.materializeFiles(tempDir.toPath().toAbsolutePath()) - - val newConfiguration = configuration.copy( - outputDir = tempDir, - sourceSets = configuration.sourceSets.map { sourceSet -> - sourceSet.copy( - sourceRoots = sourceSet.sourceRoots.map { file -> tempDir.resolve(file) }.toSet(), - suppressedFiles = sourceSet.suppressedFiles.map { file -> tempDir.resolve(file) }.toSet(), - sourceLinks = sourceSet.sourceLinks.map { - link -> link.copy(localDirectory = tempDir.resolve(link.localDirectory).absolutePath) - }.toSet(), - includes = sourceSet.includes.map { file -> tempDir.resolve(file) }.toSet() - ) - } - ) - runTests( - configuration = newConfiguration, - pluginOverrides = pluginOverrides, - testLogger = loggerForTest, - block = block - ) - } - } - - private fun withTempDirectory(cleanUpAfterUse: Boolean, block: (tempDirectory: File) -> Unit) { - val tempDir = this.createTempDir() - try { - block(tempDir) - } finally { - if (cleanUpAfterUse) { - tempDir.deleteRecursively() - } - } - } - - private fun runTests( - configuration: DokkaConfiguration, - pluginOverrides: List<DokkaPlugin>, - testLogger: DokkaLogger = logger, - block: T.() -> Unit - ) { - val testMethods = testBuilder().apply(block).build() - dokkaTestGenerator( - configuration, - testLogger, - testMethods, - pluginOverrides - ).generate() - } - - private fun String.toFileMap(): Map<String, String> { - return this.trimIndent().trimMargin() - .replace("\r\n", "\n") - .sliceAt(filePathRegex) - .filter { it.isNotEmpty() && it.isNotBlank() && "\n" in it } - .map { fileDeclaration -> fileDeclaration.trim() }.associate { fileDeclaration -> - val filePathAndContent = fileDeclaration.split("\n", limit = 2) - val filePath = filePathAndContent.first().removePrefix("/").trim() - val content = filePathAndContent.last().trim() - filePath to content - } - } - - private fun String.sliceAt(regex: Regex): List<String> { - val matchesStartIndices = regex.findAll(this).toList().map { match -> match.range.first } - return sequence { - yield(0) - yieldAll(matchesStartIndices) - yield(this@sliceAt.length) - } - .zipWithNext { startIndex: Int, endIndex: Int -> substring(startIndex, endIndex) } - .toList() - .also { slices -> - /* Post-condition verifying that no character is lost */ - check(slices.sumBy { it.length } == length) - } - } - - private fun Map<String, String>.materializeFiles( - root: Path = Paths.get("."), - charset: Charset = Charset.forName("utf-8"), - ) = this.map { (path, content) -> - val file = root.resolve(path) - Files.createDirectories(file.parent) - Files.write(file, content.toByteArray(charset)) - } - - @Suppress("DEPRECATION") // TODO migrate to kotlin.io.path.createTempDirectory with languageVersion >= 1.5 - private fun createTempDir(): File = kotlin.io.createTempDir() - - protected fun dokkaConfiguration(block: TestDokkaConfigurationBuilder.() -> Unit): DokkaConfigurationImpl = - testApi.testRunner.dokkaConfiguration(block) - - - protected val jvmStdlibPath: String? by lazy { - ClassLoader.getSystemResource("kotlin/jvm/Strictfp.class") - ?.file - ?.replace("file:", "") - ?.replaceAfter(".jar", "") - } - - protected val jsStdlibPath: String? by lazy { - ClassLoader.getSystemResource("kotlin/jquery") - ?.file - ?.replace("file:", "") - ?.replaceAfter(".jar", "") - } - - protected val commonStdlibPath: String? by lazy { - // `kotlin-stdlib-common` is legacy - // we can use any platform dependency - // since common code should be resolved with all platform - jvmStdlibPath - } - - protected val stdlibExternalDocumentationLink: ExternalDocumentationLinkImpl = ExternalDocumentationLinkImpl( - URL("https://kotlinlang.org/api/latest/jvm/stdlib/"), - URL("https://kotlinlang.org/api/latest/jvm/stdlib/package-list") - ) - - public companion object { - private val filePathRegex = Regex("""[\n^](\/[\w|\-]+)+(\.\w+)?\s*\n""") - } -} - -public interface TestMethods - -public open class CoreTestMethods( - public open val pluginsSetupStage: (DokkaContext) -> Unit, - public open val verificationStage: (() -> Unit) -> Unit, - public open val documentablesCreationStage: (List<DModule>) -> Unit, - public open val documentablesMergingStage: (DModule) -> Unit, - public open val documentablesTransformationStage: (DModule) -> Unit, - public open val pagesGenerationStage: (RootPageNode) -> Unit, - public open val pagesTransformationStage: (RootPageNode) -> Unit, - public open val renderingStage: (RootPageNode, DokkaContext) -> Unit, -) : TestMethods - -public abstract class TestBuilder<M : TestMethods> { - public abstract fun build(): M -} - -public abstract class DokkaTestGenerator<T : TestMethods>( - protected val configuration: DokkaConfiguration, - protected val logger: DokkaLogger, - protected val testMethods: T, - protected val additionalPlugins: List<DokkaPlugin> = emptyList(), -) { - public abstract fun generate() -} |