Search code examples
ruby-on-railsshellrakerails-console

Command to know Rails project root from shell script


Is there any obvious command (be it a rails command, rake command, or other) that I can use to get the path to the root of a rails project from within a shell script?

Context:

I'm writing a shell script. I'm going to execute that script from an arbitrary directory inside a rails project, and the script needs to determine the absolute path of the rails project root.

So, for example, if the script were

#!/bin/bash
rails_root=# get the root somehow...

and given that the root directory of my project is

/home/myuser/projects/myrailsapp

then I should be able to place that script in

/home/myuser/projects/myrailsapp/scripts/myscript

and call it from elsewhere in the project

cd /home/myuser/projects/myrailsapp/app/assets
../../scripts/myscript

and the script should be able to know the path of the root directory.

I've come up with two different ways of solving this problem:

#!/bin/bash
rails_root=$(rake about | grep 'Application root' | sed 's/Application root[ ]*//')
#!/bin/bash
rails_root=$(rails c <<-EORUBY | grep ^rails_root_is | sed 's/rails_root_is//' 
  puts "rails_root_is#{Rails.root}" 
EORUBY
)

But I feel like there should be a more obvious way to do this. I was expecting to use an existing command.


Solution

  • Instead of a shell script you can use rake. Besides the simplicity of dealing with a high level language you also have full access to the rails environment and you don't have to deal with all the pitfalls and issues when dealing with shell scripts which should work across platforms and shells.

    To generate a rake task from rails:

    rails g task foo dosomething
    

    Which would generate an a rakefile in lib/tasks/foo.rake. From the rake task you can access the Rails root directory though Rails.root.

    namespace :foo do
      desc "TODO"
      task dosomething: :environment do
        puts "Rails root is: #{ Rails.root }"
        puts "Current working directory is: #{ Dir.pwd }"
        # You can invoke the shell with backticks, exec or ...
        puts "You are: " + `whoami`
      end
    end
    

    A few good resources: