2021/11/29

rebar3 configuration

Configuration

Base Config

  • OS 環境變數
REBAR_PROFILE="term"         # force a base profile
HEX_CDN="https://..."        # change the Hex endpoint for a private one
QUIET=1                      # only display errors
DEBUG=1                      # show debug output
                             # "QUIET=1 DEBUG=1" displays both errors and warnings
REBAR_COLOR="low"            # reduces amount of color in output if supported
REBAR_CACHE_DIR              # override where Rebar3 stores cache data
REBAR_GLOBAL_CONFIG_DIR      # override where Rebar3 stores config data
REBAR_CONFIG="rebar3.config" # changes the name of rebar.config files
REBAR_GIT_CLONE_OPTIONS=""   # pass additional options to all git clone operations
                             # for example, a cache across project can be set up
                             # with "--reference ~/.cache/repos.reference"
http_proxy                   # standard proxy ENV variable is respected
https_proxy                  # standard proxy ENV variable is respected
TERM                         # standard terminal definition value. TERM=dumb disables color
  • Alias

執行多個指令的 alias

{alias, [{check, [eunit, {ct, "--sys_config=config/app.config"}]}]}.
  • Artifacts

在成功編譯後,必須要存在的 a list of files

rebar3 會知道 non-Erlang artifacts (例如 shared libraries in C code)是否有 built 成功

{artifacts, [file:filename_all()]}.

template keys

template key description default value
profile_dir base output dir with the profile string appended _build/default/
base_dir base output dir _build
out_dir applicaiton's output dir _build/default/lib/
{escript_name, rebar3}.

{provider_hooks, [{post, [{compile, escriptize}]}]}.

%% path 是 umbrella project 的 toplevel 的相對目錄
{artifacts, ["bin/rebar3"]}.

%% {{profile_dir}}
{artifacts, ["{{profile_dir}}/bin/rebar3"]}.
  • Compilation

compiler options,可使用的 options 可參考 文件

% version string might look like "22.0-x86_64-apple-darwin18.5.0-64"
{erl_opts, [{platform_define,
               "(linux|solaris|freebsd|darwin)",
               'HAVE_SENDFILE'},
              {platform_define, "(linux|freebsd)",
                'BACKLOG', 128},
              {platform_define, "^18",
                'OTP_GREATER_THAN_18'},
              {platform_define, "^R13",
                'old_inets'}]
}.

erlfirstfiles 可在編譯其他檔案時,先編譯這些 modules

{erl_first_files, ["src/mymodule.erl", "src/mymodule.erl"]}.

還有一些 general options

