In tools.deps, when using git deps, the following declared dependencies:
{io.github.xadecimal/riddley {...}}
{com.github.xadecimal/riddley {...}}
{com.xadecimal/riddley {:git/url "https://github.com/xadecimal/riddley.git" ...}}
{com.xadecimal/riddley {:mvn/version ...}}
{garbage/whatever {:git/url "https://github.com/xadecimal/riddley.git" ...}}
will all resolve, but they will not conflict against one another, even though they are all the same lib.
As it stands, the consumer that declares the dependency can choose from all these equivalent declarations, but if it chooses differently than any of its transitive dependencies have chosen, a hidden conflict is created, and more than one version of the lib will be pulled into the classpath, giving non-deterministic behavior to what version of the code will actually be used at runtime.
This problem could be solved by letting the lib author choose the canonical lib group/name that users must use always when declaring a dependency on it.
This can be achieved by adding a new key to deps.edn
, such as :lib
which takes a fully qualified symbol which will be validated against the symbol declared in the :deps
map of the consuming libs.
deps.edn
of the library being depended upon:
{:lib com.xadecimal/riddley ;; <-- This new key is added to deps.edn, declaring the canonical lib name
:paths ["src"]
:deps {...}
...}
deps.edn
of the libraries that declare a dependency on the above lib:
{:paths ["src"]
:deps {com.xadecimal/riddley {...}}
...}
When tools.deps resolves the above, it will check if the pulled lib has :lib
key declared in its deps.edn
, if it does, it will assert that the symbol used here matches the declared :lib
symbol, if it does not, it will error to the user, making this an illegal dependency declaration. In the above it is correct, but in the following it is wrong:
deps.edn
of a library that badly declared an illegal dependency on the above lib:
{:paths ["src"]
:deps {com.github.xadecimal/riddley {...}}
...}
This would error, because even if the library is found at github.com/xadecimal/riddley.git
and thus the above resolves, the library at github.com/xadecimal/riddley.git
declared that its canonical lib name was com.xadecimal/riddley
and not com.github.xadecimal/riddley
. Therefore, in this case the only valid git dependency declaration is:
{:paths ["src"]
:deps {com.xadecimal/riddley {:git/url "https://github.com/xadecimal/riddley.git" ...}}
...}
This validation would follow a similar ideology to asserting that the git/tag matches the git/sha, by asserting that the lib name used matches what the lib expects to uniquely be identified by.
Doing this allows conflict resolution to work as expected, and avoids the possibility that transitive dependencies use a different name, causing hidden runtime version conflicts not detected and resolved by tools.deps.