|
10 | 10 | (:require
|
11 | 11 | [clojure.java.process :as proc]
|
12 | 12 | [clojure.edn :as edn]
|
13 |
| - [clojure.java.io :as jio])) |
| 13 | + [clojure.java.io :as jio] |
| 14 | + [clojure.string :as str])) |
14 | 15 |
|
15 | 16 | (set! *warn-on-reflection* true)
|
16 | 17 |
|
| 18 | +(def ^:private build (atom nil)) |
| 19 | + |
| 20 | +(defn- cli-build |
| 21 | + "Return CLI build number (a long) or nil if it can't be determined. |
| 22 | + The build number is cached if found and subsequently read from cache." |
| 23 | + [] |
| 24 | + (or @build |
| 25 | + (let [result (try |
| 26 | + (proc/exec "clojure" "--version") |
| 27 | + (catch Exception e "")) |
| 28 | + ;; Version string: "Clojure CLI version 1.11.3.1463" |
| 29 | + ;; Match MAJOR.MINOR.PATCH.BUILD and take a capture group just for the last BUILD part |
| 30 | + version (-> (re-find #"[0-9]+\.[0-9]+\.[0-9]+\.([0-9]+)" result) (nth 1))] |
| 31 | + (when version |
| 32 | + (reset! build (parse-long version)))))) |
| 33 | + |
| 34 | +(defn- validate-version |
| 35 | + [version] |
| 36 | + (if version |
| 37 | + (when (< version 1347) |
| 38 | + (throw (RuntimeException. "Clojure CLI version is older than minimum required version, 1.11.1.1347. Please update to latest version."))) |
| 39 | + (throw (ex-info "Clojure CLI version unknown, please install the latest version." {})))) |
| 40 | + |
17 | 41 | (defn ^:dynamic invoke-tool
|
18 | 42 | "Invoke tool using Clojure CLI. Args (one of :tool-alias or :tool-name, and :fn
|
19 | 43 | are required):
|
|
29 | 53 | :or {preserve-envelope false}
|
30 | 54 | :as opts}]
|
31 | 55 | (when-not (or tool-name tool-alias) (throw (ex-info "Either :tool-alias or :tool-name must be provided" (or opts {}))))
|
32 |
| - (when-not (symbol? fn) (throw (ex-info (str "fn should be a symbol " fn) (or opts {})))) |
| 56 | + (when-not (symbol? fn) (throw (ex-info (str ":fn should be a symbol " fn) (or opts {})))) |
| 57 | + (validate-version (cli-build)) |
33 | 58 | (let [args (conj [fn] (assoc args :clojure.exec/invoke :fn))
|
34 | 59 | _ (when (:debug opts) (println "args" args))
|
35 | 60 | command-strs ["clojure" (str "-T" (or tool-alias tool-name)) "-"]
|
36 | 61 | _ (when (:debug opts) (apply println "Invoking: " command-strs))
|
37 | 62 | proc (apply proc/start command-strs)
|
38 | 63 | in (proc/stdin proc)
|
39 |
| - out (proc/stdout proc)] |
| 64 | + out (proc/stdout proc) |
| 65 | + err (proc/stderr proc)] |
40 | 66 | (binding [*print-length* nil
|
41 | 67 | *print-level* nil
|
42 | 68 | *print-namespace-maps* false]
|
|
45 | 71 | (doseq [a args]
|
46 | 72 | (.write w (pr-str a))
|
47 | 73 | (.write w " ")))))
|
48 |
| - (let [envelope (edn/read-string (slurp out))] |
| 74 | + (if-let [envelope (edn/read-string (slurp out))] |
49 | 75 | (if preserve-envelope
|
50 | 76 | envelope
|
51 | 77 | (let [{:keys [tag val]} envelope
|
52 | 78 | parsed-val (edn/read-string val)]
|
53 | 79 | (if (= :ret tag)
|
54 | 80 | parsed-val
|
55 |
| - (throw (ex-info (:cause parsed-val) (or parsed-val {}))))))))) |
| 81 | + (throw (ex-info (:cause parsed-val) (or parsed-val {})))))) |
| 82 | + (let [err-str (slurp err) |
| 83 | + err-msg (if (= "" err-str) "Unknown error invoking Clojure CLI" err-str)] |
| 84 | + (throw (ex-info err-msg |
| 85 | + {:command (str/join " " command-strs) |
| 86 | + :in (str/join " " args)})))))) |
56 | 87 |
|
57 | 88 | (comment
|
58 | 89 | ;; regular invocation, should return {:hi :there}
|
|
0 commit comments