2013-07-09 39 views
2

我正在編寫一個有幾個gem依賴項的gem,其中一個取決於在新版本中打破向後兼容性的gem。這讓我想到了 - 我不希望我正在構建的寶石變成「寶石」,這使人們難以更新其應用程序。我也不想強迫使用我的寶石的人必須使用它在其他應用程序中依賴的特定版本的寶石。一方面,我可以重寫這些依賴關係中的所有代碼,將它們與我的gem捆綁在一起,並且一起去除依賴關係,但這似乎有點乏味。有沒有什麼辦法讓我直接在gem中包含gem依賴項,然後將它們包裝在模塊中,這樣我的打包版本就不會與其他應用程序使用的版本衝突?有沒有辦法把所有的寶石的我的寶石包裝取決於我的寶石?

+0

也許會創建一個元寶石,它完全依賴於所有各種相關的子寶石的相互依賴版本,它們一起工作? – rogerdpack

回答

1

我不認爲你想要的是通過現有的Ruby工具。但是,如果依賴於依賴關係向後兼容純粹是語法/用法問題,而不是版本之間的低級別差異,那麼您不必導入和維護舊的Gem代碼。你有另一種選擇:在你的gem中創建一個「shim」圖層,它提供你需要的依賴關係的新界面或舊界面所需的功能。

在實踐中,可能是這樣的,通過舉例的方式假定它是構造函數的Thingy類已經改變:

module DependencyShim 

    def new_Thingy(new_style_args) 
    if thingy_is_new 
     Thingy.new(new_style_args) 
    else 
     Thingy.new(convert_args_to_old_style(new_style_args)) 
    end 
    end 

    # convert_args_to_old_style() not shown 

    private 

    def thingy_is_old 
    Thingy::VERSION < '1.3.4' 
    end 

    def thingy_is_new 
    Thingy::VERSION >= '1.3.4' 
    end 
end 

更好的抽象很可能可能,但難以作爲預測我不知道新舊差異的本質,以及你的代碼與你的依賴的綁定程度。

如果版本之間有根本性的變化,並且您自己的gem大量使用依賴關係,那麼這顯然很痛苦。但即使如此,它仍然可能比重新實現和維護您自己的創業板中的依賴關係更不痛苦。

我建議你看看如何讓你的寶石大多數與你的依賴關係的最新版本相兼容,並且根據你對用戶羣的瞭解,長期以來不再支持舊的依賴關係。所有參與者可能有充分的理由擺脫舊的依賴。

+0

謝謝!看起來這只是目前問題的最佳答案。 – brightball

0

假設你正在使用捆綁,你可以像這樣在你的Gemfile指定依賴版本:

gem "my_dependency", "0.6.1" 

還有其他選項也如等閱讀bundler docs「版本大於X」整個負載獲取更多信息。

+0

我認爲OP知道這一點,並且正在尋找當1.0.1版本與他們發佈的gem不兼容時應該怎麼做。理想情況下,解決方案的方式意味着最終用戶可以在*用戶的*項目中使用版本'1.0.1',並且不需要版本'1.0.1'。 AFAIK,這要麼不可能,要麼很難實現。 –

+0

但是整個想法是有缺陷的 - 他說'我也不想強迫使用我的寶石的人必須使用它在其他應用程序中依賴的寶石的特定版本',而不是這種情況,他們會只需要安裝這些版本,供他的寶石使用。 – omnikron

+0

我錯誤地認爲Gemfile.lock管理整個應用程序中的Gem依賴關係,如果我的Gem需要舊版本的Nokogiri,它會限制整個應用程序使用該版本的Nokogiri?這一直是我對Gem依賴如何工作的理解。 – brightball