{validate_app_modules, true}. % Make sure modules in .app match those found in code
{app_vars_file, undefined | Path}. % file containing elements to put in all generated app files
%% Paths the compiler outputs when reporting warnings or errors
%% relative (default), build (all paths are in _build, default prior
%% to 3.2.0, and absolute are valid options
{compiler_source_format, relative}.

其他相關 compiler options

rebar3 compiler options

%% Disable or enable recursive compiling globally
{erlc_compiler,[{recursive,boolean()}]}.

%%%%%%%%%%
%% Disable or enable recursive compiling on src_dirs
{src_dirs, [{"src", [{recursive, true|false}]}]}
%% Or alternatively:
{erl_opts, [{src_dirs,[{string(),[{recursive,boolean()}]}]}]}.

%%%%%%%%%%%
%% Disable or enable recursive compiling on for extra_src_dirs:
{extra_src_dirs, [{"test", [{recursive, true | false}]}]}
%% or
{erl_opts, [{extra_src_dirs,[{string(),[{recursive,boolean()}]}]}]}.

example: Disable recursive compiling globally, but enable it for a few dirs

{erlc_compiler,[{recursive,false}]},
{erl_opts,[{src_dirs,["src",{"other_src",[{recursive,true}]}]}]}.

example: Disable recursive compiling on test and other dirs

{erl_opts, [
            {extra_src_dirs,[
                    {"test", [{recursive,boolean()}]},
                    {"other_dir", [{recursive,boolean()}]}]}
            ]
}.
  • Common Test
{ct_first_files, [...]}. % {erl_first_files, ...} but for CT
{ct_opts, [...]}. % same as options for ct:run_test(...)
{ct_readable, true | false}. % disable Rebar3 modifying CT output in the shell

ref: ct_opts

  • Cover

{cover_enabled, true} enable code coverage in tests

{cover_opts, [verbose]} 讓 coverage report 印到 terminal,不只是在 files

{cover_excl_mods, [Modules]} blacklist some modules

{cover_excl_apps, [AppNames]} blacklist some apps

  • Dialyzer
-type warning() :: no_return | no_unused | no_improper_lists | no_fun_app | no_match | no_opaque | no_fail_call | no_contracts | no_behaviours | no_undefined_callbacks | unmatched_returns | error_handling | race_conditions | overspecs | underspecs | specdiffs

{dialyzer, [{warnings, [warning()]},
            {get_warnings, boolean()},
            {plt_apps, top_level_deps | all_deps} % default: top_level_deps
            {plt_extra_apps, [atom()]},
            {plt_location, local | file:filename()},
            {plt_prefix, string()},
            {base_plt_apps, [atom(), ...]},
            {base_plt_location, global | file:filename()},
            {base_plt_prefix, string()}]}.
  • Distribution
{dist_node, [
    {setcookie, 'atom-cookie'},
    {name | sname, 'nodename'},
]}.
  • Directories

以下是可使用的 目錄變數 的預設值

%% directory for artifacts produced by Rebar3
{base_dir, "_build"}.
%% directory in '<base_dir>/<profile>/' where deps go
{deps_dir, "lib"}.
%% where Rebar3 operates from; defaults to the current working directory
{root_dir, "."}.
%% where checkout dependencies are to be located
{checkouts_dir, "_checkouts"}.
%% directory in '<base_dir>/<profile>/' where plugins go
{plugins_dir, "plugins"}.
%% directories where OTP applications for the project can be located
{project_app_dirs, ["apps/*", "lib/*", "."]}.
%% Directories where source files for an OTP application can be found
{src_dirs, ["src"]}.
%% Paths to miscellaneous Erlang files to compile for an app
%% without including them in its modules list
{extra_src_dirs, []}.
%% Paths the compiler outputs when reporting warnings or errors
%% relative (default), build (all paths are in _build, default prior
%% to 3.2.0, and absolute are valid options
{compiler_source_format, relative}.

rebar3 有另外儲存資料在這個目錄,可用這個方式修改 {global_rebar_dir, "./some/path"}.

%% 設定資料
~/.config/rebar3

%% cache
~/.cache/rebar3
  • EDoc

參考 文件

{edoc_opts, [...]}.
  • Escript

參考escriptize command

{escript_main_app, AppName}. % specify which app is the escript app
{escript_name, "FinalName"}. % name of final generated escript
{escript_incl_apps, [App]}. % apps (other than the main one and its deps) to be included
{escript_emu_args, "%%! -escript main Module\n"}. % emulator args
{escript_shebang, "#!/usr/bin/env escript\n"}. % executable line
{escript_comment, "%%\n"}. % comment at top of escript file
  • EUnit

eunit options

{eunit_first_files, [...]}. % {erl_first_files, ...} but for CT
{eunit_opts, [...]}. % same as options for eunit:test(Tests, ...)
{eunit_tests, [...]}. % same as Tests argument in eunit:test(Tests, ...)
  • Hex Repos and Indexes

Rebar3 version 3.7.0 以後就支援多個 Hex repositories

如果要使用 private repository,就要安裝 rebar3_hex plugin

% 認證
rebar3 hex auth

% 會產生 ~/.config/rebar3/hex.config 記錄 keys
{hex, [
   {repos, [
      %% A self-hosted repository that allows publishing may look like this
      #{name => <<"my_hexpm">>,
        api_url => <<"https://localhost:8080/api">>,
        repo_url => <<"https://localhost:8080/repo">>,
        repo_public_key => <<"-----BEGIN PUBLIC KEY-----
        ...
        -----END PUBLIC KEY-----">>
      },
      %% A mirror looks like a standard repo definition, but uses the same
      %% public key as hex itself. Note that the API URL is not required
      %% if all you do is fetch information
      #{name => <<"jsDelivr">>,
        repo_url => <<"https://cdn.jsdelivr.net/hex">>,
        ...
       },
       %% If you are a paying hex.pm user with a private organisation, your
       %% private repository can be declared as:
       #{name => <<"hexpm:private_repo">>}
       %% and authenticate with the hex plugin, rebar3 hex user auth
   ]}
]}.

