3 ms·
Oh and this. 3. It inherently excludes some valid compatibility cases, unless the developer is forced to hack around the package manager Suppose 'foo' depends
by FooBarWidget 16y ago
Oh and this.
3. It inherently excludes some valid compatibility cases, unless the developer is forced to hack around the package manager
Suppose 'foo' depends on 'bar'. bar consists of features A, B and C. Furthermore bar has made the guarantee that it will never break the compatibility of feature 'A', ever. It also has a compatibility policy that states it will increment its major version number every time it breaks B and C.
foo only uses feature A in bar, so we know that foo is compatible with every version bar that will ever be released.
foo also depends on 'libcat'. libcat depends on bar, but uses all its features. The current release of bar is 1.0.0, so we know libcat depends on 1.0.0 <= bar < 2.0.0.
Suppose that 'frobnicator' depends on bar. It uses feature B and it uses the interface provided by bar 2.x.
This seems like a completely reasonable case. Developers aren't being lazy about compatibility guarantees here. The only way to solve this problem is by versioning bar on the filesystem level. That is, while bar 1.x requires developer to type
require 'bar/feature_a'
require 'bar/feature_b'
bar 2.x requires the developer to type
require 'bar-2/feature_a'
require 'bar-2/feature_b'
You have to rename the entire library directory. In my opinion this is an ugly hack around the fact that your package manager doesn't support multiple versions. I think this is solved much more elegantly if the package manager allows you to switch the version on-the-fly... in other words, what RubyGems does.
- regularfry 16y agoThis is one case that rubygems handles well, but I think your specific example is broken. If libcat requires 1.0.0 <= bar < 2.0.0, foo requires libcat, foo requires 2.0.0 < bar, you've got conflicting requirements - foo requires both bar < 2.0.0 and 2.0.0 < bar. Rubygems will barf at that. > You have to rename the entire library directory. In my opinion this is an ugly hack around the fact that your package manager doesn't support multiple versions. I think this is solved much more elegantly if the package manager allows you to switch the version on-the-fly... in other words, what RubyGems does. It may be an ugly hack, but it's fairly traditional at this point.
- FooBarWidget 16y ago> Rubygems will barf at that. Only if you activate gems linearly. Bundler solves exactly this: it looks at all dependencies then figures out a combination that works. Bundler will only activate bar 1.x because it sees that foo is compatible with all versions but libcat is only compatible with 1.x. > It may be an ugly hack, but it's fairly traditional at this point. I argue against the notion that being traditional here equals being good. There's no good reason why the developer should do this manually instead of having some system do it for him. RubyGems actually implicitly does this. By installing each gem to its own directory it separates the versions on the filesystem level.
- regularfry 16y ago> Only if you activate gems linearly. Bundler solves exactly this: it looks at all dependencies then figures out a combination that works. Bundler will only activate bar 1.x because it sees that foo is compatible with all versions but libcat is only compatible with 1.x. You're absolutely right, I misread your example. > I argue against the notion that being traditional here equals being good. There's no good reason why the developer should do this manually instead of having some system do it for him. It's a trade-off. Either the developer has to do it manually (once, which will then work with every sane distro), or the sysadmin has extra work to do (many times, once for each language-specific package manager). In an ideal world, the language communities would gang up on Debian and Red Hat and improve dpkg and rpm to make this issue go away. I don't see this happening.