nebula-plugins / gradle-contacts-plugin

Structure to define the owners of a project, then contributing this back to other plugins
Apache License 2.0
14 stars 8 forks source link

Use in kotlin dsl #12

Open snowe2010 opened 6 years ago

snowe2010 commented 6 years ago

What is the appropriate use in the kotlin dsl? I cannot seem to get it to work, I think due to the methodMissing style of closure you're using

plugins {
    id("nebula.maven-publish")
    id("nebula.info")
    id("nebula.source-jar")
    id("nebula.javadoc-jar")
    id("nebula.nebula-bintray-publishing")
    id("nebula.release")
    id("org.ajoberstar.github-pages")
}

contacts {
    "tyler.b.thrailkill@gmail.com" {
        moniker "Tyler Thrailkill"
        role "owner"
    }
}

results in


Script compilation errors:

  Line 13:         moniker "Tyler Thrailkill"
                           ^ Unexpected tokens (use ';' to separate expressions on the same line)

  Line 14:         role "owner"
                        ^ Unexpected tokens (use ';' to separate expressions on the same line)

  Line 11: contacts {
           ^ Unresolved reference: contacts

  Line 12:     "tyler.b.thrailkill@gmail.com" {
               ^ Expression '"tyler.b.thrailkill@gmail.com"' of type 'String' cannot be invoked as a function. The function 'invoke()' is not found

  Line 13:         moniker "Tyler Thrailkill"
                   ^ Unresolved reference: moniker

  Line 14:         role "owner"
                   ^ Unresolved reference: role

6 errors
gildor commented 6 years ago

First of all, you should apply nebula.contacts plugin to have access to type-safe extension accessor:

id("nebula.contacts")

Next, you can add a person. But unfortunately nebula.contacts uses dynamic API to do that instead of NamedDomainObjectContainer that provides standard syntax for dynamic items. So you should use the method addPerson instead:

addPerson("tyler.b.thrailkill@gmail.com")

Another proble, that you should configure Contact, but API is also dynamic, so you have to use special adapter for dynamic Groovy closures:

addPerson("tyler.b.thrailkill@gmail.com", delegateClosureOf<Contact> {
    // Use Contact DSL here
})

And finally, Kotlin doesn't support syntax someProperty "someArg", you should use property syntax someProperty = "someArg" or method syntax setSomeProperty("someArg"), depending on case. So in your case final snippet would look like:

plugins {
    id("nebula.contacts") version "3.0.1" // Apply plugin
}

contacts {  // Use statically-typed extension accessor
    addPerson("tyler.b.thrailkill@gmail.com", delegateClosureOf<Contact> { // type-safe adapter for dynamic Groovy Closure
        moniker = "Tyler Thrailkill" // This can be assigned as property
        role("owner") // To add role to `roles` set, you also can call it directle `roles.add("owner")`
    })
}

I think nebula.contacts should be improved to support non-dynamic APIs, so final DSL for Kotlin would look like:

contacts {
    "tyler.b.thrailkill@gmail.com" {
        moniker = "Tyler Thrailkill"
        roles += "owner" // or role("owner")
    }
}

Easiest way to achive this: use NamedDomainObjectContainer as base class for contacts extension (in this case Kotlin-DSL can use NamedDomainObjectContainerScope) Or, even more simple: provid method addPerson with Action<Contact> instead of dynamic Closure to configure it.

snowe2010 commented 6 years ago

@gildor I forgot to comment back apparently. Your help worked, but I'm unsure whether to leave the issue open or not since the syntax is still pretty ugly.

gildor commented 6 years ago

@snowe2010 Yes, I think it can be improved for Kotlin DSL, maybe someone from project owners can comment

chali commented 6 years ago

Hi @gildor, @snowe2010 I agree that Kotlin DSL version is not the most elegant configuration and would be nice to improve it. Unfortunately, we are focused on other priorities now so I cannot promise this change anytime soon. If you want to contribute I'm happy to review your PRs or you can reach me out with any questions about the plugin. If you don't plan work on it I would close this issue for now.