Fork me on GitHub
#tools-deps
<
2019-08-20
>
Lone Ranger10:08:55

is there any way that you can specify extra deps on the command line without using an alias? I've developed a template to help my coworkers quick-start on clojurescript but explaining to them how to add an alias for clj-new to their .clojure/deps.edn is just one more annoyance for them to figure out. I'd like to be able to do something like

clj -m clj-new.create --middleware "[seancorfield/clj-new]"  some.example

souenzzo17:08:19

why not clj -Sdeps '{:deps,{seancorfield/clj-new,{:mvn/version,"0.5.5"}}}' -m clj-new.create some.example

bananadance 4
Lone Ranger10:08:51

or perhaps read a deps.edn from stdin that I could have them just paste in via file descriptor?

Lone Ranger10:08:59

clj -i -m clj-new.create  some.example <(cat << eof
{:aliases   :new {:extra-deps {seancorfield/clj-new
                           {:mvn/version "0.5.5"}}
              :main-opts  ["-m" "clj-new.create"]}
eof
)
something like that would also work but I haven't been able to figure that one out yet either

vlaaad10:08:31

it's worth explaining IMHO: there is no magic, everything is simple and configurable

Alex Miller (Clojure team)11:08:37

-Sdeps lets you add an extra deps.edn on the command line

8
Lone Ranger19:08:28

does anyone have an example of the -Sdeps syntax? Is a string?

lispyclouds19:08:21

clj -Sdeps "{:deps {clj-http {:mvn/version \"3.10.0\"}}}" ?

Lone Ranger19:08:33

the command I'm hoping for is clj -Sdeps '{seancorfield/clj-new {:mvn/version {"0.5.5"}}' -m clj-new.create project.name

Lone Ranger19:08:50

thanks I wasn't sure the exact syntax

4
Alex Miller (Clojure team)19:08:35

it is literally the text of a deps.edn file

Lone Ranger21:08:05

outstanding ... exactly what I needed, works exactly as advertised, thank you!

cfleming22:08:22

I’m having a problem loading a namespace which requires t.d.a, using version 0.7.535. I’m getting the following error:

Syntax error compiling at (clojure/tools/deps/alpha/reader.clj:98:5).
No such var: io/read-edn

cfleming22:08:45

This seems weird, because io/read-edn does exist.

cfleming22:08:04

I’m just running a standard REPL, classpath looks ok to me.

cfleming22:08:49

( "clojure/tools/deps/alpha/reader.clj")
=>
#object[java.net.URL
        0x2bf95d38
        "jar:file:/Users/colin/.gradle/caches/modules-2/files-2.1/org.clojure/tools.deps.alpha/0.7.535/11de58e45ac07ea473f2322f335ef6d162dffde9/tools.deps.alpha-0.7.535.jar!/clojure/tools/deps/alpha/reader.clj"]
( "clojure/tools/deps/alpha/util/io.clj")
=>
#object[java.net.URL
        0x2b2beaaa
        "jar:file:/Users/colin/.gradle/caches/modules-2/files-2.1/org.clojure/tools.deps.alpha/0.7.535/11de58e45ac07ea473f2322f335ef6d162dffde9/tools.deps.alpha-0.7.535.jar!/clojure/tools/deps/alpha/util/io.clj"]

hiredman22:08:07

maybe check (get (ns-publics ') 'read-edn)

hiredman22:08:38

the namespace could have been created somehow and added to the lib-map, without loading the source file, stopping require from actually loading it

cfleming22:08:39

(get (ns-publics ') 'read-edn)
=> nil
(ns-publics ')
=>
{printerrln #',
 write-file #',
 slurp-edn #'

cfleming22:08:29

All the vars are there except that read-edn

hiredman22:08:04

no install-deps either (not sure if that is in 0.7.535, I am looking at master)

cfleming22:08:45

No, I don’t see that in the 0.7.535 rev

cfleming22:08:08

I can’t see anything in the source doing anything funky like unmapping vars.

hiredman22:08:48

read the diff wrong, install-deps is a different namespace

cfleming22:08:57

If I just restart the REPL and then require http://c.t.d.a.u.io directly, then the publics are wrong right off the bat.

cfleming22:08:49

Is there a good way to diagnose where the ns is actually being loaded from?

hiredman22:08:20

you could change the require function to print debugging information(a stacktrace, maybe clojure.lang.Compiler/LOADER, but I guess that is just a dynamic classloader) every time it is called

hiredman22:08:13

you could also see what (.getResource (RT/baseLoader) "clojure/tools/deps/alpha/util/io.clj") returns, maybe check for aot'ed classfiles too

cfleming22:08:48

(.getResource (RT/baseLoader) "clojure/tools/deps/alpha/util/io.clj")
=>
#object[java.net.URL
        0x37339a
        "jar:file:/Users/colin/.gradle/caches/modules-2/files-2.1/org.clojure/tools.deps.alpha/0.7.535/11de58e45ac07ea473f2322f335ef6d162dffde9/tools.deps.alpha-0.7.535.jar!/clojure/tools/deps/alpha/util/io.clj"]

cfleming22:08:59

The same as before, looks like it’s coming from the right jar.

hiredman22:08:30

you could also look in the jar and see if has the right file contents 🙂

cfleming22:08:41

It does 🙂

hiredman22:08:38

something like

(alter-var-root #'require (fn [orig]
                            (fn [& args]
                              (println (.getResource (clojure.lang.RT/baseLoader) "clojure/core.clj"))
                              (apply orig args))))
with the funky namespace's resource name instead of clojure/core.clj and then requiring the namespace might show something

cfleming23:08:21

(alter-var-root #'require (fn [orig]
                            (fn [& args]
                              (println (.getResource (clojure.lang.RT/baseLoader) "clojure/tools/deps/alpha/util/io.clj"))
                              (apply orig args))))
=> #object[user$eval1256$fn__1257$fn__1258 0x1a272414 "user$eval1256$fn__1257$fn__1258@1a272414"]
(require '[])
#object[java.net.URL 0x76f46991 jar:file:/Users/colin/.gradle/caches/modules-2/files-2.1/org.clojure/tools.deps.alpha/0.7.535/11de58e45ac07ea473f2322f335ef6d162dffde9/tools.deps.alpha-0.7.535.jar!/clojure/tools/deps/alpha/util/io.clj]
#object[java.net.URL 0x6db91f0c jar:file:/Users/colin/.gradle/caches/modules-2/files-2.1/org.clojure/tools.deps.alpha/0.7.535/11de58e45ac07ea473f2322f335ef6d162dffde9/tools.deps.alpha-0.7.535.jar!/clojure/tools/deps/alpha/util/io.clj]

cfleming23:08:17

I’m not sure why require would be called twice there.

hiredman23:08:06

that may be a clue

cfleming23:08:26

And if I use:

(alter-var-root #'require (fn [orig]
                            (fn [& args]
                              (println (slurp (.getResource (clojure.lang.RT/baseLoader) "clojure/tools/deps/alpha/util/io.clj")))
                              (apply orig args))))
then the correct file contents are printed out.

hiredman23:08:36

I think I've seen that behavior when the namespace in question has already been loaded (why that results in two require calls I have no idea)

hiredman23:08:14

in a fresh repl before requiring anything maybe try the ns-publics call for the namespace again

cfleming23:08:08

In a plain clj -Adeps REPL, where the publics are correct, it’s also printed twice.

cfleming23:08:50

Yeah, (find-ns ') returns nil in a fresh REPL.

cfleming23:08:17

Weirdly though, requiring something like clojure.zip only prints once.

Alex Miller (Clojure team)23:08:18

-Adeps loads an uberjar

Alex Miller (Clojure team)23:08:32

That won’t play nice with the lib jar

cfleming23:08:58

No, I was just using -Adeps without a deps.edn to test in a clean REPL.

cfleming23:08:10

i.e. to compare to what I was seeing in the problematic one.

Alex Miller (Clojure team)23:08:02

Nothing unusual about how this ns is defined or loaded afaik

cfleming23:08:20

No, I can’t see anything.

hiredman23:08:44

could you have some aot classfiles somewhere on the classpath, if they have a newer last modified they will be loaded instead of the clojure source

cfleming23:08:32

I’m wondering that. I have the debugger set up, and Compiler.load() is never called.

Alex Miller (Clojure team)23:08:32

I don’t think that fn was added till 541

cfleming23:08:51

Ugh, that was the problem.

cfleming23:08:00

Rogue AOT classes sitting around.

cfleming23:08:06

Sorry for the noise.

cfleming23:08:45

Thanks for the help!

cfleming23:08:34

I’m not sure why there would have been AOT classes for the .io namespace but not the one calling it, though. I guess it must have been a previous transitive compilation.