I'm currently thinking more about invoking clojure
from babashka. This will satisfy the use case when your deps.edn map needs some dynamism, e.g. merging multiple maps together from multiple places, which currently isn't supported with the official clojure
.
The main question I'm asking right now is: should invoking (babashka.deps/clojure ...)
return something or should that function just hand over control to the java
process and exit accordingly to its return code.
https://github.com/borkdude/babashka/issues/678
Maybe it's useful to return something and not exit in the case of -Spath
, -Stree
etc.
So maybe returning a babashka.process
kind of thing and having its API available on the return value could work.
(babashka.deps/clojure ...)
could hand back the babashka.process
handle, so you can call check
on it or do something else according to your use case...
right
makes the most sense for library behavior
The iffy part is that clojure
sometimes does create a process (e.g. a REPL, or executing a file) but for some parts it doesn't, e.g. when invoking -Sdescribe
or -Spath
. So maybe it should only return a process when invoking main or exec.
it always starts a process (either bash+java or just bash), so it feels like its ok to always return a babashka.process process
that's not how it works in babashka because it's going to use borkdude/deps.clj. the bash is just in-process code.
i.e. no need to install the official clojure CLI, etc.
cross-platform solution
oh, gotcha
feels like there should be multiple functions in the namespace then, one for each major mode in the bash cli: 1. run a main 2. execute a function 3. ...
and the ones that execute java return a process, the other ones return data
I think it'd be nice if people can just pass what they're used to on the command line. E.g.:
$ bb '(-> (babashka.deps/clojure ["-M" "-e" "(+ 1 2 3)"] {:out :string}) babashka.process/check :out)'
"6\n"
$ bb '(-> (babashka.deps/clojure ["-M" "-e" "(+ 1 2 3)"] {:out :inherit}) babashka.process/check) nil'
6
So maybe for -Stree
and some others, we can just document that they won't return a process and users should program accordingly
A simple REPL invocation:
$ bb '(-> (babashka.deps/clojure [] {:inherit true}) babashka.process/check) nil'
Clojure 1.10.2-alpha2
user=> (System/exit 0)
$ bb '(babashka.deps/clojure ["-O"])'
----- Error --------------------------------------------------------------------
Type: java.lang.Exception
Message: -O is no longer supported, use -A with repl, -M for main, or -X for exec
Location: <expr>:1:1
Was thinking about this more. How about the idea of two levels of api?
Level 1: DWIM, can just copy/paste in cli args that you would have passed to clojure
and it will do the right thing, would sometimes return process or data.
Level 2: individual functions for each task type, for deeper integration and control, takes native data structures or args, some functions return process, others return data.
Could just do level 1 at first, and see if there's demand for level 2 to crystallize later.
Good thoughts
Current impl of 1 never returns data. It either prints to out or it returns a process
e.g. for -Spath you can use with-out-str
This is just because I'm re-using borkdude/deps code, not something that necessarily should be the default impl
But since the Clojure CLI is also printing this stuff, it might make sense
Maybe :inherit true
should then also be the default:
so (deps/clojure)
will just invoke a Clojure REPL
(deps/clojure ["-M" "-e" "(+ 1 2 3)"])
will print 6 to stdout and returns a process
(deps/clojure ["-M" "-e" "(+ 1 2 3)"] {:out :string})
prints to a :out
:string
and returns the process
but maybe changing the defaults of babashka.process
isn't nice
although :inherit true
is probably closer to DWIM
Hm, that's a tough one. If you want to mimic bash, every command has inherit true.
The idea is to have a easy programmatic Clojure launcher. I think deps/clojure
will often be the exit point of the script
Changing babashka.process's default would be an upheaval. Maybe it should have been called babashka.process.alpha1 . Heh. (Mostly kidding)
Yes, I agree that it will likely be the end of the script.
No, I don't mean changing babashka.process itself, but the options passed to clojure
will implictly have :inherit true
as default
ah cool, yes, that makes sense
Ah so {:out :inherit :in :inherit :err :inherit
is the default and can then be overriden per key via opts. Maybe that works
$ clojure -M:babashka/dev '(System/exit (:exit @(babashka.deps/clojure)))'
Clojure 1.10.2-alpha2
user=> (System/exit 1)
borkdude@MBP2019 ~/Dropbox/dev/clojure/babashka (babashka-deps*) $ echo $?
1
basically rewriting the CLI in fns... hmm. I'll contemplate that while sleeping. Thanks.
👍 rest well