简单介绍下,常用的rebar3的命令和一些结合我们项目实际需求(坑)解决方案。

rebar2 vs rebar3

rebar3虽然所有代码基本重写,但是对于用户来说,操作命令基本还是差不多,没有太大的改变。

直观的变化无非目录变了,支持多种环境(生产,开发,测试等)编译,deps的维护等。在rebar2的年代,deps基本都是版本冲突的,github上面经常有人不维护代码了,然后这个项目的deps又做了升级。所以经常折衷的方式,就是fork人家的项目,或者尝试删除再clone,clone貌似是不检查版本冲突的,都是一些不太正常路子,后面经常不会去更新deps。现在到了rebar3,就放心使用deps这个特性吧。

deps

文档:http://www.rebar3.org/docs/dependencies

跟rebar2相比,新增了个Dependency Lock Management,这个会生成一个rebar.lock,这个文件可以加入到版本管理,这样获取依赖的时候,能保证所有项目里面的依赖代码是一致。

建议,专人维护rebar.lock,然后尽量使用hex.pm的带版本号的包

rebar.config.script

文档:http://www.rebar3.org/docs/dynamic-configuration

可以动态调整rebar.config里面的参数,下面是gproc项目的一个实际例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
%% -*- erlang -*-
Script = fun(D,S,Vs) ->
Scr = filename:join(D, S),
case file:script(Scr, orddict:store('SCRIPT', Scr, Vs)) of
{ok, Res} -> Res;
{error,_} = Err ->
io:fwrite("Error evaluating script ~s~n", [S]),
Err
end
end.
CFG1 = case os:getenv("REBAR_DEPS") of
false -> CONFIG;
[] -> CONFIG;
Dir ->
lists:keystore(deps_dir, 1, CONFIG, {deps_dir, Dir})
end.
Priv = filename:join(filename:dirname(SCRIPT), "priv").
CFG2 = case os:getenv("GPROC_DIST") of
"true" ->
CFG1;
F when F=="false"; F==false ->
Script(Priv, "remove_deps.script",
[{'CONFIG', CFG1}, {'DEPS', [gen_leader]}])
end.
Script(Priv, "check_edown.script", [{'CONFIG', CFG2}]).

templates

文档:http://www.rebar3.org/docs/using-templates

默认模板查找路径有$REBAR3/priv/templates/和$HOME/.config/rebar3/templates/,但是项目协作来讲,我是更期望,有部分项目模板要放到项目目录去,但是在文档上面是没找到相应的说明的,不过通过分析源码发现是可以配置的。在rebar.config加一行{template_dir, “priv/templates”}.即可,然后项目模板放到priv/templates即可

模板的语法是mustache,一种Logic-less templates,http://mustache.github.io/mustache.5.html,个人觉得做点简单变量替换,足够用,稍微复杂一点带逻辑就有点弱了。

ct

我们项目使用了common test来测试项目的协议功能。

rebar2和rebar3启动ct有所区别,rebar2是直接启动ct进程,rebar3是直接函数调用,所以两者参数有所区别了,我们项目依赖了两个配置,一个是test.config,这个是ct使用的,另外一个是app.config,这个是App用到的。然后,最蛋疼的是,rebar3函数调用的时候,没有设置app.config的方法,虽然也是情理之中,最后我们的解决方案就是通过环境变量来指定app.config

1
$ ERL_AFLAGS="-config test/app.config -name ct@ct.example.com" rebar3 ct

不建议用的功能

Releases

文档 http://www.rebar3.org/docs/releases

如果从服务端开发来讲,我们发布的话,都是将ebin上传到服务器,按照我们指定的规则,然后服务器安装erlang,然后这样就可以跑起来了,这样是最简单也是最灵活的,我们的需求也就是这样简单。

但是relx,是将一个项目编译之后,添加启动脚本,打包成OTP目录格式,还是支持了热更新目录,总体而言,功能完备,但是我们用不太上,并且不那么简单实用。

我们的解决方案,就是写个简单的脚本,将编译好的ebin复制到我们发布目录,然后那个目录由svn或者git维护,同时将一些脚本什么也复制过去。本质就是稍微复杂的cp而已。

其他

以上是我个人一些使用rebar3的经验,如果有其他要补充,可以通过关于联系我,我后续会添加一些大家想知道的东西。

![][image-1]