jreleaser / jreleaser

:rocket: Release projects quickly and easily with JReleaser
https://jreleaser.org
Apache License 2.0
952 stars 111 forks source link

Awkwardness with Gradle Kotlin DSL #624

Closed yschimke closed 2 years ago

yschimke commented 2 years ago

Task List

Steps to Reproduce

Attempt to configure jreleaser in the Gradle Kotlin DSL project

Expected Behaviour

distributions should use jreleaser block

Actual Behaviour

Gradle default distributions is used instead

image

Environment Information

Please paste stacktraces from [out|build|target]/jreleaser/trace.log.

yschimke commented 2 years ago

Close if kotlin dsl support is out of scope, otherwise I'll catalogue any confusing issues here.

yschimke commented 2 years ago

Also requires a lot of

field.set(...) like

  this.distributions.create("okurl") {
    active.set(org.jreleaser.model.Active.ALWAYS)
aalmiray commented 2 years ago

I suppose the confusion with the distributions name is that there are 2 possible options:

  1. coming from the application or distribution Gradle plugin.
  2. coming from the jreleaser extension.

Isn't the use of <property>.set(...) the standard way? AFAICT Gradle should provide magic bridges to let the Kotlin DSL be as terse as its Groovy counterpart, shouldn't it? JReleaser uses Gradle's standard Property/Provider APIs already.

yschimke commented 2 years ago

I suspect there is some magic kotlin-dsl helpers that make it work cleanly for highly used plugins.

It's loosely discussed here https://docs.gradle.org/current/userguide/kotlin_dsl.html

But yeah, no problem calling .get() for now. I hope you don't mind these reports, trying to give useful feedback.

aalmiray commented 2 years ago

Please, continue. I don't use the Kotlin DSL at all, but try to follow best practices to implement plugin features that so that both DSLs work as expected. Which is why I find it surprising that the magic accessors are not accessible for the Kotlin DSL (I see your project is using [almost] latest Gradle [7.3.3 being latest as of today]).

yschimke commented 2 years ago

I'll take a look at how it works for other plugins and submit a PR if I work it out.

aalmiray commented 2 years ago

FWIW the project block inside jreleaser did not cause trouble but you'll get in trouble if you try to read a project property to assign a value, such as

gradle.properties

website = https://acme.com

build.gradle.kts

jreleaser {
    project {
        website = project.website
    }
}

Results in endless recursion and a StackOverflowError. You have to alias propject properties to avoid using the project. prefix.

aalmiray commented 2 years ago

I wonder if the problem with the distributions block inside jreleaser extension is one of wrong scope applied by the Gradle runtime given the fact that it works without any problems using the Groovy DSL. May be worth asking at the Gradle forum or their Community Slack.

yschimke commented 2 years ago

Asked in https://discuss.gradle.org/t/name-conflict-resolution-ordering/41791 and https://discuss.gradle.org/t/idiomatic-kotlin-plugins-property-get-set/41790

yschimke commented 2 years ago

Some suggestions on https://discuss.gradle.org/t/name-conflict-resolution-ordering/41791/2

The better solution is within the org.jreleaser plugin. As I just shortly described the relevant precedence rules, you might have guessed it already. If the JReleaserExtensions has a member function called distributions which takes an Action<>, then it will win over the extensions function as member functions always win if possible.

Even an extension function JReleaserExtension.distributions would work as then the extension function on the inner scope would win over the extension function on the outer scope.

aalmiray commented 2 years ago

Hmm jreleaser.distributions is a NamedDomainObjectContainer exposed as is, not through a function. wonder how would that be setup.

aalmiray commented 2 years ago

@yschimke latest commit fixes the problem with named containers