babashka

https://github.com/babashka/babashka. Also see #sci, #nbb and #babashka-circleci-builds .
pithyless 2021-05-13T07:26:32.241800Z

What is the idiomatic way to know what was the original task that bb was called with?

borkdude 2021-05-13T07:36:19.243300Z

@pithyless this is why I wanted to add these :before and :after things, but I decided not to add those yet because it wasn't clear what the added value was. Right now I believe there is no way to know this. What is your use case?

pithyless 2021-05-13T07:44:43.245600Z

Probably some self-inflicted pain. ;] I used the :enter hooks to log some info about each running task, but I was thinking in CI I want to spew a lot more info about each task (since it's harder to recover the context), but e.g. on my dev machine I may just want to log that the primary task is running (without having all the dependencies logging their info).

pithyless 2021-05-13T07:45:32.246600Z

I thought I could maybe just use :init for this, but not sure if there is a reference to a task I can grab at that point?

borkdude 2021-05-13T07:46:21.247200Z

not really no

borkdude 2021-05-13T07:50:30.252200Z

Maybe you can make some DEV environment variable which turns off the logging?

pithyless 2021-05-13T07:51:30.253200Z

also FYI, I was surprised this morning about the way :continue works in shell. I expected it to ignore the error if passed true and otherwise call the proc if one was passed as :continue Turns out if you pass true it works as expected, but if you pass a proc then you deal with all exit-codes (including zero). It makes sense, when you actually read the code for handle-non-zero but it was surprising nonetheless. Maybe that part of the docs could be revised? I thought of :continue as "how to handle errors", but it seems the name comes more from "override the default handling logic, ala continuation-passing style code"

borkdude 2021-05-13T07:53:26.255500Z

the :continue fn should return either true or false (or some other truthy value), what is surprising there?

pithyless 2021-05-13T07:54:03.256300Z

> Maybe you can make some `DEV` environment variable which turns off the logging? Actually, I'm passing around a :task/log-level in my context so no issue there; what I wanted to solve was can I have an :enter that logs stuff dependent on the log-level AND if we're now in the primary original task

pithyless 2021-05-13T07:55:34.257700Z

🤦 re-reading the code now; OK, so I totally misread that part of the codebase this morning

borkdude 2021-05-13T07:55:50.258200Z

I guess we can add a :primary flag to current-task but what if you have tasks like:

{a :task-a
 b {:depends [a] :task :task-b}
 b:clean (do (clean) (run 'b)}
When you run b:clean then b isn't the primary task anymore and I think you still want to treat it as such in some cases?

pithyless 2021-05-13T07:57:31.258600Z

so actually, what I need to do was override what the error-handling code does (the part that throws the ex-info); and I wanted to avoid rewriting a lot of the exit-checking code, but handle-non-zero is an internal detail of shell right now without much of a way to override it

borkdude 2021-05-13T07:57:56.259200Z

btw, perhaps the b:clean approach is also a way to deal with your problem: since you can execute something before the task (set some state?) and then run the "primary" task?

borkdude 2021-05-13T07:59:10.260Z

should we "rename" / "change" :continue to :non-zero ?

pithyless 2021-05-13T08:00:15.260900Z

I would consider whatever bb XX was originally called with as the primary task; there just doesn't seem to be a way to hook in and know what bb was originally called with right now, correct?

pithyless 2021-05-13T08:00:27.261300Z

But not sure how important of a use-case this is for everyone

borkdude 2021-05-13T08:01:13.261900Z

@pithyless yes, I tried to explain what the problem with this is here: https://clojurians.slack.com/archives/CLX41ASCS/p1620892550258200

borkdude 2021-05-13T08:01:34.262200Z

(afk, brb)

pithyless 2021-05-13T08:04:11.264400Z

for me the run 'b doesn't really change anything, since it's no longer what the user initiated from the shell; but I can see how the reverse may also be considered true and obvious; so I guess I don't have a really good case to argue here :]

pithyless 2021-05-13T08:05:48.265200Z

so, let me take a step back; if :continue is either true or a fn that returns a truthy value, I think the name is fine; it was a misunderstanding on my part

pithyless 2021-05-13T08:06:38.265400Z

for me the bigger issue, is if :continue is falsy, I can't change the behavior of the error condition (aside from just catching the ex-info exception)

pithyless 2021-05-13T08:08:21.265600Z

ideally, I'd like to re-use all the logic of shell and handle-non-zero but pass in an alternative operation for the (throw (ex-info ..)) part of handle-non-zero

pithyless 2021-05-13T08:09:03.265800Z

something like :error-handler (fn [proc opts] ...)

pithyless 2021-05-13T08:11:11.266Z

^ a good example of this is replacing the existing exception handler with something like (line-status/die exit-code "...") that will both exit the process and print a nice visible warning

pithyless 2021-05-13T08:17:49.266200Z

this, BTW, is also what lread seems to want to do here - https://github.com/lread/rewrite-clj/blob/main/script/helper/shell.clj - but since he's just wrapping babashka.process/process he's missing out on the other goodies like automatic tokenize , etc.

Jakub Zika 2021-05-13T08:35:48.267100Z

Hi, do you know why i am getting “WARNING: this project requires babashka 1.0.0 or newer, but you have: 0.4.0”?

borkdude 2021-05-13T08:38:39.267600Z

@zikajk This is printed when someone has in bb.edn: :min-bb-version "1.0.0"

1
borkdude 2021-05-13T08:38:52.267900Z

but version 0.4.0 is currently the most recent :)

borkdude 2021-05-13T08:43:00.268Z

@pithyless gotcha. So maybe we can have an additional :error-handler function then, which will be triggered on a non-zero exit code or if :continue returns false?

pithyless 2021-05-13T08:45:20.268200Z

@borkdude Yep, that'd be great!

borkdude 2021-05-13T08:45:41.268400Z

alrighty

🙏 1
pithyless 2021-05-13T08:47:24.269400Z

Someone's already living the dream of bb 1.0 🙂

👍 1
borkdude 2021-05-13T08:47:46.269800Z

I had this in the docs somewhere as an example, perhaps someone copied it ;)

borkdude 2021-05-13T08:48:31.270600Z

I had to use future version as an example since it didn't work with other versions in the first version that this feature was added ;)

borkdude 2021-05-13T08:49:17.270700Z

and about the "main" task, what should we do there? we can add back what we had with :dependents perhaps? if :dependent is empty, then you know you are the primary task. although with explicit run this will probably not behave like you think it will?

Jakub Zika 2021-05-13T08:51:32.271100Z

The joke is one me 😄

Jakub Zika 2021-05-13T08:51:54.271200Z

{:paths          ["src"]
 :deps           {seancorfield/honeysql                                {:mvn/version "2.0.0-beta2"}
                  douglass/clj-psql                                      {:mvn/version "0.1.2"}
                  clojure-term-colors/clojure-term-colors                {:mvn/version "0.1.0"}
                  borkdude/spartan.spec                                  {:git/url "<https://github.com/borkdude/spartan.spec>"
                                                                          :sha "12947185b4f8b8ff8ee3bc0f19c98dbde54d4c90"}}
 :min-bb-version "1.0.0"}

borkdude 2021-05-13T08:52:28.271700Z

:)

