# Draft - On Package Managers and Dist. of Artifacts
## Dependency hell Scenarios
> The following are some of the most common “dependency hell” scenarios:
**Inappropriate Versioning** - A package may specify an inappropriate version for a release. For example, a version is tagged 1.2.3, but introduces extensive, breaking API changes that should be reflected by a major version bump to 2.0.0.
**Incompatible Major Version Requirements** - A package may have dependencies with incompatible version requirements for the same package. For example, if Foo depends on Baz at version ~>1.0 and Bar depends on Baz at version ~>2.0, then there is no one version of Baz that can satisfy both requirements. This situation often arises when a dependency shared by many packages updates to a new major version, and it takes a long time for all of those packages to update their dependency.
**Incompatible Minor or Update Version Requirements** - A package may have dependencies that are specified too strictly, such that version requirements are incompatible for different minor or update versions. For example, if Foo depends on Baz at version ==2.0.1 and Bar depends on Baz at version ==2.0.2, once again, there is no one version of Baz that can satisfy both requirements. This is often the result of a regression introduced in a patch release of a dependency, which causes a package to lock that dependency to a particular version.
**Namespace Collision** - A package may have two or more dependencies that have the same name. For example, a Person package depends on an Addressable package that defines a protocol for assigning a mailing address to a person, as well as an Addressable package that defines a protocol for speaking formally to another person.
**Broken Software** - A package may have a dependency with an outstanding bug that is impacting usability, security, or performance. This may simply be a matter of timeliness on the part of the package maintainers, or a disagreement about their expectations for the package.
**Global State Conflict** - A package may have two or more dependencies that presume to have exclusive access to the same global state. For example, one package may not be able to accommodate another package writing to a particular file path while reading from that same file path.
**Package Becomes Unavailable** - A package may have a dependency on a package that becomes unavailable. This may be caused by the source URL becoming inaccessible, or maintainers deleting a published version.
## List of Package Managers
- `alcatraz`: [Cocoa Packages](http://alcatraz.io/).
- `apt-get`: [Ubuntu Packages](https://apps.ubuntu.com).
- `brew`: [Homebrew Forumale/Cask](http://brew.sh).
- `chef`: [Chef Cookbooks](https://supermarket.chef.io).
- `cocoa`: CocoaDocs.
- `composer`: PHP [Composer Packages](https://packagist.org).
- `cordova`: [Apache Cordova plugins](https://cordova.apache.org/plugins/).
- `docker`: [Docker Images](http://registry.hub.docker.io).
- `definitelytyped`: DefinitelyTyped [TypeScript Definitions](http://definitelytyped.org).
- `gems`: [Ruby Gems](http://rubygems.org).
- `gradle`: Java [Gradle Packages](http://www.gradle.org).
- `grunt`: Node.js task-runner [Grunt Plugins](http://gruntjs.com).
- `gulp`: Node.js task-runner [Gulp Plugins](http://gulpjs.com).
- `hackage`: Haskell [package archive](https://hackage.haskell.org).
- `hex`: Elixir [Hex Packages](http://hex.pm).
- `maven`: Java [Maven Libraries](http://mvnrepository.com).
- `metacran`: [R Packages](https://www.r-pkg.org/).
- `npm`: Node.js [NPM Packages](https://www.npmjs.org).
- `nuget`: .Net [NuGet Packages](http://nuget.org).
- `pear`: PHP [Pear Packages](http://pear.php.net).
- `puppet`: [Puppet Modules](https://forge.puppetlabs.com).
- `pypi`: [Python Packages](https://pypi.python.org).
- `raspbian`: [Rasberry Pi Packages](http://www.raspbian.org).
- `rpm`: [Red Hat Linux Packages](http://rpmfind.net).
- `snap`: [Snapcraft Packages](https://snapcraft.io).
- `st`: [Sublime Text Packages](https://packagecontrol.io).
- `yarn`: [Yarn Packages](https://yarnpkg.com/lang/en/).
- `yo`: [Yeoman Generators](http://yeoman.io).
- `zsh`: [Zsh Plugins](http://zsh.sourceforge.net/Doc/Release/External-Modules.html).
- `distributions` will be an `Array` of objects defining conditions where a different package will be refieid & linked as the original target
* Place _all_ distribution targets as optional<sup>(or peer?)</sup> of the `foo` package
* Any that cannot be placed are not placed (eg, package not found, cannot be placed for conflicting peer deps, etc.), similar to `optionalDependencies`
* Record status of `idealTree` placed distributions of the main "foo" package, along with their selection criteria
- the `idealTree` **should not** be platform-specific
* Choose one distribution of the main package, and reify that
* **Do not** reify the others, or any of their dependencies (unless they are required to meet another dependency in the tree)
* Reify the main package as a `Link` to the chosen distribution
### For Publisher's:
* Publish the main package with the source, pointing to distribution package specifiers and selection criteria
* Publish pre-built distributions as needed
This is amenable to publishing distributions post-hoc as a CI build. If any fail to build and publish, no matter, they will simply fail to install, and fall back to the main package.