1. 全局(所有命令)配置
- rebar3支持一些系统环境变量
变量设置 | 解释 |
---|---|
REBAR_PROFILE="term" | 强制使用基础配置 |
HEX_CDN="https://..." | CDN端点设置 |
REBAR_CONFIG="rebar3.config" | 修改rebar配置文件名称 |
QUIET=1 | 只输出错误信息 |
DEBUG=1 | 输出DEBUG信息 |
REBAR_COLOR="low" | 如果支持,减少输出信息的颜色数量 |
2. Alias(别名)
- 别名允许你根据现有命令,创造一个新的命令出来,当然他们必须有固定的执行顺序才行。
{alias, [{check, [eunit, {ct, "--sys_config=config/app.config"}]}]}.
- 可以像命令行一样,使用
{provider, Args}
替代Provider
来传入参数。
3. Artifacts
-
Artifacts
是项目编译成功之后生成的文件的集合体。这对于rebar3
发现一些非Erlang的模块是否被编译是非常有用的。比如你用C编写了共享库,将它的产出文件配置进去,就可以判断编译是否成功 -
如果发现一个依赖已经被构建(意味着它的
.app
文件的模块列表匹配其.beam
文件并且其所有依赖项已经存在),则在随后的rebar3运行期间将不会编译该部分,也不会出发其hook。
{artifacts, [file:filename_all()]}.
- 相对路径取决于它是否定义在大型项目的顶层。例如,如果我们有一个项目
my_project
,它包含一个apps/my_app/
下的项目应用程序my_app
,my_app
会创建一个escript,告诉rebar3
不要在意my_project/rebar.config
中的配置,因为它是项目顶层的rebar.config
,该artifact
会相对于profile_dir
,默认情况下是_build/default/
:
{escript_name, rebar3}.
{provider_hooks, [{post, [{compile, escriptize}]}]}.
{artifacts, ["bin/rebar3"]}.
- 如果不是在大型项目,即使
my_app
在顶层,,rebar.config
在根目录下,artifact
的相对路径也是_build/default/lib/my_app/
,而不是_build/default
,我们可以使用一个模板来扩展它:
{escript_name, rebar3}.
{provider_hooks, [{post, [{compile, escriptize}]}]}.
{artifacts, ["{{profile_dir}}/bin/rebar3"]}.
- 在下表中列出了所有可用的模板键
Template Key | Description |
---|---|
profile_dir | 配置文件基本输出目录,默认_build/default/ |
base_dir | 基本输出目录, 默认_build |
out_dir | 应用的输出目录, 默认_build/default/lib/<application>/ |
-
再举一个例子
eleveldb
{overrides, [{override, eleveldb, [{artifacts, ["priv/eleveldb.so"]}, ... ] }]}.
-
该artifact
定义在应用程序
eleveldb中,因此它是相对输出目录,意思是上面使用的路径就是
{{out_dir}}/priv/eleveldb.so`
4. 编译
- 编译器选项可以使用
erl_opts
设置,可用的选项列表请查看编译模块。
{erl_opts, []}
- 此外还可以设置平台特定的选项
{erl_opts, [{platform_define, "(linux|solaris|freebsd|darwin)", 'HAVE_SENDFILE'},
{platform_define, "(linux|freebsd)", 'BACKLOG', 128},
{platform_define, "R13", 'old_inets'}]
}.
- 一个单独的选项,是声明在其他模块编译之前的模块(首先需要编译的模块)
{erl_first_files, ["src/mymodule.erl", "src/mymodule.erl"]}.
- 还有一些其他的经常用到的选项
{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}.
- 其他与erlang相关的编译器以及它们自己的配置选项
- Leex compiler:
{xrl_opts, [...]}
- SNMP MIB Compiler:
{mib_opts, [...]}
- Yecc compiler:
{yrl_opts, [...]}
- Leex compiler:
5. 通用测试
{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
-
ct_opts
的支持的配置可以在这里找到 -
可以使用配置项
{ct_opts, [{sys_config, ["name.of.config"]}]}
来加载一个默认的sys.config
的集合。 -
常用的选项可以指定为
Commands
参数
6. Cover
- 使用
{cover_enabled, true}
在tests启用代码覆盖分析,然后cover
提供测试报告。选项{cover_opts, [verbose]}
用于强制将覆盖报告打印到终端,而不仅仅打印到文件中。通过在配置文件中添加{cover_excl_mods, [Modules]}
,可以将特定模块列入代码覆盖分析黑名单。应用程序可以使用{cover_excl_apps, [AppNames]}
选项作为一个整体被列入黑名单。
7. 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()}]}.
- 有关在模块中禁止警告的相关信息,请查看 Dialyzer 文档的
Requesting or Suppressing Warnings in Source Files
部分。
8. Distribution
- 多个功能和插件可能需要支持分布式Erlang。通常,所有此类命令都遵循以下配置值:
{dist_node, [
{setcookie, 'atom-cookie'},
{name | sname, 'nodename'},
]}.
9. Directories(目录)
- 可支持选项和默认值如下:
%% rebar3生成模块目录
{base_dir, "_build"}.
%% '<base_dir>/<profile>/'中的依赖项的目录
{deps_dir, "lib"}.
%% rebar3操作的目录; 默认是当前工作目录
{root_dir, "."}.
%% 依赖项需要被加载的目录
{checkouts_dir, "_checkouts"}.
%% '<base_dir>/<profile>/'中插件的目录
{plugins_dir, "plugins"}.
%% 项目中OTP应用被加载的目录
{project_app_dirs, ["apps/*", "lib/*", "."]}.
%% OTP应用的源码路径
{src_dirs, ["src"]}.
%% app erlang杂项文件编译目录
%% 不包含模块列表
{extra_src_dirs, []}.
%% 当抛出警告或错误的时候的编译输出目录
%% 默认为relative
%% build (all paths are in _build, default prior)
%% 3.2.0版本之后, 选项设置为 absolute
{compiler_source_format, relative}.
- 此外,
rebar3
将一些配置数据存储在~/.config/rebar3
中,并且缓存一些数据到~/.cache/rebar3
中。两者都可以通过指定{global_rebar_dir, "./some/path"}
来覆盖。
10. EDoc
EDoc
支持的所有选项都可以配置到{edoc_opts, [...]}
中。
11. Escript
- 详细信息在
escriptize命令
中,例如下面的配置值。
{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
- 由于
escript
构建的结构,顶级rebar.config
文件中的选项只用于构建一个escript。
12. EUnit
{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, ...)
13. Hex Repos and Indexes (Hex知识库和索引)
-
从
rebar3
的3.7.0版本开始,可以同时使用多个Hex存储库或索引。存储库被定义在一个有序列表中,优先级由高到低。 -
当查找一个包时,存储库按顺序遍历。只要其中一个包符合描述,它就会被下载。每个被找到的包的hash值都被保存到项目的lockfile文件中。因此如果存储库的顺序发生变化,而其中有包名和版本相同的定义,那就只会下载一个包。
-
相同的机制适用于镜像,私有存储库(由hex.pm提供)和自托管索引。
-
要发布或使用私有存储库,你必须使用
rebar3_hex
插件进行身份验证,rebar3 hex auth
。会创建一个特定的配置文件~/.config/rebar3/hex.config
来存储key值。
{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">>,
...
}
]}
]}.
14. 最小OTP版本
- 可以指定Erlang/OTP的最低版本,如果使用早期版本构建应用程序,则会导致构建失败。
{minimum_otp_vsn, "17.4"}.
15. Overrides
-
覆盖允许从更高级别的应用程序修改依赖项的配置。它们旨在允许快速修复和解决办法,如果可能的话,我们建议致力于永久修复以使其成为目标应用程序的配置。
-
覆盖支持3中形式:add、应用程序覆盖、所有覆盖。
{overrides, [{add, app_name(), [{atom(), any()}]},
{override, app_name(), [{atom(), any()}]},
{override, [{atom(), any()}]}]}.
-
有一些应用到依赖关系,依赖关系也可以具有它们应用的自己的覆盖。在所有的覆盖,每个应用程序覆盖按顺序添加。
-
例如,如下配置可以强制设置所有的依赖关系在默认情况下使用
debug_info
编译,生产环境配置为强制使用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}]}]}
]}.
16. Hooks
- 有两种类型的钩子:shell钩子和功能钩子。
Shell Hooks
- 钩子提供了一种在hookable功能之前或之后运行任意命令的方法,首先可以选择匹配系统类型选择运行哪个钩子,shell钩子在功能钩子之后运行。
-type hook() :: {atom(), string()}
| {string(), atom(), string()}.
{pre_hooks, [hook()]}.
{post_hooks, [hook()]}.
- 使用
rebar3
利用pre_hooks
构建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
。为了在命名空间中执行命令,使用一个元组作为第二个参数。功能钩子在shell钩子之前运行。
{provider_hooks, [{pre, [{compile, clean}]}
{post, [{compile, {erlydtl, compile}}]}]}
功能可以hook的点
-
只有特定的内置功能支持附着钩子。控制取决于功能是否操作项目的应用程序(每个应用程序和依赖项)或者是否期望它仅仅在整个项目上运行。
-
功能钩子运行在shell钩子之前。
Hook | before and after |
---|---|
clean | 每个应用程序和依赖, 和/或每个顶级应用编译完成之前和之后 |
ct | 整个运行前后 |
compile | 每个应用程序和依赖, 和/或每个顶级应用编译完成之前和之后 |
edoc | 整个运行前后 |
escriptize | 整个运行前后 |
eunit | 整个运行前后 |
release | 整个运行前后 |
tar | 整个运行前后 |
erlc_compile | 编译应用程序的beam文件 |
app_compile | 应用程序的.app.src 构建.app 文件 |
-
默认情况下,这些钩子为每个程序运行,因为依赖关系可以在自己的上下文中指定自己的钩子。区别在于,某些情况下(大型项目),钩子可以在许多级别上定义(省略覆盖)
- 应用程序根目录下的
rebar.config
- 每个顶级应用程序(在
apps/
或者libs/
)的rebar.config
- 每个依赖项的
rebar.condig
- 应用程序根目录下的
-
默认情况下,没有大型项目时,定义在顶级
rebar.config
中的钩子被归为顶级应用程序的一部分,这允许钩子在以后发布的时候继续为依赖程序工作。 -
然而,如果钩子定义在顶级应用程序的项目根目录的
rebar.config
中,钩子将在任务运行之前/之后为所有顶级应用程序运行。 -
要在一个大型项目中保留每个应用程序的行为,必须在每个应用程序的
rebar.config
中定义钩子。
17. Relx
- 请查看Releases
18. Shell
-
rebar3 shell
如果relx
找到条目,REPL将自动启动应用程序,但可以使用显式指定{shell, [{apps, [App]}]}
由shell启动应用程序 -
其他选项包括:
Option | Value | Description |
---|---|---|
apps | [app1, app2, ...] | 要启动的app列表,追加在relx的配置后 |
config | "path/to/a/file.config" | 加载指定配置 |
script_file | "path/to/a/file.escript" | 执行自定义脚本 |
app_reload_blacklist | [app1, app2, ...] | 重新加载项目时,不进行重新加载的应用列表 |
19. 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}]}.