|
21 | 21 | [cljs.compiler :as comp]
|
22 | 22 | [cljs.closure :as closure]
|
23 | 23 | [cljs.js-deps :as js-deps])
|
24 |
| - (:import [java.io File] |
25 |
| - [java.lang ProcessBuilder Process] |
26 |
| - (java.util.concurrent TimeUnit))) |
| 24 | + (:import [java.io |
| 25 | + File StringWriter |
| 26 | + BufferedReader |
| 27 | + Writer InputStreamReader IOException] |
| 28 | + [java.lang ProcessBuilder])) |
27 | 29 |
|
28 | 30 | ;; =============================================================================
|
29 | 31 | ;; Useful Utilities
|
|
236 | 238 | ret)))
|
237 | 239 | [] deps)))
|
238 | 240 |
|
| 241 | +(defn- alive? [proc] |
| 242 | + (try (.exitValue proc) false (catch IllegalThreadStateException _ true))) |
| 243 | + |
| 244 | +(defn- pipe [^Process proc in ^Writer out] |
| 245 | + ;; we really do want system-default encoding here |
| 246 | + (with-open [^java.io.Reader in (-> in InputStreamReader. BufferedReader.)] |
| 247 | + (loop [buf (char-array 1024)] |
| 248 | + (when (alive? proc) |
| 249 | + (try |
| 250 | + (let [len (.read in buf)] |
| 251 | + (when-not (neg? len) |
| 252 | + (.write out buf 0 len) |
| 253 | + (.flush out))) |
| 254 | + (catch IOException e |
| 255 | + (when (and (alive? proc) (not (.contains (.getMessage e) "Stream closed"))) |
| 256 | + (.printStackTrace e *err*)))) |
| 257 | + (recur buf))))) |
| 258 | + |
239 | 259 | (defn node-module-deps
|
240 | 260 | "EXPERIMENTAL: return the foreign libs entries as computed by running
|
241 | 261 | the module-deps package on the supplied JavaScript entry point. Assumes
|
242 | 262 | that the module-deps & JSONStream NPM packages are either locally or
|
243 | 263 | globally installed."
|
244 | 264 | [{:keys [file]}]
|
245 |
| - (let [code (string/replace |
246 |
| - (slurp (io/resource "cljs/module_deps.js")) |
247 |
| - "JS_FILE" file) |
248 |
| - proc (-> (ProcessBuilder. |
249 |
| - (into-array |
250 |
| - ["node" "--eval" (str code)])) |
251 |
| - .start) |
252 |
| - timeout? (.waitFor proc 10 TimeUnit/SECONDS)] |
253 |
| - (when timeout? |
254 |
| - (println "Node.js process timed out")) |
255 |
| - (if (and (not (.isAlive proc)) |
256 |
| - (zero? (.exitValue proc))) |
257 |
| - (let [is (.getInputStream proc)] |
258 |
| - (into [] |
259 |
| - (map (fn [{:strs [file]}] file |
260 |
| - {:file file :module-type :commonjs})) |
261 |
| - (butlast (json/read-str (slurp is))))) |
| 265 | + (let [code (string/replace |
| 266 | + (slurp (io/resource "cljs/module_deps.js")) |
| 267 | + "JS_FILE" file) |
| 268 | + proc (-> (ProcessBuilder. |
| 269 | + ["node" "--eval" code]) |
| 270 | + .start) |
| 271 | + is (.getInputStream proc) |
| 272 | + iw (StringWriter. (* 16 1024 1024)) |
| 273 | + es (.getErrorStream proc) |
| 274 | + ew (StringWriter. (* 1024 1024)) |
| 275 | + _ (do (.start |
| 276 | + (Thread. |
| 277 | + (bound-fn [] (pipe proc is iw)))) |
| 278 | + (.start |
| 279 | + (Thread. |
| 280 | + (bound-fn [] (pipe proc es ew))))) |
| 281 | + err (.waitFor proc)] |
| 282 | + (if (zero? err) |
| 283 | + (into [] |
| 284 | + (map (fn [{:strs [file]}] file |
| 285 | + {:file file :module-type :commonjs})) |
| 286 | + (butlast (json/read-str (str iw)))) |
262 | 287 | (do
|
263 | 288 | (when-not (.isAlive proc)
|
264 |
| - (let [es (.getErrorStream proc)] |
265 |
| - (println (slurp es)))) |
| 289 | + (println (str ew))) |
266 | 290 | []))))
|
267 | 291 |
|
268 | 292 | (comment
|
|
0 commit comments