|
| 1 | +(ns cljs-cli.util |
| 2 | + (:require |
| 3 | + [clojure.string :as string] |
| 4 | + [clojure.java.io :as io] |
| 5 | + [clojure.java.shell :as shell] |
| 6 | + [clojure.test :refer [is]]) |
| 7 | + (:import |
| 8 | + (java.io File) |
| 9 | + (java.nio.file Files CopyOption) |
| 10 | + (java.nio.file.attribute FileAttribute))) |
| 11 | + |
| 12 | +(def ^:dynamic *repl-env* "nashorn") |
| 13 | +(def ^:dynamic *repl-env-filter* (constantly true)) |
| 14 | +(def ^:dynamic *repl-opts* nil) |
| 15 | +(def ^:dynamic *sources* nil) |
| 16 | +(def ^:dynamic *post-condition* nil) |
| 17 | + |
| 18 | +(defmacro with-sources |
| 19 | + [sources & body] |
| 20 | + `(binding [*sources* ~sources] |
| 21 | + ~@body)) |
| 22 | + |
| 23 | +(defmacro with-post-condition |
| 24 | + [post-condition & body] |
| 25 | + `(binding [*post-condition* ~post-condition] |
| 26 | + ~@body)) |
| 27 | + |
| 28 | +(defmacro with-repl-env-filter |
| 29 | + [repl-env-filter & body] |
| 30 | + `(binding [*repl-env-filter* ~repl-env-filter] |
| 31 | + ~@body)) |
| 32 | + |
| 33 | +(defn- ^File make-temp-dir [] |
| 34 | + (.toFile (Files/createTempDirectory "cljs-cli-test" (make-array FileAttribute 0)))) |
| 35 | + |
| 36 | +(defn- delete-recursively [fname] |
| 37 | + (doseq [f (reverse (file-seq (io/file fname)))] |
| 38 | + (io/delete-file f))) |
| 39 | + |
| 40 | +(defn- copy-uberjar [^File dest] |
| 41 | + (Files/copy (.toPath (io/file "target/cljs.jar")) (.toPath (io/file dest "cljs.jar")) (make-array CopyOption 0))) |
| 42 | + |
| 43 | +(defn- write-sources [temp-dir] |
| 44 | + (let [qualified #(io/file temp-dir %)] |
| 45 | + (run! #(io/make-parents (qualified %)) (keys *sources*)) |
| 46 | + (run! (fn [[file source]] |
| 47 | + (spit (qualified file) source)) |
| 48 | + *sources*))) |
| 49 | + |
| 50 | +(defn- run-in-temp-dir [args] |
| 51 | + (let [temp-dir (make-temp-dir)] |
| 52 | + (try |
| 53 | + (write-sources temp-dir) |
| 54 | + (copy-uberjar temp-dir) |
| 55 | + (let [result (shell/with-sh-dir temp-dir |
| 56 | + #_(apply println "running:" args) |
| 57 | + (apply shell/sh args))] |
| 58 | + (when *post-condition* |
| 59 | + (is (*post-condition* temp-dir))) |
| 60 | + result) |
| 61 | + (finally |
| 62 | + (delete-recursively temp-dir))))) |
| 63 | + |
| 64 | +(defn form-cp [] |
| 65 | + (string/join File/pathSeparator ["cljs.jar" "src"])) |
| 66 | + |
| 67 | +(defn cljs-main [& args] |
| 68 | + (if (*repl-env-filter* *repl-env*) |
| 69 | + (let [command-line-args (map str args)] |
| 70 | + (run-in-temp-dir |
| 71 | + (keep (fn [arg] |
| 72 | + (when arg |
| 73 | + (str arg))) |
| 74 | + (into ["java" "-cp" (form-cp) "cljs.main" |
| 75 | + "-re" *repl-env* |
| 76 | + (when *repl-opts* "-ro") (when *repl-opts* *repl-opts*)] |
| 77 | + command-line-args)))) |
| 78 | + {:exit 0 :out "" :err ""})) |
| 79 | + |
| 80 | +(def ^:private expected-browser-err |
| 81 | + "Compiling client js ...\nServing HTTP on localhost port 9000\nListening for browser REPL connect ...\n") |
| 82 | + |
| 83 | +(defn- maybe-print-result-err [{:keys [err]}] |
| 84 | + (when (and (not (empty? err)) |
| 85 | + (not (= expected-browser-err err))) |
| 86 | + (binding [*out* *err*] |
| 87 | + (println err)))) |
| 88 | + |
| 89 | +(defn output-is [result & expected-lines] |
| 90 | + (is (zero? (:exit result))) |
| 91 | + (maybe-print-result-err result) |
| 92 | + (is (= (apply str (map print-str (interleave expected-lines (repeat "\n")))) |
| 93 | + (:out result)))) |
0 commit comments