Buildr In Action @devoxx france 2012
Upcoming SlideShare
Loading in...5
×
 

Buildr In Action @devoxx france 2012

on

  • 1,002 views

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 ...

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

Statistics

Views

Total Views
1,002
Views on SlideShare
999
Embed Views
3

Actions

Likes
1
Downloads
10
Comments
0

1 Embed 3

https://twitter.com 3

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

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

Buildr In Action @devoxx france 2012 Buildr In Action @devoxx france 2012 Presentation Transcript

  • 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
  • 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" => ["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”
  • $ rake(in /home/buildr/example)compiling A ...compiling B ...compiling C ...packaging A,B,C ...
  • Buildr projects, lifecycle, artifacts, pluginsRake tasks, files, dependenciesRuby awesome scripting language
  • # 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
  • # 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
  • 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-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
  • 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? @prerequisites.any? { |n| n.timestamp > timestamp} endend
  • artifactsand repositories
  • Dependency resolutionLocal files (no kidding!!!)Maven2 (built-in)Ivy (plugin)Aether (plugin)or roll your own.
  • # Buildfilerepositories.remote << "http://www.ibiblio.org/maven2/"LOG4J = "log4j:log4j:jar:1.2.15"define my-library do compile.with LOG4J package :jarend
  • 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
  • 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
  • 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
  • Languages we got em
  • 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
  • Low Barrier to entry# if you have Ruby installed$ gem install buildror,# JRuby all-in-one package$ unzip buildr-all-in-one.zip
  • 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/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: 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
  • # 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
  • 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 sqlend
  • # 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]
  • 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
  • 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
  • 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
  • # apply to a single projectdefine my-project do extend GitVersionend# apply to all projectsclass Buildr::Project include GitVersionend