Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Demystifying Gradle DSL

Demystifying Gradle DSL

Slides from my talk at the GrailsConf 2015, New Delhi.

Kunal Dabir

January 10, 2015
Tweet

More Decks by Kunal Dabir

Other Decks in Programming

Transcript

  1. Demystifying  Gradle  DSL
    !
    !
    Kunal  Dabir
    1

    View Slide

  2. 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

    View Slide

  3. 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

    View Slide

  4. DSL  Intro
    Repeating  the  Cliché
    4

    View Slide

  5. 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

    View Slide

  6. 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

    View Slide

  7. 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

    View Slide

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

    View Slide

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

    View Slide

  10. Gradle  Intro
    A  build  tool  that  needs  no  Intro
    10

    View Slide

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

    View Slide

  12. 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

    View Slide

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

    View Slide

  14. 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

    View Slide

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

    View Slide

  16. Groovy  Recap
    Groovy  Just  Enough  For  Gradle  DSL
    16

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  20. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  26. How  it  starts
    26

    View Slide

  27. How  it  starts
         apply  plugin:  'java'
    26

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  31. 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

    View Slide

  32. Project  API
    28

    View Slide

  33. 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

    View Slide

  34. 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

    View Slide

  35. 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

    View Slide

  36. 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

    View Slide

  37. 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

    View Slide

  38. 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

    View Slide

  39. Script  Blocks
    !
    repositories  {  
       mavenCentral()  
    }  
     
    35

    View Slide

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

    View Slide

  41. 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

    View Slide

  42. 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

    View Slide

  43. 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

    View Slide

  44. 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

    View Slide

  45. Task  API
    41

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide