summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Sloughter <t@crashfast.com>2014-11-01 10:21:46 -0500
committerTristan Sloughter <t@crashfast.com>2014-11-01 10:21:46 -0500
commit6c1201f1ace6870adb5547a8e4f2fb1f22106cc2 (patch)
tree435fc22f1c90a773b706754bca3ac7c794daacc6
parentef1df1222dbed3d219159efdb2d7abfb5974d344 (diff)
dynamicly find module for fullfilling dependency
-rw-r--r--src/rebar_fetch.erl60
-rw-r--r--src/rebar_prv_install_deps.erl84
-rw-r--r--src/rebar_resource.erl15
3 files changed, 108 insertions, 51 deletions
diff --git a/src/rebar_fetch.erl b/src/rebar_fetch.erl
index f26cd7a..4c1713c 100644
--- a/src/rebar_fetch.erl
+++ b/src/rebar_fetch.erl
@@ -12,20 +12,54 @@
-include("rebar.hrl").
+%% map short versions of resources to module names
+-define(RESOURCES, [{git, rebar_git_resource}, {pkg, rebar_pkg_resource}]).
+
+-spec lock_source(file:filename_all(), rebar_resource:resource()) ->
+ rebar_resource:resource() | {error, string()}.
lock_source(AppDir, Source) ->
- rebar_git_resource:lock(AppDir, Source).
+ case get_resource_type(Source) of
+ {error, _}=Error ->
+ Error;
+ Module ->
+ Module:lock(AppDir, Source)
+ end.
+-spec download_source(file:filename_all(), rebar_resource:resource()) -> true | {error, any()}.
download_source(AppDir, Source) ->
- TmpDir = ec_file:insecure_mkdtemp(),
- AppDir1 = ec_cnv:to_list(AppDir),
- ec_file:mkdir_p(AppDir1),
- case rebar_git_resource:download(TmpDir, Source) of
- {ok, _} ->
- ok = ec_file:copy(TmpDir, filename:absname(AppDir1), [recursive]);
- {tarball, File} ->
- ok = erl_tar:extract(File, [{cwd, TmpDir}
- ,compressed]),
- BaseName = filename:basename(AppDir1),
- [FromDir] = filelib:wildcard(filename:join(TmpDir, BaseName++"-*")),
- ec_file:copy(FromDir, AppDir1, [recursive])
+ case get_resource_type(Source) of
+ {error, _}=Error ->
+ Error;
+ Module ->
+ TmpDir = ec_file:insecure_mkdtemp(),
+ AppDir1 = ec_cnv:to_list(AppDir),
+ ec_file:mkdir_p(AppDir1),
+ case Module:download(TmpDir, Source) of
+ {ok, _} ->
+ ok = ec_file:copy(TmpDir, filename:absname(AppDir1), [recursive]),
+ true;
+ {tarball, File} ->
+ ok = erl_tar:extract(File, [{cwd, TmpDir}
+ ,compressed]),
+ BaseName = filename:basename(AppDir1),
+ [FromDir] = filelib:wildcard(filename:join(TmpDir, BaseName++"-*")),
+ ok = ec_file:copy(FromDir, AppDir1, [recursive]),
+ true
+ end
end.
+
+get_resource_type({Type, Location, _}) ->
+ case lists:keyfind(Type, 1, ?RESOURCES) of
+ false ->
+ case code:which(Type) of
+ non_existing ->
+ {error, io_lib:format("Cannot fetch dependency ~s.~n"
+ " No module for resource type ~p", [Location, Type])};
+ _ ->
+ Type
+ end;
+ {Type, Module} ->
+ Module
+ end;
+get_resource_type(_) ->
+ rebar_pkg_resource.
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index 61a6809..a4be809 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -68,19 +68,25 @@ init(State) ->
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
ProjectApps = rebar_state:project_apps(State),
- {ok, State1} = case rebar_state:get(State, locks, []) of
- [] ->
- handle_deps(State, rebar_state:get(State, deps, []));
- Locks ->
- handle_deps(State, Locks)
- end,
-
- Source = ProjectApps ++ rebar_state:src_apps(State1),
- case rebar_topo:sort_apps(Source) of
- {ok, Sort} ->
- {ok, rebar_state:set(State1, deps_to_build, lists:dropwhile(fun rebar_app_info:valid/1, Sort -- ProjectApps))};
- {error, Error} ->
- {error, Error}
+ try
+ {ok, State1} = case rebar_state:get(State, locks, []) of
+ [] ->
+ handle_deps(State, rebar_state:get(State, deps, []));
+ Locks ->
+ handle_deps(State, Locks)
+ end,
+
+ Source = ProjectApps ++ rebar_state:src_apps(State1),
+ case rebar_topo:sort_apps(Source) of
+ {ok, Sort} ->
+ {ok, rebar_state:set(State1, deps_to_build,
+ lists:dropwhile(fun rebar_app_info:valid/1, Sort -- ProjectApps))};
+ {error, Error} ->
+ {error, Error}
+ end
+ catch
+ _:Reason ->
+ Reason
end.
-spec format_error(any(), rebar_state:t()) -> {iolist(), rebar_state:t()}.
@@ -102,7 +108,7 @@ handle_deps(State, Deps) ->
handle_deps(State, Deps, false).
-spec handle_deps(rebar_state:t(), [dep()], boolean() | {true, binary(), integer()})
- -> {ok, rebar_state:t()}.
+ -> {ok, rebar_state:t()} | {error, string()}.
handle_deps(State, [], _) ->
{ok, State};
handle_deps(State, Deps, Update) ->
@@ -120,7 +126,7 @@ handle_deps(State, Deps, Update) ->
Solved = case rebar_state:pkg_deps(State2) of
[] -> %% No pkg deps
- [];
+ [];
PkgDeps1 ->
%% Find pkg deps needed
{ok, S} = rlx_depsolver:solve(Graph, PkgDeps1),
@@ -133,8 +139,8 @@ handle_deps(State, Deps, Update) ->
end,
AllDeps = lists:ukeymerge(2
- ,lists:ukeysort(2, rebar_state:src_apps(State2))
- ,lists:ukeysort(2, Solved)),
+ ,lists:ukeysort(2, rebar_state:src_apps(State2))
+ ,lists:ukeysort(2, Solved)),
%% Sort all apps to build order
State3 = rebar_state:set(State2, all_deps, AllDeps),
{ok, State3}.
@@ -164,23 +170,25 @@ update_src_deps(Level, State, Update, Seen) ->
SrcDeps = rebar_state:src_deps(State),
case lists:foldl(fun(AppInfo, {SrcDepsAcc, PkgDepsAcc, StateAcc, SeenAcc}) ->
SeenAcc1 = sets:add_element(rebar_app_info:name(AppInfo), SeenAcc),
- {SrcDepsAcc1, PkgDepsAcc1, StateAcc1} = case Update of
- {true, UpdateName, UpdateLevel} ->
- handle_update(AppInfo
- ,UpdateName
- ,UpdateLevel
- ,SrcDepsAcc
- ,PkgDepsAcc
- ,Level
- ,StateAcc);
- _ ->
- maybe_fetch(AppInfo, false, SeenAcc),
- handle_dep(AppInfo
- ,SrcDepsAcc
- ,PkgDepsAcc
- ,Level
- ,StateAcc)
- end,
+ {SrcDepsAcc1, PkgDepsAcc1, StateAcc1} =
+ case Update of
+ {true, UpdateName, UpdateLevel} ->
+ handle_update(AppInfo
+ ,UpdateName
+ ,UpdateLevel
+ ,SrcDepsAcc
+ ,PkgDepsAcc
+ ,Level
+ ,StateAcc);
+ _ ->
+ maybe_fetch(AppInfo, false, SeenAcc),
+ handle_dep(AppInfo
+ ,SrcDepsAcc
+ ,PkgDepsAcc
+ ,Level
+ ,StateAcc)
+
+ end,
{SrcDepsAcc1, PkgDepsAcc1, StateAcc1, SeenAcc1}
end, {[], rebar_state:pkg_deps(State), State, Seen}, SrcDeps) of
{[], NewPkgDeps, State1, Seen1} ->
@@ -258,8 +266,12 @@ maybe_fetch(AppInfo, Update, Seen) ->
true ->
?INFO("Fetching ~s~n", [rebar_app_info:name(AppInfo)]),
Source = rebar_app_info:source(AppInfo),
- rebar_fetch:download_source(AppDir, Source),
- true;
+ case rebar_fetch:download_source(AppDir, Source) of
+ {error, _}=Error ->
+ throw(Error);
+ Result ->
+ Result
+ end;
_ ->
io:format("Was ~p seen: ~p~n", [rebar_app_info:name(AppInfo)
,sets:is_element(rebar_app_info:name(AppInfo), Seen)]),
diff --git a/src/rebar_resource.erl b/src/rebar_resource.erl
index 7e79356..17db13b 100644
--- a/src/rebar_resource.erl
+++ b/src/rebar_resource.erl
@@ -4,6 +4,16 @@
-export([]).
+-export_types([resource/0
+ ,type/0
+ ,location/0
+ ,ref/0]).
+
+-type resource() :: {type(), location(), ref()}.
+-type type() :: atom().
+-type location() :: string().
+-type ref() :: any().
+
-ifdef(have_callback_support).
%% In the case where R14 or lower is being used to compile the system
@@ -19,7 +29,8 @@ behaviour_info(_) ->
-else.
--callback lock(string(), tuple()) -> ok.
--callback download(string(), tuple()) -> ok.
+-callback lock(file:filename_all(), tuple()) -> rebar_resource:resource().
+-callback download(file:filename_all(), tuple()) ->
+ {tarball, file:filename_all()} | {ok, any()} | {error, any()}.
-endif.