diff options
author | Tristan Sloughter <t@crashfast.com> | 2014-11-01 10:21:46 -0500 |
---|---|---|
committer | Tristan Sloughter <t@crashfast.com> | 2014-11-01 10:21:46 -0500 |
commit | 6c1201f1ace6870adb5547a8e4f2fb1f22106cc2 (patch) | |
tree | 435fc22f1c90a773b706754bca3ac7c794daacc6 | |
parent | ef1df1222dbed3d219159efdb2d7abfb5974d344 (diff) |
dynamicly find module for fullfilling dependency
-rw-r--r-- | src/rebar_fetch.erl | 60 | ||||
-rw-r--r-- | src/rebar_prv_install_deps.erl | 84 | ||||
-rw-r--r-- | src/rebar_resource.erl | 15 |
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. |