I just noticed that write-pom supports :optional in deps, to produce in pom.xml... I don't remember any discussions about that and, I'll be honest, I don't really understand what it's for (after reading various Maven docs)...
I hoped that a [edit: this actually does seem to work on a second test so I'm not sure why I wasn't seeing this before]
However, deps.edn project that depends on a JAR with an optional dep in pom.xml would not bring in that transitive dep -- which seemed to be what the Maven docs indicated -- but that's not the case. is something that has been asked for and discussed and I believe that would omit the transitive dep (yes?). Is there still some blocker to something like :scope :provided in a dependency being handled by write-pom?
write-pom and deps.edn deps are two different contexts of course, and those contexts have different intents. write-pom is about literally writing a Maven pom, producing a Maven specified artifact. I don't remember what drove supporting :optional there but in general, I'm fine with providing features to let you make the pom you want to make. If you want more things that don't exist there, feel free to ask for them. The goal of the deps.edn has nothing to do with Maven or its features. The domain is similar and we support many features that overlap, but the goal is not Maven in Clojure syntax. In general, deps chooses to specify the classpath in :deps, and then allow you to add modifiers to specify alternate classpaths. I'm in support of solving a user problem. but I don't think "support :provided" is the problem, so I'd rather state what that is and see if people have that need, and then decide how to solve it. I don't really care whether it maps to Maven :provided scope or not in this context.
I don't recall an issue for this already, maybe there is one. it's not something people ask me about often.
I think it mostly crops up in the context of http://cljdoc.org which needs "extra" deps for some projects that are not part of the regular deps for a project. <scope>provided</scope> works for http://cljdoc.org and it seems like when deps.edn specifies a Maven dep (Clojars) that has that, it "does the right thing", i.e., doesn't bring in the provided dep.
So the problem is that there's currently no way to tell write-pom to add that.
I happened to notice :optional true support in the source when wondering what would be involved and hoped -- based on the Maven docs -- that it would do something similar to <scope>provided</scope> but, alas, it does not.
My workaround for now is to have the "provided" dep under a :provided alias -- with :optional true, so I can use it when testing etc and then call write-pom with a :basis that is built with that alias... and then slurp/replace/spit the pom.xml file between write-pom and jar calls, changing <optional>true</optional> to <scope>provided</scope> -- this seems to work just fine, but of course it's abusing :optional true support 🙂
that seems fine and not abusing it. optional and provided are practically the same in Maven. except provided is a scope and optional is a flag
in both cases they are marking a dependency that is not required (but for different reasons - either the runtime environment provides or it is not always needed)
Well, I tried <optional>true</optional> and depending on the JAR still brought in that optional dep -- which surprised me. When I switched it to <scope>provided</scope> then it worked.
So, it seems (based on my admittedly limited testing) that an optional Maven dep is not treated the same as scope provided by tools.deps?
(hence, part of my original question was "what does <optional> really do?" 🙂 )
> depending on the JAR still brought in that optional dep what is the actor here? maven?
In deps.edn, I had a :local/root dep on the JAR file.
(and now I've tested it with a :mvn/version dep too)
so you're saying tools.deps including a Maven artifact with an optional dep is including that transitive dep?
that is not the intent, if you're seeing that
In both cases, <scope>provided</scope> works (i.e., the dep is not brought in), but an <optional>true</optional> dep doesn't (i.e., the dep is still brought in).
It was limited testing, but I was surprised to see the optional dep show up on the classpath, yes.
https://github.com/clojure/tools.deps/blob/029041e3729ee5a877c512c45f721b14b8b69742/src/main/clojure/clojure/tools/deps/extensions/maven.clj#L151 is intending to remove optional deps
Hmm, looks like that should work...
I'll have a play around but maybe something is dropping the optional key somewhere... It would certainly be convenient if that actually does work 🙂
I'll get back to you on that...
I created a couple of new projects to test this and... :optional true does work there... I'll do some more digging on why it didn't work for what I was trying before...
Looks like this is a solution for http://cljdoc.org too -- :optional true in an :extra-deps dep under an alias.
https://github.com/seancorfield/rephrase/blob/main/deps.edn#L4-L6
https://github.com/seancorfield/rephrase/blob/main/build.clj#L34
Doesn't show up when used via deps.edn:
> clojure -Spath -Sforce -Sdeps '{:deps {org.corfield/rephrase {:mvn/version "1.0.2"}}}'
src:/home/sean/.m2/repository/org/clojure/clojure/1.12.5/clojure-1.12.5.jar:/home/sean/.m2/repository/org/corfield/rephrase/1.0.2/rephrase-1.0.2.jar:/home/sean/.m2/repository/org/clojure/core.specs.alpha/0.4.74/core.specs.alpha-0.4.74.jar:/home/sean/.m2/repository/org/clojure/spec.alpha/0.5.238/spec.alpha-0.5.238.jarthe line I pointed to is really for pulling deps from a maven artifact, not an extension to dep maven coordinate spec
Yes, agreed.
that is, :optional is not a valid key for maven deps like you're using it
But write-pom explicitly supports it.
It's supported in the coord just like exclusions is.
that's not a documented feature of write-pom
Maybe it should be? 🙂
hrm
Looks like that code is at least six years old now?
I'm sure it's older than that. I'm not going to take it away or anything.
If it was documented, you could probably close out requests for :scope :provided where those are intended to solve the cljdoc issue...
At this point, I think :optional is a good solution to that (despite being undocumented), and it leaves the whole <scope> thing for consideration independently.