Skip to content

Commit

Permalink
Fix #38: support :out :bytes (#138)
Browse files Browse the repository at this point in the history
  • Loading branch information
hansbugge authored Jun 19, 2023
1 parent 7ad806c commit b912d8e
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 6 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,16 @@ user=> (->> (with-out-str (check (process {:out *out*} "ls"))) str/split-lines (
("API.md" "CHANGELOG.md")
```

The `:out` option also supports `:string`. You will need to `deref` the process
in order for the string to be there, since the output can't be finalized if the
process hasn't finished running:
The `:out` option also supports `:string` for collecting stdout into a string
and `:bytes` for getting the raw output as a byte array. You will need to
`deref` the process in order for the string or byte array to be there, since the
output can't be finalized if the process hasn't finished running:

``` clojure
user=> (-> @(process {:out :string} "ls") :out str/split-lines first)
"API.md"
user=> (-> @(process {:out :bytes} "head -c 10 /dev/urandom") :out seq)
(119 -43 -68 -64 -16 -56 32 45 86 56)
```

## Piping output
Expand Down
2 changes: 2 additions & 0 deletions script/wd.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
;; :err <somestring> - dump <somestring> to stderr
;; :ls <somefile> - dir of <somefile> to stdout
;; :env - dump env to stdout
;; :echo - redirect the content of stdin to stdout
;; :grep <somestring> - returns all lines from stdin matching <somestring>
;; :upper - read and emit lines from stdin, but converted to uppercase
;; :ps-me - dump some info for current process (macOS & Linux only)
Expand All @@ -21,6 +22,7 @@
":err" (binding [*out* *err*] (println val))
":ls" (pr (->> val io/file (.listFiles) (map str) sort))
":env" (pr (->> (System/getenv) (into {})))
":echo" (io/copy System/in System/out)
":grep" (doseq [l (->> *in* io/reader line-seq (filter #(str/includes? % val)))]
(println l))
":upper" (doseq [l (->> *in* io/reader line-seq)]
Expand Down
10 changes: 7 additions & 3 deletions src/babashka/process.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,9 @@
(defn- copy [in out encoding]
(let [[out post-fn] (if (keyword? out)
(case out
:string [(java.io.StringWriter.) str])
:string [(java.io.StringWriter.) str]
:bytes [(java.io.ByteArrayOutputStream.)
#(.toByteArray ^java.io.ByteArrayOutputStream %)])
[out identity])]
(io/copy in out :encoding encoding)
(post-fn out)))
Expand Down Expand Up @@ -366,10 +368,12 @@
stdout (.getInputStream proc)
stderr (.getErrorStream proc)
out (if (and out (or (identical? :string out)
(identical? :bytes out)
(not (keyword? out))))
(future (copy stdout out out-enc))
stdout)
err (if (and err (or (identical? :string err)
(identical? :bytes err)
(not (keyword? err))))
(future (copy stderr err err-enc))
stderr)]
Expand Down Expand Up @@ -425,8 +429,8 @@
For redirecting to Clojure's `*in*`, `*out*` or `*err*` stream, set
the corresponding option accordingly.
The `:out` and `:err` options support `:string` for writing to a string
output. You will need to `deref` the process before accessing the string
via the process's `:out`.
output and `:bytes` for writing to a byte array. You will need to `deref`
the process before accessing the string or byte array via the process's `:out`.
To redirect `:err` to `:out`, specify `:err :out`.
For writing output to a file, you can set `:out` and `:err` to a `java.io.File` object, or a keyword:
- `:write` + an additional `:out-file`/`:err-file` + file to write to the file.
Expand Down
10 changes: 10 additions & 0 deletions test/babashka/process_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -488,3 +488,13 @@
(.close in)
@res
(is (false? (p/alive? res))))))

(deftest byte-array-out-test
(when-let [bb (u/find-bb)]
(let [ba (byte-array (range 1000))
result (-> (format "%s %s :echo" bb u/wd)
(process {:in ba :out :bytes})
deref
:out)]
(is (bytes? result))
(is (= (seq ba) (seq result))))))

0 comments on commit b912d8e

Please # to comment.