Rebar3 requires that all dependencies be structured as OTP applications.
There are, however, lots of cases when you just want to include a dependency in your project from which to pull unstructured resources, whether source code, graphics, text, or any number of other possibilities.
This rebar3
plugin allows you to do just that.
This resource provider does two things:
-
Wraps dependency specifications for other resource providers, leveraging their abilities to retrieve and provide information about their target dependencies.
-
Creates a minimal OTP application structure in retrieved dependencies that satisfies rebar's structure requirements.
Everything the plugin does is configured in your project's rebar.config
file.
What you do with the dependency once you get it into rebar's build tree is up to you, but rebar3
has a (somewhat) documented set of environment variables that allow you to find it so you can do with it what you need. The variable $REBAR_DEPS_DIR
, in particular, points to the directory under which you'll find the downloaded dependency.
You'll find some information in the rebar3 configuration documentation, but you may need to run rebar3
with DEBUG
set and/or review the source to find all of the accessible information.
The following addition to rebar.config
makes the plugin available for use with your dependencies. Since it is available on hex, this ought to work:
{plugins, [ rebar_raw_resource ] }.
The raw
resource type is simply a wrapper around another type, so the basic structure of a raw dependency is:
{deps, [
. . .
{mydep1, {raw, {mydep1-resource-specification} }},
{mydep2, {raw, {mydep2-resource-specification}, [raw-options] }},
. . .
]}.
In the above, the resource-specification tuples are as described in Rebar's documentation, and might look like this:
{git, "git://some/git/repo.git", {branch, "master"}}
or
{hg, "https://some/mercurial/repo"}
The raw
resource doesn't know anything about other resource types, it just uses their specifications to call into other resource providers to fetch and report on the dependencies.
You can optionally include a description and/or version in a raw
dependency specification which will affect the generated .app
file.
By default, for a dependency named foo
that has neither a src/foo.app.src
or ebin/foo.app
file, a ebin/foo.app
file will be written that looks like this:
%%
%% Generated by rebar_raw_resource
%%
{application, foo,
[
{description, "foo"},
{vsn, "some-version-string"},
{modules, []},
{registered, []},
{applications, [kernel, stdlib]}
]}.
The description
field is simply the dependency's name, and the vsn
field is whatever the underlying resource provider returns from the downloaded dependency. You can override these values by providing your own as in the following:
{deps, [
. . .
{snappy, {raw, {git, "git://github.com/google/snappy.git", {branch, "master"}},
[ {description, "Google's Snappy compression library"},
{vsn, "probably-not-a-good-idea-to-override-this"} ] }}
. . .
]}.
There are probably very few, if any, legitimate use cases for these dependency options.
If the dependency is going to be included in your project as an OTP application, you should almost certainly craft a more appropriate .app
or .app.src
file.
At present, I don't discriminate between scopes, assuming a given dependency location always maps to the same name. Including the dependency's version selector and profile would allow complete uniqueness of mappings, but subsequent operations may alter the version selector, resulting in matches not being found. Overall, I think it's reasonable to have a constraint saying "You MUST use the same name for a given dependency URL across profiles" - in fact, that constraint may also be implicit in rebar3 itself, though it doesn't appear to be formally declared.
Because the nested resource specifiers (rightly) don't have a specified schema, we treat them as relatively opaque tuples where the first element is the type and the second element is the location.
Old-style dependencies with a version regex immediately following the dependency name SHOULD be accommodated but ignored, though this aspect hasn't been, and isn't likely to be, rigorously tested as it's moot in rebar3.
Currently, we satisfy rebar's need for an OTP application by scribbling a minimal app config file in dep-path/ebin/dep-name.app
if there's neither such a file already, nor its equivalent source in the dep-path/src
directory. If anything that will satisfy rebar3's OTP application requirement is found, the plugin won't write any file.
It would be preferable to build the rebar_app_info
record dynamically and insert it into the state so we didn't have to leave droppings in the dependency's filesystem, but it's unclear whether there's a reliable place to hook that functionality into the processing sequence or whether rebar would accept it if we did without an actual file to check for changes.
Note that the above means that if you go into the dependency's source directory and check its status it will appear to have pending changes, but you probably don't want to commit the generated file.
If you find a bug, please report an issue, or better yet, fix it and submit a pull request.
Everything here is covered by this license.