Fork me on GitHub
#babashka
<
2020-08-07
>
borkdude15:08:17

babashka.process, a small wrapper around java.lang.Process. WIP. Feedback welcome: https://github.com/babashka/babashka.process

lread15:08:16

Cool! I like your design for stdout handling: {:out :inherit} vs {:out :string} . In my usages of ProcessBuilder, I have found that I sometimes need to capture stderr to a string. Your process kind of implies it can do that, but I don’t think that it is implemented yet.

lukasz15:08:15

That's really cool - I have a bunch of hairy ECS deployment scripts and moving to bb will simplify a lot of stuff

lread15:08:52

Rewrite-cljc scripts have an internal shell/command based on one of your examples I think. Here’s the https://github.com/lread/rewrite-cljc-playground/blob/3aa4741a773ccd329c350208c50a83b1e8ce9671/script/helper/shell.clj#L60.

borkdude15:08:26

@lee Added support for {:err :string}

borkdude15:08:57

Also updated the README

lread15:08:05

@borkdude is as fast as !

borkdude15:08:25

I realize you can also just use slurp instead of those StringWriter stuff :)

lread15:08:52

I also like your naming: process is more apt that something like shell or shell-command.

lread16:08:56

Slurpy cool! I guess that stderr is never binary… is stdout ever binary?

borkdude16:08:46

can be yeah

borkdude16:08:00

in that case you can use

borkdude16:08:04

to copy it to a file or whatever

borkdude16:08:09

we can support :out-enc as well

lread16:08:54

yeah and your design is extensible you could {:out something-else} if the need arises.

borkdude16:08:34

I remember doing that too somewhere

borkdude16:08:38

I'll make an issue for it

lread16:08:50

I think this will make a very handy addition to babashka! I remember when first translating a bash script to babashka thinking cool, cool, cool - then, oh but that’s a bit of a big fn to just call a process, then, cool, cool, cool. simple_smile

lread17:08:01

Oh, I think you have helped me see that my version is adding too many backslashes maybe.

borkdude17:08:14

Maybe I can get rid of this workaround once and for all with babashka.process

lread17:08:28

That would be awesomeness. Lib will be handy for regular Clojure too, no?

borkdude17:08:44

Of course yes

borkdude17:08:58

It's available right now, with the risk of things still changing :)

lread17:08:57

I think I will likely be an early adopter.

borkdude17:08:42

I'm still a bit unsure about some things: maybe :out :string and :err :string should be the default. And when it is, maybe :exit should be the exit code directly, not a future / delay with an exit code. This is also how babashka.curl works. Also maybe throw with the contents of :err if :exit is non-zero, unless :throw is false.

Darin Douglass17:08:17

yeah i like that paradigm

lread20:08:42

I’m a sample size of 1, but when scripting I only occasionally capture output to strings. So :out and :err defaulting to :inherit would make more sense for me. My bash scripts always start with set -eou pipefail meaning that when anything goes wrong, I’d like my script to fail, so a default of throwing on error in babashka would make sense for me. That said, if I don’t like the defaults, I can very easily write a little wrapper fn that changes them.

borkdude21:08:26

@lee I'm willing to change it later, based on more feedback

lread21:08:05

Ya, I am totally happy with whatever you choose.

borkdude21:08:56

Added this now: Both :in and :out may contain objects that are compatible with :

clojure
user=> (with-out-str (process ["cat"] {:in "foo" :out *out*}))
"foo"

user=> (with-out-str (process ["ls"] {:out *out*}))
"LICENSE\nREADME.md\ndeps.edn\nsrc\ntest\n"

borkdude22:08:31

Probably exit code should also be wrapped in a future when :inherit is used. Since this is getting fairly complex, it might be better to just always wrap it in a future. Or maybe it should be an option.

borkdude23:08:26

Made it an option: :wait false which returns the exit code in a future.

borkdude23:08:42

Also came up with this (could not sleep because of the heat): Forwarding the output of a process as the input of another process can also be done with thread-first:

(-> (process ["ls"])
    (process ["grep" "README"]) :out)
"README.md"