%% The default Hex config is always implicitly present.
%% You could however replace it wholesale by using a 'replace' value,
%% which in this case would redirect to a local index with no signature
%% validation being done. Any repository can be replaced.
{hex, [
   {repos, replace, [
      #{name => <<"hexpm">>,
        api_url => <<"https://localhost:8080/api">>,
        repo_url => <<"https://localhost:8080/repo">>,
        ...
       }
   ]}
]}.
  • Minimum OTP Version
{minimum_otp_vsn, "17.4"}.
  • Overrides

可修改某個 dependency 的 config,以便快速解決一些套件的設定問題

有三種:add, override on app, override on all

{overrides, [{add, app_name(), [{atom(), any()}]},
             {del, app_name(), [{atom(), any()}]},
             {override, app_name(), [{atom(), any()}]},
             {add, [{atom(), any()}]},
             {del, [{atom(), any()}]},
             {override, [{atom(), any()}]}]}.

apply 順序:override on all, app override, per app additions

example: 強制編譯時,增加 debug_info,並在 production profile,強制為 no_debug_info

{overrides, [{override, [{erl_opts, [debug_info]}]}]}.

{profiles, [{prod, [{overrides, [{override, [{erl_opts,[no_debug_info]}]}]},
                    {relx, [{dev_mode, false},
                            {include_erts, true}]}]}
           ]}.

example: 對所有 app 移除 warnings_as_errors 編譯設定

{overrides, [
    %% For all apps:
    {del, [{erl_opts, [warnings_as_errors]}]},
    %% Or for just one app:
    {del, one_app, [{erl_opts, [warnings_as_errors]}]}
]}.
  • Shell Hooks
-type hook() :: {atom(), string()}
              | {string(), atom(), string()}.

{pre_hooks, [hook()]}.
{post_hooks, [hook()]}.

example: 用 rebar3 編譯 merl

{pre_hooks, [{"(linux|darwin|solaris)", compile, "make -C \"$REBAR_DEPS_DIR/merl\" all -W test"},
             {"(freebsd|netbsd|openbsd)", compile, "gmake -C \"$REBAR_DEPS_DIR/merl\" all"},
             {"win32", compile, "make -C \"%REBAR_DEPS_DIR%/merl\" all -W test"},
             {eunit, "erlc -I include/erlydtl_preparser.hrl -o test test/erlydtl_extension_testparser.yrl"},
             {"(linux|darwin|solaris)", eunit, "make -C \"$REBAR_DEPS_DIR/merl\" test"},
             {"(freebsd|netbsd|openbsd)", eunit, "gmake -C \"$REBAR_DEPS_DIR/merl\" test"},
             {"win32", eunit, "make -C \"%REBAR_DEPS_DIR%/merl\" test"}
            ]}.
  • Provider Hooks

在 compile 以前要先做 clean

{provider_hooks, [{pre, [{compile, clean}]}
                  {post, [{compile, {erlydtl, compile}}]}]}

Hookable Points in Providers

Hook before and after
clean each application and dependency, and/or before and after all top-level applications are compiled*
ct the entire run
compile each application and dependency, and/or before and after all top-level applications are compiled*
edoc the entire run
escriptize the entire run
eunit the entire run
release the entire run
tar the entire run
erlc_compile compilation of the beam files for an app
app_compile building of the .app file from .app.src for an app
  1. the rebar.config file at the application root

  2. each top-level app’s (in apps/ or libs/) rebar.config

  3. each dependency’s rebar.config

  • Relx

參考 Release 章節

  • Plugins

參考 Plugins 章節

  • Shell

如果有 relex entry,rebar3 shell REPL 會自動 boot applications

