Risposte:
Il Gemfile
è dove si specifica che le gemme che si desidera utilizzare e consente di specificare quali versioni.
Il Gemfile.lock
file è dove Bundler registra le versioni esatte installate. In questo modo, quando la stessa libreria / progetto viene caricata su un altro computer, l'esecuzione bundle install
esaminerà Gemfile.lock
e installerà le stesse versioni esatte, anziché semplicemente utilizzare Gemfile
e 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.
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
).
Come vedi se non ne hai Gemfile.lock
e 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.lock
viene utilizzato. Nel Gemfile.lock
solo 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.
Viene creato automaticamente con il primo:
bundle install
comando. Dopodiché ogni volta che bundle install
eseguirai, il bundle prima cercherà Gemfile.lock
e installerà le gemme specificate lì. È abitudine distribuire questo file tra i tuoi progetti per fornire coerenza e stabilità.
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.lock
con la tua versione più recente di app.
nokogiri ~> 1.4.4
non consentirebbe 1.5.3
l'installazione; il massimo consentito sarebbe 1.4.x
dove 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.d
significa che qualsiasi versione di foo
va bene purché sia ancora abc {qualcosa} dove {qualcosa} >=
d. Vedi anche la domanda correlata
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?
~> 1.4.4
equivale 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'
.
bundle install
controllerà Gemfile
anche se c'è un Gemfile.lock
e imporrà nuove restrizioni Gemfile.lock
?
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.
Gemfile.lock
in alcuni casi include le versioni "aperte" (ad es.rails (4.0.0)
Richiedebundler (>= 1.3.0, < 2.0)
), il che causa problemi. Qualche idea su come evitare quelle dipendenze 'aperte'?