hands on the gradle
DESCRIPTION
A talk I did on the DroidCon 2011 barcamp, it's on Gradle and its Android plug-inTRANSCRIPT
S
Hands on the Gradle Painless Android builds
© 2011 Matthias Käppler Qype GmbH
What is Gradle?
S Gradle is a task based build system. From files and configuration it assembles build artifacts.
S Gradle is flexible. It is not bound to any specific process or technology.
S Gradle uses a Groovy based DSL to write configuration. This makes it easy to read and write Gradle scripts.
The Gradle manifesto
S „Build scripts are code.“
S Don‘t expect, allow.
S Don‘t re-invent, re-use.
S Don‘t inherit, inject.
S Scale to the complexity of a problem. – „Make the impossible possible, the possible easy, and the easy elegant.“
Gradle vs. Maven
<build> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <phase>install</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo message="what’s with the bloat?" /> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build>
Gradle vs. Maven (cont.)
println "dunno, must be a Maven thing."
Gradle vs. Maven (cont.)
S Maven is declarative. Gradle is imperative.
S Maven is verbose. Gradle is concise.
S Maven assumes Maven. Gradle doesn‘t.
S Maven scales poorly to simple problems. Gradle scales with the complexity of a problem.
Gradle vs. Maven (cont.)
S Maven has a rich plug-in ecosystem. Gradle still needs to catch-up here.
S Maven has very good IDE support. Gradle has... IDE support.
S Maven has project archetypes. Gradle doesn‘t.
How is Gradle used?
$ls build/ build.gradle ...
...
$gradle tasks
$gradle clean build
$gradle androidInstall androidInstrument
build.gradle
env = System.getenv()
dependsOnChildren()
apply from: ‘shared.gradle'
allprojects { apply plugin: 'java' }
task hello << { println ‘hello from Gradle‘ }
Demo
Move along, nothing to see here.
More about tasks
S There are different ways how tasks can be used or exposed in a build script: 1 – by writing them 2 – through project.ant 3 – by applying a plug-in
Writing tasks
task hello << { 4.times { println ‘hello from Gradle‘ } } hello.dependsOn initLang hello.someProperty = 1
Writing tasks (cont.)
project.task(‘hello‘, dependsOn: ‘initLang‘) greeter = { println it } hello.doLast greeter.curry(‘hello from Gradle‘)
Ant tasks
S Ant tasks are first class citizens in Gradle. You access them through Groovy‘s AntBuilder DSL.
myProp = ant.properties["my.prop"] ant.copy { from zipTree("/path/to/lib.jar") into "$buildDir/extracted-classes" exclude "com.example/**" }
Plug-ins
S Most of Gradle‘s functionality comes from plug-ins. This helps in keeping the core Gradle APIs lean and clean.
apply plugin: 'java' apply plugin: 'maven' ... $gradle clean install
Plug-ins (cont.)
S Writing Gradle plug-ins is very simple. Check this out.
class MyPlugin implements Plugin<Project> { def apply(Project project) { project.task(‘hello‘) << { println ‘hello, people‘ } } }
Dependencies
S Gradle doesn‘t define ist own dependency management system. Instead, it builds on Apache Ivy.
repositories { mavenCentral() mavenRepo urls: "http://my.repo.com" flatDir dirs: "libs" }
Dependencies (cont.)
S Dependencies are grouped into configurations. A configuration is simply a set of files bound to a name.
dependencies { compile "commons-lang:commons-lang:2.5" compile fileTree(dir: "libs", include: "*.jar") testCompile "junit:junit:4.8.2" }
Android
S There‘s a Gradle plug-in for Android.
https://github.com/jvoegele/gradle-android-plugin
Setting it up
S Now: buildscript { repositories { mavenRepo(urls: 'http://jvoegele.com/maven2/‘) } dependencies { classpath 'com.jvoegele.gradle.plugins:android-plugin:0.9.8‘ } } apply plugin: com.jvoegele.gradle.plugins.android.AndroidPlugin
S Soon: apply plugin: 'android'
What‘s in store
S The plug-in adds the following tasks: S :androidProcessResourcesS :androidPackageS :androidInstallS :androidInstrumentS [:proguard]$gradle clean andInstall :test-proj:andInstr
Instrumentation tests
androidInstrument { runners { run testpackage: "unit", with: "com.my.UnitTestRunner",
name: "instrumentation-unit-tests" run annotation: "android.test.suitebuilder.annotation.Smoke" run with: "com.my.OtherTestRunner”, options: "…” } }
Thanks
Thanks for listening!
Android in Practice
Charlie Collins, Michael Galpin, Matthias Käppler • Real world practical recipes • Focus on intermediate to professional developers • Two chapters on testing and build automation
Summer 2011 MEAP edition available http://manning.com/collins