tzinfo-0.3.11 bundled with activesupport-2.1.2 is incomplete

Hi folks,

the tzinfo version packaged with rails 2.1.2 is incorrect and missing some files. If you compare the version stored in activesupport/lib/ active_support/vendor/tzinfo-0.3.11 with a fresh gem install of tzinfo-0.3.11, the activesupport-2.1.2 version is missing all the country_code files.

(rails/activesupport/lib at v2.1.2 · rails/rails · GitHub active_support/vendor/tzinfo-0.3.11/tzinfo) (still seems broken in master: http://github.com/rails/rails/tree/master/activesupport/lib/active_support/vendor/tzinfo-0.3.11/tzinfo)

This means that if the rails version is loaded up, calling   TZInfo::Country.get('US').zones

fails, while if the standard gem version is loaded, it works.

I was explicitly setting, in environment.rb config.gem "tzinfo", :version => '0.3.10'

but rails 2.1.2 sets 0.3.11, and because I didn't have that gem installed on my system, it loaded the broken one from activesupport-2.1.2.

The way to get all of this to work is to install the 0.3.11 gem and change my environment.rb file to require the 0.3.11 version, and then it loads up the full gem version and bypasses the bad rails 2.1.2 version. But this definitely doesn't seem like the correct behavior, starting with the bad vendorized tzinfo-0.3.11 gem in activesupport-2.1.2.

Thanks, Adam

Adam,

The bundled tzinfo is a slimmed-down version that only includes the classes and zone definitions necessary to support ActiveSupport::TimeZone. This chops ~2.8MB from the size of tzinfo, and hundreds of files, so it seems worth it.

But as far as trying to require a complete version of the gem that's older than the bundled version -- indeed, that wouldn't work. I agree it's confusing, given that you've declared the explicit version of tzinfo via config.gem.

Maybe we could be smarter about how we require bundled libraries in activesupport/lib/vendor.rb -- maybe add logic so that we don't clobber existing gem requirements?

Geoff

Why does it need to be bundled rather than be a normal gem dependency?

By bundling tzinfo, everything works out of the box -- if you freeze rails into vendor, you can then deploy anywhere, even on boxes that don't have rails or tzinfo installed.

Isn’t there a method of freezing not just rails, but all gems your project uses?

Seems to me that if you’re dealing with an uncooperative host, that’s the route you want to go – those of us with cooperative hosts would probably rather manage things with gems. Often, that’s unavoidable – rmagick, for example.

Certainly seems odd to be doing this in a support library.

Right, but why is tzinfo special? Because it is the only “non-rails” dependency for rails itself. Seems like the root cause of the problem is that rails freeze command is broken, because it does not freeze the entire dependency graph of rails, which includes tzinfo. Instead, the rails freeze command should freeze whatever version of the tzinfo gem is specified by the current version of activesupport. Then, you get all the benefits and no problems:

  1. Rails is not packaging a hacked version of tzinfo

  2. Since tzinfo is not bundled, you don’t need to use a hacked smaller version, you can just depend on the real gem

  3. People who want to manage tzinfo via gems using whatever version they want can do so (which is the original bug report here)

  4. People who want to freeze rails will automatically get the real, correct version of tzinfo frozen as well - and shouldn’t care if this is big, because people who freeze gems will have ginormous apps regardless…

– Chad

Please keep in mind, you *can* manage the full Tzinfo gem via config.gem -- the bug you identified only occurs when you try to require a version that's older than the bundled one.

Also, Tzinfo is not the only non-Rails dependency: see the vendor directories in ActionMailer, ActionController and ActiveSupport. Do you suggest that Rails unbundle TMail, Builder, XmlSimple, etc., and add them as dependencies to the rails gem?

I would, unless they have patches which haven’t made it upstream. And in that case, I’d break them out into rails-tmail, rails-builder, etc.

Assuming gem freezing works, what is the reason not to do that? If gem freezing is broken, why not fix it?

That’s a real question – there may be a good reason. I’m new here.

Also, Tzinfo is not the only non-Rails dependency: see the vendor directories in ActionMailer, ActionController and ActiveSupport. Do you suggest that Rails unbundle TMail, Builder, XmlSimple, etc., and add them as dependencies to the rails gem?

I would, unless they have patches which haven't made it upstream. And in that case, I'd break them out into rails-tmail, rails-builder, etc.

Assuming gem freezing works, what is the reason not to do that? If gem freezing is broken, why not fix it?

That's a real question -- there may be a good reason. I'm new here.

The bundled gems already favour installed gems if user's have them. The rationale for bundling them is that they're not a dependency to use *all* of rails, just a small piece of functionality (e.g. the memcache cache store).

There's no practical benefit to be gained by changing this policy, the new config.gems code will already provide information to people who make this same 'mistake' again.

Also, Tzinfo is not the only non-Rails dependency: see the vendor directories in ActionMailer, ActionController and ActiveSupport. Do you suggest that Rails unbundle TMail, Builder, XmlSimple, etc., and add them as dependencies to the rails gem?

I would, unless they have patches which haven't made it upstream. And in that case, I'd break them out into rails-tmail, rails-builder, etc.

Assuming gem freezing works, what is the reason not to do that? If gem freezing is broken, why not fix it?

That's a real question -- there may be a good reason. I'm new here.

The bundled gems already favour installed gems if user's have them. The rationale for bundling them is that they're not a dependency to use *all* of rails, just a small piece of functionality (e.g. the memcache cache store).

There's no practical benefit to be gained by changing this policy, the new config.gems code will already provide information to people who make this same 'mistake' again.

Good conversation!

Geoff, it sounds like there is not an easy solution except perhaps if you bundle a version like 0.3.11 but rails *requires* 0.3.9, use ~>0.3.9 for the config.gem version rather than always incrementing it to 0.3.11. But that could create additional issues like missing a dependency, etc.

If I'm the only one who was bit by this issue, then so be it. But if it keeps coming up, putting the full gem (with the extra 2.6 megs and hundreds of files; yes it is a beast!) into vendor/ doesn't seem to be all that bad, in this day and age of broadband :wink:

Thanks guys, Adam

It isn’t just the download bandwidth, it’s moving around and storing that extra 2.6 meg for every checkout, branch, deployment, release, and backup for every rails app, everywhere, forever, not to mention the few extra split-seconds on every full-project search. CPU, diskspace and bandwidth are cheap, but not infinite, and it adds up when you think of it that way. That’s why I prefer to freeze nothing :wink:

– Chad

If ActiveSupport required an older version than what was bundled, you'd run the risk of requiring an older version of the gem that happened to be installed on your system, even if you didn't explicitly declare it via config.gem.

I do think we should respect a version explicitly specified via config.gem, even if it's an older version than the bundled one (which we're not doing right now.) Or at least give feedback that we're not respecting the user's declared wishes. I don't know if this would even be possible -- we'd have to somehow introspect the gem requirements, I guess.

