The Perfect Setup: Rails on Screen
25 Feb 2011
If, like me, you prefer staying light on your feet, you probably use a powerful text editor coupled with multiple shell sessions to drive your Rails development. Unfortunately, managing said shells can get a bit unwieldy, but thankfully UNIX-based systems have a tool just for the job: GNU Screen.
This post isn’t trying to sell you on screen
. There are umpteen sites out there which do that. Instead, I’d like to share with you how I’ve engineered my setup such that it’s a joy to use.
The Premise
Each Rails project I work on has the same basic needs. I want each of those needs facilitated by a screen
window, and I don’t want to manually bootstrap the environment each time I return to a project. The things I want in each Rails app (currently) are:
- TextMate
- Autotest
- Development server
- Development Console
- GitX
- A spare Bash session
Ideally, I would be able to cd
to my application’s root directory, execute a single command, and be up and running. But…
The Problem
There is no straight forward way (that I know of) to configure screen for multiple unrelated sessions. In other words, you can configure it to always do certain things when it is invoked, but you can’t configure it to sometimes do certain things when it is invoked. WANT.
My Solution
Good news! Passing the -c
flag to screen
specifies a configuration file to use. I leverage this feature to (sometimes) load in a custom, Rails-specific configuration. That plus a wrapper function does the job perfectly. Here’s how:
1) Create a custom screenrc just for rails
In it I put everything required to get the session all set up. Mine looks like this:
source $HOME/.screenrc
screen 0 bash
title "tests"
stuff "autotest\015"
screen 1 bash
title "server"
stuff "rails server\015"
screen 2 bash
title "console"
stuff "rails console\015"
screen 3 bash
stuff "gitx && mate .\015"
The first thing to note here is that this file will source my main .screenrc
file. That means I don’t have to repeat any of those settings. Gotta love that!
Next, notice that for each separate window I have 3 lines. The first line indicates which screen
window it will be in and starts a bash shell, the second line is obviously the title of the window, and the third line is the actual command to “stuff” into the window.
I could bypass the whole “stuff” thing by passing the command directly on the “screen” line instead of passing in “bash”, but that will exit the window when the process terminates, which is annoying.
Finally, I should explain the \015
at the end of each “stuff” line. That is telling screen
to enter a line feed (LF) character which will actually execute the command.
2) A screen wrapper function
Now that I have a custom config file, I make it super-simple to invoke screen
with it by adding this function to my .bashrc
file:
function screen() {
super=`which screen`
if [ "$1" == "rails" ]; then
$super -S `basename $PWD` -c $HOME/.screenrailsrc
else
$super $@
fi
}
This should be pretty self-explanatory. It calls screen
with the custom config if the first argument is “rails”, otherwise it punts.
One noteworthy tidbit is that it also sets the -S
flag to the name of the directory holding the Rails application. That way if the session ever gets detached I can reattach it with the project name instead of some obscure session id.
One Stone, Many Birds
I like this system a lot. What is really nice about it is that I can easily extend it to many different scenarios by creating new custom config files and adding matchers to the wrapper function.
Is that perfect or what?