Fernando Luizão

Desenvolvimento de software e nerdices em geral

Organizando seus projetos Ruby com RVM

with 19 comments

O RVM (Ruby Version Manager) é uma ótima ferramenta para gerenciar versões de ruby diferentes, mantendo todas as versões instaladas dentro do seu home, sem necessidade de uma conta de superusuário. Além de permitir instalar e usar várias versões, ele tem outros recursos interessantes que podem ser usados para manter organização entre projetos com gems diferentes. Vou explicar como eu costumo trabalhar, meu workflow básico e também algumas dicas de uso do RVM. Se você nunca ouviu falar nele, recomendo uma visita ao site do projeto.

Instalando

Para instalar o RVM é necessário o curl, git e bash (nunca testei em outros shell’s), e você também
vai precisar de ferramentas de desenvolvimento para compilar os rubis (gcc, make, etc). Depois de instalar as dependências, instale o RVM com o comando:

bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )

Depois de instalado, edite (ou crie) seu ~/.bashrc e adicione o seguinte ao fim dele:

if [[ -s ~/.rvm/scripts/rvm ]]
then
    source ~/.rvm/scripts/rvm
    source ~/.rvm/scripts/completion
    rvm reload
fi

Com isso o RVM será carregado e também será possível completar comandos do RVM usando o TAB. Agora regarregue seu bashrc:

source ~/.bashrc

Pronto, já podemos instalar nossos rubies, porém, antes de instalar qualquer coisa quero explicar o conceito de gemset do RVM. Gemsets permitem manter conjuntos de gems separados, dentro de uma mesma versão de Ruby. Quando você está usando um gemset, tem acesso apenas às gems instaladas nele, em um ambiente isolado. (isso é muito bom para evitar conflitos de versões de gems entre projetos diferentes). Sempre que uma versão do Ruby é instalada o RVM cria automaticamente dois gemsets, default e global. O gemset default é usado sempre que não for especificado qual gemset deseja-se utilizar. O gemset global é compartilhado entre todos os gemsets, ou seja, todas as gems instaladas no gemset global são visíveis nos outros gemsets da versão. Ao instalar uma versão de Ruby, o RVM verifica nos arquivos ~/.rvm/gemsets/global.gems e ~/.rvm/gemsets/default.gems quais gems devem ser instaladas nos respectivos gemsets, junto com o interpretador. Eu altero o arquivo ~/.rvm/gemsets/global.gems e adiciono as seguintes gems:


rake
bundler
pg
sqlite3-ruby
mysql
rspec

Assim, sempre que eu instalar um novo Ruby essas gems também serão instaladas automaticamente no gemset global, me poupando algum tempo :). Se você não quiser fazer isso não precisa, é só um truque que eu uso para agilizar um pouco ;).

Agora podemos instalar nossos rubis. Para ver uma lista dos rubies que podem ser instalados, digite:

rvm list known

Instalar uma versão do Ruby é simples:

rvm install versao # ou versões separadas por vírgula

Eu instalo os seguintes:

rvm install 1.8.6,1.8.7,1.9.1,1.9.2,ree

O RVM vai baixar e compilar as versões selecionadas. Para usar alguma versão:

rvm use 1.9.1
# ou
rvm 1.9.1

Conferindo a versão do ruby:

ruby -v

Recomendo que vc escolha alguma versão como a default, eu deixo a 1.8.7 como default:

rvm 1.8.7 --default

Sempre que você abrir um novo shell a versão default já será usada. Se vc estiver usando outra versão e
quiser mudar para a versão default é só usar

rvm use default

Para ver qual é o ruby default:

rvm list default

Para listar todas versões instaladas:

rvm list

Para ver informações sobre uma versão (paths, variáveis de ambiente):

rvm info versao

Para remover totalmente uma versão:

rvm remove versao --gems --archive

Trabalhando com gemsets

Como dito anteriormente, gemsets permitem isolar gems dentro de uma mesma versão. Para criar um gemset:

rvm gemset create nome_gemset

Usando um gemset:

rvm gemset nome_gemset
# ou
rvm gemset versao@nome_gemset

Para criar um gemset e já usá-lo:

rvm --create use versao@nome_gemset

Todas as gems que você instalar quando estiver usando o gemset ficarão confinadas a ele.
Na listagem de gems aparecerão apenas as gems do gemset e as do gemset global.
Se vc quiser instalar uma nova gem ao gemset global, use:

rvm gemset use global
gem install nome_da_gem

Para ver qual gemset está sendo usado:

rvm gemset name

Listando todos os gemsets disponíveis para a versão:

rvm gemset list

Apagando um gemset e as gems contidas nele (–force serve para não pedir confirmação):

rvm --force gemset delete nome_gemset

Como manter gems separadas por projeto

Sempre que vc muda para um diretório (cd diretorio), o RVM verifica se existe um .rvmrc dentro dele.
Esse arquivo é um shell script que pode conter qualquer código necessário para inicializar o ambiente do projeto. Por exemplo, se vc quiser que um gemset xuxu seja carregado com a versão default sempre que você entrar no diretório do projeto, bastaria criar um .rvmrc com o conteúdo:

rvm default@xuxu

Com isso em mente, padronizei o setup dos meus projetos para:

mkdir nome_projeto
cd nome_projeto
rvm --create --rvmrc use default@nome_projeto

O último comando vai criar um gemset para o projeto, e também o .rvmrc para carregar o gemset correto.
Como eu também estou usando o bundler, eu crio um Gemfile, listando as dependências do projeto, (mesmo em projetos antigos, com Rails 1.2.6). Depois é só instalá-las com:

bundle install

Assim, tenho um ambiente de gems isolado para cada projeto, e o melhor, toda vez que eu mudar para o diretório de um projeto, o RVM já vai carregar o gemset correto com base no .rvmrc!

Rodando seus testes com RVM

Uma das coisas mais úteis do RVM é facilitar a execução testes em várias versões de Ruby diferentes. Por exemplo, para rodar sua suíte de testes em todas as versões de ruby instaladas:

# no caso de Rspec
rvm specs
# caso use Test::Unit
rvm tests

Também dá pra limitar a apenas algumas versões

rvm 1.8.6,1.8.7,1.9.1 specs

Se for necessário carregar um gemset específico para o projeto, pode ser feito da seguinte maneira

rvm 1.8.7@nome_gemset,1.9.1@nome_gemset specs

Finalizando

O RVM mudou muito meu jeito de trabalhar, essa é a forma que eu atualmente uso para manter meus projetos. Não quer dizer que é a melhor maneira, ou que você deve fazer da mesma forma. Esse post serve mais para dar uma idéia das possibilidades de uso do RVM, e servir como uma referência pra mim mesmo, pra consolidar meu workflow :). Se alguém quiser compartilhar outras dicas para organização de projetos sinta-se livre!

Referências:

http://rvm.beginrescueend.com/
http://bcardarella.com/post/699582642/rvm-gemsets-bundler-awesome

Advertisements

Written by fernandoluizao

August 26, 2010 at 12:34 am

Posted in Ruby, Shell Script

Tagged with , ,

19 Responses

Subscribe to comments with RSS.

  1. Legal o post cara 🙂

    Eu encontrei um tutorial pra quem precisar integrar RVM (usando gemsets separados) com Passenger: http://blog.inbatu.com/2010/05/29/isolated-gem-sets-under-passenger/

    =]

    Lucas Catón

    August 31, 2010 at 2:07 pm

    • Valeu Lucas :).

      fernandoluizao

      September 1, 2010 at 11:33 pm

  2. Post super legal Luizão!

    Esses dias mesmo tomei um couro do RVM e pra manter minha cabeça DRY dei um implode nele 😛

    Futuramente quando as coisas começarem à quebrar no ruby 1.8.7 + rails 3 vou aplicar seu post e aprender essa ferramenta legal.

    fabianosoriani

    September 22, 2010 at 6:57 pm

    • Fala Fabiano!

      No começo eu também penei pra pegar o jeito, mas depois de usar bastante e entender como o RVM funciona, não vivo mais sem ele :). Se precisar de uma ajuda tamos aí.

      []’s

      fernandoluizao

      September 25, 2010 at 12:19 am

  3. Ótimo post, tirou todas as minhas dúvidas sobre RVM

    Gilderlan Braz

    November 4, 2010 at 4:49 pm

  4. muito bom fernando parabens

    abraco

    Mairon Brasil

    November 11, 2010 at 12:34 am

    • Valeu Mairon!

      Abraço

      fernandoluizao

      November 11, 2010 at 2:38 pm

  5. Muito bom o post.
    Mas tenho uma dúvida, eu utilizo o Netbeans com suite de desenvolvimento, quando vc diz que posso navegar por projetos diferentes e a RVM se encarrega de configurar meu ambiente, isso é não serviria para o meu caso que uso Netbeans ou estou errado?

    Arthur

    December 2, 2010 at 7:00 pm

    • Arthur, não uso o Netbeans, mas encontrei esse artigo explicando como detectar as versões do Ruby instaladas pelo RVM. No caso dos gemsets por projeto, acho que não funcionaria. Até onde sei, o rvm só carrega os gemsets no terminal, quando vc usa “cd meu_projeto”.

      fernandoluizao

      December 3, 2010 at 4:09 pm

  6. Fernando, seu post está muito didático. Parabéns!

    Sou um iniciante na área e estou com uma dúvida:
    – como você faz para padronizar o setup dos seus projetos, de modo que ao serem criados já executem os comandos que você listou acima ?

    Grato pela atenção.

    Ricardo

    December 19, 2010 at 2:36 pm

    • Ricardo,

      Na verdade eu executo os comandos manualmente, porque a criação dos projetos pode variar, pode ser uma aplicação Rails, uma gem, ou mesmo um script simples em Ruby.

      Mas é possível criar uma funções em Bash (ou o shell que vc use) para automatizar isso. Por exemplo:

      new_rb_proj() {
           mkdir $1 && cd $1
           rvm --create --rvmrc use default@$( basename $1 )
      }
      

      Para usar:

      new_rb_proj nome_do_projeto
      

      É só uma idéia 😉

      fernandoluizao

      December 23, 2010 at 10:57 pm

      • Ok, Fernando, muito obrigado. Valeu mesmo pela dica.

        Ricardo

        January 3, 2011 at 2:27 pm

  7. Fernando, me desculpa por te encher de perguntas, cara, mas é que você se mostrou tão solícito e eu estou mesmo interessado em usar o rvm, conhecendo-o um pouco mais.

    Aconteceu o seguinte: eu já tinha instalado um projeto chamado circuito_esportivo feito em Rails 3, mas usando ruby 1.8.7. Tudo rodando beleza.

    Então quis atualizá-lo para Ruby 1.9.2.

    Para o Ruby 1.9.2 eu ainda não havia criado nenhum gemset. Então selecionei a gemset global e instalei várias gems que pretendo usar nos projetos com Rails 3: o próprio Rails 3, will_paginate, devise, e outras.

    Até aí tudo bem. Criei então a gemset circuito_esportivo (ela já existia apenas para o Ruby 1.8.7).

    $ rvm use 1.9.2
    $ rvm gemset create circuito_esportivo
    $ rvm gemset use circuito_esportivo
    $ rvm-prompt

    Fiz o seguinte:

    a) entrei na raiz do projeto e no .rvmrc alterei a linha “rvm use 1.8.7@circuito_esportivo” para “rvm use 1.9.2@circuito_esportivo”.

    b) saí da pasta e entrei novamente e me certifiquei de que estava usando a versão 1.9.2 e a gemset recem-criada circuito_esportivo, com o comando rvm-prompt.

    c) dei o comando: bundle install. Para a minha surpresa, isso provocou a instalação de várias gems que já estavam instaladas na gemset GLOBAL.

    Por que tudo foi instalado de novo, se as gems da gemset GLOBAL são compartilhadas por todas as gemsets ? Ou fiz algo de errado ?

    Ricardo

    January 3, 2011 at 11:38 pm

    • Ricado,

      Desculpe pela demora em responder… parece que o bundler não detecta as gems instaladas no gemset global, e as instala novamente. Pesquisei um pouco mas não encontrei nada relacionado, talvez seja um bug do bundler… De toda forma, a instalação é bem mais rápida, já que não é necessário baixá-las novamente.

      fernandoluizao

      January 18, 2011 at 5:27 pm

  8. Valeu pelo texto, estava precisando pra saber um pouco mais do rvm.
    Uma dica: eu já tinha muitas gems instaladas antes de usar o rvm, assim, depois de criar o gemset, eu copiei todo o diretório /usr/lib/ruby/gems/1.8/ para o gemset no qual eu utilizaria aquelas gems, e funcionou 100%, não precisei baixar nada, só atualizar.

    Jeová Guilherme

    February 5, 2011 at 11:35 am

  9. Muito bom o artigo foi o melhor que achei…

    Breno

    February 24, 2011 at 1:54 am

  10. Parabéns pelo post. Já vi alguns tutoriais de RVM, mas esse é o mais completo. Muito bem explicado

    ggarnier

    June 22, 2011 at 4:46 pm

  11. Opa! Eu de novo, heheh…

    Escrevi um post “Por que parei de usar os gemsets do RVM”:
    http://blog.lucascaton.com.br/?p=780

    Comenta lá sua opnião!
    Abraço!

    Lucas Catón

    June 23, 2011 at 1:23 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: