androidkotlingradle-plugingradle-kotlin-dslkotlin-dsl

Adding Kotlin plugins using plugins DSL


It looks like there are two ways of declaring some Kotlin plugins using plugins DSL: Using the id() method and the kotlin() method. For example, the android plugin can be added using either id("kotlin-android") or kotlin("android"). This is also the case for kapt but not for parcelize. Why can't this be kotlin("parcelize")? Is there a reason for this discrepancy? I tried to look up relevant documentation but that didn't get me very far.


Solution

  • TL;DR: Take the Gradle plugin ID for Parcelize and use everything after org.jetbrains.kotlin.

    plugins {
      kotlin("plugin.parcelize") version "1.6.10"
    }
    

    The kotlin(...) function is part of the Gradle Kotlin DSL. It is an extension function that extends

    1. PluginDependenciesSpec, the plugins {} block
    2. DependencyHandler, the dependencies {} block

    I'm going to focus on the Plugin extension function. Some of this answer is applicable to the Dependency extension.

    kotlin(...) source code

    It's generated so it's difficult to see the source code. I dug through GitHub and found it in GenerateKotlinDependencyExtensions.kt

    fun PluginDependenciesSpec.kotlin(module: String): PluginDependencySpec =
        id("org.jetbrains.kotlin.$module")
    

    (edited, to show the end result)

    kotlin(...) = id("org.jetbrains.kotlin.$module")

    So it's nothing special. It's a Kotlin-specific shortcut for id(...). So if you

    1. take the plugin ID for Parcelize, org.jetbrains.kotlin.plugin.parcelize,
    2. and remove the bits that the kotlin(...) function adds (org.jetbrains.kotlin.),
    3. you're left with plugin.parcelize.

    NOTE Because this is in the plugins {} block, it's working on the Gradle plugin ID (org.jetbrains.kotlin.plugin.parcelize), not the Maven coordinates (org.jetbrains.kotlin:kotlin-gradle-plugin).

    plugins {
      // these two are equivalent
      // id("org.jetbrains.kotlin.plugin.parcelize")
      kotlin("plugin.parcelize")
    }
    

    Oh wait... it doesn't work??

    FAILURE: Build failed with an exception.
    * Where:
    Build file '/.../build.gradle.kts' line: 3
    * What went wrong:
    Plugin [id: 'org.jetbrains.kotlin.plugin.parcelize'] was not found in any of the following sources:
    - Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
    - Plugin Repositories (plugin dependency must include a version number for this source)
    

    "Build failed with an exception" - Plugin version

    That's because unlike the DependencyHandler.kotlin(...) extension, the PluginDependenciesSpec.kotlin(...) doesn't include the version. It says that in the error message: "plugin dependency must include a version number"

    So to resolve it, add a version number.

    plugins {
      kotlin("plugin.parcelize") version "1.6.10"
    }
    

    Other Kotlin plugins

    The same goes for the other Kotlin plugins. For example...

    plugins {
    
      // https://kotlinlang.org/docs/all-open-plugin.html
      kotlin("plugin.allopen") version "1.6.10"
    
      // https://kotlinlang.org/docs/all-open-plugin.html#spring-support
      kotlin("plugin.spring") version "1.6.10"
    
      // https://kotlinlang.org/docs/no-arg-plugin.html
      kotlin("plugin.noarg") version "1.6.10"
    
      // I can't find a Gradle Plugin ID for 
      // https://kotlinlang.org/docs/sam-with-receiver-plugin.html
      // so this won't work!
      // kotlin("kotlin-sam-with-receiver") version "1.6.10"
    }