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

[Bug] Cannot Configure Custom Dokka Plugin #3869

Open
solonovamax opened this issue Oct 17, 2024 · 4 comments
Open

[Bug] Cannot Configure Custom Dokka Plugin #3869

solonovamax opened this issue Oct 17, 2024 · 4 comments
Assignees
Labels
bug runner: Gradle plugin An issue/PR related to Dokka's Gradle plugin

Comments

@solonovamax
Copy link

Describe the Bug

It is currently impossible to configure custom dokka plugins.

Expected Behaviour

It should be possible to, and documented how to, configure custom dokka plugins.

Actual Behaviour

When attempting to configure custom dokka plugins with the (entirely undocumented) DokkaPluginParametersBuilder class and pluginParameters function, eg.

dokka {
    pluginsConfiguration {
        pluginParameters("ca.solostudios.dokkascript.plugin.DokkaScriptsPlugin") {
            files("scripts") {
                from(fileTree(dokkaScripts))
            }
        }
    }
}

then the following error is produced:

Cannot create a DokkaPluginParametersBuilder because this type is not known to this container. Known types are: DokkaHtmlPluginParameters, DokkaVersioningPluginParameters

If DokkaPluginParametersBuilder then has a factory registered using

dokka {
    pluginsConfiguration {
        registerFactory(DokkaPluginParametersBuilder::class.java) { name ->
            objects.newInstance<DokkaPluginParametersBuilder>(name, name)
        }
    }
}

then, gradle will properly load, however gradle will not allow the dokkaGenerate task to run, and instead produces the following error:

Some problems were found with the configuration of task ':dokkaGenerateModuleHtml' (type 'DokkaGenerateModuleTask').
  - Type 'org.jetbrains.dokka.gradle.engine.plugins.DokkaPluginParametersBuilder' method 'jsonEncode()' should not be annotated with: @Internal.

Environment

  • Operating system: Linux
  • Build tool: Gradle 8.10.1
  • Dokka version: 2.0.0-Beta
solonovamax added a commit to solonovamax/dokka that referenced this issue Oct 17, 2024
- Register binding for `DokkaPluginParametersBuilder`
- Remove @internal annotation on `jsonEncode()` for `DokkaPluginParametersBuilder`
- Annotate the getter for `DokkaPluginParametersBuilder.objects` (the annotation only works for getters)
- Add missing functions for adding files, directories, and maps, which were implied but not present for `DokkaPluginParametersBuilder`
- remove overriden `DokkaPluginParametersBuilder.pluginFqn` property as it just caused issues
- Add documentation for configuring custom plugins in dokka-migration.md

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>
@adam-enko adam-enko self-assigned this Oct 17, 2024
@adam-enko adam-enko added the runner: Gradle plugin An issue/PR related to Dokka's Gradle plugin label Oct 17, 2024
@adam-enko
Copy link
Member

adam-enko commented Oct 17, 2024

Hi, thank you very much for the report and investigation.

For some context, the DokkaPluginParametersBuilder was an experiment from Dokkatoo that I started, but never finished, because I never found a need for it. It was intended as an improvement over the DGPv1 approach of manually writing JSON, and to correctly registering task inputs for Gradle task avoidance.

I've looked into DokkaPluginParametersBuilder further and aside from the issues you already found (bugs, missing docs, and missing functionality) I also found some more problems. I've discussed this with the Dokka team, and we're going to remove DokkaPluginParametersBuilder.

Alternative approach

For now you will have to avoid DokkaPluginParametersBuilder and instead implement a custom DokkaPluginParametersBaseSpec class. Such a class can be implemented in a build.gradle.kts. For example:

// build.gradle.kts

plugins {
  id("org.jetbrains.dokka") version "2.0.0-Beta"
}

val dokkaScripts = layout.projectDirectory.dir("dokka-scripts")

dokka {
  pluginsConfiguration {
    registerBinding(DokkaScriptsPluginParameters::class, DokkaScriptsPluginParameters::class)
    register<DokkaScriptsPluginParameters>("DokkaScripts") {
      scripts.from(dokkaScripts.asFileTree)
    }
  }
}

@OptIn(DokkaInternalApi::class)
abstract class DokkaScriptsPluginParameters @Inject constructor(
  name: String
) : DokkaPluginParametersBaseSpec(name, "ca.solostudios.dokkascript.plugin.DokkaScriptsPlugin") {

  @get:InputFiles
  @get:PathSensitive(PathSensitivity.RELATIVE)
  @get:NormalizeLineEndings
  abstract val scripts: ConfigurableFileCollection

  override fun jsonEncode(): String {
    val encodedScriptFiles = scripts.files.joinToString { "\"${it.canonicalFile.invariantSeparatorsPath}\"" }
    return """
      {
        "scripts": [ $encodedScriptFiles ]
      }
    """.trimIndent()
  }
}

If you find you need to re-use DokkaScriptsPluginParameters in multiple buildscripts, then I recommend moving the class into a shared location, like buildSrc (or another included-build for conventions).

Presently DokkaPluginParametersBaseSpec requires an opt-in for the internal Dokka Gradle API, but I'll look at removing this restriction.

Tasks

adam-enko added a commit that referenced this issue Oct 17, 2024
DokkaPluginParametersBuilder is bugged, undocumented, and untested.

It's difficult to use, and there's an alternative (see #3871).

#3869
@solonovamax
Copy link
Author

solonovamax commented Oct 17, 2024

For now you will have to avoid DokkaPluginParametersBuilder and instead implement a custom DokkaPluginParametersBaseSpec class. Such a class can be implemented in a build.gradle.kts. For example:

// build.gradle.kts

plugins {
  id("org.jetbrains.dokka") version "2.0.0-Beta"
}

val dokkaScripts = layout.projectDirectory.dir("dokka-scripts")

dokka {
  pluginsConfiguration {
    registerBinding(DokkaScriptsPluginParameters::class, DokkaScriptsPluginParameters::class)
    register<DokkaScriptsPluginParameters>("DokkaScripts") {
      scripts.from(dokkaScripts.asFileTree)
    }
  }
}

@OptIn(DokkaInternalApi::class)
abstract class DokkaScriptsPluginParameters @Inject constructor(
  name: String
) : DokkaPluginParametersBaseSpec(name, "ca.solostudios.dokkascript.plugin.DokkaScriptsPlugin") {

  @get:InputFiles
  @get:PathSensitive(PathSensitivity.RELATIVE)
  @get:NormalizeLineEndings
  abstract val scripts: ConfigurableFileCollection

  override fun jsonEncode(): String {
    val encodedScriptFiles = scripts.files.joinToString { "\"${it.canonicalFile.invariantSeparatorsPath}\"" }
    return """
      {
        "scripts": [ $encodedScriptFiles ]
      }
    """.trimIndent()
  }
}

If you find you need to re-use DokkaScriptsPluginParameters in multiple buildscripts, then I recommend moving the class into a shared location, like buildSrc (or another included-build for conventions).

I mentioned this in the slack, however this does not work and gradle will error with this. this is because it wants the class to be a static class, and for whatever reason if a class is declared in a buildscript, it is a non-static inner class

I also don't particularly want to introduce a buildSrc or a build-logic to my project, as that will increase builds needlessly, as my project does not utilize multiple subprojects.

@solonovamax
Copy link
Author

I mentioned this in the slack, however this does not work and gradle will error with this. this is because it wants the class to be a static class, and for whatever reason if a class is declared in a buildscript, it is a non-static inner class

I also don't particularly want to introduce a buildSrc or a build-logic to my project, as that will increase builds needlessly, as my project does not utilize multiple subprojects.

this is the specific issue, btw:

Could not create domain object 'scripts' (DokkaScriptsPluginParameters)
> Could not create an instance of type Build_gradle$DokkaScriptsPluginParameters.
   > Class Build_gradle.DokkaScriptsPluginParameters is a non-static inner class.

this is happening specifically because of the use of an ExtensiblePolymorphicDomainObjectContainer

@adam-enko
Copy link
Member

this is the specific issue, btw:

Could not create domain object 'scripts' (DokkaScriptsPluginParameters)
> Could not create an instance of type Build_gradle$DokkaScriptsPluginParameters.
   > Class Build_gradle.DokkaScriptsPluginParameters is a non-static inner class.

this is happening specifically because of the use of an ExtensiblePolymorphicDomainObjectContainer

Thanks for sharing the specific error. It looks like that's a Gradle error gradle/gradle#25494, caused by referencing something from the buildscript inside of the class.

I'm working on a demonstration project here to show how to configure a custom DokkaScriptsPluginParameters.

If something still isn't working, please share an example (or link to an open source project) and I can take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug runner: Gradle plugin An issue/PR related to Dokka's Gradle plugin
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants