/src/leiningen/cljs_devmode.clj
Clojure | 80 lines | 68 code | 8 blank | 4 comment | 0 complexity | 1a863406d4c6a71c97dd7faf31f2c3ae MD5 | raw file
1(ns leiningen.cljs-devmode 2 (:use clojure.java.io) 3 (:import [java.lang Process Runtime] 4 java.io.StringReader)) 5 6(def cljs-command 7 ["java" "-server" "-Xmx2G" "-Xms2G" "-Xmn256m" 8 "-cp" "lib/*:src/clj:src/cljs" 9 "clojure.main" "-e"]) 10 11(defn- build-cljs-invoke [script] 12 (conj cljs-command (apply str script))) 13 14;TODO: How can the stdout of the other JVM be redirected to the stdout 15;of this JVM (clojure.java.shell doesn't support to get the 16;InputStream from the inner java.lang.Process directly yet, so we have 17;to use Runtime.exec here) 18(defn- start-clojurescript [clojurescript-home script] 19 (let [cljs-invoke (build-cljs-invoke script) 20 runtime (Runtime/getRuntime) 21 process (.exec runtime ^"[Ljava.lang.String;" (into-array cljs-invoke) 22 ^"[Ljava.lang.String;" (into-array String []) 23 (as-file clojurescript-home))] 24 (with-open [err (.getErrorStream process)] 25 (slurp err)))) 26 27(defn generate-script [clojurescript-home script] 28 (str "#!/bin/sh\n" 29 "cd " clojurescript-home "\n" 30 (apply str (interpose " " cljs-command)) 31 " '" 32 (apply str script) 33 "'")) 34 35(def cljsc-bin-path "bin/cljsc") 36 37(defn is-clojurescript-home? [clojurescript-home] 38 (let [cljsc-bin (file (file clojurescript-home) cljsc-bin-path)] 39 (.exists cljsc-bin))) 40 41(defn check-clojurescript-home-param [clojurescript-home] 42 (binding [*out* *err*] 43 (let [clojurescript-home (or clojurescript-home (get (System/getenv) "CLOJURESCRIPT_HOME"))] 44 (cond (not clojurescript-home) 45 (println "Error: Please provide the ClojureScript home path as the last command line argument or via CLOJURESCRIPT_HOME.") 46 (not (is-clojurescript-home? clojurescript-home)) 47 (println "Error: The given ClojureScript home path '" 48 clojurescript-home 49 "' is not a ClojureScript installation " 50 "(" cljsc-bin-path " is missing.)") 51 :else clojurescript-home)))) 52 53(defn cljs-devmode 54 [project & [mode clojurescript-home]] 55 (when-let [clojurescript-home (check-clojurescript-home-param clojurescript-home)] 56 (if (and mode (not (= mode "start"))) 57 (binding [*out* *err*] 58 (println "Error: The only supported mode at the moment is 'start', which starts the ClojureScript compiler process in another JVM from this JVM via Runtime/exec \"java.exe ...\" (you will not see the stdout or stderr of the ClojureScript compiler process).")) 59 (let [root-dir (:root project) 60 dir (str root-dir "/cljs") 61 project-name (:name project) 62 defaults {:dir dir 63 :src-dir (str dir "/src") 64 :output-dir (str dir "/out") 65 :output-to (str dir "/" project-name ".js")} 66 cljs-devmode-opts (:cljs-devmode project {}) 67 options (merge defaults cljs-devmode-opts) 68 cljs-build-opts (dissoc defaults :dir :src-dir) 69 dir (:dir options) 70 src-dir (:src-dir options) 71 script `((require 'cljs.closure) 72 (defn user/compile-fn [] (cljs.closure/build ~src-dir 73 ~cljs-build-opts)) 74 (require 'cljs-devmode.core) 75 (cljs-devmode.core/start-devmode ~dir user/compile-fn))] 76 (if (= mode "start") 77 (do 78 (println "cljs-devmode started. Options: " options) 79 (println (start-clojurescript clojurescript-home script))) 80 (spit "cljs-devmode.sh" (generate-script clojurescript-home script)))))))