-
Notifications
You must be signed in to change notification settings - Fork 15
SinanConfig
At first glance the sinan.config file can be a little confusing. You see a config tuple in the file that looks like this:
{build_dir, "_build"}.
That makes sense, its a simple tuple key value pair. Then you see something like this:
{types, [{task, release},
{release, b}], [{a, load}]}.
You think to yourself Wah? Its a bit disconcerting but don't worry. We are going to explain it in detail in this article.
You can think of a config entry as a key value pair like our first example:
{build_dir, "_build"}.
This is a global config entry that applies to the entire project. However, you can specialize that config, basically restrict the entry to only apply to parts of the project, to specific tasks, specific releases, etc. That's what that middle element we saw in our second example is all about.
{types, [{task, release},
{release, b}], [{a, load}]}.
The middle list (and it must always be a list) is a list
specializers. In this case the specializer
[{task, release}, {release, b}]
indicates that this config value
{types, [{a, load}]}
applies only to the release
task and only
when release b
is being built.
There are four specializers available to specialize a config entry. These areas of specialization are.
- Task Name;
{task, <task-name>}
- Release Name;
{release, <release-name>}
- App Name;
{app, <app-name>}
- Module Name;
{module, <module-name>}
Lets look at an example of a config entry that we can heavily
specialize. We will start at the broadest (unspecialized) and then
specialize it down to the narrowest specialization. We will look at
the compile_args
entry used by build. That's a configuration that
could, realistically, be specialized down to a very fine level.
Lets say that we wanted to turn on debug_info
for every module in
the project. In that case we would simple have a global,
unspecialized config entry
{compile_args, [debug_info]}.
We have two releases in our project. Release A and Release B and now
we want debug_info
to only apply to Release B. We would then
specialize our config entry to Release B.
{compile_args, [{release, b}], [debug_info]}.
Lets say we wanted to specialize it even further. We want to
specialize it to just the foo
app in release B. We could do that by
adding an app specializer as follows:
{compile_args, [{app, foo}
{release, b}], [debug_info]}.
Now debug info
only applies to app foo in Release B. What happens if
we leave off the release specializer?
{compile_args, [{app, foo}], [debug_info]}.
Then it will (of course) apply to app foo in any of the releases in the project.
What if we want to turn on debug_info
for a single module bar
in
app foo
in Release B?
{compile_args, [{module, bar},
{app, foo}
{release, b}], [debug_info]}.
Now our compile_args
entry will only apply to module bar
in app
foo
in Release B.
You wont use it very often, but you can specialize on a task as
well. Lets say that we had two tasks in sinan, task build and task
super. Both take a compile_args
entry, but we want our compile_args
to apply only to task build. We would then add a task specializer as
follows:
{compile_args, [{task, build},
{module, bar},
{app, foo}
{release, b}], [debug_info]}.
One thing that you can not do is have two specializers of the same type. If you specialize a config differently you must have two config entries. For example, you could not do:
{compile_args, [{task, build},
{module, bar},
{app, foo}
{release, b}
{release, a}], [debug_info]}.
Notice that there is a Release A and Release B. This simply will not work. What you must do is provide two config entries one for Release A and another for Release B.
Specializers are a way to control how a configuration entry applies during a sinan build. If you don't need them you can more or less ignore them. If you do, the let you control the configuration of a build to a very fine level.