Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Boot: Build tooling for Clojure(script)

Boot: Build tooling for Clojure(script)

Talk given at ClojureD in Berlin in January 2015.

746d139f9b7c20f00641fd91bd26b451?s=128

mklappstuhl

January 24, 2015
Tweet

Transcript

  1. Hi

  2. WHAT'S BOOT?

  3. WHY ANOTHER BUILD TOOL?

  4. None
  5. <script type="text/hoplon"> (page "index.html" (:refer-clojure :exclude [nth]) ;; A lot

    more ClojureScript </script> <html lang="en"> <head> <meta charset="utf8"> </head> <body> <!-- A lot more HTML --> </body> </html>
  6. NO ABSTRACTIONS FOR BUILD PROCESSES

  7. TIME PASSES...

  8. 2.0

  9. HOW

  10. TASKS ABSTRACTIONS FOR BUILD PROCESSES

  11. ;; build.boot (set-env! :source-paths #{"src"} :dependencies '[[pandeiro/boot-http "0.4.2"] ...]) (require

    '[pandeiro.boot-http :refer [serve]] ...) (deftask run [] (comp (serve) ; serve files (speak) ; audible notifications (watch) ; trigger new builds (cljs-repl) ; cljs REPL - hah! (reload) ; Figwheel style reloading (build)))
  12. ;; build.boot (set-env! :source-paths #{"src"} :dependencies '[[pandeiro/boot-http "0.4.2"] ...]) (require

    '[pandeiro.boot-http :refer [serve]] ...) (deftask build [] (comp (cljx) (cljs) (garden))) (deftask run [] (comp (serve) ; serve files (speak) ; audible notifications (watch) ; trigger new builds (cljs-repl) ; cljs REPL - hah! (reload) ; Figwheel style reloading (build)))
  13. COMPOSE ALL THE THINGS

  14. BUT... SIDE EFFECTS EVERYWHERE?

  15. FILESET FILES AS VALUES

  16. DEPENDENCY ISOLATION

  17. PODS ISOLATED CLOJURE RUNTIMES

  18. TWO MORE QUICK THINGS

  19. TASK OPTIONS (boot (cljs :optimizations :advanced)) ; REPL

  20. TASK OPTIONS (boot (cljs :optimizations :advanced)) ; REPL CLI <>

    REPL SYMMETRY boot serve watch cljs -O advanced # SHELL (boot (serve) (watch) (cljs :optimizations :advanced)) ; REPL
  21. Demo

  22. (ns boot-garden.core {:boot/export-tasks true} (:require [clojure.java.io :as io] [boot.core :as

    boot :refer [deftask]] [boot.pod :as pod] [boot.file :as file] [boot.util :as util])) (def initial (atom true)) (defn add-dep [env dep] (update-in env [:dependencies] (fnil conj []) dep)) (defn ns-tracker-pod [] (pod/make-pod (assoc-in (boot/get-env) [:dependencies] '[[ns-tracker "0.2.2"]]))) (defn garden-pool [] (pod/pod-pool (add-dep (boot/get-env) '[garden "1.2.5"]) :init (fn [pod] (pod/require-in pod 'garden.core)))) (deftask garden "compile garden" [o output-to PATH str "The output css file path relative to docroot." s styles-var SYM sym "The var containing garden rules" p pretty-print bool "Pretty print compiled CSS" v vendors [str] "Vendors to apply prefixed for" a auto-prefix [str] "Properties to auto-prefix with vendor-prefixes"] (let [output-path (or output-to "main.css") css-var styles-var ns-sym (symbol (namespace css-var)) tmp (boot/temp-dir!) out (io/file tmp output-path) src-paths (vec (boot/get-env :source-paths)) garden-pods (garden-pool) ns-pod (ns-tracker-pod)] (pod/with-eval-in ns-pod (require 'ns-tracker.core) (def cns (ns-tracker.core/ns-tracker ~src-paths))) (boot/with-pre-wrap fileset (when (or @initial (some #{ns-sym} (pod/with-eval-in ns-pod (cns)))) (let [c-pod (garden-pods :refresh)] (if @initial (reset! initial false)) (util/info "Compiling %s...\n" (.getName out)) (io/make-parents out) (pod/with-eval-in c-pod (require '~ns-sym) (garden.core/css {:output-to ~(.getPath out) :pretty-print ~pretty-print :vendors ~vendors :auto-prefix ~(set auto-prefix)} ~css-var)))) (-> fileset (boot/add-resource tmp) boot/commit!))))
  23. (ns boot-garden.core {:boot/export-tasks true} (:require [clojure.java.io :as io] [boot.core :as

    boot :refer [deftask]] [boot.pod :as pod] [boot.file :as file] [boot.util :as util]))
  24. ;; (ns boot-garden.core ;; {:boot/export-tasks true} ;; (:require [clojure.java.io :as

    io] ;; [boot.core :as boot :refer [deftask]] ;; [boot.pod :as pod] ;; [boot.file :as file] ;; [boot.util :as util])) (def initial (atom true))
  25. ;; ... ;; (def initial ;; (atom true)) (defn add-dep

    [env dep] (update-in env [:dependencies] (fnil conj []) dep)) (defn ns-tracker-pod [] (pod/make-pod (assoc-in (boot/get-env) [:dependencies] '[[ns-tracker "0.2.2"]]))) (defn garden-pool [] (pod/pod-pool (add-dep (boot/get-env) '[garden "1.2.5"]) :init (fn [pod] (pod/require-in pod 'garden.core))))
  26. ;; ... ;; (defn garden-pool [] ;; (pod/pod-pool (add-dep (boot/get-env)

    '[garden "1.2.5"]) ;; :init (fn [pod] (pod/require-in pod 'garden.core)))) (deftask garden "compile garden" [o output-to PATH str "The output css file path relative to docroot." s styles-var SYM sym "The var containing garden rules" p pretty-print bool "Pretty print compiled CSS" v vendors [str] "Vendors to apply prefixed for" a auto-prefix [str] "Properties to auto-prefix with vendor-prefixes"]
  27. ;; ... ;; (deftask garden ;; "compile garden" ;; [o

    output-to PATH str "The output css file path relative to docroot." ;; s styles-var SYM sym "The var containing garden rules" ;; p pretty-print bool "Pretty print compiled CSS" ;; v vendors [str] "Vendors to apply prefixed for" ;; a auto-prefix [str] "Properties to auto-prefix with vendor-prefixes"] (let [output-path (or output-to "main.css") ns-sym (symbol (namespace styles-var)) tmp (boot/temp-dir!) out (io/file tmp output-path) src-paths (vec (boot/get-env :source-paths)) garden-pods (garden-pool) ns-pod (ns-tracker-pod)]
  28. ;; ... ;; (let [output-path (or output-to "main.css") ;; ns-sym

    (symbol (namespace styles-var)) ;; tmp (boot/temp-dir!) ;; out (io/file tmp output-path) ;; src-paths (vec (boot/get-env :source-paths)) ;; garden-pods (garden-pool) ;; ns-pod (ns-tracker-pod)] (pod/with-eval-in ns-pod (require 'ns-tracker.core) (def cns (ns-tracker.core/ns-tracker ~src-paths)))
  29. ;; ... ;; (pod/with-eval-in ns-pod ;; (require 'ns-tracker.core) ;; (def

    cns (ns-tracker.core/ns-tracker ~src-paths))) (boot/with-pre-wrap fileset (when (or @initial (some #{ns-sym} (pod/with-eval-in ns-pod (cns)))) (let [c-pod (garden-pods :refresh)] (if @initial (reset! initial false)) (util/info "Compiling %s...\n" (.getName out)) (io/make-parents out)
  30. ;; ... ;; (boot/with-pre-wrap fileset ;; (when (or @initial (some

    #{ns-sym} (pod/with-eval-in ns-pod (cns)))) ;; (let [c-pod (garden-pods :refresh)] ;; (if @initial (reset! initial false)) ;; (util/info "Compiling %s...\n" (.getName out)) ;; (io/make-parents out) (pod/with-eval-in c-pod (require '~ns-sym) (garden.core/css {:output-to ~(.getPath out) :pretty-print ~pretty-print :vendors ~vendors :auto-prefix ~(set auto-prefix)} ~css-var));))
  31. ;; ... ;; (boot/with-pre-wrap fileset ;; (when (or @initial (some

    #{ns-sym} (pod/with-eval-in ns-pod (cns)))) ;; (let [c-pod (garden-pods :refresh)] ;; (if @initial (reset! initial false)) ;; (util/info "Compiling %s...\n" (.getName out)) ;; (io/make-parents out) ;; (pod/with-eval-in c-pod ;; (require '~ns-sym) ;; (garden.core/css {:output-to ~(.getPath out) ;; :pretty-print ~pretty-print ;; :vendors ~vendors ;; :auto-prefix ~(set auto-prefix)} ~css-var));)) (-> fileset (boot/add-resource tmp) boot/commit!);)))
  32. Done!

  33. RESOURCES

  34. None
  35. #HOPLON (IRC)

  36. TENZING lein new tenzing your-app

  37. FAZIT

  38. THANK YOU @martinklepsch

  39. QUESTIONS? @martinklepsch