Slide 1

Slide 1 text

Demystifying  Gradle  DSL ! ! Kunal  Dabir 1

Slide 2

Slide 2 text

About  the  Talk • Prerequisites   • Basic  understanding  of  build  systems   • Some  exposure  to  Gradle   • Beginner  level  of  exposure  to  Groovy/Java   ! • Takeaways   • Learn  a  trick  or  two  to  read  and  write  DSLs   • A  simpler  way  to  look  at  Gradle  Scripts 2

Slide 3

Slide 3 text

Introduction  (About  me) • Love  writing  code  in  Groovy,  Java,  Ruby,  Scala  and   JavaScript  (CoffeeScript).     • Work  at  ThoughtWorks   • Co-­‐organizer  of  Pune  Java  User  Group   • Projects  hosted  on  Github   • (want  to  get  better  at)  running,  playing  drums  and   writing  book 3

Slide 4

Slide 4 text

DSL  Intro Repeating  the  Cliché 4

Slide 5

Slide 5 text

Domain  Specific  Language • “A  Domain  Specific  Language  (DSL)  is  a  programming   language  designed  specifically  to  express  solutions  to   problems  in  a  specific  domain”   ! ! ! ! ! • http://c2.com/cgi/wiki?DomainSpecificLanguage   • http://en.wikipedia.org/wiki/Domain-­‐specific_language 5

Slide 6

Slide 6 text

Example  of  DSL ! create("my-­‐project")  {      dir("src/main/java")  {          file("Hello.java")  {              """       ………              """.stripIndent()          }      }      file  "build.gradle",  "apply  plugin:  'java'"      file  "README.md",  "#  Hello  World  Project"   }   ! ! Directree:    https://github.com/kdabir/directree 6

Slide 7

Slide 7 text

Example  of  DSL ! create("my-­‐project")  {      dir("src/main/java")  {          file("Hello.java")  {              """                  public  static  void  main(String[]  args){                          System.out.println("Hello  World");                  }              """.stripIndent()          }      }      file  "build.gradle",  "apply  plugin:  'java'"      file  "README.md",  "#  Hello  World  Project"   }   Directree:    https://github.com/kdabir/directree 7

Slide 8

Slide 8 text

External  v/s  Internal  DSL   • Internal   • Sinatra     • Ratpack   • Gradle   • MarkupBuilder   !     ! ! ! ! ! ! ! ! ! ! • External     • Apache  httpd  config   • Gherkin  (cucumber)   • Make   • Markdown   ! ! ! 8

Slide 9

Slide 9 text

External  v/s  Internal  DSL   • Groovy  MarkupBuilder   !    builder.html  {          body  {              h1  "hello  MarkupBuilder"          }      }   ! • Markdown   !    #  hello  Markdown 9

Slide 10

Slide 10 text

Gradle  Intro A  build  tool  that  needs  no  Intro 10

Slide 11

Slide 11 text

Gradle  intro • an  advanced  build  system   • follows  conventions   • yet  very  flexible   • Groovy  build  scripts   • rich  domain  model  for  build   • …  And  much  more 11

Slide 12

Slide 12 text

Follows  Conventions • Create  a  build.gradle  file  in  project  root  :   !    apply  plugin:  'java'   ! • A  valid  minimal  Java  project  build  file   • It  can  build  a  Jar  of  project   • Uses  conventional  src/main/java  for  source  files 12

Slide 13

Slide 13 text

Provides  Flexibility • For  example,  Changing  source  directories:   !    sourceSets  {          main.java.srcDir  'src'          test.java.srcDir  'test'      } 13

Slide 14

Slide 14 text

Reuses  Existing  Infrastructure • Find  dependencies  in  MavenCentral   !    repositories  {          mavenCentral()      }   ! • And  use  them  in  your  project   !    dependencies  {          compile  'org.slf4j:slf4j-­‐api:1.7.9'          testCompile  'junit:junit:4.10'      }   14

Slide 15

Slide 15 text

Supports  Adding  Extra  Behaviour • By  defining  custom  tasks   !    task  sayHello  <<  {          println  "Hello  Gradle  users"      }   15

Slide 16

Slide 16 text

Groovy  Recap Groovy  Just  Enough  For  Gradle  DSL 16

Slide 17

Slide 17 text

Lists • Defining   !        def  list  =  []              list  =  [1,2,3]       • Accessing   !        println  list[2] 17

Slide 18

Slide 18 text

Maps • Defining   !        def  map  =  [:]              map  =  [a:4,  b:5]       • Accessing   !        println  map.a              println  map['b']   18

Slide 19

Slide 19 text

Closures • Declaring   !        def  closure  =  {}              closure  =  {  println  "closure  is  powerful"}   ! • Calling   !          closure.call()              closure()              closure("groovy")   19

Slide 20

Slide 20 text

Closure  Parameters • Sometimes  it’s  magic   !        closure  =  {  println  "$it  is  powerful"}              closure("groovy")   !        //  groovy  is  powerful       • Multiple  parameters   !        def  adder  =  {a,b  -­‐>  a  +  b}              println  adder(1,2)   20

Slide 21

Slide 21 text

Methods   • Declaring  a  method  that  takes  a  Map   !        def  method(Map  options)  {                def  a  =  options.a  ?:  10                def  b  =  options.b  ?:  20          }   ! 21

Slide 22

Slide 22 text

Methods   • Calling   !        method([a:30,b:40])      ! • Can  also  be  called  like   !        method(a:30,  b:40)      ! • Optionally   !        method(a:20) 22

Slide 23

Slide 23 text

Methods   • A  method  that  takes  a  Closure   !        def  repeat(int  a,  Closure  c)  {                a.times  {  c.call()  }          } 23

Slide 24

Slide 24 text

Methods   • Calling   !        repeat(2,  {println  "fun  begins"})   ! • Can  also  be  called  like   !        repeat(2)  {                println  "fun  begins"          } 24

Slide 25

Slide 25 text

Putting  it  all  together makes  a  powerful  DSL  for  build  scripts 25

Slide 26

Slide 26 text

How  it  starts 26

Slide 27

Slide 27 text

How  it  starts      apply  plugin:  'java' 26

Slide 28

Slide 28 text

How  it  starts      apply  plugin:  'java'      apply(plugin:  'java') 26

Slide 29

Slide 29 text

How  it  starts      apply  plugin:  'java'      apply(plugin:  'java')      apply([plugin:  'java']) 26

Slide 30

Slide 30 text

How  it  starts      apply  plugin:  'java'      apply(plugin:  'java')      apply([plugin:  'java'])      project.apply([plugin:  'java']) 26

Slide 31

Slide 31 text

And  the  credit  goes  to… Project void apply(Map options)! Configures this project using plugins or scripts. The following options are available: !•! from: A script to apply to the project. Accepts any path supported by Project.uri(). !•! plugin: The id or implementation class of the plugin to apply to the project. !•! to: The target delegate object or objects. Use this to configure objects other than the project. For more detail, see ObjectConfigurationAction. ! • http://www.gradle.org/docs/current/dsl/ org.gradle.api.Project.html#org.gradle.api.Project:apply(java.util.Map) 27

Slide 32

Slide 32 text

Project  API 28

Slide 33

Slide 33 text

Project  API • Central  API  to  the  Gradle  build  script   • Available  as  ‘project’  reference  in  build  script   • Build  Script  is  evaluated  against  the  instance  of  this   project  object.   • Available  implicitly  in  the  script  top  level*   • methods/properties  are  looked  up  on  this  object   by  default.   • One  project  per  build.gradle 29

Slide 34

Slide 34 text

Project  Object • Properties   void  setDescription(String  description)   Sets  a  description  for  this  project.   ! • Methods   boolean  delete(Object...  paths)   Deletes  files  and  directories.   ! • Script  blocks   void  dependencies(Closure  configureClosure)   Configures  the  dependencies  for  this  project. 30

Slide 35

Slide 35 text

Project  Properties • Setting  project  properties  like  :   !    group  =  'org.example'      version  =  '0.1'      description  =  'An  awesome  groovy  library'   ! • Find  properties  declared  on  Project  API.     • Make  sure  they  are  not  read-­‐only. 31

Slide 36

Slide 36 text

Project  Properties • Getters  and  Setters  on  project  object.     getBuildDir()/setBuildDir(Object  path)   • Can  be  set  using  groovy  property  notation     buildDir  =  “…”   ! • Extra  properties   • can  be  declared  using  ext  namespace.     ext.myProp  =  “abc”   • it  becomes  property  of  project       println  project.myProp 32

Slide 37

Slide 37 text

Where  do  methods  come  from  ? ! • Methods  defined  on  Project  itself   • Find  those  in  Project  API  Documentation   ! • Methods  declared  in  the  build  file   • def  myMethod  … 33

Slide 38

Slide 38 text

Where  do  methods  come  from  ? • Extension/Conventions  added  by  plugins   • Plugins  can  add  more  methods  to  project   • like  sourceSets  is  added  by  java  plugin   ! • Each  task  becomes  a  method  on  project   • Each  task  name  becomes  a  method   ! ! taskA { description = “some task” }! • so  that  task  can  be  easily  referenced  in  a  script   ! •  Methods  of  parent  project 34

Slide 39

Slide 39 text

Script  Blocks ! repositories  {      mavenCentral()   }     35

Slide 40

Slide 40 text

Script  Blocks ! repositories  {      mavenCentral()   }       can  be  rewri`en  as:     ! project.repositories  ({      mavenCentral()   }) 36

Slide 41

Slide 41 text

Script  Blocks • Special  methods   • Takes  in  a  Closure  as  parameter   • Delegates  to  a  special  Handler  whose  methods  are   available  in  the  block’s  context   ! ! ! ! ! http://www.gradle.org/docs/current/dsl/org.gradle.api.Project.html#N1486F   37

Slide 42

Slide 42 text

Script  Blocks  -­‐  Example ! repositories  {  …  }   ! • RepositoryHandler  Handles  the  methods  calls   made  in  context  of  repositories  script  block   • Methods  like     mavenCentral()     jcenter()     ivy()   ! http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.dsl.RepositoryHandler.html   38

Slide 43

Slide 43 text

Script  Blocks  -­‐  Another  Example ! dependencies  {  …  }   ! • Delegates  to  DependencyHandler   • Executes  the  closure  in  against  the   DependenciesHandler   • methods  like  compile,  testCompile   ! ! http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.dsl.DependencyHandler.html 39

Slide 44

Slide 44 text

Script  Blocks allprojects { } Configures this project and each of its sub-projects. ! artifacts { } Configures the published artifacts for this project. ! buildscript { } Configures the build script classpath for this project. ! configurations { } Configures the dependency configurations for this project. ! dependencies { } Configures the dependencies for this project. ! repositories { } Configures the repositories for this project. ! sourceSets { } Configures the source sets of this project. ! subprojects { } Configures the sub-projects of this project. ! publishing { } Configures the PublishingExtension added by the publishing plugin. 40

Slide 45

Slide 45 text

Task  API 41

Slide 46

Slide 46 text

Creating  Task  Objects • Project  works  as  a  Task  Factory   • Project  has  overloaded  task  method   • All  of  which  return  an  instance  of  Task 42

Slide 47

Slide 47 text

Creating  Task  Objects ! task(String  name)   ! ! task(String  name,  Closure  configureClosure)   ! ! task(Map  args,  String  name)   ! ! task(Map  args,  String  name,                 Closure  configureClosure)   43

Slide 48

Slide 48 text

Task  Action  -­‐  the  concise  way ! ! ! task  sayHello  <<  {      println  "Hello  Gradle  user"   } 44

Slide 49

Slide 49 text

Task  Config ! ! ! sayHello  {      group  =  "my  tasks"      description  =  "greets  user"   } 45

Slide 50

Slide 50 text

Config  as  map ! ! ! task  sayBye  (description  :  "says  bye",                              group  :  "my  tasks") 46

Slide 51

Slide 51 text

Task  object’s  methods ! ! ! sayBye.doLast  {      println  "B-­‐bye"   }   ! ! ! http://www.gradle.org/docs/current/javadoc/org/gradle/api/Task.html   47

Slide 52

Slide 52 text

Available  Tasks ! ! $  gradle  tasks   …   My  tasks  tasks   -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   sayBye  -­‐  says  bye   sayHello  -­‐  greets  user 48

Slide 53

Slide 53 text

Execute  tasks   ! ! $  gradle  sH  sB   :sayHello   Hello  Gradle  user   :sayBye   B-­‐bye   ! 49

Slide 54

Slide 54 text

Bookmark  These ! • Read  the  DSL   • http://www.gradle.org/docs/current/dsl/     ! ! • Read  the  JavaDoc   • http://www.gradle.org/docs/current/javadoc/   50

Slide 55

Slide 55 text

Questions Questions  are  guaranteed  in  life,  answers  aren’t  :-­‐) 51

Slide 56

Slide 56 text

Thank  You @kdabir   https://github.com/kdabir 52