Fork me on GitHub
#babashka
<
2023-10-02
>
dev-hartmann10:10:37

Hey folks, just a quick question: is there a way to create shareable executables from babashka scripts? Maybe via GraalVM? I’m aware of bbin, but was looking for a way to share with colleagues without them having to know about babashka 😅

borkdude10:10:33

You can try this: https://github.com/babashka/babashka/wiki/Self-contained-executable But note that you have to package a binary for every OS that your colleague is using, which can be quite annoying.

dev-hartmann10:10:07

Thx, will look at that

dev-hartmann10:10:07

Hm, since I’m only interested in macOS and Linux for now, shouldn’t be a big issue

borkdude10:10:18

if you are packaging for other linux amd64 systems I'd definitely pick the -static one

dev-hartmann10:10:41

(-> uberjar exec) sounds good to me

borkdude10:10:12

not sure if I get what you mean by that

dev-hartmann10:10:57

I just wanted to say the process of bb uberjar and then caca sounds good. Just tried to be cool and obviously failed 😅

borkdude10:10:39

not sure what "exec" meant ;)

dev-hartmann10:10:31

Executable… don’t all the cool kids use shorthand’s? But reading it now it’s really misguiding. Sorry

borkdude10:10:05

exec is a hugely overloaded term

borkdude10:10:15

clojure CLI has exec, bb has exec (in two ways)

dev-hartmann10:10:11

Next time I try to be funny I’ll have more coffee first 😂

borkdude10:10:25

I'm probably not done recovering from covid, so it's probably me ;)

pesterhazy12:10:57

I'm doing a bunch of search-and-replace across a monorepo, and rather than deal with sed/`perl` idiosyncrasies I'd like to use bb to those string replaces 🧵

pesterhazy12:10:11

Here's my best version for now

git ls-files '**/deps.edn' | xargs bb -e '((fn [f] (doseq [fname *command-line-args*] (spit fname (f (slurp fname))))) #(clojure.string/replace % #"(thheller/shadow-cljs \{:mvn/version \")(.*?)(\"\})" (fn [m] (str (get m 1) "2.25.5" (get m 3)))))'

pesterhazy12:10:24

(Updates shadow-cljs in all deps.edn)

pesterhazy12:10:06

This works well but is obviously a little unwieldy. How do others do this kind of thing from the CLI (no IDE/emacs please)? Any comments welcome

borkdude12:10:07

clojure-lsp rename-var perhaps?

borkdude12:10:14

not sure if this is about a var or not

borkdude12:10:44

oh about mvn version

borkdude12:10:08

if you have a mono-repo why not make one deps.edn with your shared libs and just use local/root to depend on that one?

pesterhazy12:10:51

Right, that's all possible, but not really what my question was aimed at I'm curious about the use of bb as a generic text search/replace tool, similar to perl -pie or sed s/.../.../, except much more familiar to a Clojure programmer

pesterhazy12:10:39

I like my solution because it • is composable (I can swap out git ls-files for find or something else) • uses code (which has less cognitive load than remembering how to escape regex)

pesterhazy12:10:03

But it's a little long, so I'm trying to simplify for the next 100 times I'm doing something like this

borkdude12:10:25

spit + slurp can be replaced with fs/update-file

pesterhazy12:10:28

For example, I seem to remember had a function that did slurp, f and spit, but I can't find it now

pesterhazy12:10:33

that's a lot nicer already

borkdude12:10:35

updating EDN using regex can be a bit error-prone, there is also https://github.com/borkdude/rewrite-edn which does it in a more sophisticated way

pesterhazy12:10:17

that's really cool - I'll use this when I need the extra robustness

pesterhazy12:10:14

I guess ls-files (etc) could be wrapped in a bb lib as well

pesterhazy14:10:51

Here's the end result

#!/usr/bin/env bb

(require '[babashka.fs :as fs])
(require '[clojure.string :as str])
(require '[babashka.process :as process])

(defn ls-files [root & patterns]
  (remove empty? (str/split-lines (:out (apply process/sh {:dir root} "git" "ls-files" "--" patterns)))))

(defn f [s]
  (str/replace s
               #"(\"shadow-cljs\": \")(.*?)(\")"
               (fn [m] (str (get m 1) "2.25.5" (get m 3)))))

(defn main
  [& args]
  (doseq [fname (apply ls-files "." args)]
    (println fname)
    (fs/update-file fname f)))

(apply main *command-line-args*)

pesterhazy14:10:04

(For a similar but not the same problem)

kishima17:10:09

Hello! I’m trying to use selmer/render-file in a script, but I get this:

----- Context ------------------------------------------------------------------
37:         tree-data-map (tree-data-reducer grouped)]
38:     tree-data-map))
39:
40: (defn show-page [graph-key]
41:   (selmer/render-file
      ^--- resource-path for page.selmer returned nil, typically means the file doesn't exist in your classpath.
We don’t have this fn in babashka? I thought so because I saw it https://github.com/babashka/babashka/blob/ae01170f92a69b0e82124edbfbe6f088dc315e95/feature-selmer/babashka/impl/selmer.clj#L107: Thanks in advance!

Bob B18:10:43

it looks like that error is being reported by render-file

Bob B18:10:46

the file needs to be on the classpath, which would typically mean the path should be valid relative to one of the directories in the :paths key in bb.edn, or the classpath specified via other mechanisms as discussed in <https://book.babashka.org/#_classpath>

borkdude18:10:36

This is a workaround:

bb -e '(selmer.parser/render-file (.toURL ( "README.md")) {})'

borkdude18:10:45

so pass a URL instead of a string

kishima19:10:00

Aaah cool! Thanks!