Saturday, 19 March 2016

Gradle is really groovy

I am about to finish Building and Testing with Gradle. Quite an impressive piece of software, the Groovy-based Gradle. I like how it is (somewhat) procedural (like Ant), somewhat declarative (like Maven), easy to alter (like MSBuild) and based on a clear concept of interdependent units of work (like make).

Once you understand a few notions such as project, task and dependency, that’s pretty much it. Everything else can be explored with ease. For example, one can write a try.gradle inspecting little script:

task disect << {
  def t = tasks[System.properties['what']]
  t.properties.sort{it.key}.each {
    println sprintf('%1$-23s ==> %2s', "${it.key}", "${it.value.toString()}")
  }
}

and then run gradle -b try.gradle disect -Dwhat=tasks to obtain the properties of task ‘tasks’ (-Dwhat controls which task to inspect):

D:\Spikes\Gradle\HelloWorldJava>gradle -b try.gradle disect -Dwhat=tasks
:disect
actions                 ==> [org.gradle.api.internal.AbstractTask$TaskActionWrapper@5918c260, org.gradle.api.internal.Abstra
ActionWrapper@51ce6f85]
ant                     ==> org.gradle.api.internal.project.DefaultAntBuilder@148c7c4b
asDynamicObject         ==> org.gradle.api.internal.ExtensibleDynamicObject@61d34b4
class                   ==> class org.gradle.api.tasks.diagnostics.TaskReportTask_Decorated
clientMetaData          ==> org.gradle.configuration.GradleLauncherMetaData@25a5c7db
convention              ==> org.gradle.api.internal.plugins.DefaultConvention@58b71ceb
conventionMapping       ==> org.gradle.api.internal.ConventionAwareHelper@1108adc8
dependsOn               ==> [file collection]
description             ==> Displays the tasks runnable from root project 'HelloWorldJava'.
detail                  ==> false
didWork                 ==> false
enabled                 ==> true
executer                ==> org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter@11b377c5
extensions              ==> org.gradle.api.internal.plugins.DefaultConvention@58b71ceb
finalizedBy             ==> org.gradle.api.internal.tasks.DefaultTaskDependency@204e90f7
group                   ==> help
hasCustomActions        ==> false
impliesSubProjects      ==> true
inputs                  ==> org.gradle.api.internal.tasks.DefaultTaskInputs@71f0b72e
logger                  ==> org.gradle.logging.internal.slf4j.OutputEventListenerBackedLogger@ffaaaf0
logging                 ==> org.gradle.logging.internal.DefaultLoggingManager@3db663d0
mustRunAfter            ==> org.gradle.api.internal.tasks.DefaultTaskDependency@73fc518f
name                    ==> tasks
onlyIf                  ==> org.gradle.api.specs.AndSpec@5524b76d
outputFile              ==> null
outputs                 ==> org.gradle.api.internal.tasks.DefaultTaskOutputs@2650f79
path                    ==> :tasks
project                 ==> root project 'HelloWorldJava'
projectTaskLister       ==> org.gradle.api.internal.project.DefaultProjectTaskLister@7be7e15
projects                ==> [root project 'HelloWorldJava']
renderer                ==> org.gradle.api.tasks.diagnostics.internal.TaskReportRenderer@2330e3e0
services                ==> TaskScopeServices
shouldRunAfter          ==> org.gradle.api.internal.tasks.DefaultTaskDependency@706eab5d
standardOutputCapture   ==> org.gradle.logging.internal.DefaultLoggingManager@3db663d0
state                   ==> org.gradle.api.internal.tasks.TaskStateInternal@40e60ece
taskActions             ==> [org.gradle.api.internal.AbstractTask$TaskActionWrapper@5918c260, org.gradle.api.internal.Abstra
ActionWrapper@51ce6f85]
taskDependencies        ==> org.gradle.api.internal.tasks.DefaultTaskDependency@3f9270ed
temporaryDir            ==> D:\Spikes\Gradle\HelloWorldJava\build\tmp\tasks
temporaryDirFactory     ==> org.gradle.api.internal.AbstractTask$17@5fcfca62
textOutputFactory       ==> org.gradle.logging.internal.DefaultStyledTextOutputFactory@28501a4b
validators              ==> [org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$Validator@3d7b1f1c]

BUILD SUCCESSFUL

Total time: 4.632 secs
D:\Spikes\Gradle\HelloWorldJava>

As build scripts can embed Groovy code (in an orderly manner), the possibilities are endless.

Why I like Gradle

Because it is founded upon a small set of well defined concepts and combination rules. Due to the clarity of the concepts and the compositionality of the rules, the end result is a stunning world of possibilities.

Other awesome things sharing the same characteristics:

  • The Prolog programming language
  • The Git source control system
  • The ancient game of Go
  • … and … the DNA itself Smile

No comments:

Post a Comment