/rebar_raw_resource

A rebar3 resource wrapper to accommodate non-OTP-app dependencies

Primary LanguageErlangApache License 2.0Apache-2.0

#raw Resource Provider for Rebar3

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.

##What It Does

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.

##How to Use It

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.

###Add The Plugin

The following addition to rebar.config makes the plugin available for use with your dependencies:

{plugins, [
    {rebar_raw_resource,
        {git, "git://github.com/basho/rebar_raw_resource.git",
        {branch, "master"}}}
]}.

###Add Raw Dependencies

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.

####Dependency Options

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"} ] }}
    . . .
]}.

#####A Note About Dependency Options

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.

##Caveats

###Scope of Dependency Names and Locations

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.

###Dependency Source Tree Modification

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.

##Enhancements

If you find a bug, please report an issue, or better yet, fix it and submit a pull request.

You may find that using the develop branch here fixes a problem you're having, but it's just as likely that it'll crash and burn, so unless you're comfortable reviewing the code yourself you should probably stay away from it.

If there's something to discuss, especially if others might be interested, the rebar mailing list is the place to go.

##License

Everything here is covered by this license.