依賴和配置文件
依賴永遠按照prod模式對應的profile進行編譯,不會有其他(當然不包括default)任何東西會被額外的套用上來,即使它們是爲prod依賴項配置的,仍然會將其提取到其聲明的配置文件的配置文件目錄中。例如,頂層的依賴關係deps將放在_build/default/lib下,test將放在_build/test/lib下,並且兩者都將在prod應用其配置文件配置的情況下進行編譯。
在任何項目中,根據任務運行或運行任務的人員的角色,總會有一組所需的選項。
例如,在Erlang項目中,最常見的示例是僅針對測試運行所需的依賴項,例如模擬庫或特定測試工具或框架。
rebar3使用配置文件的概念來滿足這些要求。配置文件是一組配置設置,僅在這些特定上下文之一中使用,覆蓋或補充常規配置。他們的目標是能夠支持多個開發用例,同時保持可重複性,而無需外部工具或環境值來完成這項工作。
可以通過三種不同方式指定運行的配置文件:
- 修改REBAR_PROFILE環境變量
- 使用
rebar3 as <profile> <command>
或rebar3 as <profile1>,<profile2> <command>
- 特殊的rebar3命令,例如ct和eunit總是會添加test項的配置內容
任何這些形式(甚至是所有這些形式)都會讓rebar3知道它應該作爲特殊配置文件之一運行並相應地修改其配置。
可以在主rebar.config文件中指定配置文件配置:
{profiles, [{ProfileName1, [Options, ...]},
{ProfileName2, [Options, ...]}]}.
例如,meck僅爲測試運行添加依賴關係的測試配置文件可以定義爲:
{profiles, [{test, [{deps, [meck]}]}]}.
任何配置值都可以包含在配置文件中,包括插件,編譯器選項,發行選項等。
例子
更完整的示例如下所示:
{deps, [...]}.
{relx, [
...
]}.
{profiles, [
{prod, [
{erl_opts, [no_debug_info, warnings_as_errors]},
{relx, [{dev_mode, false}]}
]},
{native, [
{erl_opts, [{native, o3}]}
]},
{test, [
{deps, [meck]},
{erl_opts, [debug_info]}
]}
]}.
因此,這樣一個項目有四個不同的模式:
- default, 所有執行模式下的基礎配置,對應於整個rebar.config中的配置
- prod, 生產環境,可能會去掉符號鏈接,或者加入更嚴格的編譯檢查之類
- native, 強制使用HiPE進行編譯,以獲得更快的數學代碼
- test,它可以加載模擬庫,並允許在測試運行期間將調試信息保存在文件中。
這些可能在很多場景下結合在一起。以下是示例運行:
rebar3 ct
:將運行項目的常見測試套件。按順序,應用的配置文件將是default,然後test,因爲ct要求使用test配置文件。rebar3 as test ct
:將像以前一樣運行。配置文件不會重複應用多次。rebar3 as native ct
:將以純本地運行測試。配置文件的順序是’default’,然後是’native’,最後是’test’(最後由命令運行指定)。rebar3 as test,native ct
:將與上述相同。在應用配置文件時,rebar3首先將它們全部展開,然後按正確的順序應用它們。所以爲了在這裏會default,然後test,然後native,然後test再次(因爲的ct命令)。由於配置文件可應用於idempotently,這僅相當於調用rebar3 as native ct。rebar3 release
將僅作爲default配置文件構建版本。rebar3 as prod release
將使用更嚴格的編譯器選項來構建沒有開發模式的版本。rebar3 as prod, native release
將使用最後一個命令構建發行版,但同時還將模塊編譯爲本機模式。rebar3 as prod release
而REBAR_PROFILE=native在環境中將像上一個命令一樣構建發佈,但native將在prod之前應用。
因此,配置文件的應用順序如下:
default
REBAR_PROFILE
值,如果有的話as
命令行部分中指定的配置文件- 每個命令指定的配置文件
通常,配置文件因此應該是可組合的,用於配置要使用的配置子集。
依賴鎖定
只有主的rebar.config文件中定義的依賴項會被鎖定,而依賴項的依賴項則不會
如果有人想“鎖定”編譯(使用生產配置),答案是使用releases(參見[[Releases]]),它允許生成可以在任何時間重用的編譯工件,如果用於部署可以以rebar3 tar進行打包部署。
選項合併算法
嘗試自動合併所有配置選項通常很棘手。不同的工具或命令會以不同的方式期望它們,或者將lists of tuples, proplists, key/value pairs轉換爲某種字典。
爲了支持儘可能最通用的形式,rebar3將它們作proplists 和 tuple lists的鬆散組合來處理。這意味着以下選項都被視爲具有密鑰native
:
native
{native, o3}
{native, still, supported}
即使其中一些工具可能支持也可能不支持。例如,Erlang編譯器支持將宏定義爲{d, 'MACRONAME'}
或者{d, 'MACRONAME', MacroValue}
,但單獨的d不行,而它確實支持native
和{native, o3}
。
rebar3正確支持所有這些表單並以功能方式合併它們。我們以下面的配置文件爲例:
{profiles, [
{prod, [
{erl_opts, [no_debug_info, warnings_as_errors]},
]},
{native, [
{erl_opts, [{native, o3}, {d, 'NATIVE'}]}
]},
{test, [
{erl_opts, [debug_info]}
]}
]}.
以不同的順序調用這些配置將生成不同的erl_opts列表:
rebar3 as prod,native,test <command>
: [debug_info, {d, ‘NATIVE’}, {native, o3}, no_debug_info, warnings_as_errors]rebar3 as test,prod,native <command>
: [{d, ‘NATIVE’}, {native, o3}, no_debug_info, warnings_as_errors, debug_info]rebar3 as native,test,prod <command>
: [no_debug_info, warnings_as_errors, debug_info, {d, ‘NATIVE’}, {native, o3}]rebar3 as native,prod,test <command>
: [debug_info, no_debug_info, warnings_as_errors, {d, ‘NATIVE’}, {native, o3}]
請注意,應用的最後一個配置文件會生成列表中的第一個元素,並且每個配置文件列表中的元素將根據其鍵進行排序。
這將允許rebar3命令以正確的順序拾取元素,同時仍然支持需要許多元素共享相同鍵的多值列表(例如[{d, ‘ABC’}, {d, ‘DEF’}],這是兩個獨立的宏!)。不支持重複元素的命令可以在第一個元素之後停止處理它們,而那些構建字典(或映射)的命令可以選擇按原樣插入它們,或者可以安全地反轉列表(如果最後處理的元素變爲maps中的最後一個)。
所有配置文件合併規則都以這種方式安全處理。插件編寫者應該瞭解這些規則並做出相應的計劃。