|
9 | 9 | (ns clojure.tools.build.tasks.process |
10 | 10 | (:require |
11 | 11 | [clojure.java.io :as jio] |
| 12 | + [clojure.java.process :as proc] |
12 | 13 | [clojure.tools.deps :as deps] |
13 | 14 | [clojure.tools.build.api :as api] |
14 | 15 | [clojure.string :as str]) |
15 | 16 | (:import |
16 | | - [java.io InputStream StringWriter File] |
17 | | - [java.lang ProcessBuilder ProcessBuilder$Redirect] |
18 | | - [java.util List])) |
19 | | - |
20 | | -(defn- copy-stream |
21 | | - [^InputStream input-stream] |
22 | | - (let [writer (StringWriter.)] |
23 | | - (jio/copy input-stream writer) |
24 | | - (let [s (.toString writer)] |
25 | | - (when-not (zero? (.length s)) |
26 | | - s)))) |
| 17 | + [java.io InputStream StringWriter File])) |
| 18 | + |
| 19 | +(set! *warn-on-reflection* true) |
| 20 | + |
| 21 | +(defn- trim-blank [^String s] |
| 22 | + (if (str/blank? s) nil s)) |
27 | 23 |
|
28 | 24 | (defn process |
29 | 25 | "Exec the command made from command-args, redirect out and err as directed, |
|
48 | 44 | :or {dir ".", out :inherit, err :inherit} :as opts}] |
49 | 45 | (when (not (seq command-args)) |
50 | 46 | (throw (ex-info "process missing required arg :command-args" opts))) |
51 | | - (let [pb (ProcessBuilder. ^List command-args)] |
52 | | - (.directory pb (api/resolve-path (or dir "."))) |
53 | | - (case out |
54 | | - :inherit (.redirectOutput pb ProcessBuilder$Redirect/INHERIT) |
55 | | - :write (.redirectOutput pb (ProcessBuilder$Redirect/to (jio/file (api/resolve-path out-file)))) |
56 | | - :append (.redirectOutput pb (ProcessBuilder$Redirect/appendTo (jio/file (api/resolve-path out-file)))) |
57 | | - :capture (.redirectOutput pb ProcessBuilder$Redirect/PIPE) |
58 | | - :ignore (.redirectOutput pb ProcessBuilder$Redirect/PIPE)) |
59 | | - (case err |
60 | | - :inherit (.redirectError pb ProcessBuilder$Redirect/INHERIT) |
61 | | - :write (.redirectError pb (ProcessBuilder$Redirect/to (jio/file (api/resolve-path err-file)))) |
62 | | - :append (.redirectError pb (ProcessBuilder$Redirect/appendTo (jio/file (api/resolve-path err-file)))) |
63 | | - :capture (.redirectError pb ProcessBuilder$Redirect/PIPE) |
64 | | - :ignore (.redirectError pb ProcessBuilder$Redirect/PIPE)) |
65 | | - (when env |
66 | | - (let [pb-env (.environment pb)] |
67 | | - (run! (fn [[k v]] (.put pb-env k v)) env))) |
68 | | - (let [proc (.start pb) |
69 | | - exit (.waitFor proc) |
70 | | - out-str (when (= out :capture) (copy-stream (.getInputStream proc))) |
71 | | - err-str (when (= err :capture) (copy-stream (.getErrorStream proc)))] |
72 | | - (cond-> {:exit exit} |
73 | | - out-str (assoc :out out-str) |
74 | | - err-str (assoc :err err-str))))) |
| 47 | + (let [stream-opt (fn [opt file] |
| 48 | + (case opt |
| 49 | + :inherit :inherit |
| 50 | + :write (proc/to-file (api/resolve-path file)) |
| 51 | + :append (proc/to-file (api/resolve-path file) :append true) |
| 52 | + :ignore :discard |
| 53 | + (:capture :pipe) :pipe)) |
| 54 | + proc-opts {:dir (api/resolve-path (or dir ".")) |
| 55 | + :out (stream-opt out out-file) |
| 56 | + :err (stream-opt err err-file) |
| 57 | + :env env} |
| 58 | + proc (apply proc/start proc-opts command-args) |
| 59 | + out-f (when (= out :capture) (proc/io-task #(slurp (proc/stdout proc)))) |
| 60 | + err-f (when (= err :capture) (proc/io-task #(slurp (proc/stderr proc)))) |
| 61 | + exit (deref (proc/exit-ref proc)) |
| 62 | + out-str (when out-f (trim-blank @out-f)) |
| 63 | + err-str (when err-f (trim-blank @err-f))] |
| 64 | + (cond-> {:exit exit} |
| 65 | + out-str (assoc :out out-str) |
| 66 | + err-str (assoc :err err-str)))) |
| 67 | + |
| 68 | +(comment |
| 69 | + (api/process {:command-args ["ls" "-l"]}) |
| 70 | + (api/process {:command-args ["git" "log"] :out :ignore}) |
| 71 | + (api/process {:command-args ["java" "-version"] :err :capture}) |
| 72 | + (api/process {:command-args ["java" "--version"] :out :capture}) |
| 73 | + (api/process {:env {"FOO" "hi"} |
| 74 | + :command-args ["echo" "$FOO"] |
| 75 | + :out :capture}) |
| 76 | + ) |
75 | 77 |
|
76 | 78 | (defn- need-cp-file |
77 | 79 | [os-name java-version command-length] |
|
0 commit comments