2012-04-04 31 views
7

Me gustaría instalar una gema (JSON) en el lado del cliente, pero solo si no se ha instalado ya (algunas distribuciones de Ruby 1.9 tienen incluido JSON).Instalar gema bajo demanda

No pude encontrar una pista sobre cómo hacerlo desde gem help install. gem install json y funcionando en un sistema Windows con Ruby 1.9 instalado (con JSON incluido) da como resultado

ERROR: Error installing json: 
    The 'json' native gem requires installed build tools. 

- se trata de instalarlo ignorando el hecho de que la gema ya está ahí.

Y no puedo hacer bash trucos como grepping gem list salida porque el cliente podría ser Windows.

¿Cuál es la forma multiplataforma de instalar una gema solo si ya no está presente en el sistema?

Respuesta

2

Esto puede funcionar ...

begin 
    require "json" 
rescue LoadError 
    system("gem install json") 
end 

Si no desea que se requiera "JSON ", puedes eliminarlo de $ LOAD_PATH.

O, dicho como un trazador de líneas:

ruby -e 'begin; require "some_gem"; rescue LoadError; system "gem install some_gem"; end' 
+0

Genial, lo probará mañana y aceptará su respuesta ya que parece ser la solución de trabajo. El único problema es que 'json' puede ser proporcionado por dos gemas: json_pure y json, por lo que dependiendo de la variante que necesites, harás 'require 'json/ext'' o' require' json/pure''. –

+0

Sí. En realidad, creo que esta no es la mejor manera ya que tenemos que eliminar manualmente la ruta de $ LOAD_PATH. Sería mejor si json/ext o json/pure no está realmente incluido. – Tomato

+0

Estoy ejecutando el proyecto de una sola línea desde la línea de comandos, así que no necesito quitar nada, así que eso es lo que realmente necesitaba ¡gracias! –

0
gem update json 

sólo se debe instalar si es necesario, en mi Windows 7 como sistema que hace

C:\Ruby193\bin>gem update json 
Updating installed gems 
Updating json 
Fetching: json-1.6.6.gem (100%) 
Temporarily enhancing PATH to include DevKit... 
Building native extensions. This could take a while... 
Successfully installed json-1.6.6 
Updating multi_json 
Fetching: multi_json-1.2.0.gem (100%) 
Successfully installed multi_json-1.2.0 
Gems updated: json, multi_json 
Installing ri documentation for json-1.6.6... 
Installing ri documentation for multi_json-1.2.0... 
Installing RDoc documentation for json-1.6.6... 
Installing RDoc documentation for multi_json-1.2.0... 

C:\Ruby193\bin>gem update json 
Updating installed gems 
Nothing to update 

C:\Ruby193\bin> 
+1

Si intentas hacer 'gema actualizar' una gema que no está instalada - fallará –

+0

la captura de pantalla de arriba me demuestra que no, la gema no la instalé la primera vez, la instalé y la segunda vez no lo hizo – peter

2

para preguntar si se instala una joya:

gem list --installed "^json$" 

Para instalar una joya si se necesita:

ruby -e '`gem list -i \"^json$\"`.chomp=="true" or `gem install json`' 

Para hacer una secuencia de comandos de línea de comandos:

#!/usr/bin/env ruby 
# 
# Ruby script to install a gem if it's needed. 
# This script first uses gem list to see if the 
# gem is already installed, matching the exact name. 
# 
# If the gem is installed, then exit. 
# If the gem is not installed, then install it. 
# 
# You can this script whatever you like; 
# I call mine gem-install-fast because it's 
# faster than re-installing a gem each time. 
# 
# Example: 
# 
# gem-install-fast json 
# 
name=ARGV[0] and `gem list -i "^#{name}$"`.chomp=="true" or `gem install #{name}` 

Para utilizar la secuencia de línea de comando:

gem-install-fast json 
0

El mejor que he encontrado es esto (comando shell): $ gem install asciidoctor --conservative

Se instalará solamente si las especificaciones gema no puede ser cubierto por las gemas instaladas actualmente.