Make Your Builds More Groovy
Upcoming SlideShare
Loading in...5
×
 

Make Your Builds More Groovy

on

  • 4,297 views

Groovy with Ant, Maven and Gradle

Groovy with Ant, Maven and Gradle

Statistics

Views

Total Views
4,297
Views on SlideShare
4,273
Embed Views
24

Actions

Likes
3
Downloads
93
Comments
0

2 Embeds 24

http://www.slideshare.net 23
http://paper.li 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Make Your Builds More Groovy Make Your Builds More Groovy Presentation Transcript

    • © ASERT 2008-2010 Make Your Builds More Groovy Dr Paul King paulk@asert.com.au @paulk_asert ASERT, Australia ESDC 2010 - 1
    • Topics Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle • Other Tools • More Info ESDC 2010 - 2
    • Build Pain Points... • Has anyone seen? – Large monolithic balls of mud – Complex usage, assumptions, conventions – Impossible to bend in desired ways – Never been (can't be) refactored/tested – © ASERT 2008-2010 Many manual steps – Environment fragile • different machines, CI vs IDE, dev vs prod vs test ESDC 2010 - 3
    • ...Build Pain Points... • Require powerful features – Dependency management – Version management – Polyglot compilation – Artifact production and manipulation (jar, war, ...) – Templating (generation of boilerplate text files) © ASERT 2008-2010 – Multifacted testing – Reporting – Quality control (Metrics, code quality, static analysis) – Property management – Infinitely(?) extensible ESDC 2010 - 4
    • ...Build Pain Points • Useful characteristics – Tool friendly – Cross platform – IDE support, CI support – Refactorable – Testable © ASERT 2008-2010 – Minimal noise (DSL like) – Easy to extend – Conventions – Good documentation – Polyglot friendly ESDC 2010 - 5
    • Topics • Build Pain Points Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle • Other Tools • More Info ESDC 2010 - 6
    • Build Tools • Non-exhaustive list – Ant, Maven, EasyAnt – Gant, GMaven, Gradle, Graven (uptake?), Groovy Frontend for Ant (emerge from sandbox?) – Rake, Raven, Buildr – Make, SCons, Waf © ASERT 2008-2010 – MSBuild, Nant • Used by – Developers: NetBeans, Eclipse, Intellij, Command-line – CI: Hudson (Groovy support and console), Team City, CruiseControl, AnthillPro (Groovy support), Bamboo – Deployment Management: Tableaux (Groovy support) – Ad-hoc: batch processing, production applications ESDC 2010 - 7
    • Pros/Cons of Traditional Tools • Ant • Maven – Flexible (supports any – Opinionated about convention) conventions – Easy to extend • Mostly a good thing – Wealth of useful tasks – Mostly declarative – Well documented • XML != concise DSL – Numerous plugins © ASERT 2008-2010 – Partially declarative but some scope for – Some easy extension procedural instructions points but some more • XML != prog. language difficult options – Lifecycle is hand-crafted • Some things beyond some teams in your build file – Structured lifecycle – Can use Ivy or Maven Ant tasks for dependency management ESDC 2010 - 8
    • Enhancing Traditional Tools • Ant + Groovy • Maven + Groovy – Easy to write the – Easier to extend procedural pieces – More concise syntax – Easier to refactor – Some scope for – Easier to test refactoring – Ease of creating a build © ASERT 2008-2010 DSL – More concise – Better interaction with • Gradle Java – Take the best of both – No impedence worlds and combine mismatch with them developers ESDC 2010 - 9
    • A Preview Example... © ASERT 2008-2010 ESDC 2010 - 10
    • ...A Preview Example... StringUtils: Vanilla Ant + Ivy <project name="StringUtilsBuild" default="package" <?xml version="1.0" encoding="ISO-8859-1"?> xmlns:ivy="antlib:org.apache.ivy.ant" xmlns="antlib:org.apache.tools.ant"> <target name="clean"> <ivy-module version="1.0"> <delete dir="target"/> <info organisation="org" module="groovycookbook" /> <delete dir="lib"/> <dependencies> </target> <dependency name="junit" rev="4.7" /> <target name="compile" depends="-init-ivy"> </dependencies> <mkdir dir="target/classes"/> </ivy-module> <javac srcdir="src/main" destdir="target/classes"/> </target> <target name="compileTest" depends="compile"> <mkdir dir="target/test-classes"/> <ivysettings> <javac srcdir="src/test" <settings defaultResolver="chained"/> destdir="target/test-classes"> <resolvers> <classpath> <chain name="chained" returnFirst="true"> <pathelement location="target/classes"/> <ibiblio name="ibiblio" /> <fileset dir="lib" includes="*.jar"/> <url name="ibiblio-mirror"> </classpath> </javac> <artifact </target> pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/ © ASERT 2008-2010 [module]/[branch]/[revision]/[branch]-[revision].[ext]" /> <target name="test" depends="compileTest"> </url> <mkdir dir="target/test-reports"/> </chain> <junit printsummary="yes" fork="yes" haltonfailure="yes"> </resolvers> <classpath> </ivysettings> <pathelement location="target/classes"/> <pathelement location="target/test-classes"/> <fileset dir="lib" includes="*.jar"/> </classpath> <formatter type="plain"/> <formatter type="xml"/> <batchtest fork="yes" todir="target/test-reports"> <fileset dir="target/test-classes"/> </batchtest> </junit> </target> <target name="package" depends="test"> <jar destfile="target/stringutils-1.0-SNAPSHOT.jar" basedir="target/classes"/> </target> <target name="-init-ivy" depends="-download-ivy"> <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpath="lib/ivy.jar"/> <ivy:settings file="ivysettings.xml"/> <ivy:retrieve/> </target> <target name="-download-ivy"> <property name="ivy.version" value="2.1.0-rc2"/> <mkdir dir="lib"/> <get src="http://repo2.maven.org/maven2/org/apache/ivy/ivy/${ivy.version}/ivy- ${ivy.version}.jar" dest="lib/ivy.jar" usetimestamp="true"/> </target> </project> ESDC 2010 - 11
    • ...A Preview Example... StringUtils: Groovy's AntBuilder ... import static groovy.xml.NamespaceBuilder.newInstance as namespace def test() { ant = new AntBuilder() compileTest() clean() ant.mkdir dir: 'target/test-reports' doPackage() ant.junit(printsummary: 'yes', haltonfailure: 'yes', fork: 'yes') { classpath { def doPackage() { pathelement location: 'target/classes' test() pathelement location: 'target/test-classes' ant.jar destfile: 'target/stringutils-1.0-SNAPSHOT.jar', fileset dir: 'lib', includes: '*.jar' basedir: 'target/classes' } } formatter type: 'plain' formatter type: 'xml' private dependencies() { batchtest(todir: 'target/test-reports', fork: 'yes') { def ivy_version = '2.1.0-rc2' fileset dir: 'target/test-classes' def repo = 'http://repo2.maven.org/maven2' } ant.mkdir dir: 'lib' } ant.get dest: 'lib/ivy.jar', } usetimestamp: 'true', src: "$repo/org/apache/ivy/ivy/$ivy_version/ivy-${ivy_version}.jar" ant.taskdef classpath: 'lib/ivy.jar', © ASERT 2008-2010 uri: 'antlib:org.apache.ivy.ant', resource: 'org/apache/ivy/ant/antlib.xml' def ivy = namespace(ant, 'antlib:org.apache.ivy.ant') ivy.settings file: 'ivysettings.xml' ivy.retrieve() <?xml version="1.0" encoding="ISO-8859-1"?> } <ivy-module version="1.0"> <info organisation="org" module="groovycookbook" /> def clean() { <dependencies> ant.delete dir: 'target' ant.delete dir: 'lib' <dependency name="junit" rev="4.7" /> } </dependencies> </ivy-module> def compile() { dependencies() ant.mkdir dir: 'target/classes' ant.javac destdir: 'target/classes', srcdir: 'src/main', <ivysettings> includeantruntime: false <settings defaultResolver="chained"/> } <resolvers> <chain name="chained" returnFirst="true"> def compileTest() { <ibiblio name="ibiblio" /> compile() <url name="ibiblio-mirror"> ant.mkdir dir: 'target/test-classes' <artifact ant.javac(destdir: 'target/test-classes', srcdir: 'src/test', pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/ includeantruntime: false) { [module]/[branch]/[revision]/[branch]-[revision].[ext]" /> classpath { </url> pathelement location: 'target/classes' </chain> fileset dir: 'lib', includes: '*.jar' </resolvers> } </ivysettings> } } ... ESDC 2010 - 12
    • ...A Preview Example... StringUtils: Gant ... import static groovy.xml.NamespaceBuilder.newInstance as namespace target(test: '') { target('package': '') { depends 'compileTest' depends 'test' mkdir dir: 'target/test-reports' jar destfile: 'target/stringutils-1.0-SNAPSHOT.jar', junit(printsummary: 'yes', haltonfailure: 'yes', fork: 'yes') { basedir: 'target/classes' classpath { } pathelement location: 'target/classes' pathelement location: 'target/test-classes' target('-download-ivy': '') { fileset dir: 'lib', includes: '*.jar' def ivy_version = '2.1.0-rc2' } def repo = 'http://repo2.maven.org/maven2' formatter type: 'plain' mkdir dir: 'lib' formatter type: 'xml' get dest: 'lib/ivy.jar', batchtest(todir: 'target/test-reports', fork: 'yes') { usetimestamp: 'true', fileset dir: 'target/test-classes' src: "$repo/org/apache/ivy/ivy/$ivy_version/ivy-${ivy_version}.jar" } } } } target(clean: '') { delete dir: 'target' setDefaultTarget 'package' delete dir: 'lib' © ASERT 2008-2010 } target(compile: '') { depends '-init-ivy' mkdir dir: 'target/classes' <?xml version="1.0" encoding="ISO-8859-1"?> javac destdir: 'target/classes', srcdir: 'src/main' <ivy-module version="1.0"> } <info organisation="org" module="groovycookbook" /> <dependencies> target('-init-ivy': '') { depends '-download-ivy' <dependency name="junit" rev="4.7" /> taskdef classpath: 'lib/ivy.jar', </dependencies> uri: 'antlib:org.apache.ivy.ant', </ivy-module> resource: 'org/apache/ivy/ant/antlib.xml' def ivy = namespace(ant, 'antlib:org.apache.ivy.ant') ivy.settings file: 'ivysettings.xml' ivy.retrieve() <ivysettings> } <settings defaultResolver="chained"/> <resolvers> target(compileTest: '') { <chain name="chained" returnFirst="true"> depends 'compile' <ibiblio name="ibiblio" /> mkdir dir: 'target/test-classes' <url name="ibiblio-mirror"> javac(destdir: 'target/test-classes', srcdir: 'src/test') { <artifact classpath { pattern="http://mirrors.ibiblio.org/pub/mirrors/maven2/[organisation]/ pathelement location: 'target/classes' [module]/[branch]/[revision]/[branch]-[revision].[ext]" /> fileset dir: 'lib', includes: '*.jar' </url> } </chain> } </resolvers> } </ivysettings> ... ESDC 2010 - 13
    • ...A Preview Example... StringUtils: Maven <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.groovycookbook.builds</groupId> <artifactId>stringutils</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>stringutils</name> <url>http://maven.apache.org</url> <dependencies> © ASERT 2008-2010 <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <!-- this is a java 1.5 project --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </build> </project> ESDC 2010 - 14
    • ...A Preview Example... StringUtils: Maven 3 Groovy Dialect project { modelVersion '4.0.0' groupId 'org.groovycookbook.builds' artifactId 'stringutils' packaging 'jar' version '1.0-SNAPSHOT' name 'stringutils' url 'http://maven.apache.org' dependencies { dependency 'junit:junit:4.7:test' © ASERT 2008-2010 } build { plugins { /* this is a java 1.5 project */ plugin { groupId 'org.apache.maven.plugins' artifactId 'maven-compiler-plugin' configuration { source '1.5' target '1.5' } } } } } ESDC 2010 - 15
    • ...A Preview Example StringUtils: Gradle usePlugin 'java' sourceCompatibility = 1.5 version = '1.0-SNAPSHOT' repositories { © ASERT 2008-2010 mavenCentral() } dependencies { testCompile 'junit:junit:4.7' } ESDC 2010 - 16
    • Topics • Build Pain Points • Build Tool Landscape Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle • Other Tools • More Info ESDC 2010 - 17
    • What is Groovy? • “Groovy is like a super version of Java. It can leverage Java's enterprise capabilities but also has cool productivity features like closures, DSL support, builders and dynamic typing.” © ASERT 2008-2010 Groovy = Java – boiler plate code + optional dynamic typing + closures + domain specific languages + builders + metaprogramming + GDK library ESDC 2010 - 18
    • Groovy Goodies Overview • Fully object oriented • Closures: reusable and assignable pieces of code • Operators can be • GPath: efficient overloaded © ASERT 2008-2010 object navigation • Multimethods • GroovyBeans • Literal declaration for • grep and switch lists (arrays), maps, ranges and regular • Templates, builder, expressions swing, Ant, markup, XML, SQL, XML-RPC, Scriptom, Grails, tests, Mocks ESDC 2010 - 19
    • Growing Acceptance … A slow and steady start but now gaining in momentum, maturity and mindshare Now free
    • … Growing Acceptance … © ASERT 2008-2010 ESDC 2010 - 21
    • … Growing Acceptance … © ASERT 2008-2010 Groovy and Grails downloads: 70-90K per month and growing ESDC 2010 - 22
    • … Growing Acceptance … © ASERT 2008-2010 Source: http://www.micropoll.com/akira/mpresult/501697-116746 Source: http://www.grailspodcast.co ESDC 2010 - 23
    • … Growing Acceptance … © ASERT 2008-2010 http://www.jroller.com/scolebourne/entry/devoxx_2008_whitebo http://www.java.net ESDC 2010 - 24
    • … Growing Acceptance © ASERT 2006-2010 http://pollpigeon.com/jsf-grails-wicket/r/25665/ ESDC 2010 - 25
    • … Growing Acceptance … What alternative JVM language are you using or intending to use © ASERT 2008-2010 http://www.leonardoborges.com/writings ESDC 2010 - 26
    • … Growing Acceptance … © ASERT 2008-2010 http://it-republik.de/jaxenter/quickvote/results/1/poll/44 (translated using http://babelfish.yahoo ESDC 2010 - 27
    • … Growing Acceptance © ASERT 2008-2010 ESDC 2010 - 28
    • The Landscape of JVM Languages mostly dynamic typing © ASERT 2008-2010 Dynamic features call for dynamic types Java bytecode calls for static types The terms “Java Virtual Machine” and “JVM” mean a Virtual Machine for the Java™ platform. ESDC 2010 - 29
    • Groovy Starter System.out.println("Hello, World!"); // optional semicolon, println 'Hello, World!' // System.out, brackets, // main() method, class defn def name = 'Guillaume' // dynamic typing println "$name, I'll get the car." // GString String longer = """${name}, the car is in the next row.""" // multi-line string // with static typing © ASERT 2008-2010 assert 0.5 == 1/2 // BigDecimal equals() def printSize(obj) { // optional duck typing print obj?.size() // safe dereferencing } def pets = ['ant', 'bee', 'cat'] // native list syntax pets.each { pet -> // closure support assert pet < 'dog' // overloading '<' on String } // or: for (pet in pets)... ESDC 2010 - 30
    • A Better Java... import java.util.List; import java.util.ArrayList; class Erase { private List removeLongerThan(List strings, int length) { This code List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { is valid String s = (String) strings.get(i); if (s.length() <= length) { Java and } result.add(s); valid Groovy } return result; © ASERT 2008-2010 } public static void main(String[] args) { List names = new ArrayList(); names.add("Ted"); names.add("Fred"); names.add("Jed"); names.add("Ned"); System.out.println(names); Erase e = new Erase(); Based on an List shortNames = e.removeLongerThan(names, 3); System.out.println(shortNames.size()); example by for (int i = 0; i < shortNames.size(); i++) { Jim Weirich String s = (String) shortNames.get(i); System.out.println(s); & Ted Leung } } } ESDC 2010 - 31
    • ...A Better Java... import java.util.List; import java.util.ArrayList; class Erase { private List removeLongerThan(List strings, int length) { Do the List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { semicolons String s = (String) strings.get(i); if (s.length() <= length) { add anything? } result.add(s); And shouldn‟t } we us more return result; © ASERT 2008-2010 } modern list public static void main(String[] args) { List names = new ArrayList(); notation? names.add("Ted"); names.add("Fred"); names.add("Jed"); names.add("Ned"); Why not System.out.println(names); import common Erase e = new Erase(); List shortNames = e.removeLongerThan(names, 3); libraries? System.out.println(shortNames.size()); for (int i = 0; i < shortNames.size(); i++) { String s = (String) shortNames.get(i); System.out.println(s); } } } ESDC 2010 - 32
    • ...A Better Java... class Erase { private List removeLongerThan(List strings, int length) { List result = new ArrayList() for (String s in strings) { if (s.length() <= length) { result.add(s) } } return result } public static void main(String[] args) { List names = new ArrayList() © ASERT 2008-2010 names.add("Ted"); names.add("Fred") names.add("Jed"); names.add("Ned") System.out.println(names) Erase e = new Erase() List shortNames = e.removeLongerThan(names, 3) System.out.println(shortNames.size()) for (String s in shortNames) { System.out.println(s) } } } ESDC 2010 - 33
    • ...A Better Java... class Erase { private List removeLongerThan(List strings, int length) { List result = new ArrayList() for (String s in strings) { if (s.length() <= length) { result.add(s) Do we need } } the static types? } return result Must we always have a main public static void main(String[] args) { List names = new ArrayList() method and © ASERT 2008-2010 names.add("Ted"); names.add("Fred") names.add("Jed"); names.add("Ned") class definition? System.out.println(names) Erase e = new Erase() How about List shortNames = e.removeLongerThan(names, 3) improved System.out.println(shortNames.size()) for (String s in shortNames) { consistency? System.out.println(s) } } } ESDC 2010 - 34
    • ...A Better Java... def removeLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) } } return result } © ASERT 2008-2010 names = new ArrayList() names.add("Ted") names.add("Fred") names.add("Jed") names.add("Ned") System.out.println(names) shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) for (s in shortNames) { System.out.println(s) } ESDC 2010 - 35
    • ...A Better Java... def removeLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) Shouldn‟t we } } have special return result notation for lists? } And special © ASERT 2008-2010 names = new ArrayList() facilities for names.add("Ted") names.add("Fred") list processing? names.add("Jed") Is „return‟ names.add("Ned") needed at end? System.out.println(names) shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) for (s in shortNames) { System.out.println(s) } ESDC 2010 - 36
    • ...A Better Java... def removeLongerThan(strings, length) { strings.findAll{ it.size() <= length } } names = ["Ted", "Fred", "Jed", "Ned"] System.out.println(names) shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) shortNames.each{ System.out.println(s) } © ASERT 2008-2010 ESDC 2010 - 37
    • ...A Better Java... def removeLongerThan(strings, length) { strings.findAll{ it.size() <= length } } Is the method names = ["Ted", "Fred", "Jed", "Ned"] now needed? System.out.println(names) shortNames = removeLongerThan(names, 3) Easier ways to System.out.println(shortNames.size()) use common shortNames.each{ System.out.println(s) } methods? © ASERT 2008-2010 Are brackets required here? ESDC 2010 - 38
    • ...A Better Java... names = ["Ted", "Fred", "Jed", "Ned"] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } © ASERT 2008-2010 ESDC 2010 - 39
    • ...A Better Java names = ["Ted", "Fred", "Jed", "Ned"] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } © ASERT 2008-2010 [Ted, Fred, Jed, Ned] 3 Ted Jed Ned ESDC 2010 - 40
    • Topics • Build Pain Points • Build Tool Landscape • Groovy Intro Ant & friends  Calling Groovy from Ant © ASERT 2008-2010  Calling Ant from Groovy  Gant • Maven & friends • Gradle • Other Tools • More Info ESDC 2010 - 41
    • What is Ant? • Tool to assist automating (build) steps <project name="MyProject" default="dist" basedir="."> <property name="src" location="src"/> <property name="build" location="build"/> © ASERT 2008-2010 <target name="init"> <mkdir dir="${build}"/> </target> <target name="compile" depends="init" description="compile the source"> <javac srcdir="${src}" destdir="${build}"/> </target> </project> ESDC 2010 - 42
    • Groovy from Ant • Need groovy jar on your Ant classpath <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="my.classpath"/> © ASERT 2006-2010 <target name="printXmlFileNamesFromJar"> <zipfileset id="found" src="foobar.jar" includes="**/*.xml"/> <groovy> project.references.found.each { println it.name } </groovy> </target> ESDC 2010 - 43
    • Groovyc from Ant • Need groovy jar on your Ant classpath <taskdef name="groovyc" classname="org.codehaus.groovy.ant.Groovyc" classpathref="my.classpath"/> <groovyc srcdir="${testSourceDirectory}" © ASERT 2006-2010 destdir="${testClassesDirectory}"> <classpath> <pathelement path="${mainClassesDirectory}"/> <pathelement path="${testClassesDirectory}"/> <path refid="testPath"/> </classpath> <javac source="1.5" target="1.5" debug="on" /> </groovyc> ESDC 2010 - 44
    • AntBuilder... def ant = new AntBuilder() ant.echo("hello") // let's just call one task // create a block of Ant using the builder pattern ant.with { myDir = "target/AntTest/" mkdir(dir: myDir) © ASERT 2006-2010 copy(todir: myDir) { fileset(dir: "src/test") { include(name: "**/*.groovy") } } echo("done") } // now let's do some normal Groovy again file = new File("target/test/AntTest.groovy") assert file.exists() Needs ant.jar on your Groovy classpath ESDC 2010 - 45
    • ...AntBuilder • Built-in new AntBuilder().with { echo(file:'Temp.java', ''' class Temp { public static void main(String[] args) { System.out.println("Hello"); } © ASERT 2006-2010 } ''') javac(srcdir:'.', includes:'Temp.java', fork:'true') java(classpath:'.', classname:'Temp', fork:'true') echo('Done') } // => // [javac] Compiling 1 source file // [java] Hello // [echo] Done ESDC 2010 - 46
    • Using AntLibs: Maven Ant Tasks & AntUnit import static groovy.xml.NamespaceBuilder.newInstance as namespace def ant = new AntBuilder() def mvn = namespace(ant, 'antlib:org.apache.maven.artifact.ant') def antunit = namespace(ant, 'antlib:org.apache.ant.antunit') direct = [groupId:'jfree', artifactId:'jfreechart', version:'1.0.9'] indirect = [groupId:'jfree', artifactId:'jcommon', version:'1.0.12'] // download artifacts mvn.dependencies(filesetId:'artifacts') { dependency(direct) } © ASERT 2006-2010 // print out what we downloaded ant.fileScanner { fileset(refid:'artifacts') }.each { println it } // use AntUnit to confirm expected files were downloaded def prefix = System.properties.'user.home' + '/.m2/repository' [direct, indirect].each { item -> def (g, a, v) = [item.groupId, item.artifactId, item.version] antunit.assertFileExists(file:"$prefix/$g/$a/$v/$a-${v}.jar") } C:Userspaulk.m2repositoryjfreejcommon1.0.12jcommon-1.0.12.jar C:Userspaulk.m2repositoryjfreejfreechart1.0.9jfreechart-1.0.9.jar ESDC 2010 - 47
    • Builds: Gant • lightweight façade on Groovy's AntBuilder • target def’ns, pre-defined ‘ant’, operations on predefined objects includeTargets << gant.targets.Clean cleanPattern << [ '**/*~' , '**/*.bak' ] cleanDirectory << 'build' © ASERT 2006-2010 target ( stuff : 'A target to do some stuff.' ) { println ( 'Stuff' ) depends ( clean ) echo ( message : 'A default message from Ant.' ) otherStuff ( ) } target ( otherStuff : 'A target to do some other stuff' ) { println ( 'OtherStuff' ) echo ( message : 'Another message from Ant.' ) clean ( ) } ESDC 2010 - 48
    • Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends Maven & friends © ASERT 2008-2010  Writing plugins in Groovy  Building your Groovy project • Gradle • Other Tools • More Info ESDC 2010 - 49
    • What is Maven? • Tool to assist automating (build) steps © ASERT 2008-2010 ESDC 2010 - 50
    • Builds: GMaven... • Implementing Maven plugins has never been Groovier! • Groovy Mojos – A Simple Groovy Mojo • Building Plugins – Project Definition © ASERT 2006-2010 – Mojo Parameters • Putting More Groove into your Mojo – Using ant, Using fail() • gmaven-archetype-mojo Archetype • gmaven-plugin Packaging ESDC 2010 - 51
    • ...Builds: GMaven... <plugin> <groupId>org.codehaus.groovy.maven</groupId> <artifactId>gmaven-plugin</artifactId> <executions> <execution> <phase>generate-resources</phase> <goals> <goal>execute</goal> </goals> <configuration> © ASERT 2006-2010 <source> if (project.packaging != 'pom') { log.info('Copying some stuff...') def dir = new File(project.basedir, 'target/classes/META-IN ant.mkdir(dir: dir) ant.copy(todir: dir) { fileset(dir: project.basedir) { include(name: 'LICENSE.txt') include(name: 'NOTICE.txt') } } } </source> </configuration> </execution> </executions> </plugin> ESDC 2010 - 52
    • ...Builds: GMaven... <plugin> <groupId>org.codehaus.mojo.groovy</groupId> <artifactId>groovy-maven-plugin</artifactId> <executions> <execution> <id>restart-weblogic</id> © ASERT 2006-2010 <phase>pre-integration-test</phase> <goals> <goal>execute</goal> </goals> <configuration> <source> ${pom.basedir}/src/main/script/restartWeblogic.groovy </source> </configuration> </execution> ... ESDC 2010 - 53
    • ...Builds: GMaven... def domainDir = project.properties['weblogic.domain.easyimage.dir'] stopWebLogic() copyFiles(domainDir) startWebLogic(domainDir) © ASERT 2006-2010 waitForWebLogicStartup() def stopWebLogic() { weblogicServerDir = project.properties['weblogic.server.dir'] adminUrl = project.properties['easyimage.weblogic.admin.t3'] userName = 'weblogic' password = 'weblogic' ant.exec(executable: 'cmd', failonerror: 'false') { arg(line: "/C ${wlsDir}/bin/setWLSEnv.cmd && java ..." ... } ... ESDC 2010 - 54
    • ...Builds: GMaven © ASERT 2006-2010 ESDC 2010 - 55
    • Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 Gradle • Other Tools • More Info ESDC 2010 - 56
    • What is Gradle? • Tool to assist automating (build) steps task hello << { println 'Hello world!' } task intro(dependsOn: hello) << { © ASERT 2008-2010 println "I'm Gradle" } > gradle -q intro Hello world! I'm Gradle ESDC 2010 - 57
    • Gradle Features • A very flexible general purpose build tool like Ant • Switchable, build-by-convention frameworks a la Maven. But we never lock you in! • Very powerful support for multi-project builds • Very powerful dependency management (based on Apache Ivy) • Full support for your existing Maven or Ivy repository © ASERT 2006-2010 infrastructure • Support for transitive dependency management without the need for remote repositories or pom.xml and ivy.xml files • Ant tasks as first class citizens • Groovy build scripts • A rich domain model for describing your build ESDC 2010 - 58
    • Gradle Examples © ASERT 2006-2010 ESDC 2010 - 59
    • Revisiting our Preview Example Switching to IDE © ASERT 2008-2010 ESDC 2010 - 60
    • Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle Other Tools • More Info ESDC 2010 - 61
    • Hudson • Gant Plugin — This plugin allows Hudson to invoke Gant build script as the main build step • Gradle Plugin — This plugin allows Hudson to invoke Gradle build script as the main build step • Grails Plugin — This plugin allows Hudson to invoke Grails tasks as build steps © ASERT 2006-2010 • Hudson CLI and GroovyShell Source: http://weblogs.java.net/blog/kohsuke/archive/2009/05/hudson_cli_and.html ESDC 2010 - 62
    • Hudson: Groovy Postbuild Plugin... if (manager.logContains(".*uses or overrides a deprecated API.*")) { manager.addWarningBadge("Thou shalt not use deprecated methods.") manager.createSummary("warning.gif").appendText( "<h1>You have been warned!</h1>", false, false, false, "red") manager.buildUnstable() } © ASERT 2006-2010 Source: http://wiki.hudson-ci.org/display/HUDSON/Groovy+Postbuild+Plugin
    • ...Hudson: Groovy Postbuild Plugin regex = 'src/main/java/(.*).java:[^ ]* (.*) is Sun proprietary API and may be removed in a future release' map = [:] manager.build.logFile.eachMatch(regex) { full, ownClass, sunClass -> map[ownClass.replaceAll("/", ".")] = sunClass } if (map) { manager.createSummary("warning.gif").with { appendText("Classes using Sun proprietary API:<ul>", false) map.each { k, v -> appendText("<li><b>$k</b> - uses $v</li>", false) © ASERT 2006-2010 } appendText("</ul>", false) } } Adapted from: http://wiki.hudson-ci.org/display/HUDSON/Groovy+Postbuild+Plugin
    • Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle • Other Tools More Info ESDC 2010 - 65
    • More Information... • Ant – http://ant.apache.org – http://groovy.codehaus.org/The+groovy+Ant+Task – http://groovy.codehaus.org/Using+Ant+from+Groovy – http://groovy.codehaus.org/Using+Ant+Libraries+with +AntBuilder © ASERT 2008-2010 – http://gant.codehaus.org/ • Maven – http://maven.apache.org – http://gmaven.codehaus.org • Gradle – http://gradle.org ESDC 2010 - 66
    • ...More Information... • Groovy Web sites – http://groovy.codehaus.org – http://grails.codehaus.org – http://pleac.sourceforge.net/pleac_groovy (many examples) – http://www.asert.com.au/training/java/GV110.htm (workshop) • Groovy User Mailing list – user@groovy.codehaus.org © ASERT 2006-2010 • Groovy Information portals – http://www.aboutgroovy.org – http://www.groovyblogs.org • Groovy Documentation (1000+ pages) – Getting Started Guide, User Guide, Developer Guide, Testing Guide, Cookbook Examples, Advanced Usage Guide ESDC 2010 - 67
    • GinA 2ed “ReGinA” is coming ... © ASERT 2006-2010