Gemspec.extensions - warunkowe zależności

Robię fork’a gema. Generalnie problem w gem-ie polega na tym, że są na sztywno zdefiniowane wersje zależnych gemów. Próbuje osiągnąć efekt, że przy instalacji gem-u, w zależności od wersji Ruby-ego, różna wersja activerecord jest “zaciągana” jako dependency. Chciałam do tego użyć extensions w definicji gemspec. Mam coś takiego w gemspec file:

spec.extensions = ['ext/mkrf_conf.rb']

A w pliku ext/mkrf_conf.rb:

require 'rubygems'
require 'rubygems/command.rb'
require 'rubygems/dependency_installer.rb' 

begin
   Gem::Command.build_args = ARGV
   rescue NoMethodError
end

inst = Gem::DependencyInstaller.new

begin
   if RUBY_VERSION < "1.9.3"
       inst.install "activerecord", ">2.0", "< 4.0"
       inst.install 'i18n', "< 0.7"
 else
       inst.install "activerecord", "> 4.0"
 end
 rescue
     exit(1)
 end 

 f = File.open(File.join(File.dirname(__FILE__), "Rakefile"), "w")   # create dummy rakefile to indicate success
 f.write("task :default\n")
 f.close

Stworzyłam sobie testowy projekt, w którym w Gemfile jako dependency określam sobie ten gem:

gem 'my_gem', path: '/Users/xxx/Documents/my_projects/my_gem'

Robię:

bundle install

Niestety, activerecord w ogóle się nie instaluje. Próbowałam przenieść logikę do Gemfile w gem-ie, ale też activerecord nie jest instalowany jako dependency przy bundle install. Ktoś może wie, o co chodzi ?

a po co wspierac ruby w ver < 1.9.3 daj sobie spokoj

To nie mój pomysł tylko autora gem-a, który pracuje dużo z legacy code. Ostatecznie extensions nie zadziałało więc pójdziemy prawdopodobnie w stronę osobnych branch-y.

To nie miało raczej prawa zadziałać. Gem na jasno zdefiniowane zależności i dziwne byłoby gdyby pod ruby 2.2 ładowany był active record w wersji X a pod 1.9 w wersji Y.

Ja proponuję by wypuścić 2 różne gemy. Np. foo i foo1.9. Ew. tak jak napisałaś: 2 branche w repo gita podpięte w Gemfile. Efekt będzie podobny.

@ograbek próbowałeś może czegoś takiego?

gem 'activerecord', '>2.0', '<4.0', platforms: [:mri_18, :mri_19]
gem 'activerecord', '> 4.0', platforms: :mri_20

http://bundler.io/v1.3/man/gemfile.5.html

Ewentualnie możesz spróbować coś podobnego do drapera. Mają osobne gemfile w zależności od wersji Rails.


https://github.com/drapergem/draper/tree/master/gemfiles

@radarek A jednak dokumentacja twierdzi, że można: http://en.wikibooks.org/wiki/Ruby_Programming/RubyGems, znalazłam też przykłady gem-ów gdzie to stosowano: https://www.tiredpixel.com/2014/01/05/curses-conditional-ruby-gem-installation-within-a-gemspec . Moje pytanie wynikało z ciekawości dlaczego u mnie to nie działa.

@michal_s
Hmm, platforms raczej nie zadziała, bo to jest ewaluowane podczas build-a a nie podczas instalacji. W developmencie to się sprawdzi tak samo jak zwykłe warunki w gemspec-ku, ale nie jak ktoś instaluje gem-a.

Chciałam rozgryźć te extensions, bo generalnie opcja ciekawa, niekoniecznie do celów instalacji różnych zależności :smile: Ostatecznie jednak idziemy w stronę osobnych wersji gemów i branch-y, bo przy okazji można poczyścić kod.