被啟動的 app 要用這個指定 {shell, [{apps, [App]}]}.

Option Value Description
apps [app1, app2, …] Applications to be booted by the shell. Overtakes the relx entry values
config “path/to/a/file.config” 載入 .config file
script_file “path/to/a/file.escript” 在 booting app前,執行 escript
appreloadblacklist [app1, app2, …] 呼叫 r3.compile()不載入的 apps
對於 ranch 很有用,因為載入兩次會 crash
  • XRef
{xref_warnings,false}.
{xref_extra_paths,[]}.
{xref_checks,[undefined_function_calls,undefined_functions,locals_not_used,
              exports_not_used,deprecated_function_calls,
              deprecated_functions]}.
{xref_queries,[{"(xc - uc) || (xu - x - b - (\"mod\":\".*foo\"/\"4\"))", []}]}.
{xref_ignores, [Module, {Module, Fun}, {Module, Fun, Arity}]}.

可用 -ignore_xref(_). 忽略 warnings

-ignore_xref({other, call, 0}).   % ignore warnings for calls to "external" module function
-ignore_xref([{other, call, 0}]). % equivalent to the previous declaration

-ignore_xref({function,0}).       % ignore warnings for locally exported function not used in the analysis scope
-ignore_xref([{function,0}]).     % equivalent to the previous declaration
-ignore_xref(function/0).         % equivalent to the previous declaration
-ignore_xref([function/0]).       % equivalent to the previous declaration

-ignore_xref(module).             % ignore warnings related to a given module
-ignore_xref([module]).           % equivalent to previous declaration

Dependencies

  • 宣告

rebar.config 宣告 dependencies,可用 rebar3 tree 查看

rebar3 支援兩種 dependencies

  1. source (git, Mercurial)

  2. package dependencies

    使用 hex.pm 提供的 packages,會 cache 在 ~/.cache/rebar3/

{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, "git@github.com: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"}}},
  %% Source dependencies (git only) in subdirectories, from version 3.14 onwards
  {rebar, {git_subdir, "git://github.com/erlang/rebar3.git", {branch, "main"}, "subdir"}},
  {rebar, {git_subdir, "git://github.com/erlang/rebar3.git", {tag, "3.14"}, "sub/dir"},
  {rebar, {git_subdir, "git://github.com/erlang/rebar3.git", {ref, "aeaefd"}, "dir"}
]}.
  • Runtime Dependencies

要將 dependency 加到 appapp.src 裡面

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

hex dependencies 可用 semver-like syntax

{deps,[
  rebar,                   % fetches latest known version, ignoring pre-releases
  {rebar, "~> 2.0.0"},     % >= 2.0.0 and < 2.1.0`
  {rebar, "~> 2.1.2"},     % >= 2.1.2 and < 2.2.0`
  {rebar, "~> 2.1.3-dev"}` % >= 2.1.3-dev and < 2.2.0`
  {rebar, "~> 2.0"}`       % >= 2.0.0 and < 3.0.0`
  {rebar, "~> 2.1"}`       % >= 2.1.0 and < 3.0.0`
]}.

呼叫指令更新 package dependencies

rebar3 update

如果要改用其他 hex.pm CDN,可在 rebar.config 增加設定

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

如要處理 dependencies 而不需要持續 publish new version,可利用 _checkouts 目錄,只要把 dependency 建立 symlink 到 _checkouts 即可

_checkouts
└── depA
    └── src
  • Fetching Order
  A
 / \
B   C

A -> B -> C

   A
 /   \
B    C1
|
C2

A -> B -> C1 -> skip C2 (因為跟 C1 一樣)

   A
 /   \
B     C
|     |
D1    D2

A -> B -> C -> D1 -> skip D2

  A D2
 /   \
B     C
|     |
D1    D2

A -> B -> C -> D2 (將 D2 提前到 top level)

  • Lock Files
rebar.lock

由 rebar3 產生,必須要放入 source control。會紀錄確切的 dependencies 的版本號碼,避免 rebar.config 太過鬆散的版本設定

  • Upgrading Dependencies
A  B
|  |
C  D

