Docs header transparent bg

如何使用 Bundler 更新寶石

更新依賴項

當然,在某個時間點,您可能想要更新應用程式所依賴的特定依賴項版本。例如,您可能想要將 rails 更新至 3.0.0 最終版。重要的是,僅僅因為您正在更新一個依賴項,並不表示您想要重新解析所有依賴項並使用所有內容的最新版本。在我們的範例中,您只有三個依賴項,但即使在這種情況下,更新所有內容都可能導致複雜情況。

為了說明,rails 3.0.0.rc 寶石依賴於 actionpack 3.0.0.rc 寶石,而後者又依賴於 rack ~> 1.2.1(表示 >= 1.2.1< 1.3.0)。rack-cache 寶石依賴於 rack >= 0.4。讓我們假設 rails 3.0.0 最終版寶石也依賴於 rack ~> 1.2.1,且自從 rails 3.0.0 發行以來,Rack 團隊已經發布了 rack 1.2.2

如果我們天真地更新所有寶石以更新 Rails,我們將取得 rack 1.2.2,它滿足 rails 3.0.0rack-cache 的需求。但是,我們並沒有特別要求更新 rack-cache,而它可能與 rack 1.2.2 不相容(無論出於何種原因)。雖然從 rack 1.2.1 更新至 rack 1.2.2 可能不會造成任何問題,但可能會發生類似的情況,涉及更大的跳躍。(請參閱下方 [1] 以進行更廣泛的討論)

為了避免此問題,當您更新寶石時,bundler 絕不會更新該寶石的依賴項,如果其他寶石仍依賴於該依賴項。在此範例中,由於 rack-cache 仍依賴於 rack,因此 bundler 絕不會更新 rack 寶石。這可確保更新 rails 不會無意間破壞 rack-cache。由於 rails 3.0.0 的依賴項 actionpack 3.0.0 仍與 rack 1.2.1 相容,因此 bundler 會保留它,而 rack-cache 即使在與 rack 1.2.2 不相容的情況下也能繼續運作。

由於您最初宣告對 rails 3.0.0.rc 的依賴,如果您想要更新至 rails 3.0.0,只要將您的 Gemfile 更新至 gem 'rails', '3.0.0' 並執行

$ bundle install

如上所述,bundle install 指令總是執行保守更新,拒絕更新您在 Gemfile 中未明確變更的寶石(或其依賴項)。這表示如果您未在 Gemfile 中修改 rack-cache,bundler 將視其及其依賴項rack)為單一且不可修改的單元。如果 rails 3.0.0rack-cache 不相容,bundler 將報告您的快照依賴項(Gemfile.lock)與您更新的 Gemfile 之間的衝突。

如果您更新了 Gemfile,而您的系統已經具備所有必要的相依性,在您啟動應用程式時,bundler 會透明地更新 Gemfile.lock。例如,如果您將 mysql 新增到 Gemfile,且已在您的系統中安裝,您可以啟動應用程式而無需執行 bundle install,而 bundler 會將「最後已知的良好」組態保留到 Gemfile.lock 快照。

在新增或更新相依性最小的 gem(資料庫驅動程式、wirbleruby-debug)時,這會派上用場。如果您更新相依性很重要的 gem(rails),或許多 gem 相依的 gem(rack),它可能會失敗。如果透明更新失敗,您的應用程式將無法啟動,而 bundler 會列印錯誤訊息,指示您執行 bundle install

更新 Gem 而無須修改 Gemfile

有時,您想要更新相依性而無須修改 Gemfile。例如,您可能想要更新到 rack-cache 的最新版本。因為您沒有在 Gemfile 中宣告 rack-cache 的特定版本,您可能想要定期取得 rack-cache 的最新版本。為此,您需要使用 bundle update 指令

$ bundle update rack-cache

這個指令會將 rack-cache 及其相依性更新到 Gemfile 允許的最新版本(在本例中,為可用的最新版本)。它不會修改任何其他相依性。

不過,它會在必要時更新其他 gem 的相依性。例如,如果 rack-cache 的最新版本指定相依於 rack >= 1.2.2,bundler 會將 rack 更新到 1.2.2,即使您沒有要求 bundler 更新 rack。如果 bundler 需要更新其他 gem 相依的 gem,它會在更新完成後讓您知道。

如果您想要將 Gemfile 中的每個 gem 更新到最新的可能版本,請執行

$ bundle update

這會從頭解析相依性,忽略 Gemfile.lock。如果您執行此操作,請將 git reset --hard 和您的測試套件放在後口袋。從頭解析所有相依性可能會產生令人驚訝的結果,特別是如果您相依的許多第三方套件自上次執行完整更新以來已發布新版本。