SlideShare a Scribd company logo
1 of 69
Download to read offline
Tuesday, 22 June 2010
Tuesday, 22 June 2010
Agenda
             What are we discussing today?
               What makes a good build script?
               Smelly build scripts
               Choosing your tools
               Maven tips
               Ant tips




Tuesday, 22 June 2010
Introduction
             Quality build scripts - why bother
               Maintenance costs
               Learning curve
               Turn-over
               Portability
               Automation




Tuesday, 22 June 2010
Build quality - quality builds
             What makes a good build script?
               Gold Standard
               Portable
               Reproducible
               Standard
               Maintainable




Tuesday, 22 June 2010
Build quality - quality builds
             Gold Standard
               Reference build process
               Reference binaries




Tuesday, 22 June 2010
Build quality - quality builds
             Portable
               Runs anywhere
               Runs on any OS
               No local dependencies
                  Environment-specific configurations
                  Specially-installed software or databases
                  ...




Tuesday, 22 June 2010
Build quality - quality builds
             Reproducible
               “Play it again, Sam”




Tuesday, 22 June 2010
Build quality - quality builds
             Standard
               Knowing what to expect




Tuesday, 22 June 2010
Build quality - quality builds
             Maintainable
               Think of the next dude




Tuesday, 22 June 2010
Smelly builds
             So what makes a poor build script?
          1) The hard coded build
          2) The OS-specific build
          3) The IDE-only build
          4) The Magic Machine build
          5) The Oral Tradition build
          6) The Nested build
          7) The Messy Dependencies build
          8) The DYI build
          9) The untrustworthy build
          10) The slow build




Tuesday, 22 June 2010
Paths
                                                                       ..
                                                                    1/




                                                                            URLs
Smelly builds




                                                                  9.
                                                               c-
                                                             gi
                                                          lo




                                                                                               1
                                                        eb




                                                                                            00



                                                                                                           Passwords
                                                     /w




                                                                                         :7
                                                                                      om
                                                   ea




                                                                                   .c
                                               /b




                                                                                me
                                              C:




                                                                             ac
                                                                          r.
                                                                       ve
                                                                    er
                                                                 ts
                                                              es                                               .>
                                                           /t                                              "..
                                                        :/                                             ger
                                                                                                  "ti
                                                     tp                                       rd=
                The hard coded build




                                                  ht                                     swo
                                                                                   pas
                                                                            tt"
                                                                       sco
                                                                  e="
                                                            nam
                                                      ser
                                                  n u
                                              <sv
                                                                                                                            />
                                                                                                                     M E }"
                                                                                                                S_HO
                                                                                                           JBOS
                                                                                                      env.
                                                                                               = "$ {
                                                                                       alue
                                                                                s" v




                                                                                                         Environment
                                                                        jbos
                                                                 dir.
                                                          me="




                                                                                                          variables
                                                   y na
                                              pert
                                       <pro




                                                                                                                                 Tuesday, 22 June 2010
Smelly builds
             The hard coded build

             <target name="checkstyle">
                                                          Hard-coded directories
                 <delete dir="./reports" quiet="true" />
                 <mkdir dir="./reports" />
                 <checkstyle config="./docs/sun_checks.xml">
                   <formatter type="xml" tofile="./reports/checkstyle.xml"/>
                   <fileset dir="./src" includes="**/*.java"/>
                 </checkstyle>

                 <style in="./reports/checkstyle.xml"
                        out="./reports/checkstyle.html"
                        style="checkstyle.xsl"/>

             </target>




Tuesday, 22 June 2010
Smelly builds
             The hard coded build

        <target name="checkstyle">                Project-relative directory
    <property name=”reports.checkstyle.dir”
          <delete dir="./reports" quiet="true" />
              value=”${basedir}/reports”/>
          <mkdir dir="./reports" />                         DRY
          <checkstyle config="./docs/sun_checks.xml">
    <target name="checkstyle">
            <formatter type="xml" tofile="./reports/checkstyle.xml"/>
      <delete dir="${reports.checkstyle.dir}" quiet="true" />
      <mkdir<fileset dir="./src" includes="**/*.java"/>
             dir="${reports.checkstyle.dir}" />
          </checkstyle>
      <checkstyle config="./docs/sun_checks.xml">
        <formatter type="xml"
          <style in="./reports/checkstyle.xml"
                    tofile="${reports.checkstyle.dir}/checkstyle.xml"/>
        <fileset out="./reports/checkstyle.html"
                 dir="./src" includes="**/*.java"/>
                 style="checkstyle.xsl"/>
      </checkstyle>

           </target>
         <style in="${reports.checkstyle.dir}/checkstyle.xml"
                out="${reports.checkstyle.dir}/checkstyle.html"
                style="checkstyle.xsl"/>

    </target>

Tuesday, 22 June 2010
Smelly builds
             The hard coded build
  <target name="war" >
    <war destfile="c:/tomcat/jakarta-tomcat-5.0.19/webapps/app.war"
         webxml="${src}/app.xml" basedir="${bin}" />
  </target>


                        Hard-coded directories




Tuesday, 22 June 2010
Smelly builds
             The hard coded build
  <property name="wardir"
            location="c:/tomcat/jakarta-tomcat-5.0.19/webapps"/>

  <target name="war" >
    <war destfile="${wardir}" webxml="${src}/app.xml"
         basedir="${bin}" />
  </target>
                        Still hard-coded




Tuesday, 22 June 2010
Smelly builds
             The hard coded build




      <svn username="scott" password="tiger">
        <checkout url="http://subversion.acme.com/myapp/trunk"
                  destPath="${subproject.dir}" />
      </svn>

                        Hard-coded username/password




Tuesday, 22 June 2010
Smelly builds
             The hard coded build




                 <property environment="env"/>
                 <property name="dir.jboss" value="${env.JBOSS_HOME}"/>




                                         Environment variable




Tuesday, 22 June 2010
Smelly builds
             The OS-specific build


           <exec command="grep "@" ${build.dir} | wc -l"
                 outputproperty="token.count"/>




Tuesday, 22 June 2010
Smelly builds
             The OS-specific build
            ...
            CALL PAUSE.CMD
            ...
            build.cmd

                  ...
                  :: Check for a non-existent IP address
                  :: Note: this causes a small extra delay!
                  IF NOT DEFINED NonExist SET NonExist=10.255.255.254
                  PING %NonExist% -n 1 -w 100 2>NUL | FIND "TTL=" >NUL
                  ...
                        pause.cmd




Tuesday, 22 June 2010
Smelly builds
             The IDE-only build




Tuesday, 22 June 2010
Smelly builds
             The Magic Machine build



                                                          Directories

                                            App servers


                                Databases


                        Configuration files


               Environment variables


                Installed software or tools


Tuesday, 22 June 2010
Smelly builds
             The Magic Machine build


                <proprerty weblogic.dir="/u01/app/bea/weblogic-9.1"/>

                                                          Directories

                                            App servers


                                Databases


                        Configuration files


               Environment variables


                Installed software or tools


Tuesday, 22 June 2010
Smelly builds
             The Oral Tradition build




Tuesday, 22 June 2010
Smelly builds
             The Nested Build

              #! /bin/sh
              ANT_HOME=/u01/app/tools/ant-1.7.1
              ...
              $ANT_HOME/ant $1
              project/tools/ant.sh




Tuesday, 22 June 2010
Smelly builds
             The Nested Build

      <target name="build-subproject">
        <svn username="scott" password="tiger">
          <checkout url="http://subversion.acme.com/someproject/trunk"
                    destPath="${subproject.dir}" />
        </svn>

        <ant dir="${subproject.dir}" target="build-all" />
      </target>
       build.xml




Tuesday, 22 June 2010
Smelly builds
             The Messy Dependencies build
               JAR files in the SCM
               Unversioned JAR files
               Unclear dependencies




Tuesday, 22 June 2010
Smelly builds
             The DYI build
               “Not invented here”
               DYI dependencies
               DYI deployments
               DYI Maven releases
               ...




Tuesday, 22 June 2010
Smelly builds
             The untrustworthy build
               <junit fork="yes" haltonfailure="false" dir="${basedir}">
                 <classpath refid="test.class.path" />
                 <classpath refid="project.class.path"/>
                 <formatter type="plain" usefile="true" />
                 <formatter type="xml" usefile="true" />
                 <batchtest fork="yes" todir="${logs.junit.dir}">
                 <fileset dir="${test.unit.dir}">
                   <patternset refid="test.sources.pattern"/>
                 </fileset>
                 </batchtest>
               </junit>




Tuesday, 22 June 2010
Smelly builds
             The slow build




Tuesday, 22 June 2010
Choosing your tools
             Flexibility verses Convention
               What’s better: flexibility or standards?
               It depends what you’re doing...




Tuesday, 22 June 2010
Choosing your tools
                                                                            Encourage/enforce

                 Standards and Conventions              Support standards
                                                                                standards


                                                                                                3
          Easy to read




                                                                                                2
                                        Make up your
                                        own standards




                         No standards
          Hard to read




          Ad-hoc scripting                                      Standards and Conventions



Tuesday, 22 June 2010
Choosing your tools
                 Flexibility and expressiveness
                                                  3                      Do whatever you
          Easy to read



                                                                              want


                                 2
                         Encourage/enforce
                             standards
          Hard to read




     Makes you stick to conventions                   Easy to do whatever you want



Tuesday, 22 June 2010
Choosing your tools
             Flexibility verses Convention
               Build Scripting Rule 1
                        “A build script will tend to reflect the personality of
                                            it’s developer”




Tuesday, 22 June 2010
Choosing your tools
             Flexibility verses Convention
               Build Scripting Rule 2
                        “The more flexible a build script, the more likely it
                                is to become unmaintainable”




Tuesday, 22 June 2010
Choosing your tools
             Flexibility verses Convention
               Flexibility is great for some jobs:
                  Ad-hoc tasks
                  Some deployment tasks
                  “Out-of-the-box” stuff




Tuesday, 22 June 2010
Choosing your tools
             Flexibility verses Convention
               But convention pay off in lower maintenance costs




Tuesday, 22 June 2010
Ant tips
             Better Ant scripts
               Consistent conventions
               Declare your dependencies
               Make it readable
               Tidy up your mess
               Avoid long scripts




Tuesday, 22 June 2010
Ant tips
               Be consistent
                  Standardize target names
                  Document your public targets




Tuesday, 22 June 2010
Ant tips
               Declare your dependencies
                  Use an Enterprise Repository Manager
                  Several tool choices:
                    Maven Ant Tasks
                    Ivy




Tuesday, 22 June 2010
Ant tips
               Using the Maven Ant Tasks
                  Declare dependencies
                  Deploy to a Maven Enterprise Repository
           <artifact:dependencies pathId="dependency.classpath">
             <dependency groupId="junit" artifactId="junit"
                         version="3.8.2" scope="test"/>
             <dependency groupId="javax.servlet" artifactId="servlet-api"
                         version="2.4" scope="provided"/>
           </artifact:dependencies>




Tuesday, 22 June 2010
Ant tips
               Make it readable
                  Write a build script like your source code...
                  Avoid long targets
                  Avoid long build scripts
                  Use descriptive target names




Tuesday, 22 June 2010
Ant tips
               Tidy up your mess
                  Always define a ‘clean’ target.




Tuesday, 22 June 2010
Ant tips
               Move to Maven ;-)




Tuesday, 22 June 2010
Maven tips
             Better Maven scripts
               Simple
               Portable
               Reproducible
               Clean
               Automated




Tuesday, 22 June 2010
Maven tips
             Keep it simple
               Use modules
               Use an organization-level POM




Tuesday, 22 June 2010
Maven tips
             Keep it portable
               No hard-coding
               Define sensible defaults for properties and profiles
               Avoid resource filtering for production code




Tuesday, 22 June 2010
Maven tips
             Keep it reproducible
               Avoid external snapshots
               Specify plugin versions
               Use consistent environments




Tuesday, 22 June 2010
Maven tips
             Consistent environments
               Enforcing a minimum Maven version
                 <?xml version="1.0"?>
                 <project...>
                 	 <modelVersion>4.0.0</modelVersion>
                 	 <groupId>com.ciwithhudson.gameoflife</groupId>
                 	 <artifactId>gameoflife</artifactId>
                 	 <version>0.0.1-SNAPSHOT</version>
                                                       Minimum Maven version
                 	 <name>gameoflife</name>
                 	 <prerequisites>
                 	 	 <maven>2.2.1</maven>
                 	 </prerequisites>	




Tuesday, 22 June 2010
Maven tips
             Consistent environments
               Use the same version of Maven
               Use a “standard” Maven installation across the organization
                  Use a global settings.xml file
                  Store a copy in SCM
                  Enforce a minimum Maven version in your projects




Tuesday, 22 June 2010
Maven tips
             Enforcing consistency with the enforcer plugin
               Maven version
               JDK version
               Snapshots
               Plugin versions
               OS
               ...




Tuesday, 22 June 2010
Maven tips
             Enforce the Maven version
                        <plugin>
                           <groupId>org.apache.maven.plugins</groupId>
                           <artifactId>maven-enforcer-plugin</artifactId>
                           <version>1.0-beta-1</version>
                           <executions>
                             <execution>
                               <id>enforce-maven-version</id>
                               <goals>
                                 <goal>enforce</goal>
                               </goals>                      Minimum Maven version
                               <configuration>
                                 <rules>
                                   <requireMavenVersion>
                                     <version>2.2.1</version>
                                   </requireMavenVersion>
                                 </rules>
                               </configuration>
                             </execution>
                           </executions>
                         </plugin>

Tuesday, 22 June 2010
Maven tips
             Enforce the JDK version
               All developers should be using the same JDKs
                  Incompatible bytecode
                  Different XML parsers
                  Different Maven behaviour




Tuesday, 22 June 2010
Maven tips
             Enforce the JDK version
                        <plugin>
                           <groupId>org.apache.maven.plugins</groupId>
                           <artifactId>maven-enforcer-plugin</artifactId>
                           <version>1.0-beta-1</version>
                           <executions>
                             <execution>
                               <id>enforce-jdk-version</id>
                               <goals>
                                 <goal>enforce</goal>
                               </goals>                      Authorized JDK versions
                               <configuration>
                                 <rules>
                                   <requireJavaVersion>
                                     <version>[1.5.0,1.6.0)</version>
                                   </requireJavaVersion>
                                 </rules>
                               </configuration>
                             </execution>
                           </executions>
                         </plugin>

Tuesday, 22 June 2010
Maven tips
             Specify your plugin versions
               Undeclared version numbers are bad
                  Inconsistent builds across different machines
                  Non-repeatable builds
                  Plugin changes can break the build
                  Don’t use SNAPSHOT plugins either




Tuesday, 22 June 2010
Maven tips
             Specify your plugin versions
                        <plugin>
                           <groupId>org.apache.maven.plugins</groupId>
                           <artifactId>maven-enforcer-plugin</artifactId>
                           <version>1.0-beta-1</version>
                           <executions>
                             <execution>
                               <id>enforce-versions</id>
                               <goals>
                                 <goal>enforce</goal>
                               </goals>               Plugin versions must be defined
                               <configuration>
                                 <rules>
                                   <requirePluginVersions/>
                                 </rules>
                               </configuration>
                             </execution>
                           </executions>
                         </plugin>



Tuesday, 22 June 2010
Maven tips
             Keep it clean
               Keep tabs on your dependencies:
                  What dependencies are you actually using?
                  What dependencies do you really need?




Tuesday, 22 June 2010
Maven tips
             Dependency list
               What dependencies are you actually using?
                 $ mvn dependency:list
                 [INFO] Scanning for projects...        mvn dependency:list
                 [INFO] Searching repository for plugin with prefix: 'dependency'.
                 [INFO] ------------------------------------------------------------------------
                 [INFO] Building babble-core
                 [INFO]    task-segment: [dependency:list]
                 [INFO] ------------------------------------------------------------------------
                 [INFO] [dependency:list]
                 [INFO]
                 [INFO] The following files have been resolved:
                 [INFO]    antlr:antlr:jar:2.7.6:compile
                 ...
                 [INFO]    commons-collections:commons-collections:jar:2.1.1:compile
                 [INFO]    commons-logging:commons-logging:jar:1.0.4:compile
                 [INFO]    dom4j:dom4j:jar:1.6.1:compile
                 [INFO]    javax.persistence:persistence-api:jar:1.0:compile
                 [INFO]    javax.transaction:jta:jar:1.0.1B:compile
                 [INFO]    junit:junit:jar:4.5:test
                 [INFO]    net.sf.ehcache:ehcache:jar:1.2:compile
                 [INFO]    org.hamcrest:hamcrest-all:jar:1.1:compile
                 [INFO]    org.hibernate:hibernate:jar:3.2.0.ga:compile
                 [INFO]    org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile
                 [INFO]
                 [INFO] ------------------------------------------------------------------------
                 [INFO] BUILD SUCCESSFUL
                 [INFO] ------------------------------------------------------------------------