可以單獨或全部更新

rebar3 upgrade A
rebar3 upgrade B

% 全部
rebar3 upgrade A,B
rebar3 upgrade
% flush the lock file
rebar3 unlock

% 查看 dependencies
rebar3 tree

Profiles

profile 是一組 configuration settings 用在特定的 context

有三種指定方式

  1. rebar3 as <profile> <command>rebar3 as <profile1>,<profile2> <command>
  2. 特定的 rebar3 指令,例如 eunitct 都會使用 test profile
  3. REBAR_PROFILE 環境變數

在 rebar.config 中的設定

{profiles, [{ProfileName1, [Options, ...]},
            {ProfileName2, [Options, ...]}]}.

example: test profile 增加 meck dependency

{profiles, [{test, [{deps, [meck]}]}]}.

example:

{deps, [...]}.
{relx, [
    ...
]}.

{profiles, [
    {prod, [
        {erl_opts, [no_debug_info, warnings_as_errors]},
        {relx, [{dev_mode, false}]}
    ]},
    {native, [
        {erl_opts, [{native, {hipe, o3}}]}
    ]},
    {test, [
        {deps, [meck]},
        {erl_opts, [debug_info]}
    ]}
]}.

有四個 profile

  1. default
  2. prod 通常用來產生 full releases without symlinks
  3. nativeHiPE 編譯
  4. test 會載入 mocking libraries

執行時

  1. rebar3 ct

    執行 Common Test Suites,會使用 defaulttest profiles

  2. rebar3 as test ct

    跟上面一樣

  3. rebar3 as native ct

    native mode,profile: default -> native -> test

  4. rebar3 as test,native ct

    profile: default -> test -> native

  5. rebar3 release

    profile: default

  6. rebar3 as prod release

    build release without developement mode

  7. rebar3 as prod,native release

    build release 但 compiling modules to native mode

  8. rebar3 as prod release with REBAR_PROFILE=native

    build release, profile: native -> prod

profile 順序

  1. default
  2. REBAR_PROFILE
  3. as
  4. command 的特定 profile

只有 default profile 的 dependencies ,也就是 rebar.config 的 dependencies 會寫入 rebar.lock

  • Option-Merging Algorithm

rebar3 可將三種寫法的 option 合併在一起

  1. native

  2. {native, {hipe, o3}}

  3. {native, still, supported}

example:

{profiles, [
    {prod, [
        {erl_opts, [no_debug_info, warnings_as_errors]},
    ]},
    {native, [
        {erl_opts, [{native, {hipe, o3}}, {d, 'NATIVE'}]}
    ]},
    {test, [
        {erl_opts, [debug_info]}
    ]}
]}.

不同的 profile 會有不同的 options fot erl_opts

  1. rebar3 as prod,native,test <command>: [debug_info, {d, 'NATIVE'}, {native, {hipe, o3}}, no_debug_info, warnings_as_errors]
  2. rebar3 as test,prod,native <command>: [{d, 'NATIVE'}, {native, {hipe, o3}}, no_debug_info, warnings_as_errors, debug_info]
  3. rebar3 as native,test,prod <command>: [no_debug_info, warnings_as_errors, debug_info, {d, 'NATIVE'}, {native, {hipe, o3}}]
  4. rebar3 as native,prod,test <command>: [debug_info, no_debug_info, warnings_as_errors, {d, 'NATIVE'}, {native, {hipe, o3}}]

要注意,最後一個 profile 會先被 apply

Plugins

plugin 可安裝在 project (放在 project 的 rebar.config 的 plugins)或是 globally(放在 ~/.config/rebar3/rebar.config)。

  • Including Plugins

build application 需要的 plugins,會產生到 _build/<profile>/plugins/ 裡面。

可用在 provider_hooks

{plugins, [{rebar_erl_vsn, "~> 0.1"}]}.
{provider_hooks, [{pre, [{compile, {default, erl_vsn}}]}]}.
  • Project Plugins and Overriding Commands

project_plugins 定義直接以 rebar3 編譯時,可使用的 plugins

example: 在build release 時,使用 cuttlefish

{project_plugins, [rebar3_cuttlefish]}.

執行 rebar3 relaserebar3 tar 會啟動 rebar3_cuttlefish providers

example: 在開發時使用某些 plugin

以往需要在 dev profile 裡面使用 plugin,現在可定義 project plugin

{project_plugins, [rebar3_gpb_plugin]}.

然後直接這樣使用

rebar3 protobuf
  • Upgrading Plugins

必須呼叫指令才更新

  1. rebar3 plugins upgrade <plugin_name>

    更新 project-local plugin

  2. rebar3 as global plugins upgrade <plugin_name>

    更新 global plugins

如果是使用 Hex package 的 plugins,版本錯了,必須要呼叫 rebar3 update 更新 Hex index

因 plugins 並沒有被 lock file 鎖定,故建議使用時要指定版本

  • Recommended Plugins

Auto Compile and Load

{plugins, [rebar3_auto]}.

建議 global 使用 auto,也就是放在 ~/.config/rebar3/rebar.config

rebar3 auto 會啟動 shell (跟 rebar3 shell) 一樣,並監測 src dir 的 file changes,只要有更新就會自動編譯。

Auto-Test

{plugins, [{rebar3_autotest, "0.1.1"}]}.

建議 global 使用

rebar3 as test autotest 會啟動 eunit,並監測 src, headers, test-files 的異動

Hex Package Management

{plugins, [rebar3_hex]}.

建議 global 使用

參考 Hex Package Management

Port Compiler

rebar interface to build C, C++

在 project 的 rebar.config 增加以下設定

{plugins, [pc]}.

{provider_hooks,
 [
  {pre,
   [
    {compile, {pc, compile}},
    {clean, {pc, clean}}
   ]
  }
 ]
}.

支援的設定變數

%% Supported configuration variables:
%%
%% * port_specs - Erlang list of tuples of the forms
%%                {ArchRegex, TargetFile, Sources, Options}
%%                {ArchRegex, TargetFile, Sources}
%%                {TargetFile, Sources}
%%
%% * port_env - Erlang list of key/value pairs which will control
%%              the environment when running the compiler and linker.
%%              Variables set in the surrounding system shell are taken
%%              into consideration when expanding port_env.
%%
%%              By default, the following variables are defined:
%%              CC       - C compiler
%%              CXX      - C++ compiler
%%              CFLAGS   - C compiler
%%              CXXFLAGS - C++ compiler
%%              LDFLAGS  - Link flags
%%              ERL_CFLAGS  - default -I paths for erts and ei
%%              ERL_LDFLAGS - default -L and -lerl_interface -lei
%%              DRV_CFLAGS  - flags that will be used for compiling
%%              DRV_LDFLAGS - flags that will be used for linking
%%              EXE_CFLAGS  - flags that will be used for compiling
%%              EXE_LDFLAGS - flags that will be used for linking
%%              ERL_EI_LIBDIR - ei library directory
%%              DRV_CXX_TEMPLATE      - C++ command template
%%              DRV_CC_TEMPLATE       - C command template
%%              DRV_LINK_TEMPLATE     - C Linker command template
%%              DRV_LINK_CXX_TEMPLATE - C++ Linker command template
%%              EXE_CXX_TEMPLATE      - C++ command template
%%              EXE_CC_TEMPLATE       - C command template
%%              EXE_LINK_TEMPLATE     - C Linker command template
%%              EXE_LINK_CXX_TEMPLATE - C++ Linker command template
%%
%%              Note that if you wish to extend (vs. replace) these variables,
%%              you MUST include a shell-style reference in your definition.
%%              e.g. to extend CFLAGS, do something like:
%%
%%              {port_env, [{"CFLAGS", "$CFLAGS -MyOtherOptions"}]}
%%
%%              It is also possible to specify platform specific options
%%              by specifying a triplet where the first string is a regex
%%              that is checked against Erlang's system architecture string.
%%              e.g. to specify a CFLAG that only applies to x86_64 on linux
%%              do:
%%
%%              {port_env, [{"x86_64.*-linux", "CFLAGS",
%%                           "$CFLAGS -X86Options"}]}
%%
%%              Cross-arch environment variables to configure toolchain:
%%              GET_ARCH to set the tool chain name to use
%%              GET_ARCH_WORDSIZE (optional - to determine word size)"
%%              word size is 32
%%              GET_ARCH_VSN (optional - "
%%              l version of CC/CXX is requested),

Run Release

{plugins, [rebar3_run]}.

rebar3 run 會啟動 release console,取代 _build/default/rel/<release>/bin/<release> console

Alias

rebar3 (v3.5.0 以後直接支援 不需要 plugin)

舊版 rebar3

{plugins, [rebar_alias]}.

{alias, [{check, [eunit, {ct, "--sys_config=config/app.config"}]}]}.

參數以 {Provider, Args}. 方式設定

QuickCheck

{plugins, [rebar3_eqc]}.

etc_opts

{eqc_opts, [{numtests, 500}]}.
Config Option Type Description
numtests integer Number of test executions, default 100.
testing_time integer Time in seconds to execute property. If both are specified, the testing_time setting is ignored.

Command line options

Option Type Description
-n integer Number of test executions, default 100.
-t integer Time in seconds to execute property. If both are specified, the testing_time setting is ignored.
-p string Property to execute. This can be either module:property or property and the plugin will determine the module.

PropEr

可取代 Quviq QuickCheck

%% the plugin itself
{plugins, [rebar3_proper]}.

%% The PropEr dependency is still required to compile the test cases
{profiles,
    [{test, [
        {deps, [{proper, "1.1.1-beta"}]}
    ]}
]}.

options

{proper_opts, Options}

rebar.config key Command Line Description
{dir, String} -d, –dir directory where the property tests are located (defaults to “test”)
{module, [Modules]} -m, –module name of one or more modules to test
{properties, [PropNames]} -p, –prop name of properties to test within a specified module
{numtests, N} -n, –numtests number of tests to run when testing a given property
verbose | quiet -v, –verbose Whether each property tested shows its output or not (defaults to true/verbose)
{cover, true | false} -c, –cover generate cover data (default: false)
long_result –long_result enables long-result mode, displaying counter-examples on failure rather than just false
{start_size, N} –start_size specifies the initial value of the size parameter
{max_size, N} –max_size specifies the maximum value of the size parameter
{max_shrinks, N} –max_shrinks specifies the maximum number of times a failing test case should be shrunk before returning
noshrink –noshrink instructs PropEr to not attempt to shrink any failing test cases
{constraint_tries, N} –constraint_tries specifies the maximum number of tries before the generator subsystem gives up on producing an instance that satisfies a ?SUCHTHAT constraint
{spec_timeout, Millisecs} –spec_timeout duration, in milliseconds, after which PropEr considers an input to be failing
anytointeger –anytointeger converts instances of the any() type to integers in order to speed up execution

Diameter

在 rebar3 編譯 .dia files

{plugins, [rebar3_diameter_compiler]}.

%% 可用 hook 自動編譯與 clean  diameter dictionaries
{provider_hooks, [
    {pre, [
        {compile, {diameter, compile}},
        {clean, {diameter, clean}}
    ]}
]}.

options

Config Option Type Description
dia_opts list Options from diameter_make:codec/2 supported with exception of inherits.
diafirstfiles list Files in sequence to compile first.

ErlyDTL

erlydtl compiler

{plugins, [
    {rebar3_erlydtl_plugin, ".*",
     {git, "https://github.com/tsloughter/rebar3_erlydtl_plugin.git", {branch, "master"}}}
]}.

erlydtl_opts

Config Option Type Description
doc_root string Where to find templates to compile. “priv/templates” by default.
compiler_options proplist Template compilation options to pass to erlydtl. Descriptions here.
out_dir string Where to put compiled template beam files “ebin” by default.
source_ext string The file extension the template sources have “.dtl” by default.
module_ext string Characters to append to the template’s module name “_dtl” by default.
recursive boolean Boolean that determines if doc_root(s) need to be scanned recursively for matching template file names. ‘true’ by default.

Neotoma

