@borkdude as mentioned on twitter, how I compose steps in scripts…
this is the driving fn…
(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!")))
and calling it….
(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)))}
])
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?
works great. the options come from tools.cli
one big seq of side-effects
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")))
Thanks. Added to https://github.com/babashka/babashka/issues/756
Anyone has babashka doing do some work with MS Excel files? For example using DocJure?
@marco.pasopas docjure depends on apache poi which is a java lib and you can't load that in babashka unfortunately.
writing a pod for it would be the way to get it in babashka reach (but this requires work)
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?
Would love to contribute in my spare time
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
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
@otfrom might also have some ideas how to do this in the shell
I do all my excel in poi (trying out fastexcel atm)
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.
but csvkit also works if you just want a csv from an excel file
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 (->> (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?I keep getting this error: ----- Error -------------------------------------------------------------------- Type: java.lang.IllegalArgumentException Message: Cannot open <("foo.txt")> as an InputStream.
@chase-lambert *command-line-args*
is a seq, not a single string
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?
that's how I do it a lot too
is there a shared library version of babashka?
@goomba you mean, native ?
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
@goomba I have an example of that here: https://github.com/borkdude/sci/blob/master/doc/libsci.md
whaaaat
dude you rock
you will have to write your own API for this like I did for libsci of course
you did the hard part 😄 I can write a wrapper, hopefully
I have a variation of it here: https://github.com/borkdude/plsci
It's not a production quality thing but maybe useful as an example
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))
: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 itwhy not -X
?
I find -X
usually more verbose than just passing string arguments
Also '"foo"'
for passing strings is something which I don't find esthetically pleasing really
It has no way to updating vectors in maps either. It's fairly limiting
updating vectors in maps? 😮
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
ah so you're saying something like bb :paths ["new-path"] :invoke blah
would do the trick?
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
or bb :invoke your-ns/your-fn foo bar baz
, but the idea is to configure the :your-fn
named task in bb.edn
similar to bb -m your-ns foo bar baz
but now you can have arbitrary mains
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
@borkdude the current version of babashka/babashka.pods is not released to clojars, right?
there’s only a 0.0.1-snapshot release on clojars
could you make one release that’s not snapshot and is current?
my tests need it, thanks
or you expect people to use babashka/babashka instead?
ok, babashka/bashka seems to work.
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!
@huahaiy Do you use leiningen for testing? With deps.edn you can use it as a git dep
But if needed I will make a non-snapshot release
yes i use lein test
It's not enforced by any means. I usually choose .clj to have good syntax highlighting by default
ok, can you post an issue at the pods repo to remind me?
sure
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)thx
@huahaiy Done, released
Sent an PR for pod registry. Thanks https://github.com/babashka/pod-registry/pull/10
kondo doesn't warn on #!/usr/bin/env bb
afaik
bb scripts can also be .cljc
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
so it's not that easy
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
having a development process as a child process of your editor is wrong imo
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
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
People are free to use .bb
if they want
This is also supported from the perspective of bb itself, when loading files from the classpath
yup! nothing more than a convention that I thought other people were using, but that I must have made up
some people do use it
and there is a built-in support for it
so go use it
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?
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.
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
So what didn't work?
Oh, just realized I forgot to run ./bb
instead of bb
, so was picking up the babashka binary in the path 🤦. Now it works 😀
BTW, thank you for the build and dev doc files, they were quite helpful!
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?$ bb -e "(require '[hiccup.core :as html]) (html/html [:a 1])"
"<a>1</a>"
did you mean :refer [html]
?
I think my mistake was that I was using
(html [:a 1])
as opposed to
(html/html [:a 1])
Checking that now.
yep! that was it. thank you!
(and :refer does the trick as well)