I'm considering a .babashka/config.edn
or babashka.edn
where you can store things like :paths
, :classpath-cmd
(to calculate a classpath using e.g. clojure
or using a bb script itself), :pods
: pod specific settings, like where to download them.
If you have any input on this, here is the issue: https://github.com/borkdude/babashka/issues/473
What would be the easiest way to craft something in bb that simply reads a number of edn forms from some file. I must be missing something obvious, but I invariably get off into weeds with needing to have a pushback-reader to use (clojure.edn/read). A bb (or clj) program that reads a file full of edn into memory should be hello world - so I must be missing somthing bigtime.
@hoppy so you have multiple values in one file, not like one value inside a vector right?
correct, and it's full of maps that are across multiple lines
@hoppy In one-liners you can do this:
$ echo '{:a 1} {:a 2}' | bb -I -e "*input*"
({:a 1} {:a 2})
yes, but I want to open the file from within the script
let me give you the variant that is suitable for scripts
$ echo '{:a 1} {:a 2}' | bb -e "(take-while #(not= ::eof %) (repeatedly #(edn/read {:eof ::eof} *in*)))"
({:a 1} {:a 2})
when reading from a file, replace *in*
with (io/reader file)
I thought edn/read needs a pushback reader
oh right.
$ echo '{:a 1} {:a 2}' | bb -e "(let [reader (java.io.PushbackReader. (io/reader *in*))] (take-while #(not= ::eof %) (repeatedly #(edn/read {:eof ::eof} reader))))"
({:a 1} {:a 2})
that's usually the sort of thing I come up with as well. Seems a little harsh, but ok.
I was considering making this a util function in babashka
it seems to be to be a missing bit in http://clojure.java.io frankly
<http://babashka.io|babashka.io>
;)I'm all for that as well
I had an issue for that here, but then decided to close it as documentation could maybe fix that better. https://github.com/borkdude/babashka/issues/613
but maybe http://babashka.io which will replace the I/O flags (that some people find confusing) may work
it's a tricky spot. putting things in bb that wouldn't be in jvm may cause hardship for peeps that are unknowing using bb as a gateway drug.
the way I solve that is publish every namespace as a JVM lib as well
e.g. babashka.curl and babashka.process are both JVM libs
even babashka.pods
ok, that's slick
we could also make one big babaskha.core or babashka.utils namespace where we accumulate functions that are missing from other core namespaces
not sure
dunno maybe I'm biased, but it seems like this should be a 1-liner in script space, at least if you would rather edn be the storage format than json or yaml. It's a little to bitey to get this loaded for my taste.
no matter how you do it, seems worth doing.
this is fun btw: https://grep.app/search?q=edn/read%20%7B%3Aeof%20
we could make babashka.edn as a counterpart to clojure.edn and add missing functions. similar for http://clojure.java.io / http://babashka.io. even if those small nss don't contain a lot of functions, they could be bundles in a babashka.misc library that bundles these little namespaces?
<http://babashka.io|babashka.io>: push-back-reader
babashka.edn: edn-seq
;;=>
(bedn/edn-seq (bio/push-back-reader (io/reader file)))
we could make this easier. and create the pushback reader for you if it isn't one.
(bedn/edn-seq (io/reader file))
Then again, we could also call io/reader
on something if it isn't some reader:
(bedn/edn-seq file)
(defn edn-seq [reader-coercible]
(let [reader (cond (instance? java.io.PushbackReader reader-coercible)
reader-coercible
(instance? java.io.Reader reader-coercible)
(java.io.PushbackReader. reader-coercible)
:else (java.io.PushbackReader. (io/reader reader-coercible)))
sentinel (Object.)]
(take-while #(not (identical? sentinel %))
(repeatedly #(edn/read {:eof ::eof} reader)))))
I can see why a library would not offer this, e.g. line-seq
doesn't, since it depends on the usage when you want the reader to be closed. it's the lazy vs resources problem which is generally better solved with transducers@hoppy At least I added docs here how to translate i/o flags to scripts: https://github.com/borkdude/babashka/blob/master/doc/io-flags.md
looks good!