arches.io Environment Name in Console Prompt

21 Jan 2013

UPDATE: I made a gem! Just add gem "marco-polo" to your gemfile to see your app name and environment in your console prompt.

I hate when I have a bunch of consoles open and I don't know which one is local, which is staging, and which is production. I could potentially do a lot of damage by using the wrong one. I find myself typing Rails.env over and over, to figure out which environment I'm in. Super annoying! I want to have the app environment right there in my prompt so I always know for sure.

Many people have written about how to customize your IRB prompt. You set a bunch of hash values on IRB.conf, and then set the PROMPT_MODE to use them. It goes something like this:

IRB.conf[:PROMPT][:RAILS_ENV] = {
    :PROMPT_I => "my_app #{Rails.env}> ",
    :PROMPT_N => "my_app #{Rails.env}> ",
    :PROMPT_S => nil,
    :PROMPT_C => "?> ",
    :RETURN => "=> %s\n"
}

IRB.conf[:PROMPT_MODE] = :RAILS_ENV

Put that in ~/.irbrc and you're good to go. It even works in a rails console, down in your project's directory. Since IRB is running ruby, you can put ruby in that file and it'll be evaluated.

Where it doesn't work, unfortunately, is Heroku. Of course it doesn't, it's in your home directory! Well, let's check it in to our project root and push to Heroku.

$ heroku run console
irb(main):001:0> 

Damn. The normal prompt. Our .irbrc isn't being run. Luckily our rails app gives us some hooks into the IRB boot process. Adding a new argument to the command that's being used to start the console will allow us to load the irbrc automatically. The "-r" is for "require" and File.join(Rails.root, ".irbrc.rb") references our config file. You'll need to change "MyAppName" to the actual name of your app.

module MyAppName
  class Application < Rails::Application
    def load_console(app=self)
      super
      ARGV.push "-r", File.join(Rails.root, ".irbrc.rb")
    end
  end
end

And here's my actual .irbrc.rb file. The colors haven't been working for me on Heroku but I left 'em in for reference.

if ENV['RAILS_ENV']
  rails_env = ENV['RAILS_ENV'].downcase
elsif Rails and Rails.env
  rails_env = Rails.env.downcase
end

if rails_env
  current_app = Dir.pwd.split('/').last

  black = "\033[0;30m"
  red = "\033[0;31m"
  green = "\033[0;32m"
  yellow = "\033[0;33m"
  blue = "\033[0;34m"
  purple = "\033[0;35m"
  cyan = "\033[0;36m"
  reset = "\033[0;0m"

  environment_color = case rails_env
                        when 'development'
                          green
                        when 'staging'
                          yellow
                        when 'production'
                          red
                        else
                          red
                      end

  rails_env = {'development' => 'dev', 'staging' => 'staging', 'production' => 'prod'}.fetch(rails_env) { 'unknown' }

  IRB.conf[:PROMPT][:RAILS_ENV] = {
      :PROMPT_I => "#{current_app}(#{rails_env})> ",
      :PROMPT_N => "#{current_app}(#{rails_env})> ",
      :PROMPT_S => nil,
      :PROMPT_C => "?> ",
      :RETURN => "=> %s\n"
  }

  IRB.conf[:PROMPT_MODE] = :RAILS_ENV
end