ian
ian

Reputation: 12251

Bundler: why does it read the gemspec on require "bundler/setup"?

The title is the question, and here's the context that prompts it.

The Gemfile:

source "http://rubygems.org"

# Specify your gem's dependencies in the gemspec
gemspec

Here is the top of the rackup file:

require 'rubygems'
require "bundler/setup"

On running the rackup file an error is thrown:

<module:Rack>': GemName is not a class (TypeError)

Why? Because I'm writing a piece of Rack middleware, and the standard layout is:

lib/
  rack/
    gem_name.rb
    gem_name/
      version.rb

gem_name.rb will contain:

module Rack
  class GemName

version.rb will contain:

module Rack
  module GemName
    VERSION = "0.0.1"

Finally, the gem_name.gemspec will contain:

require "rack/flash-in-the-pan/version"
#...
s.version     = Rack::GemName::VERSION

Naming a module and a class by the same name isn't a problem as long as you don't require both files at the same time. Normally, this wouldn't happen, as you either need the version for building the gem, or you need to run the gem library, only one or other gets required.

But, this time I decided to use Bundler to manage the gem's dependencies. When requiring the gem library via bundler it obviously runs the gemspec too. I can "fix" it easily enough, I define the version number by hand in the gemspec.

So back to my question - why does Bundler need to look in the gemspec at the library's runtime?

bundler (1.0.21)

Any insight is much appreciated.

Upvotes: 2

Views: 871

Answers (1)

Zachary Anker
Zachary Anker

Reputation: 4520

Whenever you run bundler, it has to parse the Gemfile to actually figure out what gems need to be loaded, what has to be added to $LOAD_PATH and so on. As part of that, it has to parse gemspec.

The Gemfile.lock contains info on all of the gems as well as the dependencies to save startup time, but it doesn't alleviate the need for it to parse the Gemfile.

There are various ways you could work around it. Two simple ones would be to use File.read and some regex to pull out the version. Or require the gem_name.rb and gem_name/version.rb files.

Upvotes: 3

Related Questions