babashka

https://github.com/babashka/babashka. Also see #sci, #nbb and #babashka-circleci-builds .
steveb8n 2021-03-17T08:21:33.000500Z

@borkdude as mentioned on twitter, how I compose steps in scripts…

steveb8n 2021-03-17T08:21:45.000600Z

this is the driving fn…

steveb8n 2021-03-17T08:21:46.000800Z

(defn run!
  [{:keys [verbose]} steps]
  (let [all-results (atom {})]
    (doseq [step steps]
      (let [{:keys [action success?]} step
            result (action @all-results)]
        (println)
        (println ">>" (:name step))
        (when verbose
          (pprint result))
        (if (success? result)
          (swap! all-results assoc (:name step) result)
          (throw (ex-info "action failed" result)))))
    (println)
    (println "Success!")))

steveb8n 2021-03-17T08:24:22.001100Z

and calling it….

steveb8n 2021-03-17T08:24:23.001300Z

(utils/run! options
            [{:name     :get-tag
              :action   utils/step-get-git-tag
              :success? (fn [result]
                          (not (nil? (:latest-commit-tag result))))}
             {:name     :get-sha
              :action   utils/step-get-git-sha
              :success? (constantly true)}
             {:name     :compress-main-js
              :action   (fn [_]
                          (utils/compress-file! "./public/client-js" "main.js"))
              :success? (fn [result]
                          (> (:size-compressed result) 0))}
             {:name     :deploy-editor-js
              :action   (fn [results]
                          (let [sha (get-in results [:get-sha :sha])]
                            (utils/deploy-compressed-asset-to-s3!
                              {:region       bucket-region
                               :content-type "application/javascript"}
                              "main.js.gz"
                              (str  "/editor/main." sha ".js"))))
              :success? (fn [result]
                          (nil? (:Error result)))}
             ])

Marco Pas 2021-03-17T08:25:00.002200Z

Newbie question, if you have a deps.edn file next to a BB script how do you download the dependencies and make them available in the BB NRepl?

steveb8n 2021-03-17T08:25:10.002300Z

works great. the options come from tools.cli

steveb8n 2021-03-17T08:25:43.002500Z

one big seq of side-effects

borkdude 2021-03-17T08:42:25.002700Z

Right now bb doesn't read your deps.edn, but you can pass it manually to (babashka.deps/add-deps (edn/read-string (slurp "deps.edn")))

👍 2
borkdude 2021-03-17T08:51:29.002900Z

Thanks. Added to https://github.com/babashka/babashka/issues/756

Marco Pas 2021-03-17T10:49:40.004100Z

Anyone has babashka doing do some work with MS Excel files? For example using DocJure?

borkdude 2021-03-17T10:53:02.005Z

@marco.pasopas docjure depends on apache poi which is a java lib and you can't load that in babashka unfortunately.

borkdude 2021-03-17T10:53:17.005300Z

writing a pod for it would be the way to get it in babashka reach (but this requires work)

Marco Pas 2021-03-17T10:56:01.007300Z

Any other relevant lib that would enable me to convert excel into csv using babashka?? Maybe i am missing something. On the pod remark.. would a newbie be able to write a pod? Is it very complicated?

Marco Pas 2021-03-17T10:56:21.007800Z

Would love to contribute in my spare time

borkdude 2021-03-17T10:57:31.008600Z

It's fun but not that trivial maybe if you're just starting out with Clojure. Good learning experience though. Docs are here: https://github.com/babashka/pods Examples: https://github.com/babashka/pod-registry

borkdude 2021-03-17T10:58:26.009500Z

The other option for going from excel to csv would be to install a binary who can do that for you and then shell out to it. csvkit has support for it: https://csvkit.readthedocs.io/en/latest/scripts/in2csv.html

👍 1
borkdude 2021-03-17T11:00:20.010Z

@otfrom might also have some ideas how to do this in the shell

2021-03-17T11:18:13.010700Z

I do all my excel in poi (trying out fastexcel atm)

borkdude 2021-03-17T11:24:26.011500Z

yeah, I've also used poi via docjure in the past. but this question was about how to do it from babashka. I think a poi (docjure or otherwise) pod might be nice for scripting.

borkdude 2021-03-17T11:24:56.011800Z

but csvkit also works if you just want a csv from an excel file

Chase 2021-03-17T15:44:12.012900Z

So if I have a small script like this:

#!/usr/bin/env bb                                                                 
                                                                                  
(require '[clojure.string :as str])                                               
(require '[<http://clojure.java.io|clojure.java.io> :as io])                                               
                                                                                  
(defn read-lines [file]                                                           
  (with-open [r (io/reader file)]                                                 
    (doall (line-seq r))))                                                        
                                                                                  
(let [file *command-line-args*]                                                   
  (doseq [w (-&gt;&gt; (read-lines file)                                                
                 (str/lower-case)                                                 
                 (#(str/split % #"\W+"))                                          
                 (frequencies)                                                    
                 (sort-by val &gt;)                                                  
                 (map #(str (key %) " " (val %))))]                               
    (println w)))
How do I actually run this while feeding in the text file as a command line arg?

Chase 2021-03-17T15:51:36.013300Z

I keep getting this error: ----- Error -------------------------------------------------------------------- Type: java.lang.IllegalArgumentException Message: Cannot open <("foo.txt")> as an InputStream.

borkdude 2021-03-17T15:54:51.013800Z

@chase-lambert *command-line-args* is a seq, not a single string

Chase 2021-03-17T15:58:40.014700Z

ahh, ok, thank you. So putting (first *command-line-args*) works but what would you consider a more idiomatic way to feed in a text file?

borkdude 2021-03-17T15:58:56.015Z

that's how I do it a lot too

unbalanced 2021-03-17T16:04:20.015400Z

is there a shared library version of babashka?

borkdude 2021-03-17T16:04:46.015700Z

@goomba you mean, native ?

unbalanced 2021-03-17T16:05:47.016700Z

ah yeah, right. many operating systems. Sorry lots of moving parts. Trying to figure out how to package babashka as a binary extension for Python

borkdude 2021-03-17T16:06:07.017Z

@goomba I have an example of that here: https://github.com/borkdude/sci/blob/master/doc/libsci.md

🔥 1
unbalanced 2021-03-17T16:06:21.017400Z

whaaaat

unbalanced 2021-03-17T16:06:23.017600Z

dude you rock

borkdude 2021-03-17T16:07:35.018100Z

you will have to write your own API for this like I did for libsci of course

unbalanced 2021-03-17T16:08:02.018700Z

you did the hard part 😄 I can write a wrapper, hopefully

borkdude 2021-03-17T16:09:52.019Z

I have a variation of it here: https://github.com/borkdude/plsci

borkdude 2021-03-17T16:10:03.019400Z

It's not a production quality thing but maybe useful as an example

borkdude 2021-03-17T16:17:16.019900Z

The brainstorm continues:

$ bb :example 1 2 3
:args ("1" "2" "3")

$ cat bb.edn
{:paths ["."]
 :tasks {:example {:task/type :babashka
                   :args [:invoke utils/foo]}}}

$ cat utils.clj
(ns utils)

(defn foo [&amp; args]
  (prn :args args))

borkdude 2021-03-17T16:20:38.020700Z

:invoke would then be a built-in task like:

$ bb :invoke clojure.core/prn 123 456
"123" "456"
similar to -X with the clojure CLI which I'm still not sure about what to think of it

unbalanced 2021-03-17T16:27:03.020900Z

why not -X?

borkdude 2021-03-17T16:27:43.021300Z

I find -X usually more verbose than just passing string arguments

borkdude 2021-03-17T16:28:11.021900Z

Also '"foo"' for passing strings is something which I don't find esthetically pleasing really

borkdude 2021-03-17T16:28:34.022400Z

It has no way to updating vectors in maps either. It's fairly limiting

unbalanced 2021-03-17T16:30:05.022700Z

updating vectors in maps? 😮

borkdude 2021-03-17T16:30:57.023600Z

Say you have a preconfigured arg map as {:paths ["foo" "bar"]}. Now you want to add another path from the command line. No way to do that with -X

unbalanced 2021-03-17T16:31:55.024300Z

ah so you're saying something like bb :paths ["new-path"] :invoke blah

unbalanced 2021-03-17T16:32:00.024500Z

would do the trick?

borkdude 2021-03-17T16:32:41.025200Z

no, you will just write bespoke command line parsing that makes sense for your function. And then you can invoke it with bb :your-task foo bar baz

👍 1
borkdude 2021-03-17T16:33:39.025900Z

or bb :invoke your-ns/your-fn foo bar baz, but the idea is to configure the :your-fn named task in bb.edn

borkdude 2021-03-17T16:34:20.026300Z

similar to bb -m your-ns foo bar baz but now you can have arbitrary mains

borkdude 2021-03-17T16:35:29.027500Z

we can add something like -X later, if that way of passing args becomes popular, but every time I see a question for which the answer is '"foo"' in #tools-deps I have some doubts about this :). Just being able to pass raw strings looks like an uncontroversial first step

wilkerlucio 2021-03-17T17:19:00.028100Z

🙏 1
Huahai 2021-03-17T17:52:10.029Z

@borkdude the current version of babashka/babashka.pods is not released to clojars, right?

Huahai 2021-03-17T17:52:43.029600Z

there’s only a 0.0.1-snapshot release on clojars

Huahai 2021-03-17T17:53:38.030500Z

could you make one release that’s not snapshot and is current?

Huahai 2021-03-17T17:53:58.031Z

my tests need it, thanks

Huahai 2021-03-17T18:00:25.031500Z

or you expect people to use babashka/babashka instead?

Huahai 2021-03-17T18:13:19.031900Z

ok, babashka/bashka seems to work.

Mitch 2021-03-17T18:17:31.034400Z

I was just checking out a Cider issue for adding cider-jack-in support to Babashka: https://github.com/clojure-emacs/cider/issues/2947 . I have been suffixing my babashka scripts with a .bb extension to signify script's runtime (which would solve this issue and perhaps a related issue in clojure-lsp). Is this not common practice? For some reason, I thought it was, but it turns out that none of my coworkers add this suffix either!

borkdude 2021-03-17T18:27:46.035100Z

@huahaiy Do you use leiningen for testing? With deps.edn you can use it as a git dep

borkdude 2021-03-17T18:27:54.035400Z

But if needed I will make a non-snapshot release

Huahai 2021-03-17T18:28:12.035800Z

yes i use lein test

borkdude 2021-03-17T18:28:41.036Z

It's not enforced by any means. I usually choose .clj to have good syntax highlighting by default

borkdude 2021-03-17T18:28:58.036400Z

ok, can you post an issue at the pods repo to remind me?

Huahai 2021-03-17T18:29:11.036600Z

sure

Huahai 2021-03-17T18:30:55.036900Z

done https://github.com/babashka/pods/issues/31

Mitch 2021-03-17T18:38:05.037100Z

ah, I've added

(add-to-list 'auto-mode-alist '("\\.bb\\'" . clojure-mode))
to my emacs config. Having a canonical file extension (just like cljs does) might make major mode and linting support easier in a few ways (e.g. not kondo not warning on #!/usr/bin/env bb , or warning on use of non-babashka supported deps)

Huahai 2021-03-17T18:41:41.037400Z

thx

borkdude 2021-03-17T18:57:43.037700Z

@huahaiy Done, released

🚀 2
Huahai 2021-03-18T23:10:00.057500Z

Sent an PR for pod registry. Thanks https://github.com/babashka/pod-registry/pull/10

borkdude 2021-03-17T18:58:08.037800Z

kondo doesn't warn on #!/usr/bin/env bb afaik

borkdude 2021-03-17T18:58:19.038Z

bb scripts can also be .cljc

borkdude 2021-03-17T18:58:48.038200Z

and many times bb scripts are used on the JVM as well. So having .clj for both bb and clj is also better for that

borkdude 2021-03-17T18:59:25.038400Z

so it's not that easy

borkdude 2021-03-17T19:00:02.038600Z

imo cider-jack-in isn't worth it, I never use it myself. I always start a server in the terminal and then connect to it

borkdude 2021-03-17T19:00:26.038800Z

having a development process as a child process of your editor is wrong imo

borkdude 2021-03-17T19:01:09.039Z

e.g. when you have a non-terminating loop in your dev process, you will have to kill your editor, or vice versa: if your editor crashes, your dev REPL is also lost

Mitch 2021-03-17T19:18:29.039400Z

You are right about Kondo, sorry for the incorrect example. It is probably not worth it to make such a big design decision based solely off of jack-in, but I do think there might be value in distinguishing the runtime in the same way that clj, cljs, and cljr do (even if bb is just a subset of clj). If you are writing a script for multiple runtimes, then you can of course still use clj or cljc. Of course, you've thought everything through much more deeply then I have, so I am probably missing some other angle

borkdude 2021-03-17T19:57:24.039600Z

People are free to use .bb if they want

borkdude 2021-03-17T19:59:04.039800Z

This is also supported from the perspective of bb itself, when loading files from the classpath

Mitch 2021-03-17T20:28:42.040100Z

yup! nothing more than a convention that I thought other people were using, but that I must have made up

borkdude 2021-03-17T20:29:09.040300Z

some people do use it

borkdude 2021-03-17T20:29:23.040500Z

and there is a built-in support for it

borkdude 2021-03-17T20:29:25.040700Z

so go use it

🍾 1
frankitox 2021-03-17T20:52:18.043100Z

Hi! I was looking to add support for the <http://java.io|java.io>.Serializable interface in my own build. I made https://github.com/frankitox/babashka/commit/de2f3a660e1d61d3616c851ef6c5a19d449c0185 modification without success, based on what I found about <http://java.io|java.io>.FileFilter , because that's an interface too. Am I missing something?

frankitox 2021-03-17T20:54:20.043200Z

Note that <http://java.io|java.io>.Serializable is an old marker interface, from what I read in the https://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html. I need it in order to use https://github.com/clj-commons/ring-buffer/blob/master/src/amalloy/ring_buffer.clj#L9, which could potentially allow me to use https://github.com/BrunoBonacci/mulog.

frankitox 2021-03-17T20:55:55.043800Z

The way I tested if the compiled bb binary works is by doing something like:

cat test.clj
(ns test
  (:import [<http://java.io|java.io> Serializable]))
bb test.clj

borkdude 2021-03-17T21:08:22.044Z

So what didn't work?

frankitox 2021-03-17T22:21:02.044200Z

Oh, just realized I forgot to run ./bb instead of bb , so was picking up the babashka binary in the path 🤦. Now it works 😀

frankitox 2021-03-17T22:21:52.044400Z

BTW, thank you for the build and dev doc files, they were quite helpful!

macrobartfast 2021-03-17T23:10:41.046200Z

trying to use babashka hiccup via

(require '[hiccup.core :as html])
but html is showing up as an unrecognized symbol… sanity checking my require… is there an example I can refer to?

borkdude 2021-03-17T23:12:00.046500Z

@macrobartfast

$ bb -e "(require '[hiccup.core :as html]) (html/html [:a 1])"
"&lt;a&gt;1&lt;/a&gt;"

borkdude 2021-03-17T23:12:35.046800Z

did you mean :refer [html] ?

macrobartfast 2021-03-17T23:15:21.048400Z

I think my mistake was that I was using

(html [:a 1])
as opposed to
(html/html [:a 1])

macrobartfast 2021-03-17T23:15:39.048700Z

Checking that now.

macrobartfast 2021-03-17T23:20:25.049400Z

yep! that was it. thank you!

👍 2
macrobartfast 2021-03-17T23:23:49.050300Z

(and :refer does the trick as well)