Tuesday, 22 June 2010
Maven tips
             Dependency tree
               Where do they come from?
                 $ mvn dependency:tree
                 [INFO] Scanning for projects...       mvn dependency:tree
                 [INFO] Searching repository for plugin with prefix: 'dependency'.
                 [INFO] ------------------------------------------------------------------------
                 [INFO] Building babble-core
                 [INFO]    task-segment: [dependency:tree]
                 [INFO] ------------------------------------------------------------------------
                 [INFO] [dependency:tree]
                 [INFO] com.sonatype.training:babble-core:jar:1.0-SNAPSHOT
                 [INFO] +- org.hibernate:hibernate:jar:3.2.0.ga:compile
                 [INFO] | +- net.sf.ehcache:ehcache:jar:1.2:compile
                 [INFO] | +- javax.transaction:jta:jar:1.0.1B:compile
                 [INFO] | +- commons-logging:commons-logging:jar:1.0.4:compile
                 [INFO] | +- asm:asm-attrs:jar:1.5.3:compile
                 [INFO] | +- dom4j:dom4j:jar:1.6.1:compile
                 [INFO] | +- antlr:antlr:jar:2.7.6:compile
                 [INFO] | +- cglib:cglib:jar:2.1_3:compile
                 [INFO] | +- asm:asm:jar:1.5.3:compile
                 [INFO] | - commons-collections:commons-collections:jar:2.1.1:compile
                 [INFO] +- org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile
                 [INFO] | - javax.persistence:persistence-api:jar:1.0:compile
                 [INFO] +- junit:junit:jar:4.5:test
                 [INFO] - org.hamcrest:hamcrest-all:jar:1.1:compile
                 [INFO] ------------------------------------------------------------------------
                 [INFO] BUILD SUCCESSFUL
                 [INFO] ------------------------------------------------------------------------

Tuesday, 22 June 2010
Maven tips
             Dependencies in Eclipse
               Eclipse has an equivalent screen




Tuesday, 22 June 2010
Maven tips
             Dependency analyse
               What dependencies do you really need?
                $ mvn dependency:analyze
                [INFO] Scanning for projects...     mvn dependency:analyse
                [INFO] Searching repository for plugin with prefix: 'dependency'.
                [INFO] ------------------------------------------------------------------------
                [INFO] Building babble-core
                [INFO]    task-segment: [dependency:analyze]
                [INFO] ------------------------------------------------------------------------
                [INFO] Preparing dependency:analyze
                ...                                                  Used but not declared
                [INFO] [dependency:analyze]
                [WARNING] Used undeclared dependencies found:
                [WARNING]    javax.persistence:persistence-api:jar:1.0:compile
                [WARNING] Unused declared dependencies found:
                [WARNING]    org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile
                [WARNING]    org.hibernate:hibernate:jar:3.2.0.ga:compile
                [INFO] ------------------------------------------------------------------------
                [INFO] BUILD SUCCESSFUL
                                                                      Declared but not used
                [INFO] ------------------------------------------------------------------------




Tuesday, 22 June 2010
Maven tips
             Excluding dependencies
               What if you don’t want a dependency?
                   <dependencies>
                     <dependency>
                       <groupId>org.springframework</groupId>
                       <artifactId>spring</artifactId>
                                                              Don’t include JMS
                       <version>2.5.5</version>
                       <exclusions>
                        <exclusion>
                         <groupId>javax.jms</groupId>
                         <artifactId>jms<artifactId>
                       </exclusion>
                      </exclusions>
                     </dependency>
                     <dependency>
                       <groupId>org.apache.geronimo.specs</groupId>
                       <artifactId>geronimo-jms_1.1_spec</artifact>
                       <version>1.1</version>
                     </dependency>
                  <dependencies>
Tuesday, 22 June 2010
Maven tips
             Standardizing versions
               Use dependencyManagement for consistency

      <dependencyManagement>                       Parent pom
        <dependencies>
          <dependency>
          ! <groupId>mysql</groupId>
        ! <artifactId>mysql-connector-java</artifactId>
         ! <version>5.1.6</version>
          </dependency>
          <dependency>
          ! <groupId>postgres</groupId>
        ! <artifactId>postgres</artifactId>
         ! <version>7.3.2</version>
              <dependencies>                                  Child pom
          </dependency>
                <dependency>
        </dependencies>
                 !<groupId>mysql</groupId>
      </dependencyManagement>
                   <artifactId>mysql-connector-java</artifactId>
                          </dependency>
                        </dependencies>

Tuesday, 22 June 2010
Maven tips
             Keep it automated
               Plan your release strategy
               Use a Repository Manager
               Automatic snapshot deployments
               Automated releases




Tuesday, 22 June 2010
Maven tips
             Maven best practices for CI builds
               Use batch mode (-B)
               Always check or snapshot updates (-U)
               Use a repository per project
               Print test failures to stdout (-Dsurefire.useFile=false)




Tuesday, 22 June 2010
Maven tips
             Know when to script it
               Groovy or Ant scripting is easy in Maven
               Call external scripts when appropriate




Tuesday, 22 June 2010
Maven tips
             Know when to script it
               It’s pretty easy in Maven 2...
                <project>
                   <build>
                      <plugins>
                        <plugin>
                          <groupId>org.codehaus.groovy.maven</groupId>
                          <artifactId>gmaven-plugin</artifactId>
                          <version>1.0-rc-5</version>
                          <executions>
                             <execution>
                                <phase>compile</phase>
                                <goals>
                                  <goal>execute</goal>
                                </goals>
                                <configuration>
                                   <source>
                                     println "Hi there I’m compiling ${project.name}"
                                   </source>
                                </configuration>
                              </execution>
                          </executions>
                        </plugin>
                      </plugins>
                    </build>
                    ...

Tuesday, 22 June 2010
Maven tips
             Know when to script it
               It’s even easier in Maven 3...
                project {
                  build {
                     $execute(id: 'compilation-script', phase: 'compile') {
                       println "Hi there I’m compiling ${project.name}"
                     }
                     $execute(id: 'validation-script', phase: 'validate') {
                       println "Hi there I’m validating ${project.name}"
                     }
                     ...
                  }
                }




Tuesday, 22 June 2010
Tuesday, 22 June 2010

More Related Content

Similar to Zen and-the-art-of-build-script-maintenance

Open Business @ DMY Berlin 2011 - MakerLab
Open Business @ DMY Berlin 2011 - MakerLabOpen Business @ DMY Berlin 2011 - MakerLab
Open Business @ DMY Berlin 2011 - MakerLabMassimo Menichinelli
 
Bringing About A Broadband Future For Thailand2
Bringing About A Broadband Future For Thailand2Bringing About A Broadband Future For Thailand2
Bringing About A Broadband Future For Thailand2Thaweesak Koanantakool
 
