rbenv and GeekTool

I like GeekTool. It’s really handy for having reminders on your desktop, whether those be calendar events, logs, or simply notifications as to whether tasks have completed or not.

There’s one problem with GeekTool, and that’s that it won’t run your .*rc or .*env files (e.g. .zshrc and .zshenv for me). Normally not so much a problem - I don’t really care if GeekTool doesn’t have the same prompt format as I usually would - but there is one place it’s annoying.

rbenv is my current ruby version manager. I migrated to it from rvm when I reinstalled Lion on this laptop a month or so ago, and so far it’s proved nicer and easier than rvm (no more gemsets to worry about). In fact, the only time I really notice it is when I cd into a rails project directory with its own .rbenv-version file, and I find that pry isn’t installed there.

Oh, and when GeekTool runs my scripts with ruby-1.8.7 and none of my gems are installed.

The solution to the problem (since there’s no .geektoolrc file yet) is to run the specific bit of init code before your command in GeekTool. In this case, that code would be:

1
eval "$(rbenv init -)"

The problem is that if I put this in the front of my GeekTool script, it tells me it has no idea where rbenv is. “No problem!”, I think to myself, “I know how to deal with this!”

1
2
3
4
5
6
7
8
9
10
11
12
>  which rbenv
rbenv () {
    command="$1" 
    if [ "$#" -gt 0 ]
    then
        shift
    fi
    case "$command" in
        (shell) eval `rbenv "sh-$command" "$@"` ;;
        (*) command rbenv "$command" "$@" ;;
    esac
}

…huh.

It turns out that running our eval script above actually overwrites rbenv with the above function, handily masking the original rbenv script. In hindsight, this is obvious, but it took me half an hour of frustratedly running the same script over and over to work out. And if I decide to re-run the init script, we can see it get set as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>  rbenv init -
export PATH="/Users/jan/.rbenv/shims:${PATH}"
source "/usr/local/Cellar/rbenv/0.3.0/libexec/../completions/rbenv.zsh"
rbenv rehash 2>/dev/null
rbenv() {
    command="$1"
    if [ "$#" -gt 0 ]; then
        shift
    fi

    case "$command" in
    shell)
        eval `rbenv "sh-$command" "$@"`;;
    *)
        command rbenv "$command" "$@";;
    esac
}

In the end I simply added a which rbenv line to my .zshenv file, which handily located the original rbenv file at /usr/local/bin/rbenv. Since GeekTool has a rather minimalist PATH, I guess it misses /usr/local/bin. The solution, then, is to make my GeekTool script something like the following:

1
PATH="/usr/local/bin:$PATH" && eval "$(rbenv init -)" && ruby -v

This will get you the ruby you want, completed with gems. The main drawback here is that you need to use that bit of script for every geeklet that requires more advanced ruby than basic math or a bit of YAML manipulation (or at least, that’s how it feels to me). Unless GeekTool has a super secret init file hiding somewhere in the file system, I don’t think there’s any way around that.