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

Gradle Basics

Anton
April 19, 2016

Gradle Basics

I gave a talk about Gradle basics at the Google Developer Group meetup at Dresden at the 19.04.2016.

Anton

April 19, 2016
Tweet

More Decks by Anton

Other Decks in Programming

Transcript

  1. > General information & Groovy > Gradle Quickstart > Build

    script basics & execution > Tasks > Dependency Management > Plugins Contents
  2. > Build automation tool (like Ant or Maven) > handles

    full workflow of building, testing, deploying software > declarative, “build-by-convention” > Open Source (Apache 2.0) What is Gradle?
  3. > based on Java, runs in JVM > build declarations

    in Groovy -> uses Gradle DSL (Domain Specific Language) > supports currently Java, Groovy, Scala > additional plugins for > runtime integration (OSGi, Jetty/war, ..) > software development (checkstyle, findbugs, sonar ..) > deep API to hook into every point of execution Specs
  4. > running on JVM (can interoperate w/ java code/libs) >

    dynamic, object oriented language (like Ruby or Python) > easy scripting > compact code (rich set of default imports) World!” Groovy //Java System.out.println(“Hello World!”); //Groovy println “Hello World!”
  5. > property accessors: property references automatically converted into a call

    to the getter/setter method > simplified lists and maps Groovy def technologies = ["Gradle","Griffon"] technologies.each { println "Technology: $it"} //Add values devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy'] devMap.put('lastName','Perez') //Iterate over elements of a map devMap.each { println "$it.key: $it.value" }
  6. > Closures > open, anonymous, block of code > can

    take arguments > can return a value and be assigned to a variable > may reference variables declared in its surrounding scope Groovy def x = 5 def multiplyBy = { num -> num * x } println multiplyBy(10)
  7. > every Gradle build consists of > One ore more

    Projects > project is made up of one or more Tasks > Tasks are structured on a task graph (DAG: directed acyclic graph) > You can hook into every stage of execution via the TaskExecutionListener Build Script Basics
  8. Gradle build execution Initialization Configuration Execution 1 2 3 >

    Configure environment: init.gradle, gradle.properties > check and execute the settings.gradle file (only for multi-project builds) > determine which projects are going to take part in the build > create a Project instance for each project
  9. Gradle build execution Initialization Configuration Execution 1 2 3 >

    evaluate build scripts of all projects > uses each projects build.gradle file > build task execution graph
  10. Gradle build execution Initialization Configuration Execution 1 2 3 >

    determine set of tasks which were created and configured during configuration phase > set is defined by the arguments passed to gradle/gradlew call > each task is executed
  11. Gradle build execution println 'This is executed during the configuration

    phase.' task configured { println 'This is also executed during the configuration phase.' } task test { doFirst { println 'This is executed first during the execution phase.' } doLast { println 'This is executed last during the execution phase.' } println 'This is executed during the configuration phase as well.' } build.gradle println 'This is executed during the initialization phase.' settings.gradle
  12. Gradle build execution > gradlew test This is executed during

    the initialization phase. This is executed during the configuration phase. This is also executed during the configuration phase. This is executed during the configuration phase as well. :test This is executed first during the execution phase. This is executed last during the execution phase. BUILD SUCCESSFUL Total time: 1 secs Console
  13. > Basic unit of work > created by user, executed

    by Gradle > have one primary action Tasks task helloWorld << { println 'Hello World!' } >gradlew helloWorld :helloWorld Hello World!
  14. > Can be defined in diverse ways Tasks task myTask

    task myTask { configure closure } task myTask << { task action } task myTask(type: SomeType) task myTask(type: SomeType) { configure closure } task (myTask) << { task action } ...
  15. > Tasks can depend on other tasks Task Dependencies task

    helloWorld { println 'Hello World!' } task helloGradle (dependsOn: helloWorld) { println 'Hello Gradle!' } >gradlew helloGradle :helloWorld Hello World! :helloGradle Hello Gradle!
  16. > Tasks can be ordered > dependsOn > finalizedBy (e.g.

    in case of error) > mustRunAfter (only applied if both tasks run) > shouldRunAfter (less strict than mRA, when ordering not essential) Task Dependencies task helloWorld << { println 'Hello World!' } task helloGradle { mustRunAfter helloWorld doLast{ println 'Hello Gradle!' } }
  17. Task Dependencies task helloWorld << { println "Hello World!" }

    task helloGradle (){ mustRunAfter helloWorld finalizedBy "helloException" doFirst{ throw new Exception("FAIL!") } doLast{ println "Hello Gradle!" } } task helloException << { println "Hello Exception!" } Sample >gradlew hW hG Console :helloWorld Hello World! :helloGradle FAILED :helloException Hello Exception! FAILURE: Build failed with an exception.
  18. > Gradle offers several basic task types to extend from

    > Copy > Exec > Zip > … Custom Tasks task('copy', type: Copy) { from(file('srcDir')) into(buildDir) }
  19. > write your own task type by extending DefaultTask >

    declare action with @TaskAction annotation Custom Tasks class MyTask extends DefaultTask { @TaskAction void sayHello() { println "Hello!" } } task hello(type: MyTask)
  20. > a task can be skipped when: > inputs did

    not change > outputs are still there and did not change > shown as UP-TO-DATE > change detection via > snapshot of input & output files > hash of contents of each file > snapshots persisted until next execution Incremental Builds
  21. > remote or local repositories > Maven Central, jCenter, JitPack,

    … > Maven, Ivy > file dependency (on the local filesystem) > project dependencies (multi-project build) Managing Dependencies
  22. Managing Dependencies apply plugin: 'java' repositories { mavenCentral() } dependencies

    { // by String (GAV - group:artifact:version): compile 'junit:junit:4.10', 'org.mockito:mockito-core:1.9.0' // by Map: compile group: 'junit', name: 'junit', version: '4.10' // repository-less dependencies via FileCollection, FileTree instances: compile files('file1.jar'), fileTree('lib') // project dependencies: compile project(':otherProject') }
  23. > add custom repositories Managing Dependencies repositories { maven {

    url "http://repo.mycompany.com/maven2" } flatDir { dirs 'lib' } ivy { url "http://repo.mycompany.com/repo" layout "pattern", { artifact "[module]/[revision]/[type]/[artifact].[ext]" } } }
  24. > build logic packaged into Plugin container for > Reuse

    (avoid copy&paste) > Encapsulation (hide your implementation) > Modularity (clean, maintainable code) > Composition (plugins can complement each other) > typical use cases > extend basic Gradle model > add new tasks, extend specific model > configure your project Plugins
  25. > types of Plugins > Script Plugins (local or remote)

    > Binary Plugins Plugins apply from: "myscriptplugin.gradle" build.gradle task taskFromPlugin() { doLast { println "added by a script plugin!" } } myscriptplugin.gradle
  26. > Binary plugins are implementations of the Plugin interface >

    typically compiled and reused via JARs Binary Plugins package my.org class MyPlugin implements Plugin { void apply(Project project) { Task myTask = project.tasks.add("myTask") myTask.doLast { println "added by a binary plugin!" } } }
  27. > apply via the class object or plugin id >

    plugin id defined in .properties file Binary Plugins apply plugin: my.org.MyPlugin apply plugin: "my-plugin" implementation-class=my.org.MyPlugin META-INF/gradle-plugins/my-plugin.properties
  28. Plugin Extension // Extensions are just plain objects, there is

    no interface/type class MyExtension { String foo MyExtension(String foo) { this.foo = foo } } // Add new extensions via the extension container project.extensions.create('custom', MyExtension) //apply within project custom { foo "bar" }