Fork me on GitHub
#babashka
<
2020-11-07
>
borkdude15:11:22

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

NoahTheDuke00:11:39

any reason for a .babashka folder and not just the equivalent of a .babashka_rc file?

borkdude07:11:12

This is for projects, not a global thing

hoppy17:11:09

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.

borkdude17:11:03

@hoppy so you have multiple values in one file, not like one value inside a vector right?

hoppy17:11:29

correct, and it's full of maps that are across multiple lines

borkdude17:11:41

@hoppy In one-liners you can do this:

$ echo '{:a 1} {:a 2}' | bb -I -e "*input*"
({:a 1} {:a 2})

hoppy17:11:03

yes, but I want to open the file from within the script

borkdude17:11:07

let me give you the variant that is suitable for scripts

borkdude17:11:16

$ echo '{:a 1} {:a 2}' | bb -e "(take-while #(not= ::eof %) (repeatedly #(edn/read {:eof ::eof} *in*)))"
({:a 1} {:a 2})

borkdude17:11:46

when reading from a file, replace *in* with (io/reader file)

hoppy17:11:09

I thought edn/read needs a pushback reader

borkdude17:11:17

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})

hoppy17:11:49

that's usually the sort of thing I come up with as well. Seems a little harsh, but ok.

borkdude17:11:29

I was considering making this a util function in babashka

hoppy17:11:57

it seems to be to be a missing bit in http://clojure.java.io frankly

hoppy17:11:45

I'm all for that as well

borkdude17:11:54

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

borkdude17:11:26

but maybe http://babashka.io which will replace the I/O flags (that some people find confusing) may work

hoppy17:11:38

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.

borkdude17:11:04

the way I solve that is publish every namespace as a JVM lib as well

borkdude17:11:14

e.g. babashka.curl and babashka.process are both JVM libs

borkdude17:11:21

even babashka.pods

hoppy17:11:43

ok, that's slick

borkdude17:11:10

we could also make one big babaskha.core or babashka.utils namespace where we accumulate functions that are missing from other core namespaces

hoppy17:11:45

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.

hoppy17:11:00

no matter how you do it, seems worth doing.

borkdude18:11:46

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?

borkdude18:11:53

: push-back-reader
babashka.edn: edn-seq
;;=>
(bedn/edn-seq (bio/push-back-reader (io/reader file)))

borkdude18:11:04

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)

borkdude19:11:37

(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

borkdude19:11:13

@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

hoppy19:11:48

looks good!