babashka

https://github.com/babashka/babashka. Also see #sci, #nbb and #babashka-circleci-builds .
kokada 2021-04-29T03:12:34.227600Z

Probably a super niche usage, but maybe useful for someone: https://gist.github.com/thiagokokada/854e6be42fe80afb946324c62d299ce8 An equivalent of Python's os.isatty() in Babashka, to check if the stdin/`stdout`/`stderr` is connected to a TTY or not (useful to check if the script is being redirected) This uses test (the same as if [ ... ] used in shell) to check it. I don't know if it is portable, but I think it should be considering that test is POSIX.

borkdude 2021-04-29T09:02:55.228300Z

Cool, I will test this on Windows

borkdude 2021-04-29T09:05:16.228500Z

On Windows cmd.exe I get: Message: Cannot run program "test": CreateProcess error=2, The system cannot find the file specified

borkdude 2021-04-29T09:05:34.228700Z

Same in powershell

kokada 2021-04-29T14:17:17.264200Z

Yeah, I think on Windows will not work unless in WSL

kokada 2021-04-29T14:17:28.264400Z

Since test is POSIX

kokada 2021-04-29T14:17:44.264600Z

(Portable I mean, anything except Windows)

borkdude 2021-04-29T14:17:52.264800Z

ok :)

borkdude 2021-04-29T14:18:05.265100Z

is this so you are wrapping rlwrap?

kokada 2021-04-29T14:18:23.265300Z

I don't even know if Windows has the concept of stdin/stderr/stdout, I think they have something similar but the implementation is different

borkdude 2021-04-29T14:18:52.265500Z

They do have that, but the tty stuff isn't there, it's totally different

kokada 2021-04-29T14:20:43.265700Z

> is this so you are wrapping rlwrap? No, actually it is "kinda" common to have a script that needs to check if its connect to a TTY to offer a better user experience

borkdude 2021-04-29T14:21:18.265900Z

Maybe you can contribute that function/script to $BABASHKA_REPO/examples

1👍
kokada 2021-04-29T14:21:58.266100Z

In my particular case, I have a command that when called by another command, it shouldn't throw (since the commands that call it doesn't expect a stack trace in the output of this command)

kokada 2021-04-29T14:22:20.266300Z

But I still want stack trace when I use this command directly, since it makes it easier to debug

borkdude 2021-04-29T14:22:52.266600Z

Is this a command in bb.edn or just a script?

kokada 2021-04-29T14:23:02.266800Z

It is a script

borkdude 2021-04-29T14:23:20.267Z

makes sense

kokada 2021-04-29T14:23:22.267200Z

(Actually it is kinda of a full Clojure project CLI, Babashka is very powerful to makes sense for this case too 🙂 )

borkdude 2021-04-29T14:24:09.267700Z

I just gave a presentation at a company titled "Clj-kondo and babashka: keeping your Clojure projects sane." ;)

kokada 2021-04-29T14:36:07.268Z

https://github.com/babashka/babashka/pull/812 :reviewplease:

borkdude 2021-04-29T14:37:15.268300Z

Where is the actual script?

kokada 2021-04-29T14:38:23.268500Z

Oh, sorry, forgot to commit it

kokada 2021-04-29T14:38:33.268700Z

Done

borkdude 2021-04-29T14:39:28.268900Z

thanks

kokada 2021-04-29T03:17:37.227900Z

BTW, process is really great compared to other subprocess libraries that I used in Clojure in the past. Without it, this kind of feature would be impossible (since AFAIK, even Java doesn't offer anything to do it)

borkdude 2021-04-29T09:02:55.228300Z

Cool, I will test this on Windows

borkdude 2021-04-29T09:05:16.228500Z

On Windows cmd.exe I get: Message: Cannot run program "test": CreateProcess error=2, The system cannot find the file specified

borkdude 2021-04-29T09:05:34.228700Z

Same in powershell

borkdude 2021-04-29T09:53:56.229800Z

Included :enter, :leave and current-task in a branch. It works like this:

$ cat bb.edn
{:tasks {:enter (println ">>" (:name (current-task)))
         :leave (println "<<" (:name (current-task)))
         a (+ 1 2 3)
         b {:depends [a]
            :task (+ 2 3 a)}
         c {:enter (println "My beautiful message")
            :leave nil
            :depends [b]
            :task b}}}
$ bb run --prn c
>> a
<< a
>> b
<< b
My beautiful message
11

2👍
borkdude 2021-04-29T09:59:17.230300Z

I wonder if :enter should be run before the dependencies of the task or like it is now (it was easier to implement like it is now).

borkdude 2021-04-29T10:06:52.231200Z

current-task gives more info, e.g. when I do :leave (clojure.pprint/pprint (current-task)) in c, I get:

{:enter (println "My beautiful message"),
 :leave (clojure.pprint/pprint (current-task)),
 :name c,
 :before [a b],
 :depends [b],
 :task b}

borkdude 2021-04-29T10:07:22.231500Z

:before are the tasks that were scheduled before the current task

borkdude 2021-04-29T10:07:56.231800Z

you can stick any data in the task and it will also be available in current-task

borkdude 2021-04-29T10:08:45.232500Z

Binaries in #babashka-circleci-builds if you want to play around with this. Perhaps @karol.wojcik this is useful for logging somehow.

pithyless 2021-04-29T10:11:37.234100Z

for what it's worth, I consider enter/leave wrapping the specific task, so I agree it should work as it does now; i.e. [enter-dep dep leave-dep enter-task task leave-task] :thumbsup:

1😅
borkdude 2021-04-29T10:15:54.235Z

If I put :enter (clojure.pprint/pprint (current-task)) in b you will also get:

:dependees #{c}
so you can answer the question "why am I running" in the task. Am I the main task, or am I a dependency?

pithyless 2021-04-29T10:19:00.236700Z

Cool, but is it a set to future-proof with parallel tasks, etc? ie. is it smart enough to parse a graph and understand all potential dependees? Or is it basically "who called me"?

borkdude 2021-04-29T10:19:51.237400Z

In the --parallel setting, if c depends on the current task, c will always wait before the current task is finished.

borkdude 2021-04-29T10:20:00.237700Z

Same is true for the non-parallel setting

borkdude 2021-04-29T10:20:17.237900Z

oh, you mean, why is it a set?

1☝️
borkdude 2021-04-29T10:20:46.238700Z

because there is not really an ordering of who depends on "me" , I guess

borkdude 2021-04-29T10:21:56.239900Z

you will also get :after [c] which is the exact ordering (scheduling) of tasks that are run after you, even if they don't depend on you

borkdude 2021-04-29T10:22:58.240700Z

the algorithm is deterministic (but may change over versions, not likely)

pithyless 2021-04-29T10:23:52.241600Z

Makes sense and it's nice to have this metadata available during runtime; I also like the move to the function current-task and that it returns a map with all this context!

pithyless 2021-04-29T10:29:00.244400Z

I think there is some unwritten rule that any data-driven Clojure library slowly grows into an ad hoc, informally specified DAG (and basically just differs with the amount of work that is put into the implementation of graph traversals and inspection tooling). 😅

borkdude 2021-04-29T10:30:47.244800Z

hehe. maybe I should base tasks on EQL / Pathom or something? ;)

borkdude 2021-04-29T10:31:40.245800Z

Btw, maybe it's better to make :after, :before and :dependees functions of the current-task rather than putting it in the map, since there might be some work needed to calculate this (although it's pretty fast right now)

borkdude 2021-04-29T10:33:55.248500Z

:after and :before are basically free because I'm adding them as I go through a loop, they are readily available, but :dependees is calculated once at the start by basically reversing :depends of all the relevant tasks

pithyless 2021-04-29T10:34:29.248900Z

How exactly would that work? you would still need to pass all the info needed to generate that context info, right? I can't imagine a lot of extra work is going into actually generating the sets and maps. (And it's not like we're spending a lot of memory, either)

pithyless 2021-04-29T10:38:40.251600Z

yeah, so you build an index once and use it; I suppose you could wrap it in a function/delay so it won't run if nobody ever needs it, but ¯\(ツ)

pithyless 2021-04-29T10:40:18.252300Z

and so then :dependees can be a function so it can be lazy-calculated

borkdude 2021-04-29T10:42:22.252500Z

yeah

borkdude 2021-04-29T10:42:49.252700Z

(dependees (current-task))

borkdude 2021-04-29T10:43:09.253200Z

(dependees (current-task) {:transitive true})

borkdude 2021-04-29T10:44:45.254Z

but anyway, yeah, it's pretty cheap to add it in a field right now.

borkdude 2021-04-29T10:55:18.255100Z

even with 100 tasks it's below 1ms:

user=> (def test-case (zipmap (range 0 100) (repeatedly #(do {:depends (take (rand-int 5) (repeatedly (fn [] (rand-int 100))))}))))
#'user/test-case
user=> (time (tasks->dependees (range 100) test-case))
"Elapsed time: 0.769574 msecs"

borkdude 2021-04-29T11:01:30.255400Z

heck, I guess it can even be lazily calculated when people call current-task. I guess that's the nice thing about exposing a function rather than a dynamic var

Karol Wójcik 2021-04-29T11:27:28.255600Z

I'm totally satisfied with current printing 🙂 Here are some screenshots:

borkdude 2021-04-29T11:28:49.256400Z

You mean, you don't need any hooks for this, you do it manually, right?

Karol Wójcik 2021-04-29T11:30:13.256600Z

I'm using

(def TASK_NAME (or (resolve 'babashka.tasks/*-task-name*)
                   (resolve 'babashka.tasks/*task-name*)))

(alter-var-root #'babashka.tasks/-log-info
                (fn [f]
                  (fn [& strs]
                    (hpr (str "Command " (red "<") (accent @TASK_NAME) (red ">"))))))
As long as this API stays I'm very happy 🙂

Karol Wójcik 2021-04-29T11:30:38.256800Z

Anything else I'm doing manually

borkdude 2021-04-29T11:31:52.257Z

This API will slightly change to (:name (current-task))

borkdude 2021-04-29T11:32:16.257200Z

also -log-info won't be there anymore

Karol Wójcik 2021-04-29T11:32:26.257400Z

😞

borkdude 2021-04-29T11:32:29.257600Z

(everything starting with -foo is private, you should not be using it, only for experimentation)

Karol Wójcik 2021-04-29T11:34:04.257900Z

Ok got it. Next release of babashka and I will have to use hooks

borkdude 2021-04-29T11:40:59.258100Z

How did you get the "required" commands, by parsing the EDN manually?

Karol Wójcik 2021-04-29T11:42:59.258300Z

I just know what holy-lambda needs. I'm trying to check whether tool exists via which. If it does not exists then I'm returning a warning.

borkdude 2021-04-29T11:44:10.258500Z

ah, I thought it was about the required tasks. in the next version one could print:

:enter (println "Already completed tasks" (:depends (current-task)))
for example

1👍
2021-04-29T12:01:29.259500Z

BTW if someone depends on me they are my dependent, so perhaps :dependees should be :dependents

borkdude 2021-04-29T12:52:16.260Z

Ah, is that how you call it

borkdude 2021-04-29T13:06:02.260200Z

I will rename it

1👍
borkdude 2021-04-29T13:49:27.263200Z

For the auto-completion stuff, I was also playing around with the idea in my head to just generate stub scripts:

bb tasks --gen-stubs run
so you could get
run/task-a
run/task-a.bat
run/task-b
run/task-b.bat
(for windows and unix) so you can just do run/<TAB> and get task- autocompletions, where run/task-a just contains #!/usr/bin/env bb\n bb run task-a For subcommands this can become run/task-a/subcmd-1. Maybe a dumb idea, but might work? ;) At least it's robust enough to work crossplatform.

wilkerlucio 2021-05-14T14:01:22.317200Z

@cldwalker thank you very much!!

1
wilkerlucio 2021-05-14T14:05:45.318200Z

proposed adding to the book: https://github.com/babashka/book/pull/28

borkdude 2021-05-14T14:08:04.318600Z

@wilkerlucio I'd be happy to merge this as is, but please read this: https://github.com/babashka/book/blob/master/CONTRIBUTING.md Also @cldwalker should give his permissions to use the code :)

2021-05-14T14:11:29.319Z

Gave permission 🙂

wilkerlucio 2021-05-14T14:11:36.319200Z

https://github.com/babashka/book/pull/29

wilkerlucio 2021-05-14T14:12:23.319500Z

I guess @cldwalker you may need to create PR similar to ☝️ , @borkdude can confirm if that's the case

wilkerlucio 2021-05-14T14:12:55.319700Z

for easy in process, I did mine though here: https://github.com/babashka/book/tree/master/.license-assignments

borkdude 2021-05-14T14:14:18.320200Z

merged

2🎉
borkdude 2021-05-14T14:14:43.320500Z

republishing book now

borkdude 2021-05-14T14:18:15.320800Z

https://book.babashka.org/#_terminal_tab_complete_on_zsh

1🙌
borkdude 2021-04-29T14:01:47.264100Z

Interestingly this library (which has been suggested to me to use for bb itself) supports generating an auto-completion script: https://picocli.info/autocomplete.html

2👌
kokada 2021-04-29T14:17:17.264200Z

Yeah, I think on Windows will not work unless in WSL

kokada 2021-04-29T14:17:28.264400Z

Since test is POSIX

kokada 2021-04-29T14:17:44.264600Z

(Portable I mean, anything except Windows)

borkdude 2021-04-29T14:17:52.264800Z

ok :)

borkdude 2021-04-29T14:18:05.265100Z

is this so you are wrapping rlwrap?

kokada 2021-04-29T14:18:23.265300Z

I don't even know if Windows has the concept of stdin/stderr/stdout, I think they have something similar but the implementation is different

borkdude 2021-04-29T14:18:52.265500Z

They do have that, but the tty stuff isn't there, it's totally different

kokada 2021-04-29T14:20:43.265700Z

> is this so you are wrapping rlwrap? No, actually it is "kinda" common to have a script that needs to check if its connect to a TTY to offer a better user experience

borkdude 2021-04-29T14:21:18.265900Z

Maybe you can contribute that function/script to $BABASHKA_REPO/examples

1👍
kokada 2021-04-29T14:21:58.266100Z

In my particular case, I have a command that when called by another command, it shouldn't throw (since the commands that call it doesn't expect a stack trace in the output of this command)

kokada 2021-04-29T14:22:20.266300Z

But I still want stack trace when I use this command directly, since it makes it easier to debug

borkdude 2021-04-29T14:22:52.266600Z

Is this a command in bb.edn or just a script?

kokada 2021-04-29T14:23:02.266800Z

It is a script

borkdude 2021-04-29T14:23:20.267Z

makes sense

kokada 2021-04-29T14:23:22.267200Z

(Actually it is kinda of a full Clojure project CLI, Babashka is very powerful to makes sense for this case too 🙂 )

borkdude 2021-04-29T14:24:09.267700Z

I just gave a presentation at a company titled "Clj-kondo and babashka: keeping your Clojure projects sane." ;)

kokada 2021-04-29T14:36:07.268Z

https://github.com/babashka/babashka/pull/812 :reviewplease:

borkdude 2021-04-29T14:37:15.268300Z

Where is the actual script?

kokada 2021-04-29T14:38:23.268500Z

Oh, sorry, forgot to commit it

kokada 2021-04-29T14:38:33.268700Z

Done

borkdude 2021-04-29T14:39:28.268900Z

thanks

2021-04-29T16:27:54.269400Z

Yeah i think this is a valid approach as well :)

2021-04-29T16:45:06.269600Z

Regarding subcommands, that’s not a thing in bb.edn yet, right?

borkdude 2021-04-29T16:46:07.269800Z

arg parsing is the job of a task, bb doesn't really get in the way but doesn't help with it either

borkdude 2021-04-29T16:46:29.270Z

it just provides the raw args

2021-04-29T16:48:42.270200Z

yeah exactly, I’ve used this property during experimentation. It’s useful

2021-04-29T16:49:23.270400Z

Did you find examples of generated scripts? I’m curious what they will look like

borkdude 2021-04-29T16:51:31.270700Z

no, I guess you could try it

2021-04-29T16:51:39.270900Z

Or am i misunderstanding and it’s not generating a bash script

2021-04-29T16:51:50.271100Z

yeah i’ll try it eventually 🙂

2021-04-29T16:57:06.271600Z

So the magic happens in bash… I think we can do better 🙂

2021-04-29T16:57:38.271800Z

But good for inspiration

borkdude 2021-04-29T16:58:20.272Z

port to bb ;)

borkdude 2021-04-29T16:58:47.272200Z

Here is a version of generating stubs:

(require '[clojure.edn :as edn])

(def tasks (->> (slurp "bb.edn")
                (edn/read-string)
                :tasks
                keys
                (filter simple-symbol?)))

(require '[babashka.fs :as fs])

(fs/create-dirs "run")

(doseq [t tasks
        :let [f (fs/file "run" (str t))]]
  (spit f (str "#!/usr/bin/env bash\nbb run " t))
  (.setExecutable f true))

borkdude 2021-04-29T16:59:04.272400Z

And then run/a, run/b

2021-04-29T16:59:40.272700Z

Maybe we can use our Dutch charm here. I believe the creator of PicoCli is Dutch

borkdude 2021-04-29T17:00:21.272900Z

I mean for our usage, not for picocli, I don't think picocli will make users require bb ;)

2021-04-29T17:00:24.273100Z

Nice 🙂

2021-04-29T17:00:48.273300Z

haha maybe not

borkdude 2021-04-29T17:05:12.273500Z

1👌
2021-04-29T17:08:11.274Z

I’m not sure it is common practise, but I’m used to use script/ (I guess I copied this from Rails). Is using run/ as directory also common practise?

borkdude 2021-04-29T17:08:38.274200Z

No, I did this because bb run <task> is the command, but script would also work. This should be configurable.

1👍
borkdude 2021-04-29T17:08:45.274400Z

I personally like script

2021-04-29T17:09:14.274600Z

Cool. Yeah it seems many people use it

2021-04-29T17:09:51.274900Z

Many old Rails users maybe I don’t know

borkdude 2021-04-29T17:12:46.275600Z

A script that dumps scripts in script so you can invoke a task using auto-completion based on filename:

#!/usr/bin/env bb

(require '[clojure.edn :as edn]
         '[clojure.string :as str])

(def tasks (->> (slurp "bb.edn")
                (edn/read-string)
                :tasks
                keys
                (filter simple-symbol?)))

(require '[babashka.fs :as fs])

(def script-dir "script")
(fs/create-dirs script-dir)

(doseq [t tasks
        :let [f (fs/file script-dir (str t))]
        :when (not (str/starts-with? t "-"))]
  (spit f (str "#!/usr/bin/env bash\n# generated by stubs.clj\nbb run " t))
  (.setExecutable f true))

wilkerlucio 2021-04-29T17:15:24.275900Z

I understand this is a safe path, but having completion over bb ... would be much cooler IMO, I love that now with bb my scripts directory is gone, and I hope for good 🙂 I guess would be nice to have both approaches, so people/teams that need more compatible solutions could use that, and others could avoid the extra files

1➕
borkdude 2021-04-29T17:16:04.276400Z

Kind of an happy accident that forward slashes don't work in task names ;)

wilkerlucio 2021-04-29T17:16:12.276500Z

I dont know anything about how shells do auto-complete, is the issue that different shells (bash, zsh…) have different ways to do it?

borkdude 2021-04-29T17:20:10.276700Z

yeah, I think it can be supported using these bash/zsh scripts

2021-04-29T17:37:18.281600Z

Hi! A friend of mine showed me using docopt with Babashka, loaded using deps/add-deps:

(deps/add-deps
 '{:deps {nubank/docopt {:git/url "<https://github.com/nubank/docopt.clj>"
                         :sha "12b997548381b607ddb246e4f4c54c01906e70aa"}}})

(require '[docopt.core :as docopt])
With some experimentation I was able to load local dependencies
(deps/add-deps
 '{:deps {
          ;; A local dependency:
          eigenhombre/example {:local/root "."}}})
and even Maven dependencies:
(deps/add-deps
 '{:deps {eigenhombre/namejen {:mvn/version "0.1.14"})
My question is, how does this work?! I thought Babashka used sci under the hood to provide a sort of interpreted Clojure, taking advantage of GraalVM’s native compilation. (1) What is it actually doing when it loads these dependencies? How are they executing within the Babashka process? (2) Can this be used to make Babashka more stripped down, so fewer libraries need to be built in? (3) What are the tradeoffs of loading libraries this way, as opposed to building them into Babashka? Thanks!

2021-04-29T17:56:29.281900Z

Hopefully I’m answering this right, I’m happy to be corrected 🙂

2021-04-29T17:56:32.282100Z

1) Code is loaded from the classpath by shelling out to the clj command line tool

2021-04-29T17:56:35.282300Z

2) Babashka has many dependencies built in because a) some cannot be dynamically loaded b) are big and would add extra latency because of extra parsing. So yes, you could strip down babashka if that’s important to you (see the different versions of Babashka based on feature flags)

2021-04-29T17:56:39.282500Z

3) See 2

2021-04-29T17:59:12.284300Z

An alternative to libraries are Pods. These are binaries themselves, often Clojure programmes compiled by Graalvm itself (not a requirement), and connect with Babashka via a socket

2021-04-29T18:09:15.286700Z

I’m trying to understand https://github.com/remkop/picocli/blob/master/src/test/resources/picocompletion-demo-help_completion.bash as we speak 😅 on a second look it doesn’t look that complicated. I’ll let you know

borkdude 2021-04-29T18:11:30.289500Z

A few additions. 1) You can set the BABASHKA_CLASSPATH or --classpath manually using your favorite build tool. This became tedious so now babashka also supports a bb.edn similar to deps.edn (but with less features, no aliases yet for example). 2) When bb must calculate the classpath using bb.edn or babashka.deps/add-deps it will shell out to java and uses a tools.deps uberjar to download deps and calc the classpath, This is effectively what the clojure bash script also does. 3) So this happens similar to how the clojure CLI does it, but it does not use or need the installed clojure CLI, because this is done using https://github.com/borkdude/deps.clj as a built-in library 4) Interpreted libs are slower than built-in ones and not all of the code is compatible with babashka, so not all libs can be run from source. Having some things built-in, even if they are source-compatible with bb, sometimes makes sense, like clojure.tools.cli. 5) Babashka has feature flags that can be used to trim the binary down, if you don't need all of the built-in libs. It also has feature flags to enable more built-in libs. 6) Most notably libs relying on non-standard Java classes, deftype or definterface are not source-compatible with babashka 7) Some non-compatible libs can be made compatible by introducing :bb reader conditionals

1👍
borkdude 2021-04-29T18:12:38.290Z

^ @eigenhombre

2021-04-29T20:08:44.291600Z

This semi works. Needs proper unit tests for all the weird edge cases https://gist.github.com/jeroenvandijk/42a570415a45c68989f4f506977050c4

borkdude 2021-04-29T20:11:03.291900Z

how must one use it?

2021-04-29T20:12:06.292100Z

this should do it https://gist.github.com/jeroenvandijk/42a570415a45c68989f4f506977050c4#file-autocomplete-clj-L6-L19 although it can be a bit funky. There seems to be some state involved

2021-04-29T20:12:56.292300Z

so in this case bb-complete is not a command but it will be autocompleted. If you type bb-complete and press TAB it should do something

2021-04-29T20:13:24.292500Z

very vague sorry. I need to test it more thoroughly and several times to make sure it works in any state

2021-04-29T20:14:13.292700Z

I’ll look into it later again, but i’m just posting it here in case someone wants to try it

kokada 2021-04-29T20:30:59.293Z

I have some other questions: 3) This still needs java installed right? If I want a fully "static" (something that only depends on Babashka) script I need either to use uberscript or uberjar right? 4) If I add the built-in libraries to babashka in my bb.edn, does it load the built-in ones or the ones defined in bb.edn. I am asking this because I include some builtin libraries in my bb.edn because my Babashka's project also have a project.clj with lein-tools-deps to make development easier (e.g.: at least for now, CIDER doesn't support Babashka REPL very well), but I wouldn't want to inccur an additional load for this. If this is an issue I may move all bb.edn dependencies to project.clj. 7) Does Babashka's interprets :clj reader macro? If yes, what it does in case of having both :clj and :bb?

borkdude 2021-04-29T20:37:40.293200Z

3) correct, or take care that the deps have been already downloaded and provide the classpath manually 4) it loads the built-in ones, unless you use (:require [foo.bar] :reload) 7) Yes, it does, for compatibility with existing libraries. If you have both, then put :bb as the first branch

1👍
kokada 2021-04-29T20:38:51.293400Z

> If this is an issue I may move all `bb.edn` dependencies to `project.clj`. Actually, this seems to work fine, and seems to be a better idea regardless so I did it Anyway, I am still curious if Babashka will load the dependencies from bb.edn or the builtin ones

2021-04-29T20:42:21.293800Z

Thank you @borkdude. So, when Babashka pulls in a dependency from, say, Maven, and runs it, it is literally interpreting the source code it gets out of the downloaded jar file?

borkdude 2021-04-29T20:42:30.294Z

yes

2021-04-29T20:43:05.294200Z

Wow, cool. It is so great to see Babashka continuing to evolve in new and useful ways.

kokada 2021-04-29T20:44:19.294400Z

> it is literally interpreting the source code it gets out of the downloaded jar file? And this only works for Clojure jars right? Since sci can't interpret Java files

borkdude 2021-04-29T20:45:20.294600Z

True. It only works for Clojure source

1👍1✔️
kokada 2021-04-29T20:47:33.295Z

It is really amazing how well eveything works, thanks for the explanation @borkdude

1👍
borkdude 2021-04-29T21:08:48.297500Z

@pithyless and others. I have one other naming bikeshed:

:after [update-project-clj -uberjar build-server -jar lsp-jar]
:before [java1.8]
If you see this in the output of (current-task), how do you interpret this? What I want to express: these jobs were scheduled before, these other jobs were scheduled after. But I imagine one could also read it as: this job comes before these and after these others.

pithyless 2021-04-30T07:08:32.299Z

I think the question is why you want this info. The depends/dependents is used to identify dependency relationships between tasks. What you're proposing is how those dependencies (multiple potential orderings) were actually flattened to a single concrete ordering. So this may be interesting for auditing (the past ones) and planning (the future ones). I think the names should reflect that - perhaps one of #{:processed :executed :audit :completed :past} for the previous and #{:queued :planned :plan :upcoming :future} for the future ones?

borkdude 2021-04-30T07:24:29.299200Z

I was contemplating on adding just the :plan [a b c d e] but if you are task c it might be awkward to see where you are in the plan.

borkdude 2021-04-30T07:25:00.299400Z

but this info doesn't necessarily mean that a and b were already completed if you use --parallel, unless you :depends on them (or you depend on them transitively)

borkdude 2021-04-30T07:25:52.299700Z

so maybe I'll just leave it out for now

pithyless 2021-04-30T07:31:14.299900Z

> but this info doesn't necessarily mean that a and b were already completed if you use `--parallel`, unless you `:depends` on them (or you depend on them transitively) (edited) Are you referring to the proposed before/after or to the aforementioned [:plan a b c d e]?

borkdude 2021-04-30T07:32:18.300100Z

both are the same, but before/after is just a split of the whole sequence based on the current task

pithyless 2021-04-30T07:34:50.300300Z

OK, so this doesn't convey that the previous tasks were completed, but the previous ones have definitely been already started, correct? And in that order. (Even if running in parallel, so may not complete in that order)

borkdude 2021-04-30T07:35:45.300500Z

correct

borkdude 2021-04-30T07:36:58.300700Z

Maybe just a transitive depends and transitive dependents is more useful, since you can rely on those being completed / not yet started

pithyless 2021-04-30T07:36:59.300900Z

OK, so the names were not that obvious to me; perhaps something more vague ala :started / :planned ?

pithyless 2021-04-30T07:37:54.301100Z

And if we don't have this, what do we lose? The ability to understand all tasks that would be run in this session (without processing all the transitive deps)?

borkdude 2021-04-30T07:40:23.301300Z

OK, so to back up a bit: The primary reason for me to add :enter and :leave and (current-task) + :name is so you can decide on your own logging, when the job begins and ends. You may not want to log certain stuff if you are not the main invoked task (:dependents is empty) or maybe you do if you are invoked by some main wrapping task (the only task in dependents is main-task which does some setup and then calls you)

borkdude 2021-04-30T07:40:36.301500Z

so it seems we only need :name and :dependents for this

1👍
pithyless 2021-04-30T07:42:51.301700Z

The only use-case I can think of for a global :plan is if we want some logic in a task that is conditional on whether some arbitrary task will ever run during this session.

pithyless 2021-04-30T07:44:05.301900Z

Another use-case may be an initial logger that says: "This is everything that will run now: ..." (but that seems a bit of a stretch)

pithyless 2021-04-30T07:45:29.302200Z

But I reserve the right to not be particularly creative with use-cases 😉

borkdude 2021-04-30T08:20:00.302500Z

It might be best to not include anything at this point and just wait for the proper use cases to arise

borkdude 2021-04-30T08:36:35.302700Z

You can fairly easy get the already running tasks like this:

{:tasks {:init (def ctx (atom []))
         :enter (swap! ctx conj (:name (current-task)))
         bar []
         foo {:depends [bar]
              :task @ctx}}}

borkdude 2021-04-30T08:38:37.302900Z

or capture the first running task by putting it in some state and if this state exists, not overwrite it

borkdude 2021-04-30T08:39:11.303100Z

I mean, the main task, but hmm, this is not true, since they won't get to :enter until after the deps

borkdude 2021-04-30T08:40:38.303300Z

therefore having the entire plan might still be useful since you can see "who" invoked the entire chain

borkdude 2021-04-30T08:43:22.303500Z

Maybe :started and :pending are useful names

borkdude 2021-04-30T08:45:16.303700Z

Just :pending perhaps

borkdude 2021-04-30T08:51:09.304Z

The use case I have in mind for this: you might have a deploy task. Subtasks may only do want to do certain work if a certain environment variable is set. So uberjar might only want to do work if it's not started because of deploy or if the CLOJARS_USERNAME is set. But this might be getting too complicated if you write tasks like this.

borkdude 2021-04-30T08:52:14.304200Z

I'll leave out these hypothetical keys and wait until later

borkdude 2021-04-29T21:10:31.297800Z

I could also just leave this information out completely, and only add :dependents #{-jar update-project-clj -uberjar}. I guess that info is useful in the sense of answering the question "why am I being invoked", whereas the exact order of tasks isn't very useful information and can even be confusing (with respect to parallel).

Tommy DeVito 2021-04-29T22:22:30.298400Z

:past :future or :previous :next?

1👍
kokada 2021-04-29T22:56:52.298700Z

I think this kind of information maybe interesting to debugging purposes, but not if it is showed always