Bazel Lockfile

回報問題 查看來源

Bazel 的 Lockfile 功能可記錄專案所需的特定版本或依附元件。透過儲存模組解析度和擴充功能評估的結果,達成了這個目標。Lockfile 會推廣可重現的建構作業,確保開發環境的一致性。此外,還能在專案依附元件沒有變更時,讓 Bazel 略過解析程序,藉此提升建構效率。此外, Lockfile 可防止外部程式庫發生非預期的更新或破壞性變更,藉此提高穩定性,進而降低引入錯誤的風險。

產生鎖定檔案

這個 Lockfile 會在工作區根目錄下產生,名為 MODULE.bazel.lock。它會在建構程序中建立或更新,特別是在模組解析和擴充功能評估之後。Lockfile 會擷取專案目前的狀態,包括 MODULE 檔案、標記、覆寫及其他相關資訊。重要的是,其中只包含目前版本叫用中的依附元件。

當影響其依附元件的專案發生變更時, Lockfile 會自動更新以反映新的狀態。如此可確保鎖定檔案能專注於目前建構所需的特定依附元件組合,準確呈現專案解析的依附元件。

鎖定檔案使用方式

這個鎖定檔案可由標記 --lockfile_mode 控管,以便在專案狀態與鎖定檔案不同時自訂 Bazel 的行為。可用的模式如下:

  • update (預設):如果專案狀態與 Lockfile 相符,系統會立即從 Lockfile 傳回解析度結果。否則,系統會執行解析度,並更新鎖定檔案,反映目前的狀態。
  • error:如果專案狀態與 Lockfile 相符,則系統會從 Lockfile 傳回解析度結果。否則 Bazel 會擲回錯誤,指出專案與 Lockfile 之間的差異。如要確保專案的依附元件保持不變,並將任何差異視為錯誤,這個模式就特別實用。
  • off:完全未檢查鎖定檔案。

鎖定檔案的優點

Lockfile 提供多項優點,且可多種運用方式:

  • 可重現的版本。透過擷取軟體程式庫的特定版本或依附元件,鎖定檔案可確保建構作業可在不同環境和一段時間後重現。開發人員在建構專案時,可以依賴一致且可預測的結果。

  • 有效率地略過解決方案。如果專案依附元件自上次建構後沒有任何變更,而 Lockfile 可讓 Bazel 略過解析程序。這可大幅改善建構效率,特別是在解析度耗費時間的情境中。

  • 穩定性與風險降低:這個 Lockfile 可防止外部程式庫發生非預期更新或破壞性變更,有助於維持穩定性。將依附元件鎖定於特定版本後,就能降低因不相容或未經測試的更新而引入錯誤的風險。

Lockfile 內容

Lockfile 包含判斷專案狀態是否變更的所有必要資訊。同時也包括在目前狀態下建構專案的結果。Lockfile 包含兩個主要部分:

  1. 模組解析度的輸入內容 (例如 moduleFileHashflagslocalOverrideHashes),以及解析度的輸出內容 (moduleDepGraph)。
  2. 針對每個模組擴充功能,鎖定檔案會包含影響其的輸入內容 (以 transitiveDigest 表示),以及執行該擴充功能的輸出內容 (稱為 generatedRepoSpecs)

以下範例呈現了 Lockfile 的結構,以及各區段的說明:

{
  "lockFileVersion": 1,
  "moduleFileHash": "b0f47b98a67ee15f9.......8dff8721c66b721e370",
  "flags": {
    "cmdRegistries": [
      "https://bcr.bazel.build/"
    ],
    "cmdModuleOverrides": {},
    "allowedYankedVersions": [],
    "envVarAllowedYankedVersions": "",
    "ignoreDevDependency": false,
    "directDependenciesMode": "WARNING",
    "compatibilityMode": "ERROR"
  },
  "localOverrideHashes": {
    "bazel_tools": "b5ae1fa37632140aff8.......15c6fe84a1231d6af9"
  },
  "moduleDepGraph": {
    "<root>": {
      "name": "",
      "version": "",
      "executionPlatformsToRegister": [],
      "toolchainsToRegister": [],
      "extensionUsages": [
        {
          "extensionBzlFile": "extension.bzl",
          "extensionName": "lockfile_ext"
        }
      ],
      ...
    }
  },
  "moduleExtensions": {
    "//:extension.bzl%lockfile_ext": {
      "transitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
      "generatedRepoSpecs": {
        "hello": {
          "bzlFile": "@@//:extension.bzl",
          ...
        }
      }
    }
  }
}

模組檔案雜湊

moduleFileHash 代表 MODULE.bazel 檔案內容的雜湊。如果這個檔案發生任何變更,雜湊值會有所不同。

旗幟

Flags 物件會儲存會影響解析度結果的所有旗標。

本機覆寫雜湊

如果根模組包含 local_path_overrides,這個區段會將 MODULE.bazel 檔案的雜湊儲存在本機存放區。追蹤這個依附元件的變更

模組依附元件圖

moduleDepGraph 代表使用上述輸入內容的解決程序結果。它構成了執行專案所需的所有模組的依附元件圖。

模組擴充功能

moduleExtensions 區段是一個地圖,只包含目前叫用或先前叫用中使用的擴充功能,並排除不再使用的擴充功能。換句話說,如果依附元件圖表中不再使用某個擴充功能,就會從 moduleExtensions 地圖中移除。

這項對應中的每個項目都會對應至使用的擴充功能,並以包含檔案和名稱進行識別。每個項目的對應值都包含與該擴充功能相關聯的相關資訊:

  1. transitiveDigest 擴充功能實作項目及其遞移 .bzl 檔案的摘要。
  2. 使用目前的輸入內容執行擴充功能的 generatedRepoSpecs 結果。

其他可能影響擴充功能結果的因素為用途。雖然未儲存在 Lockfile 中,但在比較擴充功能與鎖定檔案中的目前狀態時,會考慮使用權限。

最佳做法

如要充分發揮鎖定檔案功能的優點,請參考下列最佳做法:

  • 定期更新鎖定檔案,反映專案依附元件或設定的異動。這可確保後續建構是以最新且準確的依附元件組合為基礎。

  • 將 Lockfile 納入版本管控,以利協同合作,並確保所有團隊成員都能存取相同的 Lockfile,促進專案中一致的開發環境。

只要按照這些最佳做法,您就可以有效利用 Bazel 中的 Lockfile 功能,創造更有效率、更穩定、協同運作的軟體開發工作流程。