/src/leiningen/cljs_devmode.clj
Clojure | 80 lines | 68 code | 8 blank | 4 comment | 10 complexity | 1a863406d4c6a71c97dd7faf31f2c3ae MD5 | raw file
- (ns leiningen.cljs-devmode
- (:use clojure.java.io)
- (:import [java.lang Process Runtime]
- java.io.StringReader))
- (def cljs-command
- ["java" "-server" "-Xmx2G" "-Xms2G" "-Xmn256m"
- "-cp" "lib/*:src/clj:src/cljs"
- "clojure.main" "-e"])
- (defn- build-cljs-invoke [script]
- (conj cljs-command (apply str script)))
- ;TODO: How can the stdout of the other JVM be redirected to the stdout
- ;of this JVM (clojure.java.shell doesn't support to get the
- ;InputStream from the inner java.lang.Process directly yet, so we have
- ;to use Runtime.exec here)
- (defn- start-clojurescript [clojurescript-home script]
- (let [cljs-invoke (build-cljs-invoke script)
- runtime (Runtime/getRuntime)
- process (.exec runtime ^"[Ljava.lang.String;" (into-array cljs-invoke)
- ^"[Ljava.lang.String;" (into-array String [])
- (as-file clojurescript-home))]
- (with-open [err (.getErrorStream process)]
- (slurp err))))
- (defn generate-script [clojurescript-home script]
- (str "#!/bin/sh\n"
- "cd " clojurescript-home "\n"
- (apply str (interpose " " cljs-command))
- " '"
- (apply str script)
- "'"))
- (def cljsc-bin-path "bin/cljsc")
- (defn is-clojurescript-home? [clojurescript-home]
- (let [cljsc-bin (file (file clojurescript-home) cljsc-bin-path)]
- (.exists cljsc-bin)))
- (defn check-clojurescript-home-param [clojurescript-home]
- (binding [*out* *err*]
- (let [clojurescript-home (or clojurescript-home (get (System/getenv) "CLOJURESCRIPT_HOME"))]
- (cond (not clojurescript-home)
- (println "Error: Please provide the ClojureScript home path as the last command line argument or via CLOJURESCRIPT_HOME.")
- (not (is-clojurescript-home? clojurescript-home))
- (println "Error: The given ClojureScript home path '"
- clojurescript-home
- "' is not a ClojureScript installation "
- "(" cljsc-bin-path " is missing.)")
- :else clojurescript-home))))
- (defn cljs-devmode
- [project & [mode clojurescript-home]]
- (when-let [clojurescript-home (check-clojurescript-home-param clojurescript-home)]
- (if (and mode (not (= mode "start")))
- (binding [*out* *err*]
- (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)."))
- (let [root-dir (:root project)
- dir (str root-dir "/cljs")
- project-name (:name project)
- defaults {:dir dir
- :src-dir (str dir "/src")
- :output-dir (str dir "/out")
- :output-to (str dir "/" project-name ".js")}
- cljs-devmode-opts (:cljs-devmode project {})
- options (merge defaults cljs-devmode-opts)
- cljs-build-opts (dissoc defaults :dir :src-dir)
- dir (:dir options)
- src-dir (:src-dir options)
- script `((require 'cljs.closure)
- (defn user/compile-fn [] (cljs.closure/build ~src-dir
- ~cljs-build-opts))
- (require 'cljs-devmode.core)
- (cljs-devmode.core/start-devmode ~dir user/compile-fn))]
- (if (= mode "start")
- (do
- (println "cljs-devmode started. Options: " options)
- (println (start-clojurescript clojurescript-home script)))
- (spit "cljs-devmode.sh" (generate-script clojurescript-home script)))))))