简体   繁体   中英

Bundler.require doesn't require dependencies which are in the gemspec

I have an application using bundler which works fine at the moment but I have to run it out of the project's bin directory. Now I'm trying to convert it to a gem.

bin/myexecutable (no changes):

#!/usr/bin/env ruby
require 'mygem'
MyGem::MyExecutable.new.main(ARGV)

lib/mygem.rb (no changes):

require 'rubygems'
require 'bundler/setup'
Bundler.require

require 'mygem/version'
require 'mygem/my_executable'

mygem.gemspec (new):

# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'mygem/version'

Gem::Specification.new do |spec|
  # ... omitting boilerplate specs of gem ...

  spec.files         = `git ls-files`.split($/)
  spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
  spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
  spec.require_paths = ['lib']

  spec.add_development_dependency 'bundler', '~> 1.3'
  spec.add_development_dependency 'rake'

  spec.add_runtime_dependency 'bindata'
end

Gemfile (moved dependencies to mygem.gemspec):

source 'https://rubygems.org'
gemspec

When I install the gem and attempt to run the executable, I get:

.../resource_file.rb:2:in `<class:ResourceFile>': uninitialized constant ResourceFile::BinData (NameError)

Copying the dependencies back to Gemfile makes it work again, but now I have redundant declarations of the same dependencies in two locations.

Why doesn't it work when using the gemspec declaration?

You need to call require 'bindata' at the top of lib/mygem.rb .

In addition, I recommend removing these lines from mygem.rb :

require 'rubygems'
require 'bundler/setup'
Bundler.require

Bundler expects that gems require their own dependencies (so that they still work when you require them without Bundler, too). When you have gemspec in your Gemfile , Bundler.require directly requires your gem, but not any of its dependencies. Putting that into a gem will cause it to interact poorly with apps that already use Bundler, and creates a runtime dependency from your gem to Bundler (which is not declared in your gemspec).

This is intentional behavior. There is some discussion on these Bundler issues:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM