Migrating to Relx
July 7, 2015
Recently I migrated a bunch of Erlang projects at CHEF to use
relx to build the release instead of
reltool
. An easy way to get started with relx
in your project is to try out
concrete if you're working with rebar2
, or
get in on rebar3. I recently migrated
chatterbox to rebar3
and it's been
great (just don't keep your common_tests in a directory called common_test
).
relx
is a breath of fresh air after working with reltool
. There will always
be a soft spot in my heart for
node_package
Including dependencies
The biggest problem I encountered with relx
was that my release's lib
directory contained way fewer libraries than the reltool
version of the
release.
It turns out that relx
is really smart about dependencies. It's up to you to
include your application's direct dependencies in your relx.config
file, but
relx
handles all their dependencies for you.
Well, at least it tries to.
relx
figures out what your dependencies depend on by looking at their
.app.src
files. Or maybe the compiled .app
files. If the application you're
including has done a good job with that, relx
can take that information and run
with it. If it hasn't done a good job, you have two real options:
Fix it
If it's your repo, you can update the repo's .app.src
with the right
dependencies. If it's not, you can open a pull request.
Manually manage the dependency
If you opened a PR to fix it, you might not be able to wait for it to get
merged. You also might not be able to upgrade to the latest version of that
application. In that case you can add those dependencies to relx.config
.
This is the standard way to handle this, although I found no documentation
of this, what I assume is a common occurrence. Tristan was kind enough to
confirm this for me in IRC.
A Simple Case: boundary/folsom
The project (chef-mover) I was migrating when I encountered the problem included an older version of folsom. They know about it Issue 82, and they've fixed it PR 83, but not in the version I was locked to.
relx.config
(abridged):
{release,{mover,"12.2.0"},[
mover,
bear, %% Add this!
folsom %% This was here already
]}.
But, adding bear
here wasn't enough. I also needed to add it to my
mover.app.src
:
{application, mover,
[{description, ""},
{vsn, "12.2.0"},
{applications, [kernel,
stdlib,
%% ...
bear, %% Add this!
folsom %% And this!
]},
{mod, {mover_app, []}}
]}.
I tried this same technique with other dependencies in mover, but it turned out
that this only applies to application dependencies. library dependencies don't
need to be added to .app.src
; however, the way they need to be handled in
relx.config
is a little different.
relx.config
(stil abridged):
{release,{mover,"12.2.0"},[
mover,
bear,
folsom,
{chef_db, load}, %% Use this syntax to keep the app from starting
{chef_objects, load} %% As many times as you need
]}.
Conclusion
I hope this helps you. I thought at first that the only way to manage this
problem was to fix the dependencies' .app.src
. The good news here is that
having this in your relx.config
and the dependencies' .app.src
is just
redundant. So it won't break anything when we upgrade mover
to the latest
folsom
.