Apache Sling : JCR, OSGi, Scripting and REST
Apache Sling : JCR, OSGi, Scripting and RESTApache Sling : JCR, OSGi, Scripting and REST
Apache Sling : JCR, OSGi, Scripting and RESTCarsten Ziegeler
 
OpenID Overview - Seoul July 2007
OpenID Overview - Seoul July 2007OpenID Overview - Seoul July 2007
OpenID Overview - Seoul July 2007David Recordon
 
On Open Business @ EDUfashion conference - Ljubljana 02/06/2011
On Open Business @ EDUfashion conference - Ljubljana 02/06/2011On Open Business @ EDUfashion conference - Ljubljana 02/06/2011
On Open Business @ EDUfashion conference - Ljubljana 02/06/2011Massimo Menichinelli
 
Digital ID World 2007 - Understanding Openid
Digital ID World 2007 - Understanding OpenidDigital ID World 2007 - Understanding Openid
Digital ID World 2007 - Understanding OpenidDavid Recordon
 

Similar to Zen and-the-art-of-build-script-maintenance (6)

Open Business @ DMY Berlin 2011 - MakerLab
Open Business @ DMY Berlin 2011 - MakerLabOpen Business @ DMY Berlin 2011 - MakerLab
Open Business @ DMY Berlin 2011 - MakerLab
 
Bringing About A Broadband Future For Thailand2
Bringing About A Broadband Future For Thailand2Bringing About A Broadband Future For Thailand2
Bringing About A Broadband Future For Thailand2
 
Apache Sling : JCR, OSGi, Scripting and REST
Apache Sling : JCR, OSGi, Scripting and RESTApache Sling : JCR, OSGi, Scripting and REST
Apache Sling : JCR, OSGi, Scripting and REST
 
OpenID Overview - Seoul July 2007
OpenID Overview - Seoul July 2007OpenID Overview - Seoul July 2007
OpenID Overview - Seoul July 2007
 
On Open Business @ EDUfashion conference - Ljubljana 02/06/2011
On Open Business @ EDUfashion conference - Ljubljana 02/06/2011On Open Business @ EDUfashion conference - Ljubljana 02/06/2011
On Open Business @ EDUfashion conference - Ljubljana 02/06/2011
 
Digital ID World 2007 - Understanding Openid
Digital ID World 2007 - Understanding OpenidDigital ID World 2007 - Understanding Openid
Digital ID World 2007 - Understanding Openid
 

More from John Ferguson Smart Limited

My Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin ScenariosMy Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin ScenariosJohn Ferguson Smart Limited
 
Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...John Ferguson Smart Limited
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceJohn Ferguson Smart Limited
 
Sustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and ScreenplaySustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and ScreenplayJohn Ferguson Smart Limited
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceJohn Ferguson Smart Limited
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...John Ferguson Smart Limited
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...John Ferguson Smart Limited
 
Screenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testingScreenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testingJohn Ferguson Smart Limited
 
All the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practicesAll the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practicesJohn Ferguson Smart Limited
 
It's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for TestersIt's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for TestersJohn Ferguson Smart Limited
 

More from John Ferguson Smart Limited (20)

My Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin ScenariosMy Reading Specs - Refactoring Patterns for Gherkin Scenarios
My Reading Specs - Refactoring Patterns for Gherkin Scenarios
 
Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...Artisti e Condotierri - How can your team become artists of the 21st century ...
Artisti e Condotierri - How can your team become artists of the 21st century ...
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a difference
 
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANTBE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
BE A POD OF DOLPHINS, NOT A DANCING ELEPHANT
 
Sustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and ScreenplaySustainable Test Automation with Serenity BDD and Screenplay
Sustainable Test Automation with Serenity BDD and Screenplay
 
Feature Mapping Workshop
Feature Mapping WorkshopFeature Mapping Workshop
Feature Mapping Workshop
 
Engage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a differenceEngage! Bringing teams together to deliver software that makes a difference
Engage! Bringing teams together to deliver software that makes a difference
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
 
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
 
Shift left-devoxx-pl
Shift left-devoxx-plShift left-devoxx-pl
Shift left-devoxx-pl
 
Screenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testingScreenplay - Next generation automated acceptance testing
Screenplay - Next generation automated acceptance testing
 
Cucumber and Spock Primer
Cucumber and Spock PrimerCucumber and Spock Primer
Cucumber and Spock Primer
 
All the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practicesAll the world's a stage – the next step in automated testing practices
All the world's a stage – the next step in automated testing practices
 
CukeUp 2016 Agile Product Planning Workshop
CukeUp 2016 Agile Product Planning WorkshopCukeUp 2016 Agile Product Planning Workshop
CukeUp 2016 Agile Product Planning Workshop
 
BDD Anti-patterns
BDD Anti-patternsBDD Anti-patterns
BDD Anti-patterns
 
Serenity and the Journey Pattern
Serenity and the Journey PatternSerenity and the Journey Pattern
Serenity and the Journey Pattern
 
BDD - Collaborate like you mean it!
BDD - Collaborate like you mean it!BDD - Collaborate like you mean it!
BDD - Collaborate like you mean it!
 
BDD-Driven Microservices
BDD-Driven MicroservicesBDD-Driven Microservices
BDD-Driven Microservices
 
BDD Anti-patterns
BDD Anti-patternsBDD Anti-patterns
BDD Anti-patterns
 
It's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for TestersIt's Testing, Jim, but not as we know it - BDD for Testers
It's Testing, Jim, but not as we know it - BDD for Testers
 

Recently uploaded

Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfngoud9212
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 

Recently uploaded (20)

Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdf
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 

Zen and-the-art-of-build-script-maintenance

  • 3. Agenda What are we discussing today? What makes a good build script? Smelly build scripts Choosing your tools Maven tips Ant tips Tuesday, 22 June 2010
  • 4. Introduction Quality build scripts - why bother Maintenance costs Learning curve Turn-over Portability Automation Tuesday, 22 June 2010
  • 5. Build quality - quality builds What makes a good build script? Gold Standard Portable Reproducible Standard Maintainable Tuesday, 22 June 2010
  • 6. Build quality - quality builds Gold Standard Reference build process Reference binaries Tuesday, 22 June 2010
  • 7. Build quality - quality builds Portable Runs anywhere Runs on any OS No local dependencies Environment-specific configurations Specially-installed software or databases ... Tuesday, 22 June 2010
  • 8. Build quality - quality builds Reproducible “Play it again, Sam” Tuesday, 22 June 2010
  • 9. Build quality - quality builds Standard Knowing what to expect Tuesday, 22 June 2010
  • 10. Build quality - quality builds Maintainable Think of the next dude Tuesday, 22 June 2010
  • 11. Smelly builds So what makes a poor build script? 1) The hard coded build 2) The OS-specific build 3) The IDE-only build 4) The Magic Machine build 5) The Oral Tradition build 6) The Nested build 7) The Messy Dependencies build 8) The DYI build 9) The untrustworthy build 10) The slow build Tuesday, 22 June 2010
  • 12. Paths .. 1/ URLs Smelly builds 9. c- gi lo 1 eb 00 Passwords /w :7 om ea .c /b me C: ac r. ve er ts es .> /t ".. :/ ger "ti tp rd= The hard coded build ht swo pas tt" sco e=" nam ser n u <sv /> M E }" S_HO JBOS env. = "$ { alue s" v Environment jbos dir. me=" variables y na pert <pro Tuesday, 22 June 2010
  • 13. Smelly builds The hard coded build <target name="checkstyle"> Hard-coded directories <delete dir="./reports" quiet="true" /> <mkdir dir="./reports" /> <checkstyle config="./docs/sun_checks.xml"> <formatter type="xml" tofile="./reports/checkstyle.xml"/> <fileset dir="./src" includes="**/*.java"/> </checkstyle> <style in="./reports/checkstyle.xml" out="./reports/checkstyle.html" style="checkstyle.xsl"/> </target> Tuesday, 22 June 2010
  • 14. Smelly builds The hard coded build <target name="checkstyle"> Project-relative directory <property name=”reports.checkstyle.dir” <delete dir="./reports" quiet="true" /> value=”${basedir}/reports”/> <mkdir dir="./reports" /> DRY <checkstyle config="./docs/sun_checks.xml"> <target name="checkstyle"> <formatter type="xml" tofile="./reports/checkstyle.xml"/> <delete dir="${reports.checkstyle.dir}" quiet="true" /> <mkdir<fileset dir="./src" includes="**/*.java"/> dir="${reports.checkstyle.dir}" /> </checkstyle> <checkstyle config="./docs/sun_checks.xml"> <formatter type="xml" <style in="./reports/checkstyle.xml" tofile="${reports.checkstyle.dir}/checkstyle.xml"/> <fileset out="./reports/checkstyle.html" dir="./src" includes="**/*.java"/> style="checkstyle.xsl"/> </checkstyle> </target> <style in="${reports.checkstyle.dir}/checkstyle.xml" out="${reports.checkstyle.dir}/checkstyle.html" style="checkstyle.xsl"/> </target> Tuesday, 22 June 2010
  • 15. Smelly builds The hard coded build <target name="war" > <war destfile="c:/tomcat/jakarta-tomcat-5.0.19/webapps/app.war" webxml="${src}/app.xml" basedir="${bin}" /> </target> Hard-coded directories Tuesday, 22 June 2010
  • 16. Smelly builds The hard coded build <property name="wardir" location="c:/tomcat/jakarta-tomcat-5.0.19/webapps"/> <target name="war" > <war destfile="${wardir}" webxml="${src}/app.xml" basedir="${bin}" /> </target> Still hard-coded Tuesday, 22 June 2010
  • 17. Smelly builds The hard coded build <svn username="scott" password="tiger"> <checkout url="http://subversion.acme.com/myapp/trunk" destPath="${subproject.dir}" /> </svn> Hard-coded username/password Tuesday, 22 June 2010
  • 18. Smelly builds The hard coded build <property environment="env"/> <property name="dir.jboss" value="${env.JBOSS_HOME}"/> Environment variable Tuesday, 22 June 2010
  • 19. Smelly builds The OS-specific build <exec command="grep "@" ${build.dir} | wc -l" outputproperty="token.count"/> Tuesday, 22 June 2010
  • 20. Smelly builds The OS-specific build ... CALL PAUSE.CMD ... build.cmd ... :: Check for a non-existent IP address :: Note: this causes a small extra delay! IF NOT DEFINED NonExist SET NonExist=10.255.255.254 PING %NonExist% -n 1 -w 100 2>NUL | FIND "TTL=" >NUL ... pause.cmd Tuesday, 22 June 2010
  • 21. Smelly builds The IDE-only build Tuesday, 22 June 2010
  • 22. Smelly builds The Magic Machine build Directories App servers Databases Configuration files Environment variables Installed software or tools Tuesday, 22 June 2010
  • 23. Smelly builds The Magic Machine build <proprerty weblogic.dir="/u01/app/bea/weblogic-9.1"/> Directories App servers Databases Configuration files Environment variables Installed software or tools Tuesday, 22 June 2010
  • 24. Smelly builds The Oral Tradition build Tuesday, 22 June 2010
  • 25. Smelly builds The Nested Build #! /bin/sh ANT_HOME=/u01/app/tools/ant-1.7.1 ... $ANT_HOME/ant $1 project/tools/ant.sh Tuesday, 22 June 2010
  • 26. Smelly builds The Nested Build <target name="build-subproject"> <svn username="scott" password="tiger"> <checkout url="http://subversion.acme.com/someproject/trunk" destPath="${subproject.dir}" /> </svn> <ant dir="${subproject.dir}" target="build-all" /> </target> build.xml Tuesday, 22 June 2010
  • 27. Smelly builds The Messy Dependencies build JAR files in the SCM Unversioned JAR files Unclear dependencies Tuesday, 22 June 2010
  • 28. Smelly builds The DYI build “Not invented here” DYI dependencies DYI deployments DYI Maven releases ... Tuesday, 22 June 2010
  • 29. Smelly builds The untrustworthy build <junit fork="yes" haltonfailure="false" dir="${basedir}"> <classpath refid="test.class.path" /> <classpath refid="project.class.path"/> <formatter type="plain" usefile="true" /> <formatter type="xml" usefile="true" /> <batchtest fork="yes" todir="${logs.junit.dir}"> <fileset dir="${test.unit.dir}"> <patternset refid="test.sources.pattern"/> </fileset> </batchtest> </junit> Tuesday, 22 June 2010
  • 30. Smelly builds The slow build Tuesday, 22 June 2010
  • 31. Choosing your tools Flexibility verses Convention What’s better: flexibility or standards? It depends what you’re doing... Tuesday, 22 June 2010
  • 32. Choosing your tools Encourage/enforce Standards and Conventions Support standards standards 3 Easy to read 2 Make up your own standards No standards Hard to read Ad-hoc scripting Standards and Conventions Tuesday, 22 June 2010
  • 33. Choosing your tools Flexibility and expressiveness 3 Do whatever you Easy to read want 2 Encourage/enforce standards Hard to read Makes you stick to conventions Easy to do whatever you want Tuesday, 22 June 2010
  • 34. Choosing your tools Flexibility verses Convention Build Scripting Rule 1 “A build script will tend to reflect the personality of it’s developer” Tuesday, 22 June 2010
  • 35. Choosing your tools Flexibility verses Convention Build Scripting Rule 2 “The more flexible a build script, the more likely it is to become unmaintainable” Tuesday, 22 June 2010
  • 36. Choosing your tools Flexibility verses Convention Flexibility is great for some jobs: Ad-hoc tasks Some deployment tasks “Out-of-the-box” stuff Tuesday, 22 June 2010
  • 37. Choosing your tools Flexibility verses Convention But convention pay off in lower maintenance costs Tuesday, 22 June 2010
  • 38. Ant tips Better Ant scripts Consistent conventions Declare your dependencies Make it readable Tidy up your mess Avoid long scripts Tuesday, 22 June 2010
  • 39. Ant tips Be consistent Standardize target names Document your public targets Tuesday, 22 June 2010
  • 40. Ant tips Declare your dependencies Use an Enterprise Repository Manager Several tool choices: Maven Ant Tasks Ivy Tuesday, 22 June 2010
  • 41. Ant tips Using the Maven Ant Tasks Declare dependencies Deploy to a Maven Enterprise Repository <artifact:dependencies pathId="dependency.classpath"> <dependency groupId="junit" artifactId="junit" version="3.8.2" scope="test"/> <dependency groupId="javax.servlet" artifactId="servlet-api" version="2.4" scope="provided"/> </artifact:dependencies> Tuesday, 22 June 2010
  • 42. Ant tips Make it readable Write a build script like your source code... Avoid long targets Avoid long build scripts Use descriptive target names Tuesday, 22 June 2010
  • 43. Ant tips Tidy up your mess Always define a ‘clean’ target. Tuesday, 22 June 2010
  • 44. Ant tips Move to Maven ;-) Tuesday, 22 June 2010
  • 45. Maven tips Better Maven scripts Simple Portable Reproducible Clean Automated Tuesday, 22 June 2010
  • 46. Maven tips Keep it simple Use modules Use an organization-level POM Tuesday, 22 June 2010
  • 47. Maven tips Keep it portable No hard-coding Define sensible defaults for properties and profiles Avoid resource filtering for production code Tuesday, 22 June 2010
  • 48. Maven tips Keep it reproducible Avoid external snapshots Specify plugin versions Use consistent environments Tuesday, 22 June 2010
  • 49. Maven tips Consistent environments Enforcing a minimum Maven version <?xml version="1.0"?> <project...> <modelVersion>4.0.0</modelVersion> <groupId>com.ciwithhudson.gameoflife</groupId> <artifactId>gameoflife</artifactId> <version>0.0.1-SNAPSHOT</version> Minimum Maven version <name>gameoflife</name> <prerequisites> <maven>2.2.1</maven> </prerequisites> Tuesday, 22 June 2010
  • 50. Maven tips Consistent environments Use the same version of Maven Use a “standard” Maven installation across the organization Use a global settings.xml file Store a copy in SCM Enforce a minimum Maven version in your projects Tuesday, 22 June 2010
  • 51. Maven tips Enforcing consistency with the enforcer plugin Maven version JDK version Snapshots Plugin versions OS ... Tuesday, 22 June 2010
  • 52. Maven tips Enforce the Maven version <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.0-beta-1</version> <executions> <execution> <id>enforce-maven-version</id> <goals> <goal>enforce</goal> </goals> Minimum Maven version <configuration> <rules> <requireMavenVersion> <version>2.2.1</version> </requireMavenVersion> </rules> </configuration> </execution> </executions> </plugin> Tuesday, 22 June 2010
  • 53. Maven tips Enforce the JDK version All developers should be using the same JDKs Incompatible bytecode Different XML parsers Different Maven behaviour Tuesday, 22 June 2010
  • 54. Maven tips Enforce the JDK version <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.0-beta-1</version> <executions> <execution> <id>enforce-jdk-version</id> <goals> <goal>enforce</goal> </goals> Authorized JDK versions <configuration> <rules> <requireJavaVersion> <version>[1.5.0,1.6.0)</version> </requireJavaVersion> </rules> </configuration> </execution> </executions> </plugin> Tuesday, 22 June 2010
  • 55. Maven tips Specify your plugin versions Undeclared version numbers are bad Inconsistent builds across different machines Non-repeatable builds Plugin changes can break the build Don’t use SNAPSHOT plugins either Tuesday, 22 June 2010
  • 56. Maven tips Specify your plugin versions <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.0-beta-1</version> <executions> <execution> <id>enforce-versions</id> <goals> <goal>enforce</goal> </goals> Plugin versions must be defined <configuration> <rules> <requirePluginVersions/> </rules> </configuration> </execution> </executions> </plugin> Tuesday, 22 June 2010
  • 57. Maven tips Keep it clean Keep tabs on your dependencies: What dependencies are you actually using? What dependencies do you really need? Tuesday, 22 June 2010
  • 58. Maven tips Dependency list What dependencies are you actually using? $ mvn dependency:list [INFO] Scanning for projects... mvn dependency:list [INFO] Searching repository for plugin with prefix: 'dependency'. [INFO] ------------------------------------------------------------------------ [INFO] Building babble-core [INFO] task-segment: [dependency:list] [INFO] ------------------------------------------------------------------------ [INFO] [dependency:list] [INFO] [INFO] The following files have been resolved: [INFO] antlr:antlr:jar:2.7.6:compile ... [INFO] commons-collections:commons-collections:jar:2.1.1:compile [INFO] commons-logging:commons-logging:jar:1.0.4:compile [INFO] dom4j:dom4j:jar:1.6.1:compile [INFO] javax.persistence:persistence-api:jar:1.0:compile [INFO] javax.transaction:jta:jar:1.0.1B:compile [INFO] junit:junit:jar:4.5:test [INFO] net.sf.ehcache:ehcache:jar:1.2:compile [INFO] org.hamcrest:hamcrest-all:jar:1.1:compile [INFO] org.hibernate:hibernate:jar:3.2.0.ga:compile [INFO] org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ Tuesday, 22 June 2010
  • 59. Maven tips Dependency tree Where do they come from? $ mvn dependency:tree [INFO] Scanning for projects... mvn dependency:tree [INFO] Searching repository for plugin with prefix: 'dependency'. [INFO] ------------------------------------------------------------------------ [INFO] Building babble-core [INFO] task-segment: [dependency:tree] [INFO] ------------------------------------------------------------------------ [INFO] [dependency:tree] [INFO] com.sonatype.training:babble-core:jar:1.0-SNAPSHOT [INFO] +- org.hibernate:hibernate:jar:3.2.0.ga:compile [INFO] | +- net.sf.ehcache:ehcache:jar:1.2:compile [INFO] | +- javax.transaction:jta:jar:1.0.1B:compile [INFO] | +- commons-logging:commons-logging:jar:1.0.4:compile [INFO] | +- asm:asm-attrs:jar:1.5.3:compile [INFO] | +- dom4j:dom4j:jar:1.6.1:compile [INFO] | +- antlr:antlr:jar:2.7.6:compile [INFO] | +- cglib:cglib:jar:2.1_3:compile [INFO] | +- asm:asm:jar:1.5.3:compile [INFO] | - commons-collections:commons-collections:jar:2.1.1:compile [INFO] +- org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile [INFO] | - javax.persistence:persistence-api:jar:1.0:compile [INFO] +- junit:junit:jar:4.5:test [INFO] - org.hamcrest:hamcrest-all:jar:1.1:compile [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ Tuesday, 22 June 2010
  • 60. Maven tips Dependencies in Eclipse Eclipse has an equivalent screen Tuesday, 22 June 2010
  • 61. Maven tips Dependency analyse What dependencies do you really need? $ mvn dependency:analyze [INFO] Scanning for projects... mvn dependency:analyse [INFO] Searching repository for plugin with prefix: 'dependency'. [INFO] ------------------------------------------------------------------------ [INFO] Building babble-core [INFO] task-segment: [dependency:analyze] [INFO] ------------------------------------------------------------------------ [INFO] Preparing dependency:analyze ... Used but not declared [INFO] [dependency:analyze] [WARNING] Used undeclared dependencies found: [WARNING] javax.persistence:persistence-api:jar:1.0:compile [WARNING] Unused declared dependencies found: [WARNING] org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile [WARNING] org.hibernate:hibernate:jar:3.2.0.ga:compile [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL Declared but not used [INFO] ------------------------------------------------------------------------ Tuesday, 22 June 2010
  • 62. Maven tips Excluding dependencies What if you don’t want a dependency? <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> Don’t include JMS <version>2.5.5</version> <exclusions> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms<artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jms_1.1_spec</artifact> <version>1.1</version> </dependency> <dependencies> Tuesday, 22 June 2010
  • 63. Maven tips Standardizing versions Use dependencyManagement for consistency <dependencyManagement> Parent pom <dependencies> <dependency> ! <groupId>mysql</groupId> ! <artifactId>mysql-connector-java</artifactId> ! <version>5.1.6</version> </dependency> <dependency> ! <groupId>postgres</groupId> ! <artifactId>postgres</artifactId> ! <version>7.3.2</version> <dependencies> Child pom </dependency> <dependency> </dependencies> !<groupId>mysql</groupId> </dependencyManagement> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies> Tuesday, 22 June 2010
  • 64. Maven tips Keep it automated Plan your release strategy Use a Repository Manager Automatic snapshot deployments Automated releases Tuesday, 22 June 2010
  • 65. Maven tips Maven best practices for CI builds Use batch mode (-B) Always check or snapshot updates (-U) Use a repository per project Print test failures to stdout (-Dsurefire.useFile=false) Tuesday, 22 June 2010
  • 66. Maven tips Know when to script it Groovy or Ant scripting is easy in Maven Call external scripts when appropriate Tuesday, 22 June 2010
  • 67. Maven tips Know when to script it It’s pretty easy in Maven 2... <project> <build> <plugins> <plugin> <groupId>org.codehaus.groovy.maven</groupId> <artifactId>gmaven-plugin</artifactId> <version>1.0-rc-5</version> <executions> <execution> <phase>compile</phase> <goals> <goal>execute</goal> </goals> <configuration> <source> println "Hi there I’m compiling ${project.name}" </source> </configuration> </execution> </executions> </plugin> </plugins> </build> ... Tuesday, 22 June 2010
  • 68. Maven tips Know when to script it It’s even easier in Maven 3... project { build { $execute(id: 'compilation-script', phase: 'compile') { println "Hi there I’m compiling ${project.name}" } $execute(id: 'validation-script', phase: 'validate') { println "Hi there I’m validating ${project.name}" } ... } } Tuesday, 22 June 2010