Often you want to build the same project in different ways depending on context, whether it be development or preparing for production deployment. Or you want some dependencies only for use in certain contexts such as running tests and don't want them conflicting with regular dependencies or bother to be fetched and built when not needed.
Those are some of the reasons we've introduced profiles.
Each profile has a separate output directory, by default under _build
:
_build
└── <profile>
├── lib
└── rel
- default
- test
Example rebar.config
:
{deps, [...]}.
{relx, [{release, {relname, "0.0.1"},
[appname]},
{dev_mode, true},
{include_erts, false}]}.
{profiles, [{prod, [{relx, [{dev_mode, false}, {include_erts, true}]}]},
{test, [{deps, [
{meck, ".*",
{git, "git://github.com/eproxus/meck.git", {tag, "0.8.2"}}}
]
}]
}]
}.
Result after running rebar3 ct
and REBAR3_PROFILE=prod rebar3 release
:
_build
├── default
│ ├── lib
│ │ ├── ...
│ └── rel
│ └── relname
├── prod
│ └── rel
│ └── relname
└── test
└── lib
└── meck
- All config values outside of
profiles
is part of thedefault
profile - When using a profile besides
default
the config keys between the profile anddefault
are merged, the profile in use takes precedence. - If the value of a config is a list of values (not a printable list) merge the keys of the lists, again with the profile in use taking precedence.
A task can declare it depends on a provider that has run within a certain profile's context. For example the Common Test provider depends on install_deps
having run run under the default
profile so that all dependencies of the project are installed and available during the test runs:
-define(DEPS, [{install_deps, default}, compile]).
Additionally the Common Test provider specifies that the profile it must run under is the test
profile:
providers:create([{name, ?PROVIDER},
{module, ?MODULE},
{deps, ?DEPS},
{bare, false},
{example, "rebar ct"},
{short_desc, "Run Common Tests"},
{desc, ""},
{opts, ct_opts(State)},
{profile, test}])
Providers and their dependencies are resolved and sorted. In this example all deps of install_deps
provider in the default
profile context will be run as well as compile
and all its dependencies in the test context, meaning install_deps
and app_discovery
run twice. This ultimately expands to the following list of providers to run:
[{app_discovery,default},
{app_discovery,test},
{install_deps,default},
{install_deps,test},
{lock,test},
{compile,test},
{ct,test}]
Thank you 👍