使用 Sean Cribbs neotoma app 產生 PEG files,此 plugin 有放在 Hex

{plugins, [rebar3_neotoma_plugin]}.

%% 可用 hook 自動編譯
{provider_hooks, [
    {pre, [{compile, {neotoma, compile}}]}
]}.

Protocol Buffers

利用 Tomas Abrahamsson’s gpb 編譯 .proto,該 plugin 有放到 Hex

{erl_opts, [{i, "./_build/default/plugins/gpb/include/"}]}.
{plugins, [{rebar3_gpb_plugin, "2.10.0"}]}.

{gpb_opts, [{i, "proto"},
        {o_erl, "src"},
        {o_hrl, "include"}]}.

%% 可用 hook 自動編譯
{provider_hooks, [
    {pre, [{compile, {protobuf, compile}}]}
]}.

Appup

generating, compiling, validating .appup.src files,有發布到 Hex

{plugins, [rebar3_appup_plugin]}.

%% 可用 hook 自動編譯
{provider_hooks, [
    {post, [{compile, {appup, compile}},
            {clean, {appup, clean}}]}
]}.

如果要產生兩個 releases 的 .appup 的步驟

git checkout <from version>
rebar3 release
git checkout <to version>
rebar3 release
rebar3 appup generate
rebar3 relup tar
Argument Type Description
previous optional Path location of the previous release to compare with
current optional Path location of the current release to compare with, defaults to build//rel/<appname>
target_dir optional Location of where to generate the .appup file.
previous_version optional Version to update from

Vendoring dependencies

儲存 vendor dependencies within a project

自 rebar3 v3.7.0 開始,可使用 rebar3_path_deps plugin 指定 vendored paths for dependency retrieval

example:

在 helloworld project 裡面新增 helloutils OTP app

# inside of hello-world/
$ rebar3 new app hello_utils

會產生 hello_utils folder,裡面有 rebar.config 及 src

為了讓 rebar3 知道有這個 app,必須在 helloworld/rebar.config 裡面 add helloutils

也就是 helloworld depend on helloutils

{deps, [
  {hello_utils, {path, "hello_utils"}},
  ...
]

把 plugin 放到 rebar.config

{plugins, [
   rebar3_path_deps
]}.

編譯時

$ rebar3 compile
===> Compiling rebar3_path_deps
===> Verifying dependencies...
===> Fetching hello_utils ({path,"hello_utils",
                            {mtime,<<"2018-10-17T11:21:18Z">>}})
===> Compiling hello_utils
===> Compiling hello_world

在 v3.7.0 以前,要 add plugin

{plugins, [rebar3_vendor]}.

儲存 fetched dependencies 到 ./deps/

rebar3 vendor store

取得 dependencies,放到 build dir

rebar3 vendor apply

SVN Dependencies

rebar3svndeps

Elixir Dependencies

自 v3.7.0 開始,以 rebar_mix 支援 Mix dependencies

{plugins, [rebar_mix]}.

{provider_hooks, [{post, [{compile, {mix, consolidate_protocols}}]}]}.

consolidate_protocols hook 會將 beams 放到 _build//consolidated

release 時要自己複製進去

{overlay, [{copy, "{{base_dir}}/consolidated", "releases/{{release_version}}/consolidated"}]}

update vm.args.src

-pa releases/${REL_VSN}/consolidate

v3.7.0 以前,建議使用 rebar3elixircompile plugin

Config Scripts

rebar.config*.app.src 可透過 file:script/2 做 dynamic configuration

在原始 file 的相同目錄,有 .script 檔案,該檔案會作為 configuration

ex: rebar.config 以及 rebar.config.script

example: rebar.config.script

case os:getenv("REBAR_DEPS") of
    false -> CONFIG; % env var not defined
    []    -> CONFIG; % env var set to empty string
    Dir ->
    lists:keystore(deps_dir, 1, CONFIG, {deps_dir, Dir})
end.

如果要 build properly,就先呼叫 unset REBAR_DEPS

References

rebar3 docs

eeeggghit rebar3

Erlang:Rebar3的简单使用

Automatic release upgrades in Erlang

relx

沒有留言:

張貼留言