2012-01-20 2 views
18

보석을 설치할 때 조건부로 의존성을 설정해야하는 보석 작업을하고 있습니다. 나는 약간의 파기를했다루비 보석을 만들고 의존성을 조건부로 지정합니다.

그리고 그것은 내가이 필요에 혼자가 아닌 것처럼 보인다.

Rubygems: How do I add platform-specific dependency?

이 긴 스레드

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

나는 보석이의 보석 :: Specifiction 블록 내에서 방법을 add_dependency 사용하는 것입니다에 종속성을 추가하기 위해 볼 수있는 유일한 방법에게 있습니다. 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 

그물에서 찾은 모든 문서와 스레드를 기반으로했을 때, RB-fsevent가 설치 될

  • 윈도우 - - 당신이

    • 리눅스에 보석을 설치하는 경우 t는, 다음, RB-inotify를 종속성 및 자동 설치
    • 맥 것이다 RB-fchange가 설치된다

    그러나 그렇다고 볼 수 없습니다. 블럭 내의 "if"문은 보석이 만들어지고 패키징 될 때 평가됩니다. 따라서 Linux에서 gem을 빌드하고 패키지하면 rb-inotify가 종속성, Mac, rb-fsevent, Windows-rb-fchange로 추가됩니다.

    여전히 솔루션이 필요하므로 루비 젬 코드를 둘러 보았습니다. 다음과 같은 일이 발생하는 경우가 많습니다.

    • 빌드 당신의 보석에 대한 모든 코드 : foo.gem
    • 는 foo.gemspec 파일
    • 빌드, 패키지를 만들고, 같은 rubygems.org
    • 같은 보석 서버에 보석을 해제 모두들
    • 개발자는 다음을 통해 로컬로 설치합니다. gem install foo
    • foo.gem 파일이 다운로드되고 압축이 풀린 후 설치됩니다. 모든 종속성도 설치됩니다.
    • 모든 항목을 설정해야하며 보석을 사용하여 고정 할 수 있습니다.

    보석이 지어 놓을 때 foo.gemspec 파일을로드하고 보석 :: 사양 블록이 평가 YAML로 변환되고, metadata.gz로 압축하고, foo.gem에 포함 된 것으로 보인다 . 루비 코드는 data.tar.gz로 압축되어 포함됩니다. gem이 로컬 개발자 머신에 설치되면 YAML이 metadata.gz에서 추출되고 다시 Gem :: Specification 블록으로 변환되지만 다시 원래 블록으로 변환되지 않습니다.

    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 
    

    확인 :

    대신, 다음과 같은 것을 볼 수 있습니다.그래서, 저는 프로세스의 조감도를 보았습니다. 그것은 하나의 보석을 만들고 욕망을 변화시키지 않고 OS 타겟 범위에 대한 의존성을 조건 적으로 지정합니다.

    누구든지 각 대상 OS에 대해 여러 .gemspec 파일을 만드는 것 이외의 솔루션을 가지고 있다면 ... 나는 모두 귀입니다 !!

  • +0

    내 대답을 봐 http://stackoverflow.com/a/10249133/309514, 잘 작동합니다. – Fotios

    답변

    0

    본인도이를 조사하고 설계 상 불가능한 결론을 내 렸습니다. 모든 플랫폼에 대해 하나의 'mega gem'을 갖는 것은 보석이 다운로드되어 설치 될 때까지 플랫폼이 지원되는지 여부를 모르는 문제를 야기합니다. 보석은 플랫폼에 따라 올바른 설치 방법을 결정할만큼 똑똑해야합니다. 플랫폼이 전혀 지원되지 않으면 보석이 끔찍하게 실패 할 수 있으며 큰 웜을 열 수 있습니다. 동일한 이유로 제거 된 보석을 콜백하는 데 사용합니다. 보석을 올바르게 설치하는 마법은 없습니다. 어떤 사람들은 mkmf를 사용하여 이것을 해킹했지만 더 나은 해결책으로 플랫폼 당 낡은 보석 경로를 따르는 것이 좋습니다.

    이것을 바탕으로 루비와 jruby 용 보석을 만드는 프로젝트에서 각 보석을 수동으로 만들어서 RubyGem에 업로드해야합니다. Jeweler을 사용하면 Gemfile을 지정하는 것만 큼 간단하지만 보석을 포장 할 때마다 보석 사양을 다시 작성해야합니다. 단지 2 개의 플랫폼 만 지원할 때는 매우 사소한 일이지만 빌드 프로세스는 자동화되어 여러 플랫폼 보석을 지원할 수있을만큼 충분히 직선적입니다.

    1

    나는 또한이 문제를 과거에 우연히 발견했습니다. 유일한 대안은 종속성을 설치하기위한 레이크 작업을 만드는 것입니다. 물론, 그 단계에서, 사용자는 자신이받는 오류 메시지를 기초로 누락 된 보석을 알아낼 수 있습니다. 필자의 경우, 플랫폼 의존적 인 의존성이 여러 가지로 설치되어있어 옵션이 아니었다.

    Rakefile :

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

    설치 :

    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 
    

    그런 다음, 사용자가 해당 종속성을 설치 얻을 rake install를 사용할 수 있습니다.

    RubyGems에는 조건부 종속성 설치 (예 : 플랫폼 기반이 아닌 사용자 입력 기반)가 빠져 있습니다. 앞으로 구현 되길 바랍니다.

    관련 문제