• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
make builds groovy
 

make builds groovy

on

  • 2,334 views

ant, groovy, maven and gradle

ant, groovy, maven and gradle

Statistics

Views

Total Views
2,334
Views on SlideShare
2,331
Embed Views
3

Actions

Likes
1
Downloads
18
Comments
1

1 Embed 3

http://www.slideshare.net 3

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

11 of 1 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • Very useful presentation. Thanks for sharing.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    make builds groovy make builds 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: Gradle usePlugin 'java' sourceCompatibility = 1.5 version = '1.0-SNAPSHOT' repositories { © ASERT 2008-2010 mavenCentral() } dependencies { testCompile 'junit:junit:4.7' } ESDC 2010 - 15
    • Topics • Build Pain Points • Build Tool Landscape Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle • Other Tools • More Info ESDC 2010 - 16
    • 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 - 17
    • 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 - 18
    • Growing Acceptance … A slow and steady start but now gaining in momentum, maturity and mindshare Now free
    • … Growing Acceptance … © ASERT 2008-2010 ESDC 2010 - 20
    • … Growing Acceptance … © ASERT 2008-2010 Groovy and Grails downloads: 70-90K per month and growing ESDC 2010 - 21
    • … Growing Acceptance … © ASERT 2008-2010 Source: http://www.micropoll.com/akira/mpresult/501697-116746 Source: http://www.grailspodcast.co ESDC 2010 - 22
    • … Growing Acceptance … © ASERT 2008-2010 http://www.jroller.com/scolebourne/entry/devoxx_2008_whitebo http://www.java.net ESDC 2010 - 23
    • … Growing Acceptance © ASERT 2006-2010 http://pollpigeon.com/jsf-grails-wicket/r/25665/ ESDC 2010 - 24
    • … Growing Acceptance … What alternative JVM language are you using or intending to use © ASERT 2008-2010 http://www.leonardoborges.com/writings ESDC 2010 - 25
    • … Growing Acceptance … © ASERT 2008-2010 http://it-republik.de/jaxenter/quickvote/results/1/poll/44 (translated using http://babelfish.yahoo ESDC 2010 - 26
    • … Growing Acceptance © ASERT 2008-2010 ESDC 2010 - 27
    • 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 - 28
    • 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 - 29
    • 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 - 30
    • ...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 - 31
    • ...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 - 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) 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 - 33
    • ...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 - 34
    • ...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 - 35
    • ...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 - 36
    • ...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 - 37
    • ...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 - 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 [Ted, Fred, Jed, Ned] 3 Ted Jed Ned ESDC 2010 - 39
    • 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 - 40
    • 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 - 41
    • 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 - 42
    • 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 - 43
    • 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 - 44
    • ...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 - 45
    • 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 - 46
    • 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 - 47
    • 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 - 48
    • What is Maven? • Tool to assist automating (build) steps © ASERT 2008-2010 ESDC 2010 - 49
    • 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 - 50
    • ...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 - 51
    • ...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 - 52
    • ...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 - 53
    • ...Builds: GMaven © ASERT 2006-2010 ESDC 2010 - 54
    • Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 Gradle • Other Tools • More Info ESDC 2010 - 55
    • 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 - 56
    • 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 - 57
    • Gradle Examples © ASERT 2006-2010 ESDC 2010 - 58
    • Revisiting our Preview Example Switching to IDE © ASERT 2008-2010 ESDC 2010 - 59
    • Topics • Build Pain Points • Build Tool Landscape • Groovy Intro • Ant & friends • Maven & friends © ASERT 2008-2010 • Gradle Other Tools • More Info ESDC 2010 - 60
    • 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 - 61
    • 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 - 64
    • 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 - 65
    • ...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 - 66
    • GinA 2ed “ReGinA” is coming ... © ASERT 2006-2010