PageRenderTime 39ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/leiningen/cljs_devmode.clj

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