Qual é a diferença entre Gemfile e Gemfile.lock no Ruby on Rails

125

Eu sou iniciante no Ruby on Rails e estou usando o Rails 3.0.9.

Qual é a diferença entre Gemfilee Gemfile.lockno Rails?

Shamith c
fonte

Respostas:

159

O Gemfileé onde você especificar quais gemas você quer usar, e permite que você especifique quais versões.

O Gemfile.lockarquivo é onde o Bundler registra as versões exatas que foram instaladas. Dessa forma, quando a mesma biblioteca / projeto é carregada em outra máquina, a execução bundle installexaminará Gemfile.locke instalará exatamente as mesmas versões, em vez de apenas usar Gemfilee instalar as versões mais recentes. (A execução de versões diferentes em máquinas diferentes pode levar a testes quebrados, etc.) Você nunca precisa editar diretamente o arquivo de bloqueio.

Confira Objetivo e justificativa do Bundler , especificamente a seção Verificando seu código no controle de versão.

Dylan Markow
fonte
2
É assim que deve funcionar - mas, aparentemente, Gemfile.lockinclui versões 'abertas' em alguns casos (por exemplo, rails (4.0.0)requer bundler (>= 1.3.0, < 2.0)), o que causa problemas. Alguma idéia de como evitar essas dependências "abertas"?
Guillermo Grau
158

Normalmente, escrevemos dependências no Gemfile como:

gem "nokogiri", "~> 1.4.4"
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'uglifier', '>= 1.2.3'
..

Aqui você basicamente diz: " Quero nokogiri, contanto que seja maior que a versão 1.4.4 ", etc. Agora, suponha que eu configurei meus Gemfile 8 meses atrás e que eu configurei com êxito meu aplicativo com esse requisito. 8 meses atrás a versão nokogiri era 1.4.4 . Meus aplicativos rails estavam funcionando perfeitamente sem problemas com esta versão.

Agora pense que estou tentando construir com o mesmo Gemfile. Mas se olharmos para as versões nokogiri , vemos que a versão estável atual mudou para 1.4.9 . Isso significa que, se tentarmos construir, o bundler instalará a versão 1.4.9 do nokogiri (suponha que não tenhamos Gemfile.lock).

O que isso significa ?

Como você vê se não possui nenhum Gemfile.locke execute:

bundle install

em seguida, as pedras preciosas usadas atualmente pode ser diferente a qualquer momento . Seu aplicativo usou a versão 1.4.4 e funciona há 8 meses sem problemas, mas se você tentar compilá-lo agora, obterá a versão 1.4.9 . Talvez esteja quebrado com a versão mais recente do nokogiri, o recurso incrível que você usou com 1.4.4 não está mais disponível, etc.

Para evitar esse tipo de problema, Gemfile.locké usado. Na Gemfile.lockúnica as versões exatas são escritos e, portanto, só estes serão instalados. Isso significa que, se você distribuir seu aplicativo com um Gemfile.lock, cada máquina terá as mesmas jóias instaladas e, o mais importante , todas elas terão a mesma versão . Isso fornecerá uma pilha de implantação estável e comum.

Como é criado o Gemfile.lock?

É criado automaticamente com o primeiro:

bundle install

comando. Depois disso, toda vez que você executa bundle install, o bundle primeiro procura Gemfile.locke instala as gemas especificadas lá. É um hábito distribuir esse arquivo entre seus projetos para fornecer consistência e estabilidade.

Como atualizar Gemfile.lock?

Se você estiver satisfeito com a versão mais recente dos seus aplicativos, poderá atualizar Gemfile.lock. Apenas reflita suas alterações em Gemfile. Isso significa alterar as dependências para as novas versões exatas em Gemfile. Depois dessa execução:

bundle install

Isso atualizará você Gemfile.lockcom sua versão mais recente dos aplicativos.

Fatih Arslan
fonte
19
Uma descrição clara e muito agradável (votei positivamente); mas um nitpick, no entanto: nokogiri ~> 1.4.4não permitiria 1.5.3a instalação; max permitido seria 1.4.xonde x>=4(para nokogiri isso seria 1.4.7). O ~>operador significa que apenas o último dígito na gema usada pode ser "maior que" a versão fornecida. Por exemplo, foo ~> a.b.c.dsignifica que qualquer versão de fooestá bem, desde que ainda esteja abc {algo} onde {algo} >=d. Veja também a pergunta relacionada
michael
1
O que me confunde é que você já está especificando versões específicas usando gem "nokogiri", "~> 1.4.4"o gemfile. Por que o empacotador não pôde usar essa versão? É porque foi projetado para instalar intencionalmente as versões mais recentes da gema por padrão?
19414 Jonny
@ Jonny, veja o comentário de michael_n. ~> 1.4.4 não especifica uma versão exata.
Matthew Flaschen
2
@ Jonny, ~> 1.4.4é equivalente a >= 1.4.4 and < 1.5. Consulte bundler.io/v1.5/gemfile.html . Para uma versão exata, basta usar gem 'foo', '1.4.4'.
Matthew Flaschen
1
Ótima resposta, mas por favor esclareça " atualizar Gemfile.lock? ": Esta seção está dizendo que bundle installverificará o Gemfilemesmo se houver um Gemfile.locke aplicará novas restrições Gemfile.lock?
JMess
4

O Gemfile.lock

Quando você executa a instalação do pacote configurável, o Bundler mantém os nomes e versões completos de todas as gemas que você usou (incluindo dependências das gemas especificadas no Gemfile (5)) em um arquivo chamado Gemfile.lock.

O empacotador usa esse arquivo em todas as chamadas subseqüentes para instalar o pacote, o que garante que você sempre use o mesmo código exato, mesmo quando o aplicativo se move pelas máquinas.

Devido à maneira como a resolução de dependência funciona, mesmo uma alteração aparentemente pequena (por exemplo, uma atualização para o lançamento pontual de uma dependência de uma gema no seu Gemfile (5)) pode resultar em gemas radicalmente diferentes sendo necessárias para satisfazer todas as dependências.

Como resultado, você deve verificar seu Gemfile.lock no controle de versão. Caso contrário, todas as máquinas que fizerem check-out do seu repositório (incluindo o servidor de produção) resolverão todas as dependências novamente, o que resultará em diferentes versões do código de terceiros sendo usadas se alguma das gemas no Gemfile (5) ou qualquer outra de suas dependências foram atualizadas.

Ajey
fonte