erlangrebarrelx

How can I include a ".mustache" file in erlang release?


I am trying to use the mustache erlang lib with the separate template and view. I am using the rebar3 release structure.

I follow the example in the docs, if I create both the simple.erl and simple.mustache. However, when I perform rebar3 compile, my final ebin directory only includes the simple.beam.

How can I make sure the compile/release process bundles the simple.mustache file?

Here is the layout of my apps:

enter image description here

Here is my rebar.config:

{erl_opts, [debug_info]}.
{deps, [
    {cowboy, {git, "git://github.com/ninenines/cowboy.git", {tag, "1.0.1"}}},
  {mustache, {git, "git@github.com:mojombo/mustache.erl.git", {tag, "v0.1.1"}}}
]}.

{relx, [{release, { kitty, "0.1.0" },
         [kitty,
          kitty_api,
          sasl]},

        {sys_config, "./config/sys.config"},
        {vm_args, "./config/vm.args"},

        {dev_mode, true},
        {include_erts, false},

        {extended_start_script, true}]
}.

{profiles, [{prod, [{relx, [{dev_mode, false},
                            {include_erts, true}]}]
            }]
}.

Here is my kitty_api_app.src, which contains the simple.mustache in it's src dir:

{application, kitty_api,
 [{description, "Kitty HTTP API"},
  {vsn, "0.1.0"},
  {registered, []},
  {mod, { kitty_api_app, []}},
  {applications,
   [kernel,
    stdlib,
    kitty,
    cowboy
   ]},
  {env,[]},
  {modules, []},

  {maintainers, []},
  {licenses, []},
  {links, []}
 ]}.

Solution

  • Erlang/OTP Application Perspective

    According to the Directory Structure chapter in the OTP Design Principles an Erlang application consists of the following subdirectories:

    src - Contains the Erlang source code.
    ebin - Contains the Erlang object code, the beam files. The .app file is also placed here.
    priv - Used for application specific files. For example, C executables are placed here. The function code:priv_dir/1 is to be used to access this directory.
    include - Used for include files

    In face that, it's not appropriate to put files that are not the source code to the src/ directory. priv/ is the right place to put them in.

    Rebar3 perspective

    The documentation of compile command in rebar3 says:

    After ensuring all dependencies are available, (...) compile will compile the needed depdendencies and the project's apps .app.src and .erl files.

    Which compiles with the OTP desing principles. As your mustache file that sits in the src/ is neither an .app.src file nor .erl file, rebar is doing nothing with it.

    Erlang/OTP Release perspetive

    And finally, the aforementioned OTP document says this about Erlang releases:

    The directory structure for the code installed by the release handler from a release package is as follows:

    $ROOT/lib/App1-AVsn1/ebin  
                        /priv  
            /App2-AVsn2/ebin
                       /priv
            ...
           /AppN-AVsnN/ebin
                      /priv
           /erts-EVsn/bin
           /releases/Vsn
           /bin
    

    As you can see, only ebin/ and priv/ are expected to be placed in an application that is a part of a release - so leaving your .mustache file in the src/ is not an option.

    Conclusion

    The .mustache files should be treated as application specific files and thus be put in the application priv/ directory. If placed in the src/, rebar won't copy them to the ebin/. When building a release, the applications that it is made up of are copied along with their priv directories.