tools-deps

Discuss tools.deps.alpha, tools.build, and the clj/clojure command-line scripts! See also #depstar #clj-new
borkdude 2020-08-16T12:07:17.189100Z

@seancorfield Would it be possible to exclude clojure and clojure.spec.alpha sources/AOT-ed assets from an uberjar? The use case would be for babashka which already has clojure built-in (spec not yet, but maybe coming). So an uberjar with only (non-clojure) source files and no AOT-ed stuff would be leaner. https://github.com/borkdude/babashka/issues/535#issuecomment-674518153 Since you're reading from a system property here https://github.com/seancorfield/depstar/blob/b7e9e4537e33bbf78fbdbc0ef56d9675cb494bc2/src/hf/depstar/uberjar.clj#L283 it might be a small tweak to override the classpath with a command line arg or file reference (java itself uses the @ convention for that).

borkdude 2020-08-16T12:36:09.190100Z

E.g.:

clojure -A:depstar -m hf.depstar.uberjar MyProject.jar -v -m proj --classpath "$(clojure -Spath)"

borkdude 2020-08-16T12:36:57.190800Z

Btw, I think depstar will be able to compile with GraalVM so maybe I can even include it in babashka itself to create babashka uberjars

1💯
Alexis Vincent 2020-08-16T16:46:46.193100Z

I’d like to distribute a deps.edn file of aliases for everyone to use in our company. But I want people to be able to have their own local ./clojure/deps.edn. Is there a way to specify a deps.edn file to merge in, either globally for all projects, or from a projects deps.edn?

alexmiller 2020-08-16T16:58:18.193300Z

no, not currently

j0ni 2020-08-16T17:29:28.197700Z

Is it possible to add a list of jar files from a project sub-dir to the classpath without having to name them? I know about :local/root and I see this in the docs https://clojure.org/guides/deps_and_cli#local_jar but I have a lot of them and they aren't published anywhere. Do I just have to make up names for them and add them individually as :deps?

alexmiller 2020-08-16T17:32:33.200100Z

It’s kind of a hack, but java supports on the classpath for this (literal path/ so not shell expanded). I think if you added a :paths entry for “path/*” that should work

2020-08-17T08:15:49.239500Z

Interesting I was wanting to do something similar too, so I could deploy an app as a zip with a directory of jars in lib but start it with the clojure command line tooling; via a :local/root; with a different deps.edn for production, rather than the one we use in dev.

alexmiller 2020-08-17T13:43:08.242300Z

the other crazy thing you can do is to reference jars in your manifest (this was part of the original applet support) with the Class-Path attribute but I think that has to be explicit jars. afaik that does not support the glob stuff

2020-08-17T14:55:34.244700Z

yeah now you mention it I’ve seen manifests do this…. a long time since I’ve seen or written an applet tho! 😆

alexmiller 2020-08-17T14:57:06.245Z

also relevant, the manifest has a line wrapping limit and so other arcane rules so it's best to use the apis to make it rather than doing it by hand

2020-08-17T14:59:06.245200Z

wow I had no idea… eitherway if I do this I think it’ll be via the :local/root method, largely motivated via the new -F -X stuff

j0ni 2020-08-16T17:32:58.200500Z

thank you @alexmiller I will try that out

j0ni 2020-08-16T17:59:13.200900Z

amazing, thank you Alex, it works

1👍
borkdude 2020-08-16T19:30:50.201600Z

@seancorfield Awesome: depstar works with GraalVM and can hence be included in babashka proper so it can make its own uberjars

borkdude 2020-08-16T19:34:36.202Z

$ bb -cp $(clojure -Spath) --uberjar foo.jar -m proj
Building uber jar: foo.jar
$ bb -jar foo.jar
:foo - failed: int?

seancorfield 2020-08-16T20:24:13.203Z

@borkdude Cool. As for your earlier question, depstar deliberately just includes everything on the current classpath, aside from itself.

ghadi 2020-08-16T20:26:28.203900Z

That was a fundamental design decision I regret

ghadi 2020-08-16T20:27:13.204900Z

In retrospect I’d use t.d.a as a library to calculate what to tar up

ghadi 2020-08-16T20:27:37.205500Z

rather than subtracting depstar itself from the classpath

borkdude 2020-08-16T20:29:21.205800Z

yep. but that can be easily changed. I've already done that in my fork

ghadi 2020-08-16T20:31:28.206200Z

You using t.d.a to calculate instead?

seancorfield 2020-08-16T20:32:26.207Z

To be honest, using the classpath has made depstar a lot easier to use for people, and a lot more predictable.

borkdude 2020-08-16T20:33:06.207500Z

@ghadi I just added a :classpath option that can be used to override

seancorfield 2020-08-16T20:34:00.208700Z

Hmm, interesting approach. Since it's easy to get clojure to produce an arbitrary classpath from deps.edn aliases etc...

borkdude 2020-08-16T20:34:10.208900Z

Exactly.

ghadi 2020-08-16T20:36:08.210Z

this is a similar thing to what I’m trying to avoid, vectors of strings

borkdude 2020-08-16T20:36:54.211500Z

So the classpath given to babashka, produced by clojure is just passed down to depstar:

$ bb -cp $(clojure -Spath) --uberjar foo.jar -m proj
which results in a foo.jar that can be invoked with bb -jar foo.jar.

ghadi 2020-08-16T20:38:43.214300Z

I understand. I’m just saying the shell is not leverage compared to a clojure library. One of the things I want to do is split a list of dependencies by their rate of change for smarter distribution to containers or Lambdas

borkdude 2020-08-16T20:41:01.218100Z

You mean, make uberjars for things not changing often?

ghadi 2020-08-16T20:42:08.220900Z

For containers, you don’t want every commit to result in a 60MB new uberjar, you want some structural sharing across commits

borkdude 2020-08-16T20:42:15.221200Z

I guess one could use the -A or -T option for that, to make groups of deps and then push that classpath into depstar

ghadi 2020-08-16T20:42:57.222700Z

Yeah I know you can hack it in shell, but why not program it directly in bb or clojure?

ghadi 2020-08-16T20:43:34.223900Z

my hope with tools.build (not that I have anything to do with it currently) is that it encourages build tasks to compose better than the lowest common denominator of the CLI

borkdude 2020-08-16T20:43:54.224400Z

bb will have an --uberjar option, but it can also have a bb -e '(babashka.uberjar/run {:classpath ...})-ish interface

borkdude 2020-08-16T20:44:17.225100Z

can have them both

vlaaad 2020-08-16T20:44:36.225300Z

Wait are tools.build out?

ghadi 2020-08-16T20:44:49.225500Z

no

seancorfield 2020-08-16T20:45:13.226600Z

depstar currently has zero dependencies, except Clojure itself, so it can't interfere with anyone's project dependencies -- that's worked very well in practice. I like @borkdude’s idea of just giving it an explicit classpath to build form 🙂

borkdude 2020-08-16T20:45:33.227100Z

bb won't do AOT btw (maybe it could but I don't think it's worth it). for JVM uberjars (with AOT-ed classes), just use clojure / depstar

borkdude 2020-08-16T20:45:53.227800Z

bb uberjars typically will contain sources and other assets, but no classes

vlaaad 2020-08-16T20:47:40.229600Z

Unless I want to have the whole build happen in a single vm, and it has to have other build-specific dependencies like data.xml for updating pom.xml. I use 2 vms for that now, but I'd rather not :)

borkdude 2020-08-16T20:47:46.229900Z

I did have depstar compile with GraalVM as is and when I didn't remove the AOT-related code, it did compile, but the binary got somewhat bloated (+ 30MB, happens when it hits a specific part of Clojure). So maybe compile just works natively, since it's just going to transform .clj into classfiles, I haven't tried it.

borkdude 2020-08-16T20:51:04.230900Z

I'll try it now... just for science

seancorfield 2020-08-16T21:02:32.231500Z

I'm not sure whether you're agreeing with depstar's approach or suggesting something different?

borkdude 2020-08-16T21:15:30.232800Z

Interesting. Compilation of a class doesn't work in a GraalVM binary because the classpath inside the binary is not set correctly for clojure RT. I guess it won't work for that reason, although technically it could maybe work.

borkdude 2020-08-16T21:24:27.233900Z

Going to try this:

(binding [*compile-path* (str tmp-c-dir)]
          (clojure.lang.RT/compile (str main-class ".clj")))

borkdude 2020-08-16T21:25:51.234100Z

crap, it's private ;)

borkdude 2020-08-16T21:38:31.235100Z

With a reflective hack it works. I see all kinds of AOT-ed sourced, even aot__init.class, but no aot.class. Maybe :gen-class isn't part of RT/compile? Eh.... enough for today.

borkdude 2020-08-16T21:42:01.236Z

So the AOT part could be useful when depstar had a binary CLI version, so to speak. I don't need it for bb, but it could be useful for fast build tooling in general.

borkdude 2020-08-16T21:45:58.237400Z

To make this work clojure.lang.RT should also have a pluggable classpath resolver. It might work for Clojure files, but I wonder how it will work if code relies on .class files from the Java world. Does the Clojure compiler kind of treat .class files as data, without actually having to have them on the classpath per se, as long as you point it to the right file? I.e. no runtime need, just able to read and analyse statically?

borkdude 2020-08-16T22:05:12.239200Z

I see, Compiler relies on reflection when dealing with interop, so there it will likely break, since the reflection API only works with classes that are part of the same runtime. OK, this was a nice tangent.