Fork me on GitHub
#babashka
<
2022-08-02
>
alexdavis12:08:39

Hi, I’m using an nrepl task I copied from the book

nrepl (do (srv/start-server! {:host "localhost"
                                :port 1667})
            (spit ".nrepl-port" "1667")
            (-> (Runtime/getRuntime)
                (.addShutdownHook
                 (Thread. (fn [] (fs/delete ".nrepl-port")))))
            (deref (promise)))
but when I try and eval a ns form which requires the hasch library I get
; (err) : Can't set!: clojure.core/*warn-on-reflection* from non-binding thread
I know hasch works because I can run it from the command line fine, so I think this is some issue with the task I’m using to start the nrepl server? Any ideas?

borkdude12:08:59

Can you make a more fuller repro?

borkdude12:08:58

I think you could fix this by doing:

(binding [*warn-on-reflection* *warn-on-reflection*] ...)
around the call to srv/... for now

alexdavis12:08:02

ok if you unzip this and run

bb -m foo
it will work ok, if you run
bb nrepl
then connect and eval the buffer (or just the ns form) it will give the error. I added the binding but same thing

borkdude12:08:04

This worked for me:

user=> (binding [*warn-on-reflection* *warn-on-reflection*] (require '[hasch.core]))
nil

borkdude12:08:10

A bit annoying, worth posting an issue about

borkdude12:08:36

This is a repro, just eval this in nREPL:

user=> (set! *warn-on-reflection* true)
: Can't set!: clojure.core/*warn-on-reflection* from non-binding thread user

alexdavis12:08:50

Alright so as a workaround I can just put that binding in my ns? I’ll make an issue

👍 1
alexdavis12:08:23

Thanks for the help

alexdavis12:08:22

this is a clj-kondo question really, but is there something I can do so kondo recognises require outside a ns?

alexdavis12:08:35

It does work though so not too bothered

borkdude12:08:50

Repeat the require once again maybe? ;)

borkdude12:08:07

Require outside of an ns is supported

borkdude12:08:13

but only on the top level

alexdavis12:08:32

ahh I see, sounds like a fun one 😄

borkdude12:08:57

you can just repeat the require a second time. for bb isn't a no-op but for clj-kondo it will work

👍 1
hlship23:08:59

I was able to extract the code for my much more verbose take on command line option/argument parsing: https://github.com/hlship/bb-tasks

👍 1
borkdude08:08:11

Looks really neat. Feel free to PR it to the toolbox :) https://babashka.org/toolbox/

borkdude09:08:10

To do something similar with args in bb cli you could do: https://gist.github.com/borkdude/29926d5ece9f79b04629a822fdc4e011

hlship15:08:31

So, right now, the bb.edn contains

{:doc "Configures the system with keys and values"
             :task (t/configure)}
If just bare, t/configure, then BB will attempt to convert command line args and call the wrong arity:
> bb configure  pages=10 skip=true -v
----- Error --------------------------------------------------------------------
Type:     java.lang.Exception
Message:  Cannot call configure with 4 arguments

> 
But what if the task code looked at the meta-data for #'configure to: • to see that it should invoke the 0 arity implementation • to extract the :doc (which can be provided by deftask from the docstring (DRY)

hlship17:08:33

I've given it some more thought and realized that what I want is an alternate to Babashka tasks as I'm trying to build reusable tools, often with sub-commands.

borkdude17:08:38

Right. Babashka tasks is mostly focused on project-local task (akin to Makefile). #babashka-neil is a tool that uses the sub-command feature from babashka CLI heavily

borkdude08:08:19

Looks pretty awesome, reminds me a lot of boot tasks

borkdude08:08:44

Personally I always found writing boot tasks too verbose, but I'm sure there's people who like the approach you've taken as well

hlship23:08:52

I have further ideas to discuss ...