This commit is contained in:
2026-02-24 09:43:47 -07:00
parent 638b12c9eb
commit aa8b89fe84

View File

@@ -5,7 +5,7 @@
[clojure.java.io :as io])
(:import (java.io FilterInputStream StringWriter InputStream
OutputStream PrintStream ByteArrayOutputStream
ByteArrayInputStream)
ByteArrayInputStream FilterOutputStream)
(java.nio.charset StandardCharsets)))
(defn deref-with-timeout [process ms]
@@ -23,7 +23,10 @@
:timed-out-after-milliseconds ms}))
@p)))
(defn tee-input-stream [sink input-stream]
(defn tee-input-stream
"Return a wrapped `InputStream` that writes all bytes read from
input-stream to sink, à la the UNIX command tee(1)."
[input-stream sink]
(proxy [FilterInputStream] [input-stream]
(read
([]
@@ -45,16 +48,72 @@
(try (proxy-super close)
(finally (.close sink))))))
(defn tee-output-stream
"Return a wrapped `OutputStream` that writes all bytes written to
output-stream to sink, à la the UNIX command tee(1)."
[output-stream sink]
(proxy [FilterOutputStream] [output-stream]
(write
([bs-or-b]
(proxy-super write bs-or-b)
(.write sink bs-or-b))
([^bytes bs off len]
(proxy-super write bs off len)
(.write sink bs off len)))
(close []
(try (proxy-super close)
(finally (.close sink))))))
#_
(defn hook-input-stream [input-stream hook]
(proxy [FilterInputStream] [input-stream]
(read
([]
(let [c (proxy-super read)]
(when (not= c -1)
(hook (byte-array [c])))
c))
([^bytes bs]
(let [n (proxy-super read bs)]
(when (not= n -1)
(let [bs* (byte-array n 0)]
(System/arraycopy bs 0 bs* 0 n)
(hook bs*)))
n))
([^bytes bs off len]
(let [n (proxy-super read bs off len)]
(when (not= n -1)
(.write sink bs off n))
n)))
(close []
(try (proxy-super close)
(finally (.close sink))))))
(comment
(with-open [sink (ByteArrayOutputStream.)
out (ByteArrayOutputStream.)
in (ByteArrayInputStream. (.getBytes "hello worms"))]
(io/copy (tee-input-stream sink in) out)
(io/copy (tee-input-stream in sink) out)
(def the-out out)
(def the-sink sink)
{:out out
:sink sink})
(with-open [sink (l/log-stream :info "blah")
out (ByteArrayOutputStream.)
in (ByteArrayInputStream. (.getBytes "hello worms"))]
(io/copy (tee-input-stream in sink) out)
(def the-out out)
(def the-sink sink)
{:out out
:sink sink}))
(comment
(let [out (ByteArrayOutputStream.)]
(p/shell {:out (tee-output-stream
out
(l/log-stream :info "blah"))}
"echo" "hello" "worms")))
(defn invoke [opts & cmd]
(l/info (str/join " " (cons "$" cmd)))
(let [r (apply p/shell