Fyi, Rails should be compatible with any tzinfo version in the 0.3.x series (and possibly the 0.2.x series, though I haven't tested this recently.) For the most part, the version upgrades are just changes to tzdata; there haven't been any changes to the api in 0.3.x that would affect compatibility.

Correction: for Ruby 1.9 compatibility, tzinfo >= 0.3.9 is required.

The caveat with this setup would be, the GMT offsets that appear in the time_zone_select could be out of sync with the tzinfo version you're using. Which would be kind of odd.

Maybe this is an argument for not allowing older versions of tzinfo to be used?

hey geoff,

If ActiveSupport required an older version than what was bundled, you'd run the risk of requiring an older version of the gem that happened to be installed on your system, even if you didn't explicitly declare it via config.gem.

that actually isn't true. I had tzinfo 0.3.10 installed using rails 2.1.1. that rails version shipped with tzinfo-0.3.9, but it correctly used my config.gem specification and used the 0.3.10 version. The issue arose because I migrated to rails 2.1.2, which came with a partially bundled tzinfo-0.3.11, used that version and ended up breaking my application (thankfully not in production; love those tests!).

Chad, I agree with your point about bundling, but at the risk of beating a dead horse, my vote would be to either bundle the full gem (instead of a partial one with broken dependencies) OR do not bundle and just have dependencies (like active-record does on a db-specific gem).

Adam

Adam and Chad -- curious to know if this setup would work for you:

I pulled together a version of tzinfo that has all the stuff (classes, definitions, indexes) that's *not* in the slimmed-down ActiveSupport version:

http://github.com/gbuesing/tzinfo_completer (works as a plugin: I tried to make a gem of it, but github won't let me use fileutils in the gemspec)

...seems to work, given my limited testing. With this setup, you can effectively have access to the full gem, and updates to the bundled version won't break it. Also slims down your app repository a bit, since you don't have to duplicate tzinfo files that are already bundled in AS.

I was just bikeshedding about the dubiousness of bundling a hacked version of a dependency gem in another gem, and adding code manage the resulting problems. I didn’t actually have a personal problem (with tzinfo). Thanks, though :slight_smile: