Compreendendo o arquivo Gemfile.lock

181

Após executar o bundle installcomando, 'Gemfile.lock ' é criado no diretório de trabalho. O que as diretivas contidas nesse arquivo significam?

Por exemplo, vamos pegar o seguinte arquivo:

PATH
  remote: .
  specs:
    gem_one (0.0.1)

GEM
  remote: http://example.org/
  specs:
    gem_two (0.0.2)
    gem_three (0.0.3)
      gem_four (0.0.4)

PLATFORMS
  platform

DEPENDENCIES
  gem_two
  gem_one!

O que descrevem ' PATH ', ' GEM ', ' PLATAFORMAS ' e ' DEPENDÊNCIAS '? Todos eles são necessários?

O que deve conter os subdiretórios ' remote ' e ' specs '?

O que significa o ponto de exclamação após o nome da gema no grupo ' DEPENDENCIES '?

Shamaoke
fonte

Respostas:

71

Você pode encontrar mais informações no site do empacotador (ênfase adicionada abaixo para sua conveniência):

Depois de desenvolver seu aplicativo por um tempo, faça o check-in junto com o instantâneo Gemfile e Gemfile.lock . Agora, seu repositório possui um registro das versões exatas de todas as jóias que você usou na última vez em que teve certeza de que o aplicativo funcionou ...

Isso é importante: o Gemfile.lock transforma seu aplicativo em um único pacote, tanto do seu próprio código quanto do código de terceiros que ele executou na última vez em que você tem certeza de que tudo funcionou. Especificar versões exatas do código de terceiros dos quais você depende no seu Gemfile não forneceria a mesma garantia, porque as gemas geralmente declaram um intervalo de versões para suas dependências.

Filipe Miguel Fonseca
fonte
65
Isso não respondeu a nenhuma de suas perguntas, ele está perguntando sobre o formato do Gemfile.lock, mas isso apenas descreve o que ele faz.
Joshua Cheek
38

no que diz respeito ao ponto de exclamação, acabei de descobrir que está nas gemas buscadas :git, por exemplo

gem "foo", :git => "[email protected]:company/foo.git"
agenteo
fonte
Uau, bom trabalho para descobrir isso, eu também me perguntei isso. Obrigado.
JP Silvashy
5
Também ocorre ao carregar gemas locais através da pathopção Acho que tem algo a ver com o carregamento de uma gema não compilada?
zykadelic
Sim, este é um motivo. Mas esse NÃO é o único motivo para uma gema ser marcada com um ponto de exclamação. Atualmente, estou vendo qualquer jóia declarada dentro de um bloco de origem como marcada com um ponto de exclamação.
Sean Moubry
35

Passei os últimos meses mexendo bastante com Gemfiles e Gemfile.locks enquanto desenvolvia uma ferramenta de atualização de dependência automatizada 1 . O abaixo está longe de ser definitivo, mas é um bom ponto de partida para entender o formato Gemfile.lock. Você também pode verificar o código-fonte do analisador de arquivos de bloqueio do Bundler .

Você encontrará os seguintes títulos em um arquivo de bloqueio gerado pelo Bundler 1.x:

GEM (opcional, mas muito comum)

Essas são dependências originárias de um servidor Rubygems. Esse pode ser o principal índice Rubygems, no Rubygems.org, ou pode ser um índice personalizado, como os disponíveis no Gemfury e outros. Nesta seção, você verá:

  • remote: uma ou mais linhas especificando a localização dos índices Rubygems
  • specs: uma lista de dependências, com seu número de versão e as restrições em quaisquer subdependências

GIT (opcional)

Essas são dependências originárias de um determinado git remote. Você verá uma seção diferente para cada controle remoto do git e, em cada seção, verá:

  • remote:o controle remoto git. Por exemplo,[email protected]:rails/rails
  • revision: a referência de confirmação para a qual o Gemfile.lock está bloqueado
  • tag: (opcional) a tag especificada no Gemfile
  • specs: a dependência git encontrada neste controle remoto, com seu número de versão e as restrições em quaisquer subdependências

CAMINHO (opcional)

Essas são dependências originárias de um dado path, fornecidas no Gemfile. Você verá uma seção diferente para cada dependência de caminho e, em cada seção, verá:

  • remote:o caminho. Por exemplo,plugins/vendored-dependency
  • specs: a dependência git encontrada neste controle remoto, com seu número de versão e as restrições em quaisquer subdependências

PLATAFORMAS

A plataforma Ruby contra a qual o Gemfile.lock foi gerado. Se alguma dependência no Gemfile especificar uma plataforma, elas somente serão incluídas no Gemfile.lock quando o arquivo de bloqueio for gerado nessa plataforma (por exemplo, através de uma instalação).

DEPENDÊNCIAS

Uma lista das dependências especificadas na Gemfile, juntamente com a restrição de versão especificada lá.

Dependências especificadas com uma fonte que não seja o principal índice Rubygems (por exemplo, dependências git, baseadas em caminhos, dependências) têm uma !que significa que estão "fixadas" a essa fonte 2 (embora às vezes seja necessário procurar no Gemfile para determinar em).

VERSÃO RUBY (opcional)

A versão Ruby especificada no Gemfile, quando este Gemfile.lock foi criado. Se uma versão do Ruby for especificada em um .ruby_versionarquivo, esta seção não estará presente (pois o Bundler considerará o Gemfile / Gemfile.lock independente da versão do Ruby do instalador).

PACOTADO COM (Empacotador> = v1.10.x)

A versão do Bundler usada para criar o Gemfile.lock. Usado para lembrar os instaladores de atualizarem sua versão do Bundler, se for mais antiga que a versão que criou o arquivo.

FONTE DE PLUGIN (opcional e muito rara)

Em teoria, um Gemfile pode especificar plugins do Bundler, bem como o gems 3 , que seriam listados aqui. Na prática, não conheço nenhum plug-in disponível em julho de 2017. Esta parte do Bundler ainda está em desenvolvimento ativo!


  1. https://dependabot.com
  2. https://github.com/bundler/bundler/issues/4631
  3. http://andre.arko.net/2012/07/23/towards-a-bundler-plugin-system/
greysteil
fonte
2
parece ser a melhor resposta
daslicious 15/08
9

O Bundler é um gerenciador de gemas que fornece um ambiente consistente para projetos Ruby, rastreando e instalando as gemas e versões exatas necessárias.

Gemfile e Gemfile.lock são os principais produtos fornecidos pela jóia Bundler (o próprio Bundler é uma jóia).

O Gemfile contém a dependência do seu projeto em gemas, mencionadas manualmente nas versões especificadas, mas essas gemas dependem de outras gemas que são resolvidas automaticamente pelo empacotador.

O Gemfile.lock contém um instantâneo completo de todas as gemas no Gemfile junto com a dependência associada.

Quando você chama pela primeira vez a instalação do pacote configurável, ele cria esse Gemfile.lock e usa esse arquivo em todas as chamadas subseqüentes para a instalação do pacote configurável, o que garante que você tenha todas as dependências instaladas e ignorará a instalação da dependência.

O mesmo acontece quando você compartilha seu código com máquinas diferentes

Você compartilha seu Gemfile.lock junto com o Gemfile; quando você executa a instalação do pacote em outra máquina, ele se refere à etapa Gemfile.lock e ignora a resolução de dependência; em vez disso, instala todas as mesmas gemas dependentes que você usou no máquina original, que mantém a consistência em várias máquinas

Por que precisamos manter a consistência em várias máquinas?

  • A execução de versões diferentes em máquinas diferentes pode levar ao código quebrado

  • Suponha que seu aplicativo tenha usado a versão 1.5.3 e funcione há 14 meses
    sem problemas, e você tente instalar em uma máquina diferente
    sem o Gemfile.lock, agora você obtém a versão 1.5.8. Talvez esteja quebrado com a versão mais recente de algumas gemas e seu aplicativo
    falhará. Manter a consistência é de extrema importância (
    prática preferida ).

Também é possível atualizar gemas no Gemfile.lock usando a atualização do pacote .

Isso se baseia no conceito de atualização conservadora

Keshav
fonte
8

Parece-me que PATH lista as dependências de primeira geração diretamente do seu gemspec, enquanto o GEM lista as dependências de segunda geração (ou seja, de que dependem suas dependências) e as do seu Gemfile. PATH :: remote é .porque ele se baseou em um gemspec local no diretório atual para descobrir o que pertence a PATH :: spec, enquanto GEM :: remote é rubygems.org, já que é para isso que ele precisa ir para descobrir o que pertence ao GEM :: spec.

Em um plug-in Rails, você verá uma seção PATH, mas não em um aplicativo Rails. Como o aplicativo não possui um arquivo gemspec, não haveria nada para colocar no PATH.

Quanto a DEPENDENCIES, gembundler.com declara:

Runtime dependencies in your gemspec are treated like base dependencies, 
and development dependencies are added by default to the group, :development

O Gemfile gerado por rails plugin new my_plugindiz algo semelhante:

# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.

O que isto significa é que a diferença entre

s.add_development_dependency "july" # (1)

e

s.add_dependency "july" # (2)

é que (1) incluirá apenas "julho" no Gemfile.lock (e, portanto, no aplicativo) em um ambiente de desenvolvimento. Portanto, quando você executar bundle install, verá "julho" não apenas em PATH, mas também em DEPENDENCIES, mas apenas em desenvolvimento. Na produção, não estará lá. No entanto, quando você usa (2), verá "julho" apenas no PATH, não em DEPENDENCIES, mas será exibido quando você estiver bundle installem um ambiente de produção (ou seja, em alguma outra jóia que inclua a sua como dependência), não único desenvolvimento.

Estas são apenas minhas observações e não posso explicar completamente por que razão é que isso é assim, mas gostaria de receber mais comentários.

Isaac Betesh
fonte
3

Parece que não há documento claro falando sobre o Gemfile.lockformato. Talvez seja porque Gemfile.locké usado apenas por pacote internamente.

No entanto, uma vez que Gemfile.locké uma captura instantânea de Gemfile, o que significa que todas as suas informações devem vir Gemfile(ou do valor padrão, se não for especificado em Gemfile).

Para GEM, lista todas as dependências introduzidas direta ou indiretamente no Gemfile. remoteabaixo GEMinforma onde obter as gemas, especificadas pela fonte em Gemfile.

Se uma gema não for buscada remote, PATHinforma o local para encontrá-la. PATHinfo 's vem de caminho em Gemfilequando você declarar uma dependência.

E PLATFORMé daqui .

Para DEPENDENCIES , é o instantâneo das dependências resolvidas por pacote.

Hong
fonte
0

O que significa o ponto de exclamação após o nome da gema no grupo 'DEPENDECIES'?

O ponto de exclamação aparece quando a gema foi instalada usando uma fonte diferente de " https://rubygems.org ".

SWiggels
fonte