Qual è la differenza tra Gemfile e Gemfile.lock in Ruby on Rails


Risposte:


159

Il Gemfileè dove si specifica che le gemme che si desidera utilizzare e consente di specificare quali versioni.

Il Gemfile.lockfile è dove Bundler registra le versioni esatte installate. In questo modo, quando la stessa libreria / progetto viene caricata su un altro computer, l'esecuzione bundle installesaminerà Gemfile.locke installerà le stesse versioni esatte, anziché semplicemente utilizzare Gemfilee installare le versioni più recenti. (L'esecuzione di versioni diverse su macchine diverse potrebbe portare a test non funzionanti, ecc.) Non dovresti mai modificare direttamente il file di blocco.

Dai un'occhiata allo scopo e alla motivazione del Bundler , in particolare la sezione Verifica del codice nel controllo della versione.


2
È così che dovrebbe funzionare, ma a quanto pare Gemfile.lockin alcuni casi include le versioni "aperte" (ad es. rails (4.0.0)Richiede bundler (>= 1.3.0, < 2.0)), il che causa problemi. Qualche idea su come evitare quelle dipendenze 'aperte'?
Guillermo Grau,

158

Di solito scriviamo dipendenze in Gemfile come:

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

Qui in pratica dici: " Voglio nokogiri purché sia ​​maggiore della versione 1.4.4 ", ecc. Ora supponi di aver configurato il mio Gemfile 8 mesi fa e di aver configurato correttamente la mia app con questo requisito. 8 mesi fa la versione di nokogiri era la 1.4.4 . Le mie app Rails funzionavano perfettamente senza problemi con questa versione.

Ora penso che sto cercando di costruire con lo stesso Gemfile. Ma se guardiamo le versioni di nokogiri vediamo che l'attuale versione stabile è cambiata in 1.4.9 . Ciò significa che se proviamo a compilare, il bundler installerà la versione 1.4.9 di nokogiri (supponiamo di non averlo Gemfile.lock).

Cosa significa ?

Come vedi se non ne hai Gemfile.locke corri:

bundle install

quindi le gemme attualmente utilizzate possono essere diverse in qualsiasi momento . La tua app ha utilizzato la versione 1.4.4 e funziona 8 mesi fa senza problemi, ma se provi a costruirla ora ottieni la versione 1.4.9 . Forse è rotto con l'ultima versione di nokogiri, la fantastica funzione che hai usato con 1.4.4 non è più disponibile, ecc.

Per prevenire questo tipo di problema Gemfile.lockviene utilizzato. Nel Gemfile.locksolo le versioni esatte sono scritti e quindi solo questi verranno installati. Ciò significa che se distribuisci la tua app con un Gemfile.lock, ogni macchina avrà le stesse gemme installate e, cosa più importante, avranno tutte la stessa versione . Questo ti darà uno stack di distribuzione stabile e comune.

Come viene creato Gemfile.lock?

Viene creato automaticamente con il primo:

bundle install

comando. Dopodiché ogni volta che bundle installeseguirai, il bundle prima cercherà Gemfile.locke installerà le gemme specificate lì. È abitudine distribuire questo file tra i tuoi progetti per fornire coerenza e stabilità.

Come aggiornare Gemfile.lock?

Se sei soddisfatto dell'ultima versione delle tue app, puoi aggiornarla Gemfile.lock. Rifletti solo le tue modifiche a Gemfile. Ciò significa cambiare le dipendenze con le nuove versioni esatte in Gemfile. Dopo quella corsa:

bundle install

Questo ti aggiornerà Gemfile.lockcon la tua versione più recente di app.


19
Una descrizione molto bella e chiara (ho votato a favore); ma un nitpick, tuttavia: nokogiri ~> 1.4.4non consentirebbe 1.5.3l'installazione; il massimo consentito sarebbe 1.4.xdove x>=4(per i nokogiri sarebbe 1.4.7). L' ~>operatore indica che solo l' ultima cifra nella gemma utilizzata può essere "maggiore di" della versione indicata. Ad esempio, foo ~> a.b.c.dsignifica che qualsiasi versione di foova bene purché sia ​​ancora abc {qualcosa} dove {qualcosa} >=d. Vedi anche la domanda correlata
michael

1
Ciò che mi confonde è che stai già specificando versioni specifiche utilizzando gem "nokogiri", "~> 1.4.4"il file di gemme. Perché il bundler non poteva semplicemente usare quella versione? È perché è progettato per installare intenzionalmente le ultime versioni della gemma di default?
Jonny,

@Jonny, vedi il commento di michael_n. ~> 1.4.4 non specifica una versione esatta.
Matthew Flaschen,

2
@Jonny, ~> 1.4.4equivale a >= 1.4.4 and < 1.5. Vedi bundler.io/v1.5/gemfile.html . Per una versione esatta, basta usare gem 'foo', '1.4.4'.
Matthew Flaschen,

1
Ottima risposta, ma per favore chiarisci " aggiorna Gemfile.lock? ": Questa sezione sta dicendo che bundle installcontrollerà Gemfileanche se c'è un Gemfile.locke imporrà nuove restrizioni Gemfile.lock?
JMess,

4

The Gemfile.lock

Quando si esegue l'installazione del bundle, Bundler persisterà i nomi completi e le versioni di tutte le gemme utilizzate (incluse le dipendenze delle gemme specificate nel Gemfile (5)) in un file chiamato Gemfile.lock.

Bundler utilizza questo file in tutte le chiamate successive per raggruppare l'installazione, il che garantisce che si usi sempre lo stesso codice esatto, anche quando l'applicazione si sposta su macchine.

A causa del modo in cui funziona la risoluzione delle dipendenze, anche una modifica apparentemente piccola (ad esempio, un aggiornamento a un rilascio in punti di una dipendenza di una gemma nel tuo Gemfile (5)) può comportare la necessità di gemme radicalmente diverse per soddisfare tutte le dipendenze.

Di conseguenza, DOVREBBE controllare Gemfile.lock nel controllo versione. In caso contrario, ogni macchina che verifica il repository (incluso il server di produzione) risolverà nuovamente tutte le dipendenze, con conseguente utilizzo di versioni diverse di codice di terze parti se una delle gemme nel Gemfile (5) o qualsiasi delle loro dipendenze sono state aggiornate.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.