zafiro topacio rubi preciosas precio piedras piedra esmeralda ruby dependencies gem conditional

ruby - topacio - construir una gema rubí y especificar condicionalmente las dependencias



rubi piedra precio (3)

He investigado esto también y he llegado a la conclusión de que no es posible por diseño. Tener una sola ''mega gema'' para todas las plataformas provoca el problema de no saber si una plataforma es compatible hasta que la gema se descarga e instala. Una gema tendría que ser lo suficientemente inteligente como para determinar cuál es la forma correcta de instalar en función de la plataforma. Si una plataforma no es compatible en absoluto, la gema puede fallar horriblemente, abriendo una gran lata de gusanos. Antes de que se instalara una gema, se solía hacer una devolución de llamada por el mismo motivo, no hay magia para que una gema se instale correctamente. Algunas personas han pirateado esto utilizando mkmf, pero sugiero seguir la ruta desgastada de una gema por plataforma como la mejor solución.

Basado en esto, en un proyecto que construye una gema para ruby ​​y jruby, tengo que crear manualmente cada gema y subirlas a RubyGem. Usar Jeweler es tan simple como especificar el Gemfile , pero tengo que reconstruir la especificación de la gema cada vez que empaco una gema. Bastante trivial cuando se admiten solo 2 plataformas, pero el proceso de compilación es tan sencillo que podría automatizarse para brindar soporte a múltiples plataformas.

Estoy trabajando en una gema que tiene que establecer dependencias condicionalmente cuando se instala la gema. He hecho algunas excavaciones

y parece que no estoy solo en esta necesidad.

Rubygems: ¿Cómo agrego la dependencia específica de la plataforma?

este es un hilo largo

http://www.ruby-forum.com/topic/957999

La única manera que puedo ver para agregar dependencias a una gema es usar el método add_dependency dentro de un bloque Gem :: Specifiction en un archivo .gemspec

Gem::Specification.new do |s| # ... standard setup stuff # conditionally set dependencies s.add_dependency "rb-inotify", "~> 0.8.8" if RUBY_PLATFORM =~ /linux/i s.add_dependency "rb-fsevent", "~> 0.4.3.1" if RUBY_PLATFORM =~ /darwin/i s.add_dependency "rb-fchange", "~> 0.0.5" if RUBY_PLATFORM =~ /mswin|mingw/i end

Basándome en todos los documentos e hilos que encontré en la red, habría esperado que si instala la gema en

  • Linux, entonces, rb-inotify sería una dependencia y autoinstalado
  • Mac - rb-fsevent se instalaría
  • Windows - se instalaría rb-fchange

Sin embargo, parece que ese no es el caso. Las declaraciones "if" dentro del bloque se evalúan en el momento en que se construye y empaqueta la gema. Por lo tanto, si construye y empaqueta la gema en Linux, entonces, rb-inotify se agrega como una dependencia, Mac, luego, rb-fsevent, Windows - rb-fchange.

Todavía necesitando una solución, busqué en el código de los rubygems y parece que la siguiente es una gran idea de lo que sucede.

  • Construye todo tu código para tu gema: foo.gem
  • crear un archivo foo.gemspec
  • construir, empaquetar y lanzar la gema a un servidor de gemas como rubygems.org
  • que todos sepan
  • los desarrolladores lo instalan localmente a través de: gem install foo
  • El archivo foo.gem se descarga, se desempaqueta e instala. Todas las dependencias están instaladas también.
  • Todo debería estar listo y podemos comenzar usando la gema.

Parece que cuando la gema se crea y libera, el archivo foo.gemspec se carga y el bloque Gem :: Specification se evalúa y convierte a YAML, se comprime como metadata.gz y se incluye en foo.gem. El código ruby ​​se comprime en data.tar.gz y también se incluye. Cuando la gema se instala en la máquina del desarrollador local, el YAML se extrae de metadata.gz y se convierte nuevamente en un bloque Gem :: Specification, sin embargo, no se vuelve a convertir al bloque original.

En su lugar, verá algo como lo siguiente:

Gem::Specification.new do |s| if s.respond_to? :specification_version then s.specification_version = 3 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new(''1.2.0'') then s.add_runtime_dependency(%q<rb-inotify>, ["~> 0.8.8"]) else s.add_dependency(%q<rb-inotify>, ["~> 0.8.8"]) end else s.add_dependency(%q<rb-inotify>, ["~> 0.8.8"]) end end

De acuerdo. Por lo tanto, tengo una visión general del proceso, sin embargo, eso no cambia mi deseo de crear una gema única y especificar condicionalmente las dependencias para un rango de objetivos de SO.

Si alguien tiene una solución que no sea la creación de múltiples archivos .gemspec para cada sistema operativo de destino ... ¡Soy todo lo que oigo!



También me he topado con este problema en el pasado. La única solución que pude encontrar fue crear una tarea de Rake para instalar las dependencias. Por supuesto, en esa etapa, es posible que desee dejar que el usuario descubra por sí mismo qué joya le falta en función del mensaje de error que está recibiendo. En mi caso, había varias dependencias dependientes de la plataforma para instalar, por lo que no era una opción.

Rakefile:

task :install do |t| require ''./lib/library/installer'' Library::Installer.install end

Instalador

module Library::Installer require ''rubygems/dependency_installer'' def self.install installer = Gem::DependencyInstaller.new dependency = case RUBY_PLATFORM when /darwin/i then ["rb-fsevent", "~> 0.4.3.1"] when /linux/i then ["rb-inotify", "~> 0.8.8"] when /mswin|mingw/i then ["rb-fchange", "~> 0.0.5"] end installer.install(*dependency) end

Luego, el usuario puede usar la rake install para instalar las dependencias apropiadas.

La instalación de dependencia condicional (no solo basada en la plataforma, sino también basada en la entrada del usuario, por ejemplo) le falta cruelmente a RubyGems. ¡Esperemos que se implemente en el futuro!