Fork me on GitHub
#babashka
<
2021-03-17
>
steveb8n08:03:33

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

steveb8n08:03:45

this is the driving fn…

steveb8n08:03:46

(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!")))

steveb8n08:03:22

and calling it….

steveb8n08:03:23

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

steveb8n08:03:10

works great. the options come from tools.cli

steveb8n08:03:43

one big seq of side-effects

Marco Pas08:03:00

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?

borkdude08:03:25

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
Marco Pas10:03:40

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

borkdude10:03:02

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

borkdude10:03:17

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

Marco Pas10:03:01

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 Pas10:03:21

Would love to contribute in my spare time

borkdude10:03:31

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

borkdude10:03:26

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
borkdude11:03:20

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

otfrom11:03:13

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

borkdude11:03:26

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.

borkdude11:03:56

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

Chase15:03:12

So if I have a small script like this:

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

Chase15:03:36

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

borkdude15:03:51

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

Chase15:03:40

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?

borkdude15:03:56

that's how I do it a lot too

unbalanced16:03:20

is there a shared library version of babashka?

borkdude16:03:46

@goomba you mean, native ?

unbalanced16:03:47

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

unbalanced16:03:23

dude you rock

borkdude16:03:35

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

unbalanced16:03:02

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

borkdude16:03:03

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

borkdude16:03:16

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 [& args]
  (prn :args args))

borkdude16:03:38

: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

borkdude16:03:43

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

borkdude16:03:11

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

borkdude16:03:34

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

unbalanced16:03:05

updating vectors in maps? 😮

borkdude16:03:57

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

unbalanced16:03:55

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

unbalanced16:03:00

would do the trick?

borkdude16:03:41

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
borkdude16:03:39

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

borkdude16:03:20

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

borkdude16:03:29

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

Huahai17:03:10

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

Huahai17:03:43

there’s only a 0.0.1-snapshot release on clojars

Huahai17:03:38

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

Huahai17:03:58

my tests need it, thanks

Huahai18:03:25

or you expect people to use babashka/babashka instead?

Huahai18:03:19

ok, babashka/bashka seems to work.

Mitch18:03:31

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!

borkdude18:03:41

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

Mitch18:03:05

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)

borkdude18:03:08

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

borkdude18:03:19

bb scripts can also be .cljc

borkdude18:03:48

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

borkdude18:03:25

so it's not that easy

borkdude19:03:02

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

borkdude19:03:26

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

borkdude19:03:09

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

Mitch19:03:29

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

borkdude19:03:24

People are free to use .bb if they want

borkdude19:03:04

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

Mitch20:03:42

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

borkdude20:03:09

some people do use it

borkdude20:03:23

and there is a built-in support for it

borkdude20:03:25

so go use it

🍾 1
borkdude18:03:46

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

borkdude18:03:54

But if needed I will make a non-snapshot release

Huahai18:03:12

yes i use lein test

borkdude18:03:58

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

borkdude18:03:43

@huahaiy Done, released

🚀 2
frankitox20:03:18

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

frankitox20:03:20

Note that .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.

frankitox20:03:55

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

cat test.clj
(ns test
  (:import [ Serializable]))
bb test.clj

borkdude21:03:22

So what didn't work?

frankitox22:03:02

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

frankitox22:03:52

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

macrobartfast23:03:41

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?

borkdude23:03:00

@macrobartfast

$ bb -e "(require '[hiccup.core :as html]) (html/html [:a 1])"
"<a>1</a>"

borkdude23:03:35

did you mean :refer [html] ?

macrobartfast23:03:21

I think my mistake was that I was using

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

macrobartfast23:03:39

Checking that now.

macrobartfast23:03:25

yep! that was it. thank you!

👍 2
macrobartfast23:03:49

(and :refer does the trick as well)