Fork me on GitHub
#tools-deps
<
2018-09-08
>
malcolmsparks07:09:06

@alexmiller @dominicm One example where type is important is where a project might depend on a .war file, containing some functionality. See https://codesjava.com/eclipse-maven-java-web-project for example. This is more likely to happen inside a large enterprise using J2EE, I doubt you'd find an example in 'public' repos but there are vast private ones out there. This still is about the classpath (Maven itself is primarily about classpaths, not file distribution). There are other types too: https://docs.oracle.com/cd/E19830-01/819-4712/ablgz/index.html. I don't think it's worth adding support for them in tools.alpha, but at the same time it would be good if any design around supporting classifiers can be extended (via growing) to support types as well.

malcolmsparks07:09:27

I think the 1-1 correspondence is actually quite a nice design. If you think of the artifact as the logical entity defined in the pom.xml file (with its version and dependencies), rather than an actual file in the Maven repo. 99% of cases there is a single file for the artifact, but sometimes there are also ancillary files (one per classifier), sometimes called secondary artifacts. While Maven does support depending on a primary artifact file of, say, version 1.0, and a secondary artifact of a different version, say, version 1.1, this is such a questionable practice it is unlikely to be worth supporting.

malcolmsparks07:09:24

So in conclusion, I don't think there needs to be an extended lib name of {:groupId "group.id", :artifactId "artifactId", :classifier "classifier"}. The libname, with the :mvn/version, already uniquely addresses the logical artefact (defined in its pom). There should be a way of specifying the required classifiers, perhaps with a :mvn/classifiers entry.

malcolmsparks07:09:54

One minor point is that Maven makes you a declare a dependency on each artifact file you want to download (and you just normally repeat the GAV coord with a different classifier). Therefore there might need a way of saying "this classifier please, but include the primary artefact too", and also 'this classifier please, but not the primary artefact". I think the latter case could be supported later if required via growing the design.

malcolmsparks08:09:14

Having read https://github.com/technomancy/leiningen/issues/898 now I do understand the point about tools.deps being only concerned about the classpath and perhaps extraction of native libs needs to be out-of-scope.

dominicm09:09:31

Some libraries do the work themselves, http://usb4java.org/nativelibs.html

alexmiller12:09:33

I can give you at least one more example that has nothing to do with native stuff

alexmiller12:09:31

ClojureScript relies on a few contrib libs (like tools.reader). All of hose libs get built in both a source form (and deployed with no classifier) and in aot form (deployed with :aot classifier).

alexmiller14:09:44

the idea of pushing this into the coord is interesting. The current extension SPI already supports extensions returning multiple artifacts per lib. I do wonder about whether this has impacts for walking the transitive deps? Something to look at.

alexmiller14:09:00

I guess there’s still only one pom defining deps for a lib, even in the case where there are multiple classifiers

alexmiller16:09:31

as I looked at it more, I like this solution and I have implemented it and committed the change for the next release - see TDEPS-12 for more

gfredericks17:09:17

I was thinking again about self-contained clojure files I realized you could have a pretty clean impl at the cost of a mildly longer shebang line, if you publish a library (ideally with a very short name) that can read deps out of lines 2->N of a file, and execute everything after that using -Sdeps so the shebang would be roughly #! clojure -Sdeps '{:deps {lib7 {:mvn/version,"1"}}}' -m lib7.main I think the tricky part is that lib7 couldn't do a unix exec to replace the original jvm; so maybe the cleanest thing for it to do would be to have tools.deps as a dep, and call it internally, and make its own classloader with the resulting classpath... so A) are there any libs yet that accomplish anything comparable to this? B) is this crazy or impossible?

gfredericks17:09:29

Startup time would be interesting

dominicm18:09:04

There's a library to make isolated class loaders from a deps edn.

dominicm18:09:20

Startup time would be boot-like

gfredericks18:09:28

do you recall the library's name?

dottedmag18:09:53

@gfredericks Shebangs do not get parsed into arguments.

dottedmag18:09:15

And yes, someone has done something like that.

dottedmag18:09:09

IIRC via file that can be read either as a shell script (that runs clj) or as Clojure code (where shell header gets ignored via e.g. ;). With #!/bin/sh shebang.

gfredericks18:09:19

oh if you can't in any syntax pass two args to clojure then I guess that would kill that idea

dottedmag18:09:47

#!/bin/sh
; exec clj .... $0
<clojure code follows>

dottedmag18:09:10

Something like this.

gfredericks18:09:27

having lots of deps crammed into one line is unfortunate

gfredericks18:09:11

I bet some fancy bash could support multiple lines

dottedmag18:09:24

Multiple lines of what?

dottedmag18:09:07

Why? I don't remember a requirement that shell script has to fit on a punched card 🙂

gfredericks18:09:19

just annoying when viewing and editing

gfredericks18:09:23

not a deal breaker

dottedmag18:09:33

I'd generate this script instead of editing it manually.

gfredericks18:09:47

generate it from what?

gfredericks18:09:07

I guess I mean the thing I'm going for is casual self-contained shell scripts

gfredericks18:09:13

not tied to anything else

gfredericks18:09:17

so generating it kind of defeats the purpose

dottedmag18:09:18

and yes, should be trivial:

#!/bin/sh
; CLJ="clj ..."
; CLJ="$CLJ ..."
; CLJ="$CLJ ..."
; exec $CLJ
<clojure code follows>

gfredericks18:09:05

I wonder if you could take advantage of the deps map being a noop to have it outside the comments

gfredericks18:09:11

so you get syntax highlighting and editor help

gfredericks18:09:57

I get Syntax error: ";" unexpected for that sort of thing

gfredericks18:09:30

this is the holy grail I think

#!/bin/sh
... magic bash
{:deps {...
        ...
        ...
        ...}}
... more magic bash, with exec
(ns wahoo ...)

borkdude19:09:52

Does anyone have an example of how to use clj/tools-deps with AOT + uberjar?

gfredericks19:09:09

":"; seems designed to avoid the error I mentioned above

borkdude19:09:15

yes, it was the shortest bash command I could find that was also valid clojure

borkdude19:09:22

I think @mfikes came up with it

gfredericks19:09:03

would "" not work?

gfredericks19:09:20

what does : mean in bash?

souenzzo12:09:50

it's not plain true it's a (def : (constantly true))

👍 4
borkdude19:09:57

it’s an alias for true

gfredericks19:09:19

so your AOT/uberjar question is about asking how to take a src dir and AOT compile it and put that in an uberjar?

borkdude19:09:38

yes, with tools.deps. With lein I can find docs on that, but with tools.deps not so much I guess

alexmiller20:09:34

There are some things there to do it

gfredericks19:09:58

I thought I saw an uberjaring lib at some point

gfredericks19:09:27

w.r.t. AOT, it might be true that by calling compile enough you will get class files written to the classes dir

gfredericks19:09:34

but there might be lots of edge cases involved that I don't know about

gfredericks19:09:09

e.g., if you have a top-level namespace that requires everything else, try clojure -e '(compile (quote that.ns))'

borkdude20:09:49

if [ ! : ];  then
    echo "True!"
else
    echo "False!"
fi
# prints "False!"

gfredericks20:09:02

who wouldn't want to be able to write code like that!

borkdude20:09:10

however, this doesn’t seem to work:

if [ : && : ];  then
    echo "True!"
else
    echo "False!"
fi