Some Guy
Some Guy

Reputation: 13568

From a Ruby Gem, how can I get the path to an installer project's root directory?

Suppose I am developing a Ruby gem that will be installed in a project by being added to its Gemfile. From my gem, I want to know the directory path to the installer project's root. How can I get that?

Upvotes: 3

Views: 1683

Answers (2)

Nayeem Zen
Nayeem Zen

Reputation: 2767

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

Upvotes: 4

jrochkind
jrochkind

Reputation: 23317

If you're using Rails, use Rails.root.

If you don't know the 'main project' is Rails... there isn't neccesarily a great way to do it.

Global $0 is the command name that the ruby script was invoked with. But this won't neccesarily include a path. You can try File.expand_path $0, but there are a very many reasons that would cause this to not give you what you want, including the program may have changed it's "working directory". Dir.pwd will give you the "current working directory", which may be the directory of the "project" only if the project was invoked from the "project directory" and the code hasn't changed the current working directory.

In general, there's actually no build-in notion of a "project" or "project directory" in ruby -- you can have a ruby script that isn't really part of a project at all, it's just a file living wherever in the file system you want.

I don't think there's a general reliable way to do this, it depends on how "the project" was set up, which of course a gem can't be sure of.

But if you're using Rails, Rails.root, because Rails has conventions for how it's set up and invoked, and implements the feature Rails.root in it's startup processes to record the Rails 'project directory'.

Upvotes: 3

Related Questions