pithyless 2021-05-13T08:52:30.271900Z

My original hack was going to be calling tasks-&gt;dependees but I noticed it's commented out for now. You're probably right, that it may not always work as expected, so maybe just #hammock it for now? I don't want to be partially responsible for some not well thought-out features that are going be a maintenance burden :D

borkdude 2021-05-13T08:57:06.272200Z

Babashka adds babashka.file to the System properties when you call bb with bb foo.clj. We could do something similar for run: babashka.task or so

borkdude 2021-05-13T08:58:01.272400Z

or we could add another function babashka.tasks/plan which returns a map with some information about the execution plan

pithyless 2021-05-13T09:04:25.272700Z

Both of those ideas sound sensible. The former would be a small overhead to the existing surface area (and would also solve my immediate ask). The latter could potentially have more use-cases, but also more edge-cases. IIRC, the last discussion about an exec plan was halted due to expectations vs non-deterministic ordering in parallel execution.

borkdude 2021-05-13T09:05:29.272900Z

right

borkdude 2021-05-13T09:05:41.273100Z

I guess adding another system property doesn't hurt

borkdude 2021-05-13T09:06:51.273300Z

As for bike-shedding the name for the error handler:

(shell {:error-handler (constantly nil)} "ls foo")
(shell {:on-error (constantly nil)} "ls foo")
(shell {:error (constantly nil)} "ls foo")
(shell {:error-fn (constantly nil)} "ls foo")

borkdude 2021-05-13T09:08:14.273500Z

perhaps :error is nice and succinct?

borkdude 2021-05-13T09:09:50.273800Z

You could then write this instead of :continue:

(shell {:error (constantly nil)} "ls foo")

borkdude 2021-05-13T09:16:36.274Z

Another question: should the :error function determine the result value of shell or should it just cause side effects (like printing or throwing)

borkdude 2021-05-13T09:17:21.274200Z

e.g.:

(def x (shell {:error (fn [_] :dude)} "ls foo"))
(= x :dude)

pithyless 2021-05-13T09:17:45.274400Z

:error-handler
:on-error
:error-fn
:error
^ I think you've just listed all legitimate and/or expected forms for the callback. :) I'm not usually the fan of the standalone version :error, but in this case I think it works fine (and symmetric to :continue)

pithyless 2021-05-13T09:19:17.274600Z

if :error is just for side-effects, what would shell be returning?

borkdude 2021-05-13T09:19:50.274800Z

the process

borkdude 2021-05-13T09:20:04.275Z

like it does now

pithyless 2021-05-13T09:20:22.275200Z

I think it's safe to assume, that :error is the new return value; the caller can easily return proc if that's the intent

borkdude 2021-05-13T09:20:36.275400Z

it surely is the more flexible solution

borkdude 2021-05-13T09:20:37.275600Z

ok

pithyless 2021-05-13T09:20:37.275800Z

so (fn [proc] proc)

pithyless 2021-05-13T09:20:55.276Z

also, should it be (fn [proc opts]) or just [proc]?

borkdude 2021-05-13T09:21:23.276200Z

it's now just one map arg: {:proc .. :task .. :babashka/exit ...}

borkdude 2021-05-13T09:21:42.276400Z

if you just decide to re-throw this entire map in an ex-info, then it will behave the same as the original error-handler

pithyless 2021-05-13T09:23:27.276800Z

handle-non-zero takes additional opts from shell; so if we don't pass that on to the handler, it can't use those options

borkdude 2021-05-13T09:24:13.277Z

those opts are part of the :proc, e.g. :in and :out

borkdude 2021-05-13T09:24:21.277200Z

or am I missing something?

pithyless 2021-05-13T09:25:02.277400Z

you tell me ;)

pithyless 2021-05-13T09:25:42.277900Z

so this could be rewritten as (get-in (deref proc) [:opts :continue]) ?

borkdude 2021-05-13T09:25:57.278100Z

why would you like to have access to :continue in the :error handler?

pithyless 2021-05-13T09:27:58.278300Z

so, not necessarily to continue, but if we call (shell {:foo :bar :error (fn []..) } "ls") I guess it doesn't necessarily make sense that we would have access to :foo ; and besides you can always wrap that error handler in a closure if you need additional context

borkdude 2021-05-13T09:28:36.278500Z

I guess so yeah

borkdude 2021-05-13T09:36:16.278700Z

Let's go with :error-fn. :continue accepts a naked boolean, whereas :error-fn only accepts a function

$ clojure -M:babashka/dev -e '(babashka.tasks/shell {:error-fn (constantly 1337)} "ls foo")'
ls: foo: No such file or directory
1337

👍 1
borkdude 2021-05-13T09:53:55.279Z

Applied both things on master now. Please test :) Binaries should appear soon in #babashka-circleci-builds

borkdude 2021-05-13T10:16:54.279700Z

:babashka/exit is safe to depend on: you can throw an ex-info anywhere in a script and set this value, then bb will exit with this value, if no other code handles the exception

pithyless 2021-05-13T10:19:57.280Z

ah cool, TIL!

borkdude 2021-05-13T10:20:46.280200Z

this is only supported since 0.4.0

pithyless 2021-05-13T10:23:39.280400Z

@borkdude confirming that "babashka.task" and "error-fn" works on my machine. Kudos for the frenzied and selfless work, as always! 🤘

🎉 1
borkdude 2021-05-13T11:47:20.280900Z

babashka 0.4.1 🎉 https://github.com/babashka/babashka/blob/master/CHANGELOG.md#041 Among other tiny updates, babashka linux static is now based on musl and should work on pretty much any amd64 linux version! 🎉 thanks @rahul080327 and @thiagokokada

7
3
grazfather 2021-05-13T13:37:28.283400Z

So has anyone yet started using BB as their installer/dotfile manager?

👀 1
2021-05-14T13:30:38.313400Z

Added a repo update for all repos. Thanks for the nudge on this. Ended up making the tasks data driven

🔥 2
grazfather 2021-05-14T14:52:32.321500Z

👀

grazfather 2021-05-14T14:53:07.321900Z

Very nice, I was planning something similar, but for all my dotfiles

grazfather 2021-05-13T13:38:06.284Z

a bb.edn with dependencies (e.g. install homebrew before installing things using homebrew) sounds like the perfect use

🤯 1
grazfather 2021-05-13T13:39:59.284800Z

there’s obviously a bootstrapping problem but with staticallly compiled bb and everything having bash/curl/wget that’s not too much of a barrier 🙂

borkdude 2021-05-13T13:42:52.285200Z

most systems have curl now, except those Alpines

borkdude 2021-05-13T13:42:58.285400Z

even Windows has it

grazfather 2021-05-13T13:49:28.286300Z

yeah, I am saying basically: curl babashkainstall &amp;&amp; ./bb <http://init.bb|init.bb> is no problem

borkdude 2021-05-13T15:14:21.287100Z

great!

borkdude 2021-05-13T15:23:50.287900Z

@cldwalker what do you do when one of your cloned repos needs updating?

2021-05-13T15:27:20.288100Z

Just manual for now as the diff b/n computers is usually only a repo or two. Could be a useful thing to add down the road

borkdude 2021-05-13T15:28:20.288300Z

:thumbsup:

grazfather 2021-05-13T15:49:54.288900Z

hah! nice. I actually didn’t know about brewfile, so that solves that part

ericdallo 2021-05-13T16:11:15.289400Z

Does https://github.com/borkdude/rewrite-edn work with babashka?

borkdude 2021-05-13T16:11:25.289800Z

it does

👍 1
ericdallo 2021-05-13T16:20:51.290300Z

How can I call a bb task from outside a folder with bb.edn?

borkdude 2021-05-13T16:21:45.291400Z

(cd the-folder; bb the-task) ?

Darin Douglass 2021-05-13T16:21:47.291500Z

(shell {:dir "the-path"} "bb my-task")
?

Darin Douglass 2021-05-13T16:21:53.291700Z

heh

ericdallo 2021-05-13T16:22:16.292200Z

yeah, I thought there was a option for that, but the cd one looks good and easy

ericdallo 2021-05-13T16:25:17.294400Z

Hum not sure cd one would work, since the CI uses on clojure JVM

(apply sh (concat command [:dir dir])
and my command would be something like
["cd" "../my-dir" "&amp;&amp;" "bb" "-m my-project.main"]

ericdallo 2021-05-13T16:25:25.294600Z

not sure that would work with clojure sh

borkdude 2021-05-13T16:26:24.295600Z

no, that won't work as shelling out from the JVM is not the same as executing bash, but you provide :dir so why not set that to the bb.edn dir?

ericdallo 2021-05-13T16:27:42.296300Z

the dir is dynamic for multiple shell tasks, and this one I want to make using babashka

ericdallo 2021-05-13T16:27:51.296700Z

I can't change that :dir 😕

borkdude 2021-05-13T16:28:13.297300Z

so shell out another time? (sh "bb" "-m" "my-project.main" :dir "../my-dir")

ericdallo 2021-05-13T16:29:09.298300Z

oh, I see, would be:

["bb" "-m my-project.main" ":dir" "../my-dir"]
right?

ericdallo 2021-05-13T16:29:18.298600Z

that's the option I want so

borkdude 2021-05-13T16:29:21.298700Z

or (sh "bb" "-m" "my-project.main" :dir (str dir "/../my-dir")) (but then using proper file system stuff)

borkdude 2021-05-13T16:29:38.298900Z

which sh are you using here?

ericdallo 2021-05-13T16:29:54.299100Z

clojure.java.shell

ericdallo 2021-05-13T16:30:22.299800Z

it's a common file for multiple tasks, I can't change that code, that's why I can only change the command one that is dynamic

borkdude 2021-05-13T16:31:15.300500Z

it's a bit yucky to execute a bunch of shell commands like this, as you can't really see what's going on, unless you print a giant string blob at the end

borkdude 2021-05-13T16:33:12.300700Z

does it execute a bash script? 🧵

borkdude 2021-05-13T16:33:37.301100Z

your "&amp;&amp;" suggests so

ericdallo 2021-05-13T16:34:06.301300Z

yeah, all other places have something like: ["../other-dir/other-script.sh"]

ericdallo 2021-05-13T16:34:13.301500Z

but this one, I want to use bb instead of a bash one

borkdude 2021-05-13T16:34:15.301700Z

and you don't see any output?

borkdude 2021-05-13T16:34:48.301900Z

just fire and forget?

ericdallo 2021-05-13T16:35:21.302100Z

yes, I think

borkdude 2021-05-13T16:36:13.302300Z

well, if it's bash, then you can append (cd the-folder &amp;&amp; bb the-task) , the parens start a subshell

ericdallo 2021-05-13T16:36:30.302600Z

hum.. sounds good

ericdallo 2021-05-13T16:36:34.302800Z

I'll try, thanks!

ericdallo 2021-05-13T16:38:16.303Z

but does clojure.java.shell understand the () ? like (apply sh ["(cd ../my-dir &amp;&amp; bb -m main)"])

borkdude 2021-05-13T16:39:12.303200Z

no. I asked if this was bash

borkdude 2021-05-13T16:39:42.303400Z

if this is a standalone sh invocation, then why don't you set the :dir yourself

ericdallo 2021-05-13T16:39:43.303600Z

yeah, sorry, it is not, it's a

(apply sh (concat command [:dir dir])

ericdallo 2021-05-13T16:40:07.303800Z

because the dir is set dynamicly for all other commands

borkdude 2021-05-13T16:40:50.304Z

what do the other commands look like?

borkdude 2021-05-13T16:41:05.304200Z

clojure.java.shell/sh can only execute one file at a time

borkdude 2021-05-13T16:41:39.304400Z

so unless the first thing is "bash" "-c" I have no clue how that setup works

ericdallo 2021-05-13T16:41:50.304600Z

It's a Nubank migration tool, that allows you create multiple migrations and we have something like a migration.edn:

{:migrations [{...
               :command ["../other-dir/migration.sh"]}
              {...
               :command ["../my-dir/migration.sh"]}]}

ericdallo 2021-05-13T16:42:12.304800Z

and I'd like to add a new command, but that uses bb with a bb.edn with custom deps like rewrite-edn

borkdude 2021-05-13T16:42:23.305Z

so each :command is executed by a separated sh invocation?

ericdallo 2021-05-13T16:42:46.305200Z

exactly

borkdude 2021-05-13T16:43:04.305400Z

can you have {:dir ... :command ["..."]} ?

ericdallo 2021-05-13T16:43:16.305600Z

The CI/other service kind of parse the edn and call (apply sh (concat command [:dir dir]))

ericdallo 2021-05-13T16:43:37.305800Z

there dir is the dir with all migrations

ericdallo 2021-05-13T16:43:46.306Z

so I can't change that easily

borkdude 2021-05-13T16:43:51.306200Z

interesting, so let's see how clojure.java.shell/merges :dir, maybe you can override it

ericdallo 2021-05-13T16:44:03.306400Z

yeah, if that works would be nice

borkdude 2021-05-13T16:45:10.306600Z

you know, you can just make a bash script which then cds into the right dir and hook that up to your command thing

ericdallo 2021-05-13T16:45:16.306800Z

> can you have `{:dir ... :command ["..."]}` ? How this works?

ericdallo 2021-05-13T16:45:24.307Z

yeah I thought about that, but...

ericdallo 2021-05-13T16:45:34.307200Z

calling directly bb would look way better 😛

ericdallo 2021-05-13T16:45:52.307400Z

and if that works, next tasks would follow the same standard

borkdude 2021-05-13T16:46:11.307600Z

then you should make your migration tool more flexible using an overridable :dir argument, I think

borkdude 2021-05-13T16:46:32.307800Z

I can't control your migration tools, sorry :)

ericdallo 2021-05-13T16:46:36.308Z

Yeah, it seems would need that change

ericdallo 2021-05-13T16:46:48.308200Z

haha no problem, is not that easy to change the migration tool

ericdallo 2021-05-13T16:46:57.308400Z

I'll probably end with a .sh to cd and call bb

👍 1
ericdallo 2021-05-13T16:47:15.308700Z

is just that maybe in the future could make sense bb has a --from-dir or something

ericdallo 2021-05-13T16:47:23.308900Z

if that is possible somehow

borkdude 2021-05-13T16:49:16.309200Z

to work around the limitations of your migration tool?

ericdallo 2021-05-13T16:50:15.309400Z

hahaha no, maybe someone can need that as well

borkdude 2021-05-13T16:52:00.309600Z

I'm not even sure if that is possible to implement

ericdallo 2021-05-13T16:52:14.309800Z

yeah me too

ericdallo 2021-05-13T16:54:06.310Z

the .sh that cd and call bb worked, thanks for the help!

borkdude 2021-05-13T16:54:17.310200Z

:thumbsup:

borkdude 2021-05-13T19:31:40.310600Z

👏 1