Z3D
Fork me on GitHub

Appunti di viaggio

ATTENZIONE - articoli ad alto contenuto tecnologico

Rails bundler: una gemma tira l’altra

Post dedicato ai Rails developers.

Quando si esegue un “bundle update” per aggiornare le gemme, il bundler  aggiorna tutte quelle presenti nel Gemfile. Se la tua applicazione smette di funzionare oppure i test iniziano a fallire, può essere piuttosto difficile capire quale gemma abbia causato il problema.

Ci sono un paio di soluzioni che vanno per la maggiore, ma nessuna di queste mi è sembrata soddisfacente:

  1. Bloccare il numero della versione nel Gemfile. Ma questo non è purtroppo cosa buona, ed in fondo è  proprio lo scopo del Gemfile.lock. Il blocco del numero di versione nel Gemfile dovrebbe essere l’eccezione, non la regola.
  2. Eseguire bundle update nomegemma

E’ facile cadere nel tranello e credere che un bundle update nomegemma aggiorni semplicemente quella gemma. Così non è, esso aggiorna anche tutte le dipendenze della gemma, che si voglia o no.

Questo è quello che dice la documentazione del Bundler riguardo al bundle update nomegemma

UPDATING A LIST OF GEMS

Sometimes, you want to update a single gem in the Gemfile(5), and leave the rest of the gems that you specified locked to the versions in the Gemfile.lock.

For instance, in the scenario above, imagine that nokogiri releases version 1.4.4, and you want to update it without updating Rails and all of its dependencies. To do this, run bundle update nokogiri.

Bundler will update nokogiri and any of its dependencies, but leave alone Rails and its dependencies.

Ok, niente male. Ma leggiamo nuovamente l’ultima frase: “Bundler aggiornerà nokogiri e tutte le sue dipendenze“. Bene. Anche se alcune gemme dipendono da una miriade di altre gemme, perchè no? Non c’è niente di male in questo. E’ giusto aggiornare le dipendenze di una gemma se qualcosa di nuovo è richiesto dall’aggiornamento per funzionare correttamente. Ma il Bundler le aggiorna tutte a prescindere. Ed eccoci tornati al problema iniziale: anche se si vuole aggiornare una singola gemma, si finisce con l’aggiornare un sacco di roba, e, se l’applicazione smette di funzionare, occorrono ore per capirne il motivo.

Volete un esempio di un effetto collaterale di un bundle update? Eccone uno. Diciamo che avete installato la gemma sextant nella vostra applicazione così da vedere le vostre “routes” in “development mode” semplicemente navigando su /rails/routes. (Si risparmia molto tempo al confronto di rake routes, dal momento che l’ambiente è già caricato). In questo esempio state sviluppando con Rails 3.2.2 e sextant 0.1.2. Adesso eseguite un bundle update sextant per aggiornale alla 0.1.3. Sapete cosa è successo? Avete appena aggiornato Rails dalla 3.2.2 alla 3.2.13. Non so voi, ma a me non piace avere la mia versione di Rails aggiornata solo perché ho voluto l’ultima versione di qualche piccola utile gemma.

Scrivendo questo post ho sperimentato con alcuni scenari, ed ho scoperto un’altra cosa interessante:

Con  bundle update nomegemma, anche se non ci sono aggiornamenti per quella gemma, vengono comunque aggiornate tutte le dipendenze.

Ecco un’altro esempio: La mia applicazione utilizza la versione 0.4 di haml-rails, attualmente l’ultima. Eseguo:

bundle update haml-rails

Dopo di che, git diff mi informa che il mio Gemfile.lock adesso contiene una nuova versione di  journey, json, multi_json, sprockets. Questo perfino se non è stato trovato nessun aggiornamento per haml-rails

La soluzione: bundle update ––source nomegemma

Bundler ha una soluzione, anche se secondo me non è facile capirne la documentazione.

Ecco cosa fare:

bundle update ––source nomegemma

Sto usando questa soluzione da più di un anno, funziona alla grande e credo sia a tutti gli effetti il modo migliore per aggiornare una gemma. Nel caso non funzionasse a causa di qualche conflitto con le altre gemme, è sempre possibile ripiegare sul bundle update nomegemma

Per quello che posso dire, usare ––source equivale a eseguire in modo semplificato le seguenti operazioni:

  1. Specificare il numero di versione per ogni gemma nel Gemfile
  2. Eseguire gem list -r nomegemma per scoprire l’ultima versione disponibile della gemma da aggiornare
  3. Cambiare il numero di versione nel Gemfile solamente per quella gemma
  4. Eseguire bundle install

Guardare la documentazione del bundle update per il –source però non è che sia di grande aiuto. Ecco quello che dice:

OPTIONS

––source=<name>

The name of a :git or :path source used in the Gemfile(5). For instance, with a :git source of http://github.com/rails/rails.git, you would call bundle update ––source rails

 

A dire il vero, la documentazione del bundle update fa riferimento a come eseguire un “aggiornamento conservativo” delle dipendenze. Ecco quello che dice: “For more information, see the CONSERVATIVE UPDATING section of bundle install(1) bundle-install.1.html.” La sezione del bundle install sul “conservative updating” descrive chiaramente come effettuare un “aggiornamento conservativo”, ma assume che venga specificato il numero di versione nel Gemfile, cosa che preferisco, se possibile, evitare.

Credits to ilikestuffblog.com

Share Your Thoughts!

Contatti

Z3N.it di Claudio Benvenuti
Via Giuseppe Abbati 18
50142, Firenze (Fi)
P.IVA: 06021030488
Cod. Fisc.: BNVCLD79P22D612O

Copyright ©2014 Z3N.it. All Rights Reserved. Privacy Policy