Fork me on GitHub
Sam Ritchie17:01:15

hey all, I’m wondering if I’ve hit a bug, or if there is some way to prevent this “unintuitive” behavior… given deps.edn

 {:cake {:exec-fn user/cake}}}
and src/user.clj
(ns user)

(defn cake [m]
  (prn "you ran cake with " m))

(defn face [m]
  (prn "you ran face with " m))
check out this behavior:
[sritchie@wintermute ~/code/clj/tools-repro]$ clj -X:cake user/face a b
"you ran face with " {a b}
[sritchie@wintermute ~/code/clj/tools-repro]$ clj -X:cake user/face a b c
"you ran cake with " {user/face a, b c}
[sritchie@wintermute ~/code/clj/tools-repro]$ clj -X:cake user/face a b c d
"you ran face with " {a b, c d}

Sam Ritchie17:01:52

depending on whether I supply an even or odd number of arguments, user/face is interpreted as a function OR as an argument

Sam Ritchie17:01:10

is there some way to cause this to error if I supply the wrong number of args? I can do it inside of a babashka task…

Sam Ritchie17:01:28

[sritchie@wintermute ~/code/clj/tools-repro]$ clj -X:cake a b c
Unqualified function can't be resolved: a


This is "expected" but perhaps surprising if you don't know how the CLI figures out what invocation you're trying to run...


Since CLI arguments are passed as key/value pairs, it uses the number of arguments to differentiate between a specific function and k/v pairs or the default function :exec-fn and k/v pairs.

Sam Ritchie17:01:29

yeah, I get it, just trying to noob-proof a template I’m creating with some babashka tasks that call into clojure via -X


Hard to noob-proof -X because you have to understand how it is called 😐

Sam Ritchie17:01:37

got it! bb.edn:

 {:init (defn X [cmd]
          (do (if (even? (count *command-line-args*))
                (apply shell cmd *command-line-args*)
                (do (println "Please supply an even number of arguments!")
                    (System/exit 1)))))

  {:doc "Start a Clerk dev server configured with this project's custom JS."
   :task (X "clojure -X:dev:nextjournal/clerk user/start!")}}}


Yeah, you basically need a wrapper around the invocation...


No, you can call -X with 1 argument, a single map


@U017QJZ9M7W What I typically do is:

{:task (apply clojure "-X:whatever" *command-line-args*))
Why wrap this with checks?

Sam Ritchie17:01:06

because the alias has a default :exec-fn , and I don’t want the user to accidentally call that

Sam Ritchie17:01:30

I can move the exec-fn to a NEW alias of course, since I’m using the clerk alias for both extra deps and the exec-fn


but you're already providing the exec-fn in the task, so the user can't call another one?

Sam Ritchie17:01:13

that’s the problem, see my paste above; if you supply an odd number of args, the first one’s interpreted as a new :exec-fn

Sam Ritchie17:01:25

oh sorry I see your “what I typically do is” note

Sam Ritchie17:01:55

it’s because Clerk’s Garden needs a :nextjournal/clerk alias with an :exec-fn that triggers the static build

Sam Ritchie17:01:50

and I think it’s confusing for consumers of this template I’m writing if I put • clerk dep in one alias with a different name • garden :exec-fn in :nextjournal/clerk alias • yet another alias with a different to supply another :exec-fn to start the local clerk dev server

Sam Ritchie17:01:24

that’s why I’m using bb.edn in the first place, because constructing these big strings out of simple decomplected parts is not something I want to explain to someone new who’s just trying to graph some functions 🙂

👍 2
Sam Ritchie17:01:30

as much as I am on board with it!!

Yuhri Graziano Bernardes17:01:26

Hi everyone. I'm trying to use in a leiningen project (throught a remote REPL). I could download the lib locally, but seems that I need to update the classpath because the lib I just fetched is not there. Does anyone knows how can I do that?


If you're using Leiningen, you already have Pomegranate available which lets you load new dependencies at runtime.


Otherwise, with tools.deps.alpha you'd need the add-lib3 branch and the add-libs function (which isn't documented and is subject to change). A variant of this may be built into Clojure 1.12 it seems.

Yuhri Graziano Bernardes17:01:26

Thanks @U04V70XH6. I'll try out Pomegranate


BTW, I recently created a #C04KJME1UPL channel as part of my clj-commons-maintenance-wip-tlc pass on this lib.

❤️ 4