Programmatically determine gem's path using bu

2019-03-24 19:10发布

问题:

I know you can do

bundle show gem_name

to show the path of some gem.

How do you do that from within the code using the Bundler object?

回答1:

Have a look at how they do it in cli.rb

def locate_gem(name)
  spec = Bundler.load.specs.find{|s| s.name == name }
  raise GemNotFound, "Could not find gem '#{name}' in the current bundle." unless spec
  if spec.name == 'bundler'
    return File.expand_path('../../../', __FILE__)
  end
  spec.full_gem_path
end


回答2:

Update: starting with Bundler v1.3.0, there is a public interface for obtaining a Gem's path:

Bundler.rubygems.find_name('json').first.full_gem_path
# => "/opt/src/foo/my_app/vendor/bundle/ruby/2.0.0/gems/json-1.8.0"

Pre-v1.3.0, you may want to use the original solution shared (a private interface):

Better yet, you can use Bundler::CLI#locate_gem directly:

require "bundler/cli"
Bundler::CLI.new.send(:locate_gem, "json")
# => "/opt/src/foo/my_app/vendor/bundle/ruby/1.9.1/gems/json-1.7.3"


回答3:

It turns out you actually want to use Gem for this, not Bundler.

path = Gem.loaded_specs[NAME_OF_GEM].full_gem_path



回答4:

Yup, cli.rb is the best way to look at. However you anyway have to find a spec's name.

I can give you a starting point, but you have to come with some solution on how to optimize to your case:


    GemSearcher = Gem::GemPathSearcher.new
    Init = GemSearcher.init_gemspecs()
    GemSearcher.lib_dirs_for(Init[0])

Unfortunately this solution provides nameless search as all Gems are in an array instead of hash, but if you want you can hack GemPathSearcher, I think that would be useful in the future.



标签: ruby bundler