SlideShare una empresa de Scribd logo
1 de 68
Descargar para leer sin conexión
Build like you code with
 Apache Buildr


        by Alexis Midon
          @alexizany
                           1
{ Why, How, Demo of }

            a Build System that

                        { does not suck,
                        gets out of the way,
                        lets you write code }


                                                2
About Me
Alexis Midon
    @alexiszany
 midon@apache.org
www.c3-e.com
Sail & Live in San Francisco, CA
          'Since 2007'
Java
Javascript
   Ruby
   Scala
     ...
Use Buildr
  on daily basis

 and still lovin'it!
Practical
Introduction to Apache Buildr
Where & Why
  it all started
Apache Ode
Large Java Enterprise
    Middleware
15+ modules
   9 databases
120+ dependencies
  3 distributions
  tooling heavy
         ...
Maven2
  5,433 lines of XML
spread over 52 files (!)
“@&#!
 There's
Got To Be
A Better
  Way”
What was
Really Wanted
No XML.
 Please!
Flexible
Easy to customize & extend
DRY Code
 Basic abstraction and
structuring mechanisms
In other words,
 a real scripting language.
Result?
      drum_roll....
roulement_de_tambour...
Before
      52 files
5,433 lines of XML.
Before
      52 files
5,433 lines of XML.




   After
   Single file.
486 lines of Ruby.
Bonus!
Twice as fast.
How
Did they do it?
Ruby   awesome scripting language
why ruby?
Scripting
easy file manipulation
    native regexp,
 lightweight syntax
    exec() friendly
          etc.
Metaprogramm'
 great host for embedded
 domain-specific language
JVM Friendly ;)
JRuby & Ruby-Java Bridge
Rake          tasks, files,
             dependencies




Ruby   awesome scripting language
Rake
The Ruby Make
Rake
The Ruby Make
        “Ant”
Your Application




  [ modules ]
[ graph of dependencies ]
# This is Rake code
task "compile A" do
  # code to compile A
end

task "compile B" do
  # code to compile B
end

task "compile C" => ["compile A", "compile B"] do
  # code to compile C
end

task "package A,B,C" => ["compile A", "...", "compile C"] do
  # code to package A, B and C
end

task :default => “package A, B, C”
$ rake
(in /home/buildr/example)
compiling A ...
compiling B ...
compiling C ...
packaging A,B,C ...
Buildr   projects, lifecycle, artifacts, plugins




Rake                 tasks, files,
                    dependencies




Ruby         awesome scripting language
# This is Buildr code
define "My application" do

  define "A" do
    package :jar
  end

  define "B" do
    package :jar
  end

  define "C" do
    compile.with projects("A", "B")
    package :jar
  end

  package(:war).using :libs => projects("A", "B", "C")
end
# This is Buildr code
define "My application" do

  define "A" do
    package :jar
  end
                                           Parent projects
  define "B" do                          implicitly depend on
    package :jar                               children
  end

  define "C" do
    compile.with projects("A", "B")
    package :jar
  end

  package(:war).using :libs => projects("A", "B", "C")
end
my-application/
├── A
│   └── src
│       ├── main
│       │    ├── java        Standard directory
│       │    └── resources
│       └── test                 structure
│            └── java
├── B
│   └── src                  (can be customized)
│       ├── main
│       │    └── scala
│       └── test
│            └── scala
├── C
│   └── src
│       └── main
│            └── groovy
└── src
    └── main
        ├── java
        └── webapp
$ buildr package

(in /home/alexis/example, development)
Building buildr-example
Compiling buildr-example:a into /home/alexis/example/a/target/classes
Compiling buildr-example:b into /home/alexis/example/b/target/classes
Packaging buildr-example-a-1.0.0.jar
Packaging buildr-example-b-1.0.0.jar
Compiling buildr-example:c into /home/alexis/example/c/target/classes
Packaging buildr-example
Packaging buildr-example-c-1.0.0.jar
Packaging buildr-example-1.0.0.war
Running integration tests...
Completed in 0.779s
All about
   tasks.
Standard tasks
   [ partial list ]
# Actual Rake code
class FileTask < Task

  def needed?
    !File.exist?(name) || out_of_date?
  end

  private

  def out_of_date?
    @prerequisites.any? { |n| n.timestamp > timestamp}
  end

end
artifacts
and repositories
Dependency resolution

Local files   (no kidding!!!)
Maven2        (built-in)
Ivy           (plugin)
Aether        (plugin)

or roll your own.
# Buildfile

repositories.remote << "http://www.ibiblio.org/maven2/"

LOG4J = "log4j:log4j:jar:1.2.15"

define 'my-library' do
  compile.with LOG4J
  package :jar
end
all your repos
                                                 are belong
                                                    to us !!
# Buildfile

repositories.remote << "http://www.ibiblio.org/maven2/"

LOG4J = "log4j:log4j:jar:1.2.15"

define 'my-library' do
  compile.with LOG4J
  package :jar
end
all your repos
                                                are belong
                                                   to us !!
# Buildfile

                                                  artifacts
repositories.remote << "http://www.ibiblio.org/maven2/"  are
LOG4J = "log4j:log4j:jar:1.2.15"
                                                 Tasks, too
define 'my-library' do
  compile.with LOG4J
  package :jar
end
all your repos
                                                are belong
                                                   to us !!
# Buildfile

                                                  artifacts
repositories.remote << "http://www.ibiblio.org/maven2/"  are
LOG4J = "log4j:log4j:jar:1.2.15"
                                                 Tasks, too
define 'my-library' do
  compile.with LOG4J
  package :jar
                                                 tasks are
end                                           wired implicitly
Languages
  we got 'em
Example: Scala plugin
require 'buildr/scala'

# brings in:
#
#   - automatic detection
#     (src/main/scala, src/test/scala, src/spec/scala)
#
#   - incremental compilation
#
#   - mixed java + scala compilation
#
#   - scaladoc generation
#
#   - scalatest, specs and scalacheck testing
#
#   - continuous compilation
Low Barrier to entry


# if you have Ruby installed
$ gem install buildr

or,

# JRuby all-in-one package
$ unzip buildr-all-in-one.zip
Demo Time!
Java + Scala + Groovy
   Mixed Project
More Stuff.
      layouts, profiles,
code coverage, notifications
more plugins, more languages
     + more awesome.
Only one thing
to remember.
Build like you code.
join us!
                http://buildr.apache.org
                        @buildr


Slides and Code available at github.com/alexism
    Alex Boisvert @boia01
Ant Example: XMLBeans

<taskdef name="xmlbean"
         classname="org.apache.xmlbeans.impl.tool.XMLBean"
         classpath="path/to/xbean.jar" />

<xmlbean classgendir="${build.dir}"
         classpath="${class.path}"
         failonerror="true">
  <fileset basedir="src" excludes="**/*.xsd"/>
  <fileset basedir="schemas" includes="**/*.*"/>
</xmlbean>
Ant Example: XMLBeans
def xmlbeans(files) do
  Buildr.ant "xmlbeans" do |ant|
    ant.taskdef 
      :name => "xmlbeans",
      :classname => "org.apache.xmlbeans.impl.tool.XMLBean",
      :classpath => 'org.apache.xmlbeans:xmlbeans:jar:2.3.0'

    ant.xmlbeans 
        :classpath   => project.compile.dependencies,
        :srcgendir   => project._('target/generated')
        :failonerror => "true" do
      files.flatten.each do |file|
        ant.fileset File.directory?(file) ? { :dir => file }
                                          : { :file => file }
      end
  end
end
# Convert .pom to ivy.xml
module POM_to_IVY
  extend self

  ANT = Buildr.ant('convertpom') do |ant|
    ant.taskdef :name => "convertpom",
                :classname => "org.apache.ivy.ant.IvyConvertPom"
    end
  end

  def convert(pom_file, ivy_file)
    ANT.convertpom :pomFile => pom_file,
                   :ivyFile => ivy_file
  end
end
define :webapp do

  # regenerate app.js when any .coffee file changes
  file('target/js/app.js') => Dir['src/main/coffee/*.coffee']) do
    sh "dependence src/main/coffee/ -t coffee -o target/js"
  end

  resources.enhance ['target/js/app.js']

end
# Generate SQL DDL schemas for all databases
%w{ derby mysql oracle sqlserver postgres }.each do |db|
  db_xml = _("src/main/descriptors/persistence.#{db}.xml")
  partial_sql = file("target/partial.#{db}.sql"=>db_xml) do
    OpenJPA.mapping_tool 
      :properties => db_xml,
      :action     => "build",
      :sql        => db.to_s,
      :classpath => projects("store", "dao")
  end

  # Add Apache license header
  header = _("src/main/scripts/license-header.sql")
  sql = concat(_("target/#{db}.sql") => [header, partial_sql])
  build sql
end
# Compile using all Eclipse BIRT libraries
BIRT_WAR = artifact(“org.eclipse.birt:birt:war:1.4.1”)

unzip_birt = unzip _("target/birt") => BIRT_WAR
unzip_birt.enhance do
  compile.with Dir[_("target/birt/WEB-INF/lib") + "/*.jar"]
end
compile.enhance [unzip_birt]
Calling Java classes

Java.classpath << [ "org.antlr:antlr:jar:3.0",
                    "antlr:antlr:jar:2.7.7",
                    "org.antlr:stringtemplate:jar:3.0" ]

Java.org.antlr.Tool.new("-i #{input} -o #{output}").process
Testing Your Build

# rspec code
check package(:war).entry('META-INF/MANIFEST'), 'should have
license' do
  it.should contain(/Copyright (C) 2011/)
end

check file('target/classes/killerapp/Code.class'), 'should exist' do
  it.should exist
end
Example: Extension

module GitVersion
  include Buildr::Extension

  @version = `git log -1 --pretty=format:%H`

  after_define do |project|
    project.packages.each do |jar|
      f = file project._("target/git-version.txt") do |f|
        Buildr.write f.to_s, @version
      end
      jar.enhance [f]
      jar.include f, :as => "META-INF/git-version.txt"
    end
  end
end
# apply to a single project
define 'my-project' do
  extend GitVersion
end


# apply to all projects
class Buildr::Project
  include GitVersion
end

Más contenido relacionado

La actualidad más candente

modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
Puppet
 

La actualidad más candente (20)

Security Goodness with Ruby on Rails
Security Goodness with Ruby on RailsSecurity Goodness with Ruby on Rails
Security Goodness with Ruby on Rails
 
Repoinit: a mini-language for content repository initialization
Repoinit: a mini-language for content repository initializationRepoinit: a mini-language for content repository initialization
Repoinit: a mini-language for content repository initialization
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
 
The Modern Developer Toolbox
The Modern Developer ToolboxThe Modern Developer Toolbox
The Modern Developer Toolbox
 
Gradle como alternativa a maven
Gradle como alternativa a mavenGradle como alternativa a maven
Gradle como alternativa a maven
 
Dessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloudDessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloud
 
Paving the way to a native Sling
Paving the way to a native SlingPaving the way to a native Sling
Paving the way to a native Sling
 
Docker for (Java) Developers
Docker for (Java) DevelopersDocker for (Java) Developers
Docker for (Java) Developers
 
Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific Languages
 
Django in the Real World
Django in the Real WorldDjango in the Real World
Django in the Real World
 
Ruby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developerRuby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developer
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Symfony Live NYC 2014 - Rock Solid Deployment of Symfony Apps
Symfony Live NYC 2014 -  Rock Solid Deployment of Symfony AppsSymfony Live NYC 2014 -  Rock Solid Deployment of Symfony Apps
Symfony Live NYC 2014 - Rock Solid Deployment of Symfony Apps
 
Magento 2 Workflows
Magento 2 WorkflowsMagento 2 Workflows
Magento 2 Workflows
 
Deploying Symfony | symfony.cat
Deploying Symfony | symfony.catDeploying Symfony | symfony.cat
Deploying Symfony | symfony.cat
 
Take control of your Jenkins jobs via job DSL.
Take control of your Jenkins jobs via job DSL.Take control of your Jenkins jobs via job DSL.
Take control of your Jenkins jobs via job DSL.
 
Introduction to Apache Ant
Introduction to Apache AntIntroduction to Apache Ant
Introduction to Apache Ant
 
Sprockets
SprocketsSprockets
Sprockets
 
Portland PUG April 2014: Beaker 101: Acceptance Test Everything
Portland PUG April 2014: Beaker 101: Acceptance Test EverythingPortland PUG April 2014: Beaker 101: Acceptance Test Everything
Portland PUG April 2014: Beaker 101: Acceptance Test Everything
 

Destacado (6)

Why I Believe MongoDB is The Dog's Bollocks
Why I Believe MongoDB is The Dog's BollocksWhy I Believe MongoDB is The Dog's Bollocks
Why I Believe MongoDB is The Dog's Bollocks
 
Munching the mongo
Munching the mongoMunching the mongo
Munching the mongo
 
Dig up the gold in your godowns
Dig up the gold in your godownsDig up the gold in your godowns
Dig up the gold in your godowns
 
Mongo db 2.6_security_architecture
Mongo db 2.6_security_architectureMongo db 2.6_security_architecture
Mongo db 2.6_security_architecture
 
Mongo db bangalore
Mongo db bangaloreMongo db bangalore
Mongo db bangalore
 
Rocking mongo db on the cloud
Rocking mongo db on the cloudRocking mongo db on the cloud
Rocking mongo db on the cloud
 

Similar a Buildr In Action @devoxx france 2012

How to start using Scala
How to start using ScalaHow to start using Scala
How to start using Scala
Ngoc Dao
 
Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01
Tino Isnich
 
Binary Packaging for HPC with Spack
Binary Packaging for HPC with SpackBinary Packaging for HPC with Spack
Binary Packaging for HPC with Spack
inside-BigData.com
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
Nick Sieger
 

Similar a Buildr In Action @devoxx france 2012 (20)

How to start using Scala
How to start using ScalaHow to start using Scala
How to start using Scala
 
Play framework
Play frameworkPlay framework
Play framework
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01
 
Buildr - build like you code
Buildr -  build like you codeBuildr -  build like you code
Buildr - build like you code
 
A jar-nORM-ous Task
A jar-nORM-ous TaskA jar-nORM-ous Task
A jar-nORM-ous Task
 
Building scala with bazel
Building scala with bazelBuilding scala with bazel
Building scala with bazel
 
Gradle: The Build system you have been waiting for
Gradle: The Build system you have been waiting forGradle: The Build system you have been waiting for
Gradle: The Build system you have been waiting for
 
Gradle
GradleGradle
Gradle
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
Java in a world of containers
Java in a world of containersJava in a world of containers
Java in a world of containers
 
Java in a World of Containers - DockerCon 2018
Java in a World of Containers - DockerCon 2018Java in a World of Containers - DockerCon 2018
Java in a World of Containers - DockerCon 2018
 
Binary Packaging for HPC with Spack
Binary Packaging for HPC with SpackBinary Packaging for HPC with Spack
Binary Packaging for HPC with Spack
 
Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014
 
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with Gradle
 
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with Gradle
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: Gradle
 
Jenkins shared librar
Jenkins shared librarJenkins shared librar
Jenkins shared librar
 
Rails Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular application
 

Último

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Último (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 

Buildr In Action @devoxx france 2012

  • 1. Build like you code with Apache Buildr by Alexis Midon @alexizany 1
  • 2. { Why, How, Demo of } a Build System that { does not suck, gets out of the way, lets you write code } 2
  • 4. Alexis Midon @alexiszany midon@apache.org
  • 6. Sail & Live in San Francisco, CA 'Since 2007'
  • 7. Java Javascript Ruby Scala ...
  • 8. Use Buildr on daily basis and still lovin'it!
  • 10. Where & Why it all started
  • 11. Apache Ode Large Java Enterprise Middleware
  • 12. 15+ modules 9 databases 120+ dependencies 3 distributions tooling heavy ...
  • 13. Maven2 5,433 lines of XML spread over 52 files (!)
  • 14. “@&#! There's Got To Be A Better Way”
  • 18. DRY Code Basic abstraction and structuring mechanisms
  • 19. In other words, a real scripting language.
  • 20. Result? drum_roll.... roulement_de_tambour...
  • 21. Before 52 files 5,433 lines of XML.
  • 22. Before 52 files 5,433 lines of XML. After Single file. 486 lines of Ruby.
  • 25. Ruby awesome scripting language
  • 27. Scripting easy file manipulation native regexp, lightweight syntax exec() friendly etc.
  • 28. Metaprogramm' great host for embedded domain-specific language
  • 29. JVM Friendly ;) JRuby & Ruby-Java Bridge
  • 30. Rake tasks, files, dependencies Ruby awesome scripting language
  • 32. Rake The Ruby Make “Ant”
  • 33. Your Application [ modules ]
  • 34. [ graph of dependencies ]
  • 35. # This is Rake code task "compile A" do # code to compile A end task "compile B" do # code to compile B end task "compile C" => ["compile A", "compile B"] do # code to compile C end task "package A,B,C" => ["compile A", "...", "compile C"] do # code to package A, B and C end task :default => “package A, B, C”
  • 36. $ rake (in /home/buildr/example) compiling A ... compiling B ... compiling C ... packaging A,B,C ...
  • 37. Buildr projects, lifecycle, artifacts, plugins Rake tasks, files, dependencies Ruby awesome scripting language
  • 38. # This is Buildr code define "My application" do define "A" do package :jar end define "B" do package :jar end define "C" do compile.with projects("A", "B") package :jar end package(:war).using :libs => projects("A", "B", "C") end
  • 39. # This is Buildr code define "My application" do define "A" do package :jar end Parent projects define "B" do implicitly depend on package :jar children end define "C" do compile.with projects("A", "B") package :jar end package(:war).using :libs => projects("A", "B", "C") end
  • 40. my-application/ ├── A │ └── src │ ├── main │ │ ├── java Standard directory │ │ └── resources │ └── test structure │ └── java ├── B │ └── src (can be customized) │ ├── main │ │ └── scala │ └── test │ └── scala ├── C │ └── src │ └── main │ └── groovy └── src └── main ├── java └── webapp
  • 41. $ buildr package (in /home/alexis/example, development) Building buildr-example Compiling buildr-example:a into /home/alexis/example/a/target/classes Compiling buildr-example:b into /home/alexis/example/b/target/classes Packaging buildr-example-a-1.0.0.jar Packaging buildr-example-b-1.0.0.jar Compiling buildr-example:c into /home/alexis/example/c/target/classes Packaging buildr-example Packaging buildr-example-c-1.0.0.jar Packaging buildr-example-1.0.0.war Running integration tests... Completed in 0.779s
  • 42. All about tasks.
  • 43. Standard tasks [ partial list ]
  • 44. # Actual Rake code class FileTask < Task def needed? !File.exist?(name) || out_of_date? end private def out_of_date? @prerequisites.any? { |n| n.timestamp > timestamp} end end
  • 46. Dependency resolution Local files (no kidding!!!) Maven2 (built-in) Ivy (plugin) Aether (plugin) or roll your own.
  • 47. # Buildfile repositories.remote << "http://www.ibiblio.org/maven2/" LOG4J = "log4j:log4j:jar:1.2.15" define 'my-library' do compile.with LOG4J package :jar end
  • 48. all your repos are belong to us !! # Buildfile repositories.remote << "http://www.ibiblio.org/maven2/" LOG4J = "log4j:log4j:jar:1.2.15" define 'my-library' do compile.with LOG4J package :jar end
  • 49. all your repos are belong to us !! # Buildfile artifacts repositories.remote << "http://www.ibiblio.org/maven2/" are LOG4J = "log4j:log4j:jar:1.2.15" Tasks, too define 'my-library' do compile.with LOG4J package :jar end
  • 50. all your repos are belong to us !! # Buildfile artifacts repositories.remote << "http://www.ibiblio.org/maven2/" are LOG4J = "log4j:log4j:jar:1.2.15" Tasks, too define 'my-library' do compile.with LOG4J package :jar tasks are end wired implicitly
  • 51. Languages we got 'em
  • 52. Example: Scala plugin require 'buildr/scala' # brings in: # # - automatic detection # (src/main/scala, src/test/scala, src/spec/scala) # # - incremental compilation # # - mixed java + scala compilation # # - scaladoc generation # # - scalatest, specs and scalacheck testing # # - continuous compilation
  • 53. Low Barrier to entry # if you have Ruby installed $ gem install buildr or, # JRuby all-in-one package $ unzip buildr-all-in-one.zip
  • 54. Demo Time! Java + Scala + Groovy Mixed Project
  • 55. More Stuff. layouts, profiles, code coverage, notifications more plugins, more languages + more awesome.
  • 56. Only one thing to remember.
  • 57. Build like you code.
  • 58. join us! http://buildr.apache.org @buildr Slides and Code available at github.com/alexism Alex Boisvert @boia01
  • 59. Ant Example: XMLBeans <taskdef name="xmlbean" classname="org.apache.xmlbeans.impl.tool.XMLBean" classpath="path/to/xbean.jar" /> <xmlbean classgendir="${build.dir}" classpath="${class.path}" failonerror="true"> <fileset basedir="src" excludes="**/*.xsd"/> <fileset basedir="schemas" includes="**/*.*"/> </xmlbean>
  • 60. Ant Example: XMLBeans def xmlbeans(files) do Buildr.ant "xmlbeans" do |ant| ant.taskdef :name => "xmlbeans", :classname => "org.apache.xmlbeans.impl.tool.XMLBean", :classpath => 'org.apache.xmlbeans:xmlbeans:jar:2.3.0' ant.xmlbeans :classpath => project.compile.dependencies, :srcgendir => project._('target/generated') :failonerror => "true" do files.flatten.each do |file| ant.fileset File.directory?(file) ? { :dir => file } : { :file => file } end end end
  • 61. # Convert .pom to ivy.xml module POM_to_IVY extend self ANT = Buildr.ant('convertpom') do |ant| ant.taskdef :name => "convertpom", :classname => "org.apache.ivy.ant.IvyConvertPom" end end def convert(pom_file, ivy_file) ANT.convertpom :pomFile => pom_file, :ivyFile => ivy_file end end
  • 62. define :webapp do # regenerate app.js when any .coffee file changes file('target/js/app.js') => Dir['src/main/coffee/*.coffee']) do sh "dependence src/main/coffee/ -t coffee -o target/js" end resources.enhance ['target/js/app.js'] end
  • 63. # Generate SQL DDL schemas for all databases %w{ derby mysql oracle sqlserver postgres }.each do |db| db_xml = _("src/main/descriptors/persistence.#{db}.xml") partial_sql = file("target/partial.#{db}.sql"=>db_xml) do OpenJPA.mapping_tool :properties => db_xml, :action => "build", :sql => db.to_s, :classpath => projects("store", "dao") end # Add Apache license header header = _("src/main/scripts/license-header.sql") sql = concat(_("target/#{db}.sql") => [header, partial_sql]) build sql end
  • 64. # Compile using all Eclipse BIRT libraries BIRT_WAR = artifact(“org.eclipse.birt:birt:war:1.4.1”) unzip_birt = unzip _("target/birt") => BIRT_WAR unzip_birt.enhance do compile.with Dir[_("target/birt/WEB-INF/lib") + "/*.jar"] end compile.enhance [unzip_birt]
  • 65. Calling Java classes Java.classpath << [ "org.antlr:antlr:jar:3.0", "antlr:antlr:jar:2.7.7", "org.antlr:stringtemplate:jar:3.0" ] Java.org.antlr.Tool.new("-i #{input} -o #{output}").process
  • 66. Testing Your Build # rspec code check package(:war).entry('META-INF/MANIFEST'), 'should have license' do it.should contain(/Copyright (C) 2011/) end check file('target/classes/killerapp/Code.class'), 'should exist' do it.should exist end
  • 67. Example: Extension module GitVersion include Buildr::Extension @version = `git log -1 --pretty=format:%H` after_define do |project| project.packages.each do |jar| f = file project._("target/git-version.txt") do |f| Buildr.write f.to_s, @version end jar.enhance [f] jar.include f, :as => "META-INF/git-version.txt" end end end
  • 68. # apply to a single project define 'my-project' do extend GitVersion end # apply to all projects class Buildr::Project include GitVersion end