solnic / virtus

[DISCONTINUED ] Attributes on Steroids for Plain Old Ruby Objects
MIT License
3.77k stars 229 forks source link

Updated dependencies #148

Closed dwbutler closed 11 years ago

dwbutler commented 11 years ago

I noticed that Virtus has backports locked at ~> 2.6.1. However, the latest version of Backports is 2.7.1.

I set out to update the backports dependency and run the specs, but it turns out I couldn't even bundle in a fresh clone without updating several other dependencies.

I've tested with updated dependencies, and rake spec, rake ci, and rake ci:metrics all run fine.

dwbutler commented 11 years ago

The problem with gem 'backports', '~> 2.7' is that you are saying "This library will only work with Backports 2.7.x or greater", and enforcing it. If someone is stuck on Backports 2.6 for whatever reason, they won't be able to bundle Virtus.

I would suggest one of the following:

solnic commented 11 years ago

I'm not sure if backports follow semver but If it does then it's safe to use the latest version in Virtus (I usually want to use the latest versions of all the deps).

@dkubb wdyt? you've been using backports longer than me.

dkubb commented 11 years ago

backports does seem to follow semver. It also is updated fairly frequently at times.

When I specify gem dependencies using ~>, usually what I mean is "I have tested this gem with versions 1.1.1, and it should work with 1.1.x". I would use the latest stable at that point in time. Many of the gems I maintain already have a huge matrix, so I can't test with anything other than the latest stable version.

I would say though that I think specifying >= by itself is almost always wrong. When you say ">= 2" you're saying that version 2, every minor/patch version, and all versions above (so 3, 4, 5, 6, etc) are going to work with your gem. You can't know that. I noticed we used that in this PR and I wanted to comment on it.

A better approach if you want to be somewhat permissive would be to combine two operators to narrow things down. you could specify something like:

gem 'backports', '~> 2.8', '>= 2.8.2'

This will allow you to install backports 2.8.2, 2.8.3, 2.9.0, 2.10.0, etc.. but not 3.0. It will also not let you use it with 2.8.1 or something below. For something like backports, which seems to be rapidly improving and following semver, I think this is a good approach to minimize conflicts.

I would still tend to bump things to the latest stable versions I test with though. The above approach works well when new versions of backports are released faster than new virtus versions.

dwbutler commented 11 years ago

Interesting perspectives!

IMO, since Virtus was tested to work fine under Backports 2.6.x and 2.7.x, it shouldn't hurt to do something like the following:

gem 'backports', '>= 2.6', '< 2.8'

This way, you are stating that Virtus has been verified to work in 2.6 and 2.7, and you are not forced to upgrade to Backports 2.7 in order to use Virtus. This also future proofs you against future minor (but possibly breaking) Backports releases.

It certainly isn't feasible to test against every single version of every dependency ever made from now until eternity. =) That would never be possible no matter how you specify your dependencies. But I think it's fair to at least give library consumers a choice about when to upgrade sub-dependencies, when possible.

I'm kind of a stickler about this, because I sometimes find that new releases don't work in my app, even though they work fine in other apps or libraries. So I cannot upgrade until the bug in that new release is fixed.

The only time I would do '~> 2.7' or >= 2.7 is when I'm using a feature that only works in 2.7+. In this case, forcing an upgrade of Backports is entirely appropriate.

dkubb commented 11 years ago

@dwbutler It's one thing to say virtus was tested with backports at 2.6 at some point in time, but it's another thing to say this exact code was tested with 2.6. I only like to make assertions that I have actually verified.

I realize that backports is a "stand-in" for this discussion and we're talking about gem dependency specifications in general.

In the event of a bug in backports that prevents some people from upgrading I would fully support setting an exact version specifier until the issue is resolved. In those situations all I need is feedback and I'm happy to hold things back. In my own Gemfile if I see = 1.2.3 it means that I have explicitly set the version because 1.2.4 (or whatever the next bump is) has a bug that is preventing a clean upgrade. Sometimes I'll comment with a link to the ticket beside this, then I check in with it periodically. If the bug is fixed in 1.2.5, I would then change it to ~> 1.2.5.

dwbutler commented 11 years ago

@dkubb, you do make some good points. I think ultimately it comes down to one's level of comfort and trust in the stability of the dependencies in question. It's totally your call of course.

Incidentally, Backports is now at 2.8. =) They sure move fast!

So this issue could cut both ways. If I wanted to start playing with the latest and greatest features in Backports 2.8, I wouldn't even be able to bundle it into my app, because Virtus 0.5.4 will refuse to use anything other than Backports 2.6. And you may not be ready to release a new version to just to update the dependencies.

dkubb commented 11 years ago

Yeah, this stuff is hard. There's no right way, and no way that would work for everyone. My personal preference is always to use the latest stable gems with everything, and barring bugs, I almost always stay up-to-date when I can.

That reminds me, I need to bump my gems ;) fwiw, backports usually isn't this fast. It's only because the ruby 2.0 release is coming out soon that it's moving quickly. Once 2.0 is out I expect it to settle down.

mbj commented 11 years ago

@dwbutler For those scenarios I just fork the lib, bump dependency, run specs and use git source while doing a PR to upstream. A never ending process ;)