Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract non-essential declarations and logic out of dokka-core #2933

Open
aSemy opened this issue Mar 21, 2023 · 2 comments
Open

Extract non-essential declarations and logic out of dokka-core #2933

aSemy opened this issue Mar 21, 2023 · 2 comments
Labels
enhancement An issue for a feature or an overall improvement tech-debt A technical issue that is not observable by the users, but improves maintainers quality of life

Comments

@aSemy
Copy link
Contributor

aSemy commented Mar 21, 2023

Is your feature request related to a problem? Please describe

Dokkatoo uses a Gradle Worker with classpath isolation to execute the Dokka Generator in Dokka Core.

Dokka Generator is configured via some Kotlin interfaces, that are defined in the same module.

interface DokkaConfiguration : Serializable {
val moduleName: String
val moduleVersion: String?
val outputDir: File
val cacheRoot: File?
val offlineMode: Boolean
val failOnWarning: Boolean
val sourceSets: List<DokkaSourceSet>
val modules: List<DokkaModuleDescription>
val pluginsClasspath: List<File>
val pluginsConfiguration: List<PluginConfiguration>
val delayTemplateSubstitution: Boolean
val suppressObviousFunctions: Boolean
val includes: Set<File>
val suppressInheritedMembers: Boolean
/**
* Whether coroutines dispatchers should be shutdown after
* generating documentation via [DokkaGenerator.generate].
*
* It effectively stops all background threads associated with
* coroutines in order to make classes unloadable by the JVM,
* and rejects all new tasks with [RejectedExecutionException]
*
* This is primarily useful for multi-module builds where coroutines
* can be shut down after each module's partial task to avoid
* possible memory leaks.
*
* However, this can lead to problems in specific lifecycles where
* coroutines are shared and will be reused after documentation generation,
* and closing it down will leave the build in an inoperable state.
* One such example is unit tests, for which finalization should be disabled.
*/
val finalizeCoroutines: Boolean
enum class SerializationFormat : Serializable {
JSON, XML
}
interface PluginConfiguration : Serializable {
val fqPluginName: String
val serializationFormat: SerializationFormat
val values: String
}
interface DokkaSourceSet : Serializable {
val sourceSetID: DokkaSourceSetID
val displayName: String
val classpath: List<File>
val sourceRoots: Set<File>
val dependentSourceSets: Set<DokkaSourceSetID>
val samples: Set<File>
val includes: Set<File>
@Deprecated(message = "Use [documentedVisibilities] property for a more flexible control over documented visibilities")
val includeNonPublic: Boolean
val reportUndocumented: Boolean
val skipEmptyPackages: Boolean
val skipDeprecated: Boolean
val jdkVersion: Int
val sourceLinks: Set<SourceLinkDefinition>
val perPackageOptions: List<PackageOptions>
val externalDocumentationLinks: Set<ExternalDocumentationLink>
val languageVersion: String?
val apiVersion: String?
val noStdlibLink: Boolean
val noJdkLink: Boolean
val suppressedFiles: Set<File>
val analysisPlatform: Platform
val documentedVisibilities: Set<Visibility>
}
enum class Visibility {
/**
* `public` modifier for Java, default visibility for Kotlin
*/
PUBLIC,
/**
* `private` modifier for both Kotlin and Java
*/
PRIVATE,
/**
* `protected` modifier for both Kotlin and Java
*/
PROTECTED,
/**
* Kotlin-specific `internal` modifier
*/
INTERNAL,
/**
* Java-specific package-private visibility (no modifier)
*/
PACKAGE;
companion object {
fun fromString(value: String) = valueOf(value.toUpperCase())
}
}
interface SourceLinkDefinition : Serializable {
val localDirectory: String
val remoteUrl: URL
val remoteLineSuffix: String?
}
interface DokkaModuleDescription : Serializable {
val name: String
val relativePathToOutputDirectory: File
val sourceOutputDirectory: File
val includes: Set<File>
}
interface PackageOptions : Serializable {
val matchingRegex: String
@Deprecated("Use [documentedVisibilities] property for a more flexible control over documented visibilities")
val includeNonPublic: Boolean
val reportUndocumented: Boolean?
val skipDeprecated: Boolean
val suppress: Boolean
val documentedVisibilities: Set<Visibility>
}
interface ExternalDocumentationLink : Serializable {
val url: URL
val packageListUrl: URL
companion object
}
}

Because Dokka Generator and the configuration classes are defined the same module, this tightly couples Dokkatoo to a specific Dokka version. This dependency also drags along Dokka Generator, even though it is not required during Gradle project configuration.

Since Dokkatoo uses classpath isolation to run Dokka Generator, the version of Dokka Generator can be set on the fly.

Describe the solution you'd like

Split the interfaces for Dokka Core configuration into a separate artifact.

  • org.jetbrains.dokka:dokka-core - contains Dokka Generator, and depends on org.jetbrains.dokka:dokka-core-api
  • org.jetbrains.dokka:dokka-core-api - contains pure configuration classes and interfaces, without logic

Declaring a feature-variant might be a possible way of doing this https://docs.gradle.org/current/userguide/feature_variants.html, but a more straight-forward way would be do create a separate subproject

Describe alternatives you've considered

Keep on using dokka-core.

Additional context

Related:

Are you willing to provide a PR?

Yes

@aSemy aSemy added the enhancement An issue for a feature or an overall improvement label Mar 21, 2023
@aSemy aSemy changed the title Provide a separate artifact for Dokka Core API classes Provide a separate artifact for Dokka Core configuration classes/interfaces Mar 21, 2023
@IgnatBeresnev IgnatBeresnev added the tech-debt A technical issue that is not observable by the users, but improves maintainers quality of life label Mar 23, 2023
@IgnatBeresnev
Copy link
Member

IgnatBeresnev commented Mar 23, 2023

Thanks for creating the issue! I kept it in mind after our discussion, and we just had a technical breakdown meeting about it.

We've actually agreed to take a bit of a turn with the core artifact/module.

The first idea was indeed to break it down into core and core-api, but after some thinking and evaluating the code that we have inside core, we decided to just refactor core instead. There was a problem that nobody knew what "core" meant, and which classes should've been put in core and which in base, so a lot of things leaked to core

We'll extract all non essential declarations from core and move it to dokka-base, including all of the logic that requires jackson, coroutines, and other dependencies.

The idea is so that core should only contain core extensions, interfaces and the documentable/page/content model, and virtually no logic. It will be much smaller this way, and much more stable between versions. In the future, we'll extract the Content model from it as well, making it even more isolated.

So after this refactoring, core should have no dependencies at all and be lightweight

Would you mind if we renamed the issue to represent the outlined refactoring? Something like "Extract non-essential declarations from dokka-core". We'll use this issue to track it then

@aSemy
Copy link
Contributor Author

aSemy commented Mar 26, 2023

To me, 'core' means Dokka Generator - the actual code that will convert source files to an intermediate format that is passed to any present Dokka Plugins, which will eventually produce a format. Plugins can receive data that Dokka Generator creates (which could be another use-case for a core-api artifact).

Moving functionality out of core makes sense. I'm not sure it will be able to make the end artifact as slim as a component that only contains the DokkaConfiguration interfaces, but so long as the end result works 👍

Would you mind if we renamed the issue to represent the outlined refactoring? Something like "Extract non-essential declarations from dokka-core". We'll use this issue to track it then

Not at all! Go ahead.

@IgnatBeresnev IgnatBeresnev changed the title Provide a separate artifact for Dokka Core configuration classes/interfaces Extract non-essential declarations and logic out of dokka-core Mar 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement An issue for a feature or an overall improvement tech-debt A technical issue that is not observable by the users, but improves maintainers quality of life
Projects
None yet
Development

No branches or pull requests

2 participants