36

Gradle myth busting: scripting

 4 years ago
source link: https://www.tuicool.com/articles/6bQrm2E
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

In the end, most of the answers cycle around the same, good old, debate: Gradle uses scripting (Groovy or Kotlin) vs Maven uses declarative. You’ll aways find people telling you that XML is better because it locks you down, its fully declarative ( is it , really?) and everybody is forced to do the same. I don’t counter those arguments, this is a strength of Maven, but it also comes with a number of drawbacks.

I promised some of the folks in the conversation some answers (please look down for direct answers to tweets), so here they are. I’m answering on a blog post because again Twitter is not good for this, it’s causing a lot of misunderstandings, because you get into multiple, parallel conversations with different people who accidentally get mentioned, and get scuds fired at you without even having time to answer… Even a blog post is not enough, there’s so much to say on this topic.

First, on the so called "declarative vs imperative" model, I will always disagree on this dichotomy. I disagree that Gradle isn’t declarative. It’s as declarative as you want it to be. Take this build file I wrote recently, which is an Asciidoctor Reveal.js presentation template (it allows writing slide decks with Asciidoctor and reveal.js). Here’s what my build file looks like:

plugins {
    id("org.gradle.presentation.asciidoctor")
}

presentation {
    githubUserName.set("melix")
}

dependencies {
    asciidoctor("org.asciidoctor:asciidoctorj-diagram:1.5.11")
}

tasks {
    asciidoctor {
        requires("asciidoctor-diagram")
    }

}

I wouldn’t particularly say this is imperative. It looks very declarative to me. Concise too. The fact it uses an imperative language is orthogonal, but it does, however, create the ability to write imperative code in the build. Note, however, that a dependency was declared for asciidoctor . This is a major, and probably the most important, difference with Maven: compile or runtime doesn’t make sense here. We declare a dependency for asciidoctor rendering . There’s no Java library being built here, it’s a presentation. Gradle lets you model precisely what you build .

So, in the end, I think what matters is not declarative vs scripting . I think what people really want is to reduce the risks of writing bad things. Locking down using XML is one way to achieve this, but it’s not the only one. For example, Gradle build scripts may be linted . In other words, you can apply on a Gradle build the same tooling you are used to work with when dealing with your own code: checkstyle, findbugs, … You don’t have to , but you can.

The consequence is that yes, there are many different ways you can layout your build with Gradle. This is not different from how you can layout your code in a project: we don’t tell you in which package you should put your beans, services, … However, there’s a big misconception that I’d like to fight:

By default, for a Java project, Gradle follows the same conventions as Maven.

That’s as simple as that. Sources will be in src/main/java . Tests will be in src/test/java . Gradle gives you the freedom to diverge from this convention, but this is not encouraged, and to be honest, I’ve almost never seen any build diverging from those conventions. On rare occasions, those were actually builds migrated from other build systems (in particular Ant) where at the time there wasn’t any convention. Gradle offers the flexibility to reuse an existing layout without much hassle.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK