tools-deps

Discuss tools.deps.alpha, tools.build, and the clj/clojure command-line scripts! See also #depstar #clj-new
cfleming 2020-09-09T00:24:21.124500Z

Just double checking - there is no way to get the deps of a subproject specified via :local/root including deps from an alias, correct? i.e. I cannot specify an alias together with :local/root in some way?

seancorfield 2020-09-09T00:26:37.124700Z

Nope.

seancorfield 2020-09-09T00:26:56.125Z

Dependencies are opaque in that respect.

seancorfield 2020-09-09T00:28:06.126300Z

Although... I guess you could read the basis (in the prerelease CLI) and figure out the actual :local/root path and see if it has deps.edn and then use t.d.a to read that and then inspect its aliases... 👀

seancorfield 2020-09-09T00:29:12.127300Z

But a :local/root could point to a JAR, or a directory with pom.xml. Or project.clj 🙂

cfleming 2020-09-09T00:32:54.127500Z

Right.

cfleming 2020-09-09T00:33:27.128100Z

This is just specifying deps in a deps.edn file, so I can’t do anything funky or programmatic.

2020-09-09T01:13:26.129900Z

What is the rationale for deprecating unqualified dependency symbols in :deps? (couldn’t see one in the release notes)

seancorfield 2020-09-09T01:17:24.130400Z

@hugod It's mentioned in this post https://insideclojure.org/2020/07/28/clj-exec/ near the end.

seancorfield 2020-09-09T01:18:46.130800Z

(IOW it was deprecated in an earlier prerelease)

2020-09-09T01:20:25.131500Z

Thanks - I missed that release 🙂

seancorfield 2020-09-09T01:25:21.132200Z

I spent the first week of August, scurrying around, fixing all our unqualified lib names at work, and all my open source projects! 🙂

cfleming 2020-09-09T02:31:32.134600Z

Is there any way to substitute values into a deps file that I’m not aware of, e.g. from env vars or properties? In my case I would like to be able to substitute a global version in several deps files. I’m aware of default-deps, but I’d need to be able to substitute it in a :local/root path.

seancorfield 2020-09-09T02:33:31.135100Z

Nope. No substitutions.

seancorfield 2020-09-09T02:39:06.135400Z

(I'm just a bundle of "nope" today, aren't I?)

cfleming 2020-09-09T02:40:34.135600Z

Haha

cfleming 2020-09-09T02:40:51.136Z

No worries, that was what I expected, just makes my life a little more tedious 🙂

2020-09-09T13:19:41.136600Z

Fwiw, having played with the pre-release, I still think the following CLI switches would be simpler, as they separate the selection of aliases from what to execute, and would simplify the doc. A given set of aliases can be used for main, exec or repl, so it makes it easier to compose a command line from other tools if the passing of options is distinct from the selection of what to invoke.

clj     [clj-opt*] [-A:aliases] [init-opt*]
clojure [clj-opt*] [-A:aliases] -x [a/fn] [kpath v]*
clojure [clj-opt*] [-A:aliases] [init-opt*] [main-opt] [arg*]
clojure [clj-opt*] -P [other exec opts]
or it could be
clojure [clj-opt*] [-A:aliases] -M [init-opt*] [main-opt] [arg*]
If that is really required, though I confess I don’t see the rationale for having to specify the -M given that you’re passing -m or have a :main-opts key. The (at least my perceived) lack of usage of the current -T, `-R`, `-C`, and -O options supports the above.

👌 1
2020-09-10T13:04:41.175400Z

main obviously takes strings and an exec-fn wants an edn value, but that doesn’t need to dictate the format of arguments passed on the cli. The cli could print edn to strings before passing it as a main argument, or read literal strings to edn strings before passing to an exec-fn. As a strawman, with intentionally hideous names, consider this: i) default to passing args as literal string values, or add a --string switch to explicitly specify this ii) add an --edn switch, that causes the next argument to be read as EDN and passed as a value to an exec-fn or as a string to a main. iii) add a --patch switch that takes an edn path vector and an edn value and patches the default value. if the value is prefixed with --string treat it as a string value rather than EDN. Allow main to have default arguments specified, in the same way as exec-fn. iv) add a --rest switch that collects the remaining arguments into an EDN vector. --rest-strings could build an EDN vector from string arguments rather than edn values. This could be used to pass glob values, for example. v) allow an exec-fn to take multiple arguments. As described this is unwieldy, but if there were volition, I’m sure it could be improved upon. The main idea would be to divorce the specification of the format of the arguments passed on the command line from how they are passed to the implementing function.

alexmiller 2020-09-09T13:21:43.137Z

Sorry, not doing that

2020-09-09T13:29:13.137200Z

That’s clear 🙂

seancorfield 2020-09-09T16:15:15.138400Z

Also, I think there's more usage of -R out there than you suspect @hugod

2020-09-09T16:22:04.138700Z

I’m sure I don’t have a good perspective on that, but don’t think it really changes my view that just using -A would be conceptually simpler.

2020-09-09T16:22:30.138900Z

Given the cli changes seem fixed, I’ll just go and update my nascent build tool invoker project to cope with multiple versions of the cli.

seancorfield 2020-09-09T16:28:13.139100Z

I still think that a) given the expansion of -M to include more than just :main-opts b) the overlap between -A and -M (both run :main-opts now) c) the current uses of -R (doesn't run :main-opts but does "most" of what -A does -- based on resolve args being the most common; it would make more sense for -R to be kept and expanded as the "REPL" usage (and quietly undocumenting -A). So we'd have -R (REPL), -M (main), -X (exec) and they all three respect all arg types in deps.edn and there would be no overlap on :main-opts or :exec-fn.

2020-09-09T17:20:45.139300Z

I do find it unfortunate that the deps.edn isn’t authoritative. By this I mean that whatever you specify in deps.edn you still have to know whether to invoke it with -M or -X.

seancorfield 2020-09-09T17:29:35.139500Z

See https://github.com/seancorfield/dot-clojure/blob/develop/deps.edn#L15-L18 -- you can support both 🙂

seancorfield 2020-09-09T17:30:08.139800Z

That works with -A today and either -M or -X tomorrow!

2020-09-09T17:36:58.140Z

I don’t think that is quite what I meant. As a deps.edn writer I would like to provide an abstract, say test, alias for doing something, and have the user be able to invoke that independent of how I chose to implement that alias. Writing it both ways seems like duplication.

alexmiller 2020-09-09T18:55:17.140200Z

well the arg structures are different, not sure how that could work

2020-09-09T19:08:13.144700Z

Hi, I have been working on a https://github.com/JeremS/mbt based on tools.deps for some time. It has a mix of functionality inspired from several other projects and it's at a stage where I use it to version, build and deploy my projects. Maybe someone other than me might find it useful! Cheers

seancorfield 2020-09-09T19:37:57.145600Z

@alexmiller It looks like clojure -X:deps mvn-pom now adds the following dependencies to all pom.xml files:

<dependency>
      <groupId>org.clojure</groupId>
      <artifactId>tools.deps.alpha</artifactId>
      <version>0.9.782</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-nop</artifactId>
      <version>1.7.25</version>
    </dependency>

seancorfield 2020-09-09T19:39:04.146700Z

That's going to cause a lot of projects to accidentally end up depending on tools.deps.alpha (and the slf4j-nop dependency is likely to be unwelcome in many cases I suspect).

☝️ 1
seancorfield 2020-09-09T19:40:45.147700Z

These deps are in a freshly-generated pom.xml file -- and they are also added to any existing pom.xml, potentially overwriting the dependency for any projects that use a different version of t.d.a

alexmiller 2020-09-09T19:43:19.148100Z

ah, interesting

alexmiller 2020-09-09T19:43:51.148600Z

thx, will fix

seancorfield 2020-09-09T19:45:29.148700Z

Exactly, as a tool writer you need to specifically support -M style invocation and/or -X style invocation as two separate functions in your code: -main taking & args which are strings and some-exec-fn taking a single hash map as its argument.

seancorfield 2020-09-09T19:59:43.151600Z

How will you fix it? For example, my clj-new project does depend on t.d.a (and has a dependency on slf4j-nop because of that) -- but I know that's an outlier -- so you'd need to also not remove any existing dependency on those?

alexmiller 2020-09-09T20:00:51.152100Z

I'll fix it by calculating the basis, not using the injected basis

alexmiller 2020-09-09T20:01:02.152300Z

basically what it did before

seancorfield 2020-09-09T20:02:56.152900Z

Won't that break anyone currently using clojure -A:some:aliases -Spom ?

alexmiller 2020-09-09T20:11:12.153300Z

it doesn't have to - the injected basis includes those argmaps

alexmiller 2020-09-09T20:11:36.153700Z

the calculated basis can use the project deps.edn + the injected basis argmaps

alexmiller 2020-09-09T20:12:30.154200Z

another option would be to take those additional aliases as args to the -X pom function

alexmiller 2020-09-09T20:12:41.154500Z

that would be an all new thing though

alexmiller 2020-09-09T20:13:24.155300Z

very similar thing exists in the datomic ion-dev tool which I was just helping with a bit :)

alexmiller 2020-09-09T20:14:04.155900Z

I am planning to reinstate the -Spom as well so looking at that right now too

alexmiller 2020-09-09T20:14:59.157Z

I had some thoughts on the -Stree thing you ran into though - I think there are several better ways to detect changing deps tree rather than scraping the -Stree stdout. not sure what your requirements on that stuff are but might be useful to talk about

alexmiller 2020-09-09T20:18:47.158400Z

from a clj pov, we're writing edn files (.libs in particular) to the cache dir (can see location with -Sdescribe), so you could be slurping and diffing Clojure maps rather than comparing strings

alexmiller 2020-09-09T20:19:56.159500Z

and from a tools.deps pov, you could probably make something that did this via the api instead, but not sure if that's worth the effort

alexmiller 2020-09-09T20:21:26.160800Z

I really consider -Stree / -X:deps tree to be human consumer tools and ones likely to hopefully improve over time, changing format. I don't consider the current particular output to be something a script should rely on.

seancorfield 2020-09-09T20:25:43.161400Z

Re: basis -- so -A and -X are distinguishable via the basis? Or am I misunderstanding?

seancorfield 2020-09-09T20:26:25.161600Z

If it's just going to be identical to -X:deps mvn-pom I wouldn't have thought it was worth the effort?

alexmiller 2020-09-09T20:26:57.161800Z

oh, I see what you're asking. well let me think about it more

seancorfield 2020-09-09T20:27:46.162Z

True, but a) how can you easily get the correct .libs file from a given invocation without scraping the output and b) that gives no sense of depth of transitivity, which is specifically what I rely on in -X:deps tree

alexmiller 2020-09-09T20:27:56.162200Z

you were the one here arguing it was breaking people last week... :)

seancorfield 2020-09-09T20:28:54.162400Z

"Because reasons"... we go one level down in the full tree (so we consider top-level deps and the first level of transitive deps, but we don't care about lower levels).

seancorfield 2020-09-09T20:30:14.162600Z

We've found that we can safely ignore the 2nd-order transitive deps and if we have a problematic 1st-order transitive dep, we just promote it to the top-level (and then its transitive deps are promoted to 1st-order transitive deps and we start to track them separately).

alexmiller 2020-09-09T20:30:42.162800Z

well the transitivity stuff is all broken in the -Stree output

alexmiller 2020-09-09T20:31:17.163Z

but maybe you're just not encountering the cases where it's bad (mostly with exclusions)

seancorfield 2020-09-09T20:31:20.163200Z

Hahaha... yeah, but you didn't seem very sympathetic to that argument, and I'm not sure having duplicate ways to do the exact same thing is better 🙂

seancorfield 2020-09-09T20:31:43.163400Z

We don't use exclusions, for the most part.

seancorfield 2020-09-09T20:32:13.163600Z

This is our only exclusion:

com.walmartlabs/lacinia {:mvn/version "0.35.0"
                           :exclusions [clojure-future-spec/clojure-future-spec]}

alexmiller 2020-09-09T20:32:52.163800Z

the main thing is, the code never actually builds the real expansion tree as a tree. -Stree is kind of faking from the libs map

seancorfield 2020-09-09T20:33:18.164Z

We decided that managing conflicts via :exclusions was a bit of a nightmare so we control conflicts by promoting transitive deps to the top level.

seancorfield 2020-09-09T20:33:45.164200Z

Right, but I'd have to write that "faking" code myself, whereas -X:deps tree already does a "good enough" job.

alexmiller 2020-09-09T20:34:22.164400Z

well, it exists as a function you could call (the one -Stree calls) :)

alexmiller 2020-09-09T20:34:48.164600Z

but that stuff is due for some significant changes soon as I fix up some of this stuff

seancorfield 2020-09-09T20:34:55.164800Z

Besides, I've had this shell script running with -Stree for ages and don't really want to rewrite it as a Clojure program right now. Maybe when I'm bored and want to go shave some more yaks...

alexmiller 2020-09-09T20:35:47.165Z

ok, just letting you know that I'm not considering stdout changes from -Stree (or its replacement) to be breaking :)

alexmiller 2020-09-09T20:36:35.165200Z

but I am planning to add some more api fns to get tree-like deps data

2