Build like you code with Apache Buildr        by Alexis Midon          @alexizany                           1
{ Why, How, Demo of }            a Build System that                        { does not suck,                        gets o...
About Me
Alexis Midon    @alexiszany midon@apache.org
www.c3-e.com
Sail & Live in San Francisco, CA          Since 2007
JavaJavascript   Ruby   Scala     ...
Use Buildr  on daily basis and still lovinit!
PracticalIntroduction to Apache Buildr
Where & Why  it all started
Apache OdeLarge Java Enterprise    Middleware
15+ modules   9 databases120+ dependencies  3 distributions  tooling heavy         ...
Maven2  5,433 lines of XMLspread over 52 files (!)
“@&#! TheresGot To BeA Better  Way”
What wasReally Wanted
No XML. Please!
FlexibleEasy to customize & extend
DRY Code Basic abstraction andstructuring mechanisms
In other words, a real scripting language.
Result?      drum_roll....roulement_de_tambour...
Before      52 files5,433 lines of XML.
Before      52 files5,433 lines of XML.   After   Single file.486 lines of Ruby.
Bonus!Twice as fast.
HowDid they do it?
Ruby   awesome scripting language
why ruby?
Scriptingeasy 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,             dependenciesRuby   awesome scripting language
RakeThe Ruby Make
RakeThe Ruby Make        “Ant”
Your Application  [ modules ]
[ graph of dependencies ]
# This is Rake codetask "compile A" do  # code to compile Aendtask "compile B" do  # code to compile Bendtask "compile C" ...
$ rake(in /home/buildr/example)compiling A ...compiling B ...compiling C ...packaging A,B,C ...
Buildr   projects, lifecycle, artifacts, pluginsRake                 tasks, files,                    dependenciesRuby    ...
# This is Buildr codedefine "My application" do  define "A" do    package :jar  end  define "B" do    package :jar  end  d...
# This is Buildr codedefine "My application" do  define "A" do    package :jar  end                                       ...
my-application/├── A│   └── src│       ├── main│       │    ├── java        Standard directory│       │    └── resources│ ...
$ buildr package(in /home/alexis/example, development)Building buildr-exampleCompiling buildr-example:a into /home/alexis/...
All about   tasks.
Standard tasks   [ partial list ]
# Actual Rake codeclass FileTask < Task  def needed?    !File.exist?(name) || out_of_date?  end  private  def out_of_date?...
artifactsand repositories
Dependency resolutionLocal files   (no kidding!!!)Maven2        (built-in)Ivy           (plugin)Aether        (plugin)or r...
# Buildfilerepositories.remote << "http://www.ibiblio.org/maven2/"LOG4J = "log4j:log4j:jar:1.2.15"define my-library do  co...
all your repos                                                 are belong                                                 ...
all your repos                                                are belong                                                  ...
all your repos                                                are belong                                                  ...
Languages  we got em
Example: Scala pluginrequire buildr/scala# brings in:##   - automatic detection#     (src/main/scala, src/test/scala, src/...
Low Barrier to entry# if you have Ruby installed$ gem install buildror,# JRuby all-in-one package$ unzip buildr-all-in-one...
Demo Time!Java + Scala + Groovy   Mixed Project
More Stuff.      layouts, profiles,code coverage, notificationsmore plugins, more languages     + more awesome.
Only one thingto remember.
Build like you code.
join us!                http://buildr.apache.org                        @buildrSlides and Code available at github.com/ale...
Ant Example: XMLBeans<taskdef name="xmlbean"         classname="org.apache.xmlbeans.impl.tool.XMLBean"         classpath="...
Ant Example: XMLBeansdef xmlbeans(files) do  Buildr.ant "xmlbeans" do |ant|    ant.taskdef       :name => "xmlbeans",     ...
# Convert .pom to ivy.xmlmodule POM_to_IVY  extend self  ANT = Buildr.ant(convertpom) do |ant|    ant.taskdef :name => "co...
define :webapp do  # regenerate app.js when any .coffee file changes  file(target/js/app.js) => Dir[src/main/coffee/*.coff...
# Generate SQL DDL schemas for all databases%w{ derby mysql oracle sqlserver postgres }.each do |db|  db_xml = _("src/main...
# Compile using all Eclipse BIRT librariesBIRT_WAR = artifact(“org.eclipse.birt:birt:war:1.4.1”)unzip_birt = unzip _("targ...
Calling Java classesJava.classpath << [ "org.antlr:antlr:jar:3.0",                    "antlr:antlr:jar:2.7.7",            ...
Testing Your Build# rspec codecheck package(:war).entry(META-INF/MANIFEST), should havelicense do  it.should contain(/Copy...
Example: Extensionmodule GitVersion  include Buildr::Extension  @version = `git log -1 --pretty=format:%H`  after_define d...
# apply to a single projectdefine my-project do  extend GitVersionend# apply to all projectsclass Buildr::Project  include...
Upcoming SlideShare
Loading in...5
×

Buildr In Action @devoxx france 2012

2,397

Published on

Buildr is a modern build system for Java-based applications including support for Scala, Groovy and a growing number of JVM languages and tools. Buildr combines the expressiveness of the Ruby scripting language with a familiar dependency-based task execution model and project-level structure similar to Apache Maven. This session will introduce Buildr and demonstrate practical solutions to common build problems.

Creative Commons License v2.0 with attribution ©Alex Boisvert

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,397
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
11
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Buildr In Action @devoxx france 2012

  1. 1. Build like you code with Apache Buildr by Alexis Midon @alexizany 1
  2. 2. { Why, How, Demo of } a Build System that { does not suck, gets out of the way, lets you write code } 2
  3. 3. About Me
  4. 4. Alexis Midon @alexiszany midon@apache.org
  5. 5. www.c3-e.com
  6. 6. Sail & Live in San Francisco, CA Since 2007
  7. 7. JavaJavascript Ruby Scala ...
  8. 8. Use Buildr on daily basis and still lovinit!
  9. 9. PracticalIntroduction to Apache Buildr
  10. 10. Where & Why it all started
  11. 11. Apache OdeLarge Java Enterprise Middleware
  12. 12. 15+ modules 9 databases120+ dependencies 3 distributions tooling heavy ...
  13. 13. Maven2 5,433 lines of XMLspread over 52 files (!)
  14. 14. “@&#! TheresGot To BeA Better Way”
  15. 15. What wasReally Wanted
  16. 16. No XML. Please!
  17. 17. FlexibleEasy to customize & extend
  18. 18. DRY Code Basic abstraction andstructuring mechanisms
  19. 19. In other words, a real scripting language.
  20. 20. Result? drum_roll....roulement_de_tambour...
  21. 21. Before 52 files5,433 lines of XML.
  22. 22. Before 52 files5,433 lines of XML. After Single file.486 lines of Ruby.
  23. 23. Bonus!Twice as fast.
  24. 24. HowDid they do it?
  25. 25. Ruby awesome scripting language
  26. 26. why ruby?
  27. 27. Scriptingeasy file manipulation native regexp, lightweight syntax exec() friendly etc.
  28. 28. Metaprogramm great host for embedded domain-specific language
  29. 29. JVM Friendly ;)JRuby & Ruby-Java Bridge
  30. 30. Rake tasks, files, dependenciesRuby awesome scripting language
  31. 31. RakeThe Ruby Make
  32. 32. RakeThe Ruby Make “Ant”
  33. 33. Your Application [ modules ]
  34. 34. [ graph of dependencies ]
  35. 35. # This is Rake codetask "compile A" do # code to compile Aendtask "compile B" do # code to compile Bendtask "compile C" => ["compile A", "compile B"] do # code to compile Cendtask "package A,B,C" => ["compile A", "...", "compile C"] do # code to package A, B and Cendtask :default => “package A, B, C”
  36. 36. $ rake(in /home/buildr/example)compiling A ...compiling B ...compiling C ...packaging A,B,C ...
  37. 37. Buildr projects, lifecycle, artifacts, pluginsRake tasks, files, dependenciesRuby awesome scripting language
  38. 38. # This is Buildr codedefine "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. 39. # This is Buildr codedefine "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. 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. 41. $ buildr package(in /home/alexis/example, development)Building buildr-exampleCompiling buildr-example:a into /home/alexis/example/a/target/classesCompiling buildr-example:b into /home/alexis/example/b/target/classesPackaging buildr-example-a-1.0.0.jarPackaging buildr-example-b-1.0.0.jarCompiling buildr-example:c into /home/alexis/example/c/target/classesPackaging buildr-examplePackaging buildr-example-c-1.0.0.jarPackaging buildr-example-1.0.0.warRunning integration tests...Completed in 0.779s
  42. 42. All about tasks.
  43. 43. Standard tasks [ partial list ]
  44. 44. # Actual Rake codeclass FileTask < Task def needed? !File.exist?(name) || out_of_date? end private def out_of_date? @prerequisites.any? { |n| n.timestamp > timestamp} endend
  45. 45. artifactsand repositories
  46. 46. Dependency resolutionLocal files (no kidding!!!)Maven2 (built-in)Ivy (plugin)Aether (plugin)or roll your own.
  47. 47. # Buildfilerepositories.remote << "http://www.ibiblio.org/maven2/"LOG4J = "log4j:log4j:jar:1.2.15"define my-library do compile.with LOG4J package :jarend
  48. 48. all your repos are belong to us !!# Buildfilerepositories.remote << "http://www.ibiblio.org/maven2/"LOG4J = "log4j:log4j:jar:1.2.15"define my-library do compile.with LOG4J package :jarend
  49. 49. all your repos are belong to us !!# Buildfile artifactsrepositories.remote << "http://www.ibiblio.org/maven2/" areLOG4J = "log4j:log4j:jar:1.2.15" Tasks, toodefine my-library do compile.with LOG4J package :jarend
  50. 50. all your repos are belong to us !!# Buildfile artifactsrepositories.remote << "http://www.ibiblio.org/maven2/" areLOG4J = "log4j:log4j:jar:1.2.15" Tasks, toodefine my-library do compile.with LOG4J package :jar tasks areend wired implicitly
  51. 51. Languages we got em
  52. 52. Example: Scala pluginrequire 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. 53. Low Barrier to entry# if you have Ruby installed$ gem install buildror,# JRuby all-in-one package$ unzip buildr-all-in-one.zip
  54. 54. Demo Time!Java + Scala + Groovy Mixed Project
  55. 55. More Stuff. layouts, profiles,code coverage, notificationsmore plugins, more languages + more awesome.
  56. 56. Only one thingto remember.
  57. 57. Build like you code.
  58. 58. join us! http://buildr.apache.org @buildrSlides and Code available at github.com/alexism Alex Boisvert @boia01
  59. 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. 60. Ant Example: XMLBeansdef 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 endend
  61. 61. # Convert .pom to ivy.xmlmodule 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 endend
  62. 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. 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 sqlend
  64. 64. # Compile using all Eclipse BIRT librariesBIRT_WAR = artifact(“org.eclipse.birt:birt:war:1.4.1”)unzip_birt = unzip _("target/birt") => BIRT_WARunzip_birt.enhance do compile.with Dir[_("target/birt/WEB-INF/lib") + "/*.jar"]endcompile.enhance [unzip_birt]
  65. 65. Calling Java classesJava.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. 66. Testing Your Build# rspec codecheck package(:war).entry(META-INF/MANIFEST), should havelicense do it.should contain(/Copyright (C) 2011/)endcheck file(target/classes/killerapp/Code.class), should exist do it.should existend
  67. 67. Example: Extensionmodule 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 endend
  68. 68. # apply to a single projectdefine my-project do extend GitVersionend# apply to all projectsclass Buildr::Project include GitVersionend
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×