We've all been there. Your project has been overwhelmed by the complex web of its software dependencies to the point of stoppage. Developers spend more time fixing these issues than writing code most of the time.
Welcome to Dependency Hell; I'll be your Virgil.
The First Circle: Limbo. Are my dependencies even correct?
Someone committed updated packages without updating a manifest like package.json.
The Second Circle: Lust. Updating a new package and breaking something else.
We all want the new function, the latest version of the library. We need it. Now we broke something else.
The Third Circle: Gluttony. Old and/or unnecessary dependencies checked in.
One more dependency won't hurt. It doesn't matter when it's finally removed because it made the git repo 2GB larger forever.
The Fourth Circle: Greed. Multiple package managers.
Your data scientist loves to use anaconda, so now there's a conda configuration file checked in alongside the pip requirements.txt. Two's company.
The Fifth Circle: Wrath. The package you need isn't in your package manager.
Now that you think about it, you're using Ubuntu Trusty Tahr. So, where are the package owner gremlins?
The Sixth Circle: Heresy. Monkey patching a dependency.
Why won't this open-source project take my specific and untested patch? Guess I'll just monkey patch it.
The Seventh Circle: Violence. Breaking changes on a minor or patch version.
In practice, it's major.minor.patch. In reality, it doesnt.mean.anything.
The Eighth Circle: Fraud. Circular dependencies.
Library A depends on a specific version of B, but B can't run without depending on a specific version of A.
The Ninth Circle: Treachery. The Diamond Dependency Problem.
Library A depends on libraries B and C, and both B and C depend on D – but B requires D version 1, and C requires D version 2.