babashka

https://github.com/babashka/babashka. Also see #sci, #nbb and #babashka-circleci-builds .
Brandon Stubbs 2021-07-01T01:12:27.270400Z

Thank again for the help yesterday, I did a bit more digging... I am not sure if this is an issue or not? Say I have two scripts: <dir>/foo <dir>/bar bar contains:

#!/usr/bin/env bb
(ns bar)
(defn hello [] (println "test"))
foo this works load-file before ns
#!/usr/bin/env bb
(require '[babashka.fs :as fs])
(load-file (str (fs/parent *file*) "/bar"))

(ns foo)

(when (= *file* (System/getProperty "babashka.file"))
  (bar/hello))
foo this doesn't work
#!/usr/bin/env bb
(ns foo
  (:require [babashka.fs :as fs]))

(when (= *file* (System/getProperty "babashka.file"))
  (load-file (str (fs/parent *file*) "/bar"))
  (bar/hello))
7:   (bar/hello))
      ^--- Could not resolve symbol: bar/hello

borkdude 2021-07-01T10:17:49.277200Z

@brandon746 Here is an example: /tmp/script/foo.clj:

(ns foo
  (:require [babashka.classpath :refer [add-classpath]]
            [babashka.fs :as fs]))

(add-classpath (str (fs/parent *file*)))

(require '[bar :as bar])

(prn (bar/bar-fn))
/tmp/script/bar.clj:
(ns bar)

(defn bar-fn []
  :bar)
$ bb /tmp/script/foo.clj
:bar

Brandon Stubbs 2021-07-01T16:02:11.278Z

@corasaurus-hex omg! Thank you so much for spending so much time and sending so many examples across πŸ’™ @borkdude great thank you for the article! I really was wondering as to they why this wasn't working.

1πŸ’œ
borkdude 2021-07-01T16:03:10.278300Z

oh I missed the examples that Cora sent, sorry :)

Cora (she/her) 2021-07-01T16:04:15.278500Z

no worries! you knew why it wasn't working which is so much more important, so thank you

Brandon Stubbs 2021-07-01T01:13:17.270500Z

For now I am just going to use preload to load them all, but was hoping of explicitly loading some scripts

Cora (she/her) 2021-07-01T02:03:17.270800Z

wow, it really, really doesn't like conditionally loading a new namespace

Cora (she/her) 2021-07-01T02:05:02.271Z

if you move the load-file out of the when but keep the bar/hello in the when then it works

Cora (she/her) 2021-07-01T02:17:09.271200Z

I guess you could use a macro for this, maybe?

Cora (she/her) 2021-07-01T02:18:53.271400Z

Cora (she/her) 2021-07-01T02:19:13.271800Z

Cora (she/her) 2021-07-01T02:20:44.272200Z

Cora (she/her) 2021-07-01T02:21:44.272600Z

if you run http://foo.bb directly it will print hello twice since it is the main file and it will load bar/hello. if you run http://baz.bb directly it will just print the bye from loading http://foo.bb and the bye from running http://baz.bb

Cora (she/her) 2021-07-01T02:33:24.272900Z

You could also add a file like this to that directory

Cora (she/her) 2021-07-01T02:33:52.273300Z

and then stick this at the top of each file...

borkdude 2021-07-01T05:22:58.275Z

This is normal behavior, you will get this with JVM Clojure as well. It’s called the Gilardi scenario. https://technomancy.us/143

borkdude 2021-07-01T05:23:39.276100Z

As I explained before you probably want to be using add-classpath + require for this

Cora (she/her) 2021-07-01T06:51:34.276900Z

oooh bookmarking that one

borkdude 2021-07-01T10:17:49.277200Z

@brandon746 Here is an example: /tmp/script/foo.clj:

(ns foo
  (:require [babashka.classpath :refer [add-classpath]]
            [babashka.fs :as fs]))

(add-classpath (str (fs/parent *file*)))

(require '[bar :as bar])

(prn (bar/bar-fn))
/tmp/script/bar.clj:
(ns bar)

(defn bar-fn []
  :bar)
$ bb /tmp/script/foo.clj
:bar

borkdude 2021-07-01T12:22:55.277700Z

Pomodoro timer in babashka: https://github.com/babashka/babashka/discussions/910

2πŸ˜ƒ2πŸ…
Brandon Stubbs 2021-07-01T16:02:11.278Z

@corasaurus-hex omg! Thank you so much for spending so much time and sending so many examples across πŸ’™ @borkdude great thank you for the article! I really was wondering as to they why this wasn't working.

1πŸ’œ
borkdude 2021-07-01T16:03:10.278300Z

oh I missed the examples that Cora sent, sorry :)

Cora (she/her) 2021-07-01T16:04:15.278500Z

no worries! you knew why it wasn't working which is so much more important, so thank you

bocaj 2021-07-01T19:18:56.279200Z

What would this look like in Tasks? bb -cp $(clojure -Spath -Aremove-clojure) --uberscript data-loader -m append-hash

borkdude 2021-07-01T19:22:01.279900Z

@bocaj you don't have to set the classpath anymore if you have a bb.edn, also the remove-clojure thing is done automatically

bocaj 2021-07-01T19:22:38.280800Z

oh, cool.

borkdude 2021-07-01T19:22:39.280900Z

probably: bb uberscript data-loader -m append-hand

borkdude 2021-07-01T19:22:51.281200Z

from within tasks you could just use shell for this

bocaj 2021-07-01T19:23:05.281500Z

ok, got it. Nice to have the classpath handled

Cora (she/her) 2021-07-01T20:25:00.281800Z

does babashka have something like sed?

Cora (she/her) 2021-07-01T20:25:10.282Z

for editing in place, I mean

kokada 2021-07-01T20:33:33.282100Z

I think you can use clojure.string/replace for the general case

Cora (she/her) 2021-07-01T20:34:07.282300Z

but to edit in place, though?

kokada 2021-07-01T20:34:09.282500Z

It doesn't do everything sed does, but it should work in the most common cases as a substitute for s/something/somethingelse//

kokada 2021-07-01T20:34:34.282700Z

> but to edit in place, though? Ah, you mean like sed -i?

Cora (she/her) 2021-07-01T20:34:39.282900Z

yep!

kokada 2021-07-01T20:35:21.283100Z

I think the easiest way would be to (-> (slurp "file") (clojure.string/replace #"foo" "bar") (spit "file"))

Cora (she/her) 2021-07-01T20:35:23.283300Z

it's a common thing I need to do. glob a bunch of filenames based on search criteria and then replace values

kokada 2021-07-01T20:35:37.283500Z

(Not tested so the arguments may be wrong)

borkdude 2021-07-01T20:36:36.283700Z

yes, I agree with what @thiagokokada wrote, just slurp, str/replace and spit. you could also use Selmer if you need templating.

Cora (she/her) 2021-07-01T20:36:50.283900Z

alrighty, I'll give that shot, thanks

bocaj 2021-07-01T20:38:24.284100Z

I was just thinking about this, Thanks!

bocaj 2021-07-01T20:39:50.285800Z

Is there a convenient way to pre-pend #!/usr/bin/env bb to for example the output file from uberscript. Related to sed, above, thinking concat with spit and slurp

borkdude 2021-07-01T20:42:01.287300Z

The reason it does not do this by default is that it's not cross platform. To do this using a Clojure expression, you can do:

(spit "uberscript.clj" (str "#!/usr/bin/env bb\n\n" (slurp "uberscript.clj")))

1πŸ‘
Cora (she/her) 2021-07-01T20:47:09.287800Z

not a great solution if your files are exceptionally large but that's not a problem for me πŸ™‚

borkdude 2021-07-01T20:48:15.288700Z

you can probably optimize that using some streaming solution if needed, but in a lot of cases this does the job fine ;)

Cora (she/her) 2021-07-01T20:48:23.288900Z

absolutely

Cora (she/her) 2021-07-01T20:48:37.289300Z

but also you'd want to stream to a new file and then move it into place after the fact too

borkdude 2021-07-01T20:49:19.289700Z

right

borkdude 2021-07-01T20:51:23.290Z

Adam is playing around with babashka and scittle on his stream now: https://www.twitch.tv/adam_james_tv