rebar3使用介紹(四)依賴

依賴關係和配置文件
將始終使用prod應用於其配置的配置文件編譯依賴項。沒有其他(default當然,除此之外)用於任何依賴。即使它們是爲prod依賴項配置的,仍然會將其提取到其聲明的配置文件的配置文件目錄中。例如,頂層的依賴deps將存放在_build/default/lib/下,而test模式會存放在_build/test/lib/下,並且兩者都將在prod應用其配置文件配置的情況下進行編譯。
簡而言之,deps存放的目錄是和當前的執行模式強相關的

  • 解決衝突
    與先前版本的rebar不同,有一組嚴格的規則,其中拿到的依賴關係不會根據提取或更新的時間而改變。對此的算法如下所述:

Rebar3認爲依賴版本僅供參考。鑑於Erlang社區中現有的開源環境,試圖強加語義版本控制或任何其他類似方案通常都在胎死腹中:

  • 人們更新了一些版本但不是全部版本(git標籤與分支名稱與OTP應用程序版本相比),它們可能相互矛盾;
  • 有些人從不更新他們的版本;
  • 不是每個人都訂閱相同的版本方案;
  • 人們在訂閱語義版本時會出錯;
  • 許多應用程序卡在小於的版本中1.0.0,因此被認爲永遠不穩定;
  • 在撰寫本文時,大多數情況下使用源依賴關係:因此,找出版本衝突需要從所有依賴項下載所有傳遞依賴項,以確定它們是否每次都發生衝突。

在rebar3出現之前,依賴關係的任何其他格式都需要對依賴進行全面檢查

相反,rebar3將在級別順序遍歷中獲取和下載依賴項。這意味着最接近依賴樹根的依賴關係是那些將被選擇的依賴關係,無論它們是什麼版本。

這意味着在項目中聲明的rebar.config任何依賴項永遠不會被傳遞依賴項覆蓋,並且傳遞依賴項永遠不會被後來遇到的衝突傳遞依賴項所覆蓋。

這也意味着如果你希望使用的版本高於其他所有版本,您只需將其添加到你的rebar.config文件中並選擇將保留的內容即可。

將衝突視爲錯誤
如果你希望rebar3在檢測到依賴項衝突時立即中止,而不是像往常一樣跳過文件並繼續,請將該行添加{deps_error_on_conflict, true}.到您的rebar配置文件中。

聲明依賴關係

可以在頂級rebar.config文件中聲明依賴關係,並使用該rebar3 tree命令進行檢查。

通常,Rebar3支持兩種類型的依賴項:

  • 源依賴
  • 包依賴

這兩種處理方式可能略有不同(在下載之前,包提供的信息比源依賴項更多,並且將在本地緩存~/.cache/rebar3/),但它們通常表現相同。

所有依賴項都是項目本地的通常是一個很好的選擇,以避免全局庫存在版本衝突的常見問題。它還有助於獨立項目的Releases。

依賴關係描述可以是以下任何格式:

{deps,[
  %% Packages
  rebar,
  {rebar,"1.0.0"},
  {rebar, {pkg, rebar_fork}}, % rebar app under a different pkg name
  {rebar, "1.0.0", {pkg, rebar_fork}},
  %% Source Dependencies
  {rebar, {git, "git://github.com/erlang/rebar3.git"}},
  {rebar, {git, "http://github.com/erlang/rebar3.git"}},
  {rebar, {git, "https://github.com/erlang/rebar3.git"}},
  {rebar, {git, "[email protected]:erlang/rebar3.git"}},
  {rebar, {hg, "https://othersite.com/erlang/rebar3"}},
  {rebar, {git, "git://github.com/erlang/rebar3.git", {ref, "aef728"}}},
  {rebar, {git, "git://github.com/erlang/rebar3.git", {branch, "master"}}},
  {rebar, {git, "git://github.com/erlang/rebar3.git", {tag, "3.0.0"}}},
  %% Legacy support -- added parts such as [raw] are ignored
  {rebar, "3.*", {git,"git://github.com/erlang/rebar3.git"}},
  {rebar, {git, "git://github.com/erlang/rebar3.git"}, [raw]},
  {rebar, "3.*", {git, "git://github.com/erlang/rebar3.git"}, [raw]}
]}.

如上例所示,對於當前版本,僅支持包,git源和mercurial源。可以通過實現資源行爲並將其包含在插件中來添加自定義依賴項源。

Rebar3將獲取所需的任何其他內容。

但是,Erlang / OTP對引導和關閉應用程序以及用於構建版本和腳本的工具(甚至是Rebar3的一部分)所做的依賴性處理依賴於更細粒度的依賴性聲明,指定項目中每個應用程序的哪個依賴於其他應用程序。

你應該每個依賴添加到對應的app或app.src文件:

{application, <APPNAME>,
 [{description, ""},
  {vsn, "<APPVSN>"},
  {registered, []},
  {modules, []},
  {applications, [kernel
                 ,stdlib
                 ,cowboy
                 ]},
  {mod, {<APPNAME>_app, []}},
  {env, []}
 ]}.

這將允許靈活地編寫和生成軟件,其中各種不相交的應用程序可以在虛擬機中共存而不會將它們的依賴性完全糾纏在一起。例如,您可能希望Web服務器能夠獨立於管理和調試工具運行,即使它們應該在生產中可用。

如果需要支持更多格式,可以通過rebar_resource行爲擴展Rebar3 ,並通過拉取請求發送給維護者。

源依賴

源依賴性將以級別順序遍歷的方式下載 - 從依賴樹中的根到葉。一旦看到並獲取了依賴項,將忽略共享相同名稱的其他依賴項,並顯示警告。

對於常規依賴關係樹,例如:

  A
 / \
B   C 

依賴項A,B和C將被提取。

但是,對於更復雜的樹,例如:

   A
 /   \
B    C1
|
C2

依賴項A,B和C1將被提取。當Rebar3遇到要求時C2,它會顯示警告:Skipping C2 (from $SOURCE) as an app of the same name has already been fetched。

比如你在你的項目中使用了cowlib,但是版本和cowboy不同,同時主項目又依賴cowboy,那麼編譯時會打印

===> Skipping cowlib (from {git,
“git://github.com/ninenines/cowlib.git”,
“1.0.0”}) as an app of the same name has already been fetched

這樣的消息應該讓用戶知道已經跳過了哪個依賴項。

那兩個傳遞依賴關係具有相同名稱並且處於同一級別的情況呢?

   A
 /   \
B     C
|     |
D1    D2

在這種情況下,D1將替代D2,因爲按B字典順序排序C。這是一個完全武斷的規則,但它至少是一個確保可重複提取的規則。

如果用戶不同意結果,他們可以D2提升到最高水平並確保提前選擇:

   A      D2
 /   \
B     C
|     |
D1    D2

這將產生A,B,C,和D2。而不是D1。
Rebar3對包(package)使用相同的算法,並且還將檢測循環依賴性和錯誤輸出。但是,Source依賴項始終優先於包。

_checkouts目錄中的依賴關係將保持不變。

包依賴

rebar3使用hex.pm來提供一組託管包及其依賴項,可以使用以下命令獲取列表:

$ rebar3 update
===> Updating package index...
$ rebar3 pkgs

然後可以包含包依賴關係,如前所示:

{deps, [
        {cowboy, "1.0.0"}
       ]
}.

包管理器將獲取一組最小的依賴項,以符合基於其拓撲排序過的依賴關係圖的構建規則。
爲了支持源依賴關係的正確行爲,將合併和處理包依賴關係集以及源依賴關係的級別順序遍歷。在發生衝突時選擇獲勝者的最終結果將類似於源依賴關係,並顯示警告。

要使用非默認的CDN,例如官方鏡像之一添加到您的項目rebar.config或~/.config/rebar3/rebar.config:

{rebar_packages_cdn, "https://s3-eu-west-1.amazonaws.com/s3-eu.hex.pm"}.

Checkout 依賴

爲了處理希望使用本地依賴的情況,提供了_checkouts目錄,通常只需創建一個符號鏈接或將依賴項複製到_checkouts目錄下,在_checkouts目錄下的app具有最高優先級,他不會被任何的其他的同名app所覆蓋

更新依賴

每當獲取並鎖定依賴項時,Rebar3將從源文件中提取引用以及時將其固定到特定版本。依賴在以後的構建中都必須強制符合這個特定版本。

rebar3允許將以前安裝的依賴項升級到更新的版本。有兩種形式:將分支的引用轉發到其最新版本(例如,舊的master直到新master的HEAD源文件,或最新版本的未指定的版本包),或使用配置在rebar.config的新版本來破壞現有的鎖定依賴關係。

但是,Rebar3只允許升級頂級依賴項; 嘗試升級傳遞依賴沒有多大意義 - 如果需要對這些依賴進行控制,它們應該被提升到頂層。

在以下依賴關係樹中:

A  B
|  |
C  D

用戶可以一次升級依賴項(rebar3 upgrade A和rebar3 upgrade B)或兩者(rebar3 upgrade A,B或者rebar3 upgrade升級所有依賴項)。

只升級A意味着A和C可升級。升級B和D將被忽略。

然而,升級源依賴性充滿了危險,並且出現了有趣的特殊案例。考慮以下依賴樹:

    A       B       C1
   / \     / \     / \
  D   E   F   G   H   I2
  |   |
  J   K
  |
  I1

在獲取上面的依賴樹之後,I2將在I1之前被選擇。不過,從之後升級C1到C2而且新的C2不再需要依賴I2,Rebar3將自動獲取I1下A樹(即使沒有升級A是必需的),以提供正確的新樹:

    A       B     C2
   / \     / \    |
  D   E   F   G   H
  |   |
  J   K
  |
  I1

這是I2不存在了,I1還在,也就是之前一直使用I2因爲C2的更新,導致系統不再使用I2而是變成了I1

鎖文件 Lock File

鎖文件(rebar.lock)是唯一一個由rebar3生成,但是不在_build目錄的產物,這個文件應該被包含在你的源代碼列表中,鎖文件包含有關代碼依賴的信息,包括源依賴中的不可變引用(入git和hg中的那些),以及他們的版本和包預期的哈希值。

這麼做的目的是爲了使用更準確的依賴而不是通過配置文件自己獲得的信息,例如,配置從master更新,這會把你更新到的依賴鎖定到一個此刻相對穩定的版本,只有unlock和upgrading才能讓他真的更新到一個更新的版本,這麼做可以保證即使你使用的源被某人修改了,你的每次構建內容也不會受影響,他是穩定的。

當切換分支或獲取傳遞deps時,Rebar3還將使用鎖定文件作爲依賴關係的真正權限來源(它將從鎖定文件中選擇數據,如果有的話)而不是rebar.config文件。當在rebar.config文件中使用鬆散的引用或版本時,這允許更容易地將安全測試狀態攜帶到其他應用程序中。

從版本3.0.0(實際上是beta-4)開始,該格式預計將向前和向後兼容。Rebar3將根據存儲的元數據格式註釋鎖定文件版本,並在舊版本的rebar3用於讀取較新版本的鎖定文件時發出警告。這可以告訴用戶使用該工具的較舊副本將丟失一些在以後被判斷爲重要的元數據。

依賴鎖管理

可以使用以下方法檢查鎖和依賴項的狀態rebar3 deps:

→ rebar3 deps
cowboy* (package)
recon* (git source)
erlware_commons (locked git source)
getopt* (locked git source)
providers (locked hg source)
relx (locked git source)

依賴項與鎖定文件將進行比較以報告其狀態。磁盤上的存在與鎖定文件不匹配的那些用星號(*)註釋。

如果依賴項已鎖定但不再需要,也不在配置文件中,則可以將其取消標記rebar3 unlock <app>(rebar3 unlock <app1>,<app2>,...,<app3>對於許多應用程序)。

調用rebar3 unlock將完全刷新鎖定文件。這以爲着你下次更新到的某些從master獲得的依賴可能和之前的依賴不一致了,這可能會導致其他問題,所以unlock的時候一定要小心,最好是unlock指定app而不是全部

rebar3 tree可用於顯示當前依賴關係樹:

→ rebar3 tree
...
|- bootstrap-0.0.2 (git repo)
|- dirmon-0.1.0 (project app)
|- file_monitor-0.1 (git repo)
|- peeranha-0.1.0 (git repo)
|  |- gproc-git (git repo)
|  |- interclock-0.1.2 (git repo)
|  |  |- bitcask-1.7.0 (git repo)
|  |  |  |- lager-2.1.1 (hex package)
|  |  |  |  |- goldrush-0.1.6 (hex package)
|  |  |- itc-1.0.0 (git repo)
|  |- merklet-1.0.0 (git repo)
|- recon-2.2.2 (git repo)
|- uuid-1.5.0 (git repo)
|  |- quickrand-1.5.0 (git repo)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章