polishing ruby by ryan davis

Oh My Gems!

Published 2012-09-21 @ 12:00

I’m tired of the complications that tools like bundler and rvm inject into my system and my workflow. I don’t want 4 billion gems installed globally. I don’t want to have rake slow down for no good reason. I don’t want rvm to regress on undefined variables over and over and over (and I don’t want to report it anymore when it does). I want as much simplicity as I can afford and still be able to get my job done.

I’ve found pretty good balance using rbenv (only when needed) and by using this 40 line shell function ohmygems (aliased to omg, of course):

export ORIG_GEM_PATH=${GEM_PATH:-}
export ORIG_GEM_HOME=${GEM_HOME:-}
export ORIG_PATH=${PATH}

ohmygems() {
    name=${1:-}

    if [ -z "$name" ]; then
        echo "usage: ohmygems <name or reset>"
        echo
        echo "  Switches gem home to a (potentially new) named repo."
        echo "  Your previous gems are still visible,"
        echo "  but new gem installs will install into ~/.gems/repos/<name>."
        echo "  Use 'reset' to go back to normal."
        echo
        echo "Available repos:"
        echo
        ls ~/.gem/repos | pr -o2 -l1
        echo
        return
    elif [ $name = "reset" ]; then
        echo Resetting repo

        if [ -z "$ORIG_GEM_HOME" ]; then
            unset GEM_HOME
        else
            GEM_HOME=${ORIG_GEM_HOME}
        fi

        GEM_PATH=${ORIG_GEM_PATH}
        PATH=$ORIG_PATH
    else
        echo Switching to $name

        export GEM_HOME=~/.gem/repos/${name}
        export GEM_PATH=${ORIG_GEM_HOME}:${ORIG_GEM_PATH}
        export PATH=${ORIG_PATH}:${GEM_HOME}/bin
    fi

    echo
    echo GEM_PATH=${GEM_PATH:-not set}
    echo GEM_HOME=${GEM_HOME:-not set}
    echo PATH=$PATH
}

alias omg=ohmygems

Now I can work on a work project without problems:

% cd newproject
% omg newproject
% gem i bundler
% bundle

I still have my system-level gems as my previous GEM_HOME gets moved into GEM_PATH so things like minitest and autotest are always available. But now I have private gems that are incredibly easy to switch around and only rely on simple environment variables to manage.

To go back to normal, simply run omg reset.

If you want to play with this, try out:

curl https://raw.github.com/gist/3661136/ohmygems.sh > ~/.ohmygems
echo ". ~/.ohmygems" >> ~/.bashrc