Video

Why a new build tool

  • builds are processes, not specifications
  • most tools oriented around configuration instead of programming
  • we’re programmers, we need to be able to program builds

Our dream build tool

  • made of many indepenent parts that each do one thing well
  • much better than one monolithic program
  • small things are only useful if composition is left to the user

What is boot?

  • uses maven for dependency resolution
  • we use it to build Clojure, ClojureScript

A common build workflow

  • no project file required
  • boot -s src show -f - like adding the directory to the path
  • boot -s src -f -- javac -- show -f - compile java, show the fileset

Installing a jar

  • boot -s src javac -- pom -p boot-demo -v 0.1 -- jar -m boot.Demo -- install - builds and installs jar locally
  • boot -d boot-demo repl - starts a REPL with a dependency

Same from the REPL

boot repl
(set-env! :source-paths #{"src"})
(boot (javac) (pom :project 'boot-demo :version "0.1") (jar :main 'boot/Demo') (install))

Anatomy of a Task

(deftask my-task []
    (let [history (atom [])]
        (fn [next-handler]
            (fn [fileset]
                (swap! history conj fileset)
                (next-handler fileset)))))

Example

(deftask build []
    (comp
        (javac)
        (pom :project 'boot-demo :version "0.1")
        (jar :main 'boot/Demo')
        (install)))

(doc build)

Composing your tasks

(boot (watch) (build))

As a build script

#!/usr/bin/env boot

(set-env! :source-paths #{"src"})

(deftask build []
    (comp
        (javac)
        (pom :project 'boot-demo :version "0.1")
        (jar :main 'boot/Demo')
        (install)))

(defn -main [& arwgv]
    (boot (build) (show :fileset true)))

As a build.boot file

(set-env! :source-paths #{"src"})

(deftask build []
    (comp
        (javac)
        (pom :project 'boot-demo :version "0.1")
        (jar :main 'boot/Demo')
        (install)))

FileSet

  • a little anonymous git repo
  • real files underneath but 100% managed
  • basis for Classpath
  • immutable!
  • query API
  • add, remove (which returns a new immutable FileSet)
  • commit: mutates underlying files

Pods

  • how we avoid dependency hell
  • isolated Clojure runtimes
  • each can have different dependencies
  • easy to create, run code inside of
  • some things can’t be passed between pods

Example

boot repl
(def env (assoc boot.pod/env :dependencies '[[org.clojure/clojure "1.5.1]]))
(def pod (boot.pod/make-pod env))
(boot.pod/with-eval-in pod (clojure-version))
(clojure-version)