Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

How to Write Gradle Scripts with Kotlin DSL — Better than Groovy?

In this article, we will setup a basic project, convert .gradle files to use Kotlin and learn how to manage project dependencies with Kotlin DSL.

Prerequisites

  • Android Studio 3.1
  • Latest Gradle version 4.5.1

What is DSL?

You might have heard of such term as DSL and GPL. But what do they actually mean and how are they different?

DSL, Domain-specific language. It’s a programming language used for writing very specific parts of an application, a certain «domain» of an app if you will. SQL, HTML, Groovy — that sounds familiar, right?

Those are examples of using DSLs at its finest. You are using SQL to write a part of your app that is communicating with a database, HTML for markups of a web page, Groovy for writing scripts to assemble your project and manage dependencies, etc. DSL does not provide us with wide functionality. However, it offers an effective solution for a very specific task.

GPL, General-purpose language. In contrast to DSL, these are languages like Kotlin, JAVA, C#, Python, etc. They are more versatile, provide you with more features and are usually a primary tool for writing your application code.

What is Kotlin DSL?

When creating a DSL based on any of the general-purpose language we are not talking about creating a completely new programming language with a brand new syntax. We are just setting up a particular way of using this particular language. Thus we are now able to use means of Kotlin to write Gradle scripts and plugins instead of Groovy language.

Advantages:

  • Proper IDE support: auto-completion, refactoring, navigation to source, etc. This is possible due to Kotlin being statically-typed language
  • Automatic detection of imports
  • Utilizing cool Kotlin features like extension methods, first-class functions
  • Using a familiar syntax
  • Mixing Kotlin DSL scripts with Groovy-based scripts. E.g. having build.gradle of one module written with Groovy, and another module — with Kotlin DSL

Update Gradle version

We will use the lates Gradle version, as it includes the latest Kotlin DSL version. Specify the version in yout gradle-wrapper.properties:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://
services.gradle.org/distributions/gradle-4.5.1-all.zip

Create buildSrc directory

Gradle offers several ways to organize your build logic. One of them is to create a buildSrc directory in the root of your application project. When you run Gradle, it checks for the existence of a directory called buildSrc.

Gradle then automatically compiles and tests this code and puts it in the classpath of your build script. You don’t need to provide any further instruction. This can be a good place to add your custom tasks and plugins.

For multi-project builds there can be only one buildSrc directory, which has to be in the root project directory.

Create a directory tree like the following:

Basically your buildSrc contains src/main/java directory (looks very much like ordinary directory structure for your app’s source code).

This way you can write code in a JVM language of your choice (Java or Kotlin) and to use it right there in your build scripts. Moreover you could cover some tricky parts of it with unit tests. But in this project we’ll do without unit testing as we just stick to defining a Config kotlin file where we will specify dependencies and their versions which we’ll be referring to later in our build script.

Take a look at the Config.kt:

We have a top level singleton class Config which contains:

  • Versions — values for dependencies versions
  • BuildPlugins — interpolated string literals with versions taken from Versions class
  • Android — class with some basic Android configuration values
  • Libs — interpolated string literals for specifying dependencies itself

In the root of buildSrc create a build.gradle.kts file and enable kotlin-dsl plugin:

Modify app module .gradle file

It’s just a matter of adding an extension to your build.gradle file. Rename it into build.gradle.kts.

This will allow Gradle to use Kotlin files when assembling your project.

But not right away:

Wow, everything is red! Lots of unresolved references, how do we even compile this?

Firstly we need to do a bit of refactoring to migrate from Groovy syntax to Kotlin.

Configuring plugins

This is how we use Kotlin to tell Gradle to build plugins for the project:

We have two functions come into play:

  • id() for regular plugins
  • kotlin() for kotlin plugins

id() function expexts a plugin id as an input. Take note that it case of community plugins it expects a fully-qualified plugin id like this:

id(«com.plugin.id”) version «1.10.11»

whereas core plugins can be added with a short name:

id(«java»)

If we look under the hood of kotlin() function it is essentially an id() function with a hardcoded artifact groupID with an interpolated string literal you pass into the function as a module ID:

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

To find out plugins ids’ you can check out the list of kotlin plugins here:

Gradle - Plugins

Configuring ‘android’ block

Here we do our routine configuration, but in a bit different way — ‘android’ is a kotlin extension function. Inside of it we are configuring our app project with values we defined previously in Config.kt file in buildSrc directory:

As you see, we are just referring to values via objects we made inside Config.kt. What you might have noticed is that such elements as compileSdkVersion, buildToolsVersion, etc are now functions and we are passing values inside them. And as far as applicationId, versionCode and versionName are concerned we are using property access syntax here.

Another difference is the way we define build types for the project. Doing like this will no longer suffice:

Instead, we need to retrieve BuildType object with a function getByName(name: String) which gets object by it’s name. We get release build type object by it’s name and configure it. The same way you can configure debug build type.

Last but not the least here is declaring the actual dependencies:

This is another example of using kotlin extension functions — dependencies {}. Inside of it we specify project dependencies. The syntax here is also differs a bit — implementation(), compile() and api() are also functions, which we feed dependencies ids and versions to.

If you are curious, the other way around here would be to do it like this:

«implementation»(Config.Libs.kotlin_stdlib)

Not a big deal, it’s precisely the same, but if you come across such a notation you won’t get taken aback :)

Configue project-level build.gradle

Just as previously with app-level build.gradle add the extension .kts to the file name and do a bit of a refactoring:

It looks almost the same as the good old Groovy-style build script except for the function syntax we’ve already come across, specifically inside the dependency {} block:

classpath() is a function we pass id’s of our plugins to get dependencies for the buildscript.

Conclusion

Now we can run the app and see that everything works just as if we are still using groovy as usual. But that feeling of realizing your app is getting built and structured with the sweet fancy Kotlin language is invaluable! Stay tuned for updates and check out the source code for this project at Github

jetruby/kotlin-dsl-example

P/S — If you liked the article, please support it with claps (you can press and hold the clap button for long claps).
Also, if you’d like to know more about the technical side of things or want to develop your own Android app, feel free to drop us a line at [email protected]

How to Write Gradle Scripts with Kotlin DSL — Better than Groovy? was originally published in JetRuby on Medium, where people are continuing the conversation by highlighting and responding to this story.



This post first appeared on JetRuby Agency - Featured Technical Stories Based In Our Experience, please read the originial post: here

Share the post

How to Write Gradle Scripts with Kotlin DSL — Better than Groovy?

×

Subscribe to Jetruby Agency - Featured Technical Stories Based In Our Experience

Get updates delivered right to your inbox!

Thank you for your subscription

×