Finding the Gem Root

Finding the gem root

Given the following project structure:

your_gem/
lib/
your_gem.rb

Here's how I would do it:

# your_gem.rb

module YourGem
def self.root
File.expand_path '../..', __FILE__
end
end

Ruby 2.0 introduced the Kernel#__dir__ method; it enables a considerably shorter solution:

# your_gem.rb

module YourGem
def self.root
File.dirname __dir__
end
end

If you need access to the other directories, you can simply build upon root:

module YourGem
def self.bin
File.join root, 'bin'
end

def self.lib
File.join root, 'lib'
end
end

Get Ruby project root path from a Gem

Check out this forum: https://www.ruby-forum.com/topic/143383
From my understanding of your question, you want to get the path of the project NOT the path of where the gem itself is located.

class MyGem

def self.get_working_dir
Dir.pwd
end

end

> MyGem.get_working_dir
> /Users/your_name/my_project_directory

This solution ended up helping out a Gem I had made where I had to iterate through a project's file tree.

From a Ruby Gem, how can I get the directory path to the project?

There is no perfect solution to this problem but you could create a fallback based solution that would work in most general cases. If Rails is defined, we use Rails.root. If Bundler is defined, we use the Bundler.root but it would only work when the Gemfile is defined at the project root (which is true in most cases). Else fallback to Dir.pwd

def project_root
if defined?(Rails)
return Rails.root
end

if defined?(Bundler)
return Bundler.root
end

Dir.pwd
end

How to find where gem files are installed

Use gem environment to find out about your gem environment:

RubyGems Environment:
- RUBYGEMS VERSION: 2.1.5
- RUBY VERSION: 2.0.0 (2013-06-27 patchlevel 247) [x86_64-darwin12.4.0]
- INSTALLATION DIRECTORY: /Users/ttm/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0
- RUBY EXECUTABLE: /Users/ttm/.rbenv/versions/2.0.0-p247/bin/ruby
- EXECUTABLE DIRECTORY: /Users/ttm/.rbenv/versions/2.0.0-p247/bin
- SPEC CACHE DIRECTORY: /Users/ttm/.gem/specs
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-darwin-12
- GEM PATHS:
- /Users/ttm/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0
- /Users/ttm/.gem/ruby/2.0.0
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :backtrace => false
- :bulk_threshold => 1000
- REMOTE SOURCES:
- https://rubygems.org/
- SHELL PATH:
- /Users/ttm/.rbenv/versions/2.0.0-p247/bin
- /Users/ttm/.rbenv/libexec
- /Users/ttm/.rbenv/plugins/ruby-build/bin
- /Users/ttm/perl5/perlbrew/bin
- /Users/ttm/perl5/perlbrew/perls/perl-5.18.1/bin
- /Users/ttm/.pyenv/shims
- /Users/ttm/.pyenv/bin
- /Users/ttm/.rbenv/shims
- /Users/ttm/.rbenv/bin
- /Users/ttm/bin
- /usr/local/mysql-5.6.12-osx10.7-x86_64/bin
- /Users/ttm/libsmi/bin
- /usr/local/bin
- /usr/bin
- /bin
- /usr/sbin
- /sbin
- /usr/local/bin

Notice the two sections for:

  • INSTALLATION DIRECTORY
  • GEM PATHS

How do I find the location of the gem?

You can always make use of the backtrace facility provided:

caller.first

It produces an amalgam of file and line but is usually separated by :. I'd be careful to allow for filenames or paths that may contain colon for whatever reason by ignoring the line information but preserving the rest. In other words, do not split but sub:

caller.first.sub(/:\d+:in .*$/, '')

Find root of project from included gem

Most modern gems don't look for a particular config file. Instead, they expect a config file of any name to be executed, which will set configurations via a .config variable on the gem's class name. For example, I might have this config file:

# config/initializers/ams.rb

ActiveModelSerializers.config.adapter = :json_api
ActiveModelSerializers.config.key_transform = :camel_lower

Now it doesn't matter where the file is located or what it's called. So long as the code is executed, ActiveModelSerializers can look at its own ActiveModelSerializers.config variable and it is good to go.

If you wanted an extensive configuration (by means of a .yml file, for example) you might create a .config.path setting and instruct users of your gem to set the path themselves and then create a file in the spot they choose:

# config/initializers/gem_b.rb

GemB.config.path = '/config/gem_b.yml'

How do I get the root directory of a Rails app in a Gem

The solution that I found to fix a similar problem to this is to include my module using the railtie initializers.

So, in your /lib/mygem/railtie.rb

module MyGem
class Railtie < Rails::Railtie
initializer "Include your code in the controller" do
ActiveSupport.on_load(:action_controller) do
include MyGem
end
end
end

With this code, your module will be included after the ActionController is loaded and you will be able to use Rails.root

Let me know if this works for you.



Related Topics



Leave a reply



Submit