PageRenderTime 46ms CodeModel.GetById 17ms app.highlight 14ms RepoModel.GetById 12ms app.codeStats 1ms

/src/leiningen/cljs_devmode.clj

http://github.com/maxweber/cljs-devmode
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)))))))