tools-deps

Discuss tools.deps.alpha, tools.build, and the clj/clojure command-line scripts! See also #depstar #clj-new
borkdude 2021-03-23T13:15:40.153300Z

New version of deps.clj, a port of the clojure bash script to clojure: https://github.com/borkdude/deps.clj/releases/tag/v0.0.12 - catch up with 1.10.3.814

unbalanced 2021-03-23T16:06:24.155100Z

messing around with this neat tool I found (https://gist.github.com/ericnormand/6bb4562c4bc578ef223182e3bb1e72c5) to make .clj files into scripts. Curious if it's possible to use either -X or -m or something to cherry pick a function from the script.

#!/bin/sh
#_(

   #_DEPS is same format as deps.edn. Multiline is okay.
   DEPS='
   {:deps {}}
   '

   #_You can put other options here
   OPTS='
   -J-Xms256m -J-Xmx256m -J-client
   '

exec clojure $OPTS -A:strapped -Sdeps "$DEPS" "$0" "$@"

) ;; code goes below here

(defn test []
  (println "[+] test successful"))

(defn -main []
  (test))

unbalanced 2021-03-23T16:07:32.156200Z

I've tried ./test.clj -X test, ./test.clj -M -m test, ./test.clj -m, ./test.clj -m test, ./test.clj -M, ./test.clj -M -m , ./test -X test/test

seancorfield 2021-03-23T16:14:29.157100Z

@goomba Since it invokes the script directly via the clojure command, you cannot use other main- or exec- options with it, as it stands.

unbalanced 2021-03-23T16:15:07.157400Z

ohhhh

unbalanced 2021-03-23T16:15:11.157600Z

would require clj?

seancorfield 2021-03-23T16:15:29.158Z

No, clj is just a wrapper around clojure that adds rlwrap.

seancorfield 2021-03-23T16:15:46.158400Z

(`clj`/`clojure` are otherwise interchangeable)

unbalanced 2021-03-23T16:15:56.158600Z

ah

seancorfield 2021-03-23T16:18:03.159600Z

You’d need to have the directory containing the script as a :local/root dependency and then you could invoke functions in it via -X but that’s a bit hacky.

unbalanced 2021-03-23T16:18:20.159800Z

I'm also a bit hacky haha

seancorfield 2021-03-23T16:25:17.160200Z

@goomba Something like:

(! 962)-> ./unbalanced.clj -X unbalanced/test :foo '"bar"'
WARNING: test already refers to: #'clojure.core/test in namespace: unbalanced, being replaced by: #'unbalanced/test
[+] test successful {:foo bar}
(! 963)-> cat unbalanced.clj 
#!/bin/sh
#_(
   #_DEPS is same format as deps.edn. Multiline is okay.
   DEPS='
   {:deps {} :paths ["."]}
   '
   #_You can put other options here
   OPTS='
   -J-Xms256m -J-Xmx256m -J-client
   '
exec clojure $OPTS -Sdeps "$DEPS" "$@"
) ;; code goes below here
(ns unbalanced)
(defn test [arg-map]
  (println "[+] test successful" arg-map))

seancorfield 2021-03-23T16:25:55.160800Z

:paths should really be dynamically constructed to be the folder for the script.

seancorfield 2021-03-23T16:26:46.161800Z

Notes: needs a ns form for -X invocation (so it has a defined namespace); removed "$0" since we don’t want to execute the script directly; added an arg to test so it can be called via -X.

unbalanced 2021-03-23T16:33:10.162100Z

I must be missing an assumption

unbalanced 2021-03-23T16:33:13.162200Z

unbalanced 2021-03-23T16:34:29.162800Z

using

:deps {     
        org.clojure/clojure      {:mvn/version "1.10.2-alpha4"}
        }                                              
               
in my ~/.clojure/deps.edn

unbalanced 2021-03-23T16:34:47.163300Z

does it require a deps.edn in the same dir?

seancorfield 2021-03-23T16:37:12.163600Z

What is your clojure version? clojure -Sdescribe

unbalanced 2021-03-23T16:37:38.163800Z

oh, fascinating

unbalanced 2021-03-23T16:37:44.164100Z

{:version "1.10.0.411"
 :config-files ["/usr/local/lib/clojure/deps.edn" "/home/jay/.clojure/deps.edn" "deps.edn" ]
 :install-dir "/usr/local/lib/clojure"
 :config-dir "/home/jay/.clojure"
 :cache-dir ".cpcache"
 :force false
 :repro false
 :resolve-aliases ""
 :classpath-aliases ""
 :jvm-aliases ""
 :main-aliases ""
 :all-aliases ""}

seancorfield 2021-03-23T16:38:16.164600Z

That is very old (and does not support -X). The current version is 1.10.3.814

unbalanced 2021-03-23T16:38:45.165Z

wow, great catch, had no idea. I thought my ~/.clojure/deps.edn would take precedence, but I suppose not 😮

seancorfield 2021-03-23T16:39:16.165500Z

Not sure what you’re asking about. That’s the user deps.edn and, yes, it factors in.

seancorfield 2021-03-23T16:39:31.165800Z

(unless you pass -Srepro)

unbalanced 2021-03-23T16:40:21.166500Z

this file /usr/local/lib/clojure/deps.edn has a different clojure version than my ~/.clojure/deps.edn , I think. Sorry for confusiion

dpsutton 2021-03-23T16:41:40.167500Z

its not the version of the jvm hosted language that's an issue. its the version of the command line program clojure which assembles a classpath and calls an entrypoint. That command line clojure is too old to understand the -X command line argument

unbalanced 2021-03-23T16:41:47.167700Z

ahhhh

unbalanced 2021-03-23T16:42:06.168100Z

time to upgrade!

seancorfield 2021-03-23T16:43:01.168400Z

Clojure CLI version != Clojure language version.

unbalanced 2021-03-23T16:43:32.169Z

works like a charm!!!!!!!

unbalanced 2021-03-23T16:43:40.169400Z

go team!!!! 🔥 🎆

unbalanced 2021-03-23T16:43:43.169700Z

thank you!!!

seancorfield 2021-03-23T16:44:07.170200Z

The prefix portion of the CLI version indicates the default version of Clojure it would use (1.10.0, 1.10.1, 1.10.2, 1.10.3) and the last segment is the commit count for that release.

unbalanced 2021-03-23T16:45:10.170500Z

aha! working great now 🙏

borkdude 2021-03-23T19:21:20.172700Z

Is there any precedent of tools that need tools.deps.alpha for downloading deps and calc classpath that also put their non-deps-related tool config in deps.edn? E.g. shadow-cljs has a config file which allows :deps true to resolve deps from deps.edn, but it does not store its own config in deps.edn. Are there any tools who do? Is this encouraged / not recommended / neutral?

seancorfield 2021-03-23T19:28:38.174900Z

@borkdude My feeling is that given the alias-as-data thing that has crept into deps.edn, we will start to see tooling be passed one or more keyword-valued exec arguments and it will be common for the tool to then lookup those keywords as aliases in the project basis and use the data structures those aliases point to. depstar already does this, deps-deploy has an open PR to add that.

seancorfield 2021-03-23T19:29:30.175900Z

That allows users to name additional tool config in deps.edn however they want and then communicate that name to the tool via a keyword-valued exec arg.

borkdude 2021-03-23T19:30:02.176500Z

ok, but depstar is a dependency-centric tool, so it's more obvious there probably

seancorfield 2021-03-23T19:30:18.176900Z

You can also specify a keyword for the whole :exec-args thing and that is looked up as an alias by the CLI -X machinery.

seancorfield 2021-03-23T19:32:05.177700Z

I think any tooling that you run via CLI can reasonably assume it could look up aliases in the basis to get configuration data.

seancorfield 2021-03-23T19:32:31.178600Z

But I strongly believe it should be via an exec arg passing a keyword and not a hard-code alias name.

borkdude 2021-03-23T19:32:33.178700Z

what if the tool isn't invoked via the CLI but maybe via a binary.

seancorfield 2021-03-23T19:33:07.179400Z

If you pass the tool a keyword argument that tells it what alias in the basis to use, I think that’s reasonable.

borkdude 2021-03-23T20:29:05.180400Z

On the other hand, if all kinds of tools start saving their config in deps.edn, this file could become pretty big and tedious to parse on every tool invocation

seancorfield 2021-03-23T21:06:04.182100Z

I think that depends on just how much config various tools have. Having some sort of “build” config in deps.edn seems reasonable but maybe a tool that has a very open-minded config (clj-kondo) should not use deps.edn for that and should keep it separate?

borkdude 2021-03-23T21:08:07.183800Z

In this case I'm thinking of a task runner (like make, npm scripts, just, etc) in babashka that you configure in EDN. It is not being invoked through the clojure CLI but it can use tools.deps.alpha for itself. This will capture commonly invoked commands, including invocations of the clojure CLI itself, so you don't have memorize those or write bash scripts to wrap them.

borkdude 2021-03-23T21:10:56.184700Z

So it leans on tools.deps.alpha but I don't think it will read from a basis file using an alias name for example.

alexmiller 2021-03-23T21:14:28.185500Z

it is discouraged to add top-level keys to deps.edn

borkdude 2021-03-23T21:14:29.185700Z

But clj-kondo is also a good example: clj-kondo could read from your deps.edn, but it doesn't necessarily belong inside deps.edn

alexmiller 2021-03-23T21:15:00.185800Z

doing so could break in the future, and would be unsupported

alexmiller 2021-03-23T21:15:14.186Z

putting named data in :aliases is ok

borkdude 2021-03-23T21:15:37.186200Z

understood. and what about an alias convention, e.g. tool X always reads from :aliases :tool-x ?

alexmiller 2021-03-23T21:16:13.186700Z

alias data good, novel top-level keys bad

✅ 1
alexmiller 2021-03-23T21:16:39.187300Z

alias data could be the name of a config edn file to read if you want to centralize definition but offload the contents

👍 1
borkdude 2021-03-23T21:16:55.187500Z

yeah, I think it's better to split it

alexmiller 2021-03-23T21:17:12.187600Z

why not use a ns?

borkdude 2021-03-23T21:17:54.188Z

I think I'll adopt the way shadow-cljs did it

thheller 2021-03-23T21:27:44.189700Z

FWIW deps.edn didn't exist when I started with shadow-cljs.edn but I would make the same choice again. I prefer having targeted configuration files over the all-in-one gigantic configs

✅ 1
seancorfield 2021-03-23T21:46:20.190100Z

Glad to have Alex confirm what I was saying there 🙂

borkdude 2021-03-23T21:55:02.191100Z

FWIW I wasn't planning on adding top level keys to deps.edn, but if I went the alias way it would probably have been a fully qualified keyword unique to the tool. But I agree with thheller's remark. Thanks for the useful exchange.