From what I could find using my google-fu;
Maven selects whichever version is closest to the head in the dependency tree¹. Users can include a specific dependency version in the main application to override any sub-package version choice.
Gradle has so called rich version constraints² that can be used to make dependency resolution more strict or relaxed. If version range is defined to be "strict" than it will halt building in case of a conflict similar to Dub.
CLR (Common Language Runtime) allows two versions of the same assembly to be loaded³. I suspect it is very similar to how Rust works but I did not dive into further details.
I believe Rust's approach to solving dependency hell is by far the best path forward⁴.
-
Implement a DMD switch for mangling and referencing symbols with an additional prefix
-mangle-prefix=path/to/common/package:v2
Relevant work for this milestone will be on mangle-prefix branch of my dmd fork.
How it works: With this switch the compiler will add "v2" as a prefix while mangling and referencing any symbols that originate frompath/to/common/package
. -
Implement a DMD switch for importing a source directory locally
-import-local=path/to/dependency/that/use/common;path/to/common/package
Relevant work for this milestone will be on import-local branch of my dmd fork.
How it works: With this switch the compiler will import files inpath/to/common/package
only for sources underpath/to/dependency/that/use/common
. It acts similar to-I=directory
except it only affects certain files to make importing multiple versions of the same package possible without clashing each other. -
Implement a Dub switch (and package config) that will make use of DMD's newly implemented features and also mention these new features in the dependency conflict error message.
--resolve=multi-verison
Relevant work for this milestone will be on multi-version branch of my dub fork.
How it works: In the first step Dub will compile common package by passing-mangle-prefix
to the compiler. After that it will pass both-mangle-prefix
and-import-local
when compiling dependency that use common. -
I'm not entirely sure what exactly I'll be doing but I have few things in my mind depending on how everything goes:
- Implementing a Dub feature that allow users to declare the exact semantic version multi-mapping in their project config.
- Extensive testing to see how these changes affect real world projects and packages.
- Proper documentation of all the newly implemented DMD & Dub features.
- Research on how to allow multiple library subconfigurations to co-exist.
- Continuing any unfinished work from previous milestones if something goes terribly wrong.
I will be maintaining a repository with example dependency hell scenarios and docs on how to test them.