diff options
author | Tristan Sloughter <t@crashfast.com> | 2014-11-29 11:06:43 -0600 |
---|---|---|
committer | Tristan Sloughter <t@crashfast.com> | 2014-11-29 15:29:33 -0600 |
commit | bdd5d902d9e66cd466a86c94d9484e68d637f888 (patch) | |
tree | 4514ba8152342c71e442807ab81f7af6920eb077 /src | |
parent | 14cb6803e0a0742613cd4e476c5db0e5a1b134e7 (diff) |
fix lock provider to work anytime it is run
Diffstat (limited to 'src')
-rw-r--r-- | src/rebar_base_compiler.erl | 9 | ||||
-rw-r--r-- | src/rebar_fetch.erl | 66 | ||||
-rw-r--r-- | src/rebar_plugins.erl | 2 | ||||
-rw-r--r-- | src/rebar_prv_install_deps.erl | 144 | ||||
-rw-r--r-- | src/rebar_prv_lock.erl | 16 | ||||
-rw-r--r-- | src/rebar_state.erl | 55 |
6 files changed, 138 insertions, 154 deletions
diff --git a/src/rebar_base_compiler.erl b/src/rebar_base_compiler.erl index b42189b..ee023e7 100644 --- a/src/rebar_base_compiler.erl +++ b/src/rebar_base_compiler.erl @@ -258,10 +258,5 @@ format_error(AbsSource, Extra, {Mod, Desc}) -> ErrorDesc = Mod:format_error(Desc), ?FMT("~s: ~s~s~n", [AbsSource, Extra, ErrorDesc]). -maybe_absname(Config, Filename) -> - case rebar_utils:processing_base_dir(Config) of - true -> - Filename; - false -> - filename:absname(Filename) - end. +maybe_absname(_Config, Filename) -> + Filename. diff --git a/src/rebar_fetch.erl b/src/rebar_fetch.erl index e763c2c..933b626 100644 --- a/src/rebar_fetch.erl +++ b/src/rebar_fetch.erl @@ -19,52 +19,40 @@ -spec lock_source(file:filename_all(), rebar_resource:resource()) -> rebar_resource:resource() | {error, string()}. lock_source(AppDir, Source) -> - case get_resource_type(Source) of - {error, _}=Error -> - Error; - Module -> - Module:lock(AppDir, Source) - end. + Module = get_resource_type(Source), + Module:lock(AppDir, Source). -spec download_source(file:filename_all(), rebar_resource:resource()) -> true | {error, any()}. download_source(AppDir, Source) -> - 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, _} -> - code:del_path(filename:absname(filename:join(AppDir1, "ebin"))), - ec_file:remove(filename:absname(AppDir1), [recursive]), - 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++"-*")), - code:del_path(filename:absname(filename:join(AppDir1, "ebin"))), - ec_file:remove(filename:absname(AppDir1), [recursive]), - ok = ec_file:copy(FromDir, filename:absname(AppDir1), [recursive]), - true - end + Module = get_resource_type(Source), + TmpDir = ec_file:insecure_mkdtemp(), + AppDir1 = ec_cnv:to_list(AppDir), + ec_file:mkdir_p(AppDir1), + case Module:download(TmpDir, Source) of + {ok, _} -> + code:del_path(filename:absname(filename:join(AppDir1, "ebin"))), + ec_file:remove(filename:absname(AppDir1), [recursive]), + 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++"-*")), + code:del_path(filename:absname(filename:join(AppDir1, "ebin"))), + ec_file:remove(filename:absname(AppDir1), [recursive]), + ok = ec_file:copy(FromDir, filename:absname(AppDir1), [recursive]), + true end. -spec needs_update(file:filename_all(), rebar_resource:resource()) -> boolean() | {error, string()}. needs_update(AppDir, Source) -> - case get_resource_type(Source) of - {error, _}=Error -> - Error; - Module -> - try - Module:needs_update(AppDir, Source) - catch - _:_ -> - true - end + Module = get_resource_type(Source), + try + Module:needs_update(AppDir, Source) + catch + _:_ -> + true end. get_resource_type({Type, Location}) -> diff --git a/src/rebar_plugins.erl b/src/rebar_plugins.erl index b7d81e2..1877751 100644 --- a/src/rebar_plugins.erl +++ b/src/rebar_plugins.erl @@ -26,7 +26,7 @@ install(State) -> handle_plugin(Plugin, State) -> try {ok, State1} = rebar_prv_install_deps:handle_deps(State, [Plugin]), - Apps = rebar_state:get(State1, all_deps, []), + Apps = rebar_state:all_deps(State1), ToBuild = lists:dropwhile(fun rebar_app_info:valid/1, Apps), lists:foreach(fun(AppInfo) -> AppDir = rebar_app_info:dir(AppInfo), diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl index 7fdddac..44d0804 100644 --- a/src/rebar_prv_install_deps.erl +++ b/src/rebar_prv_install_deps.erl @@ -66,14 +66,14 @@ do(State) -> Profile = rebar_state:current_profile(State), ProjectApps = rebar_state:project_apps(State), try - {ok, State1} = case rebar_state:get(State, locks, []) of - [] -> - handle_deps(State, rebar_state:get(State, {deps, Profile}, [])); - Locks -> - handle_deps(State, Locks) - end, - - Source = ProjectApps ++ rebar_state:src_apps(State1), + {ok, SrcApps, State1} = case rebar_state:get(State, locks, []) of + [] -> + handle_deps(State, rebar_state:get(State, {deps, Profile}, [])); + Locks -> + handle_deps(State, Locks) + end, + + Source = ProjectApps ++ SrcApps, case rebar_digraph:compile_order(Source) of {ok, Sort} -> {ok, rebar_state:set(State1, deps_to_build, @@ -106,66 +106,88 @@ handle_deps(State, Deps, Update) -> %% Split source deps from pkg deps, needed to keep backwards compatibility DepsDir = rebar_utils:deps_dir(State), {SrcDeps, PkgDeps} = parse_deps(State, DepsDir, Deps), - State1 = rebar_state:src_deps(rebar_state:pkg_deps(State, PkgDeps), - SrcDeps), %% Fetch transitive src deps - {State2, _Seen} = update_src_deps(0, State1, Update, sets:new()), - - Solved = case rebar_state:pkg_deps(State2) of - [] -> %% No pkg deps - []; - PkgDeps1 -> - %% Find pkg deps needed - S = case rebar_digraph:cull_deps(Graph, PkgDeps1) of - {ok, []} -> - throw({rebar_digraph, no_solution}); - {ok, Solution} -> - Solution; - [] -> - throw({rebar_digraph, no_solution}) - end, - - %% Create app_info record for each pkg dep - [AppInfo || Pkg <- S, - AppInfo <- package_to_app(DepsDir - ,Packages - ,Pkg), - maybe_fetch(State2, AppInfo, Update, sets:new())] - end, + {State1, SrcApps, PkgDeps1, Seen} = + update_src_deps(0, SrcDeps, PkgDeps, [], State, Update, sets:new()), + + {Solved, State2} = case PkgDeps1 of + [] -> %% No pkg deps + {[], State1}; + PkgDeps2 -> + %% Find pkg deps needed + S = case rebar_digraph:cull_deps(Graph, PkgDeps2) of + {ok, []} -> + throw({rebar_digraph, no_solution}); + {ok, Solution} -> + Solution; + [] -> + throw({rebar_digraph, no_solution}) + end, + + update_pkg_deps(S, Packages, Update, Seen, State1) + end, AllDeps = lists:ukeymerge(2 - ,lists:ukeysort(2, rebar_state:src_apps(State2)) + ,lists:ukeysort(2, SrcApps) ,lists:ukeysort(2, Solved)), %% Sort all apps to build order - State3 = rebar_state:set(State2, all_deps, AllDeps), - State4 = rebar_state:set(State3, {all_deps, rebar_state:current_profile(State)}, AllDeps), - {ok, State4}. + State3 = rebar_state:all_deps(State2, AllDeps), + + {ok, SrcApps, State3}. %% =================================================================== %% Internal functions %% =================================================================== +update_pkg_deps(Pkgs, Packages, Update, Seen, State) -> + %% Create app_info record for each pkg dep + DepsDir = rebar_utils:deps_dir(State), + {Solved, _, State1} + = lists:foldl(fun(Pkg, {Acc, SeenAcc, StateAcc}) -> + AppInfo = package_to_app(DepsDir + ,Packages + ,Pkg), + {SeenAcc1, StateAcc1} = maybe_lock(AppInfo, SeenAcc, StateAcc), + case maybe_fetch(StateAcc1, AppInfo, Update, SeenAcc) of + true -> + {[AppInfo | Acc], SeenAcc1, StateAcc1}; + false -> + {Acc, SeenAcc1, StateAcc1} + end + end, {[], Seen, State}, Pkgs), + {Solved, State1}. + +maybe_lock(AppInfo, Seen, State) -> + Name = rebar_app_info:name(AppInfo), + case sets:is_element(Name, Seen) of + false -> + {sets:add_element(Name, Seen), + rebar_state:lock(State, AppInfo)}; + true -> + {sets:add_element(Name, Seen), State} + end. + package_to_app(DepsDir, Packages, {Name, Vsn}) -> case dict:find({Name, Vsn}, Packages) of error -> - []; + {error, missing_package}; {ok, P} -> PkgDeps = proplists:get_value(<<"deps">>, P, []), Link = proplists:get_value(<<"link">>, P, ""), {ok, AppInfo} = rebar_app_info:new(Name, Vsn), AppInfo1 = rebar_app_info:deps(AppInfo, PkgDeps), AppInfo2 = rebar_app_info:dir(AppInfo1, rebar_utils:deps_dir(DepsDir, Name)), - [rebar_app_info:source(AppInfo2, {pkg, Name, Vsn, Link})] + rebar_app_info:source(AppInfo2, {pkg, Name, Vsn, Link}) end. --spec update_src_deps(integer(), rebar_state:t(), boolean(), sets:set(binary())) -> +-spec update_src_deps(integer(), list(), list(), list(), rebar_state:t(), boolean(), sets:set(binary())) -> {rebar_state:t(), [binary()]}. -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} = +update_src_deps(Level, SrcDeps, PkgDeps, SrcApps, State, Update, Seen) -> + case lists:foldl(fun(AppInfo, {SrcDepsAcc, PkgDepsAcc, SrcAppsAcc, StateAcc, SeenAcc}) -> + %% If not seen, add to list of locks to write out + {SeenAcc1, StateAcc1} = maybe_lock(AppInfo, SeenAcc, StateAcc), + {SrcDepsAcc1, PkgDepsAcc1, SrcAppsAcc1, StateAcc2} = case Update of {true, UpdateName, UpdateLevel} -> handle_update(AppInfo @@ -173,28 +195,28 @@ update_src_deps(Level, State, Update, Seen) -> ,UpdateLevel ,SrcDepsAcc ,PkgDepsAcc + ,SrcAppsAcc ,Level - ,StateAcc); + ,StateAcc1); _ -> maybe_fetch(StateAcc, AppInfo, false, SeenAcc), handle_dep(AppInfo ,SrcDepsAcc ,PkgDepsAcc + ,SrcAppsAcc ,Level - ,StateAcc) + ,StateAcc1) end, - {SrcDepsAcc1, PkgDepsAcc1, StateAcc1, SeenAcc1} - end, {[], rebar_state:pkg_deps(State), State, Seen}, SrcDeps) of - {[], NewPkgDeps, State1, Seen1} -> - {rebar_state:pkg_deps(State1, NewPkgDeps), Seen1}; - {NewSrcDeps, NewPkgDeps, State1, Seen1} -> - State2 = rebar_state:pkg_deps(State1, NewPkgDeps), - State3 = rebar_state:src_deps(State2, NewSrcDeps), - update_src_deps(Level+1, State3, Update, Seen1) + {SrcDepsAcc1, PkgDepsAcc1, SrcAppsAcc1, StateAcc2, SeenAcc1} + end, {[], PkgDeps, SrcApps, State, Seen}, SrcDeps) of + {[], NewPkgDeps, NewSrcApps, State1, Seen1} -> + {State1, NewSrcApps, NewPkgDeps, Seen1}; + {NewSrcDeps, NewPkgDeps, NewSrcApps, State1, Seen1} -> + update_src_deps(Level+1, NewSrcDeps, NewPkgDeps, NewSrcApps, State1, Update, Seen1) end. -handle_update(AppInfo, UpdateName, UpdateLevel, SrcDeps, PkgDeps, Level, State) -> +handle_update(AppInfo, UpdateName, UpdateLevel, SrcDeps, PkgDeps, SrcApps, Level, State) -> Name = rebar_app_info:name(AppInfo), Locks = rebar_state:get(State, locks, []), {_, _, _, DepLevel} = lists:keyfind(Name, 1, Locks), @@ -206,24 +228,26 @@ handle_update(AppInfo, UpdateName, UpdateLevel, SrcDeps, PkgDeps, Level, State) handle_dep(AppInfo ,SrcDeps ,PkgDeps + ,SrcApps ,Level ,State); false -> - {SrcDeps, PkgDeps, State} + {SrcDeps, PkgDeps, SrcApps, State} end; false -> - {SrcDeps, PkgDeps, State} + {SrcDeps, PkgDeps, SrcApps, State} end. -handle_dep(AppInfo, SrcDeps, PkgDeps, Level, State) -> +handle_dep(AppInfo, SrcDeps, PkgDeps, SrcApps, Level, State) -> DepsDir = rebar_utils:deps_dir(State), {AppInfo1, NewSrcDeps, NewPkgDeps} = handle_dep(State, DepsDir, AppInfo), AppInfo2 = rebar_app_info:dep_level(AppInfo1, Level), {NewSrcDeps ++ SrcDeps ,NewPkgDeps++PkgDeps - ,rebar_state:src_apps(State, AppInfo2)}. + ,[AppInfo2 | SrcApps] + ,State}. -spec handle_dep(rebar_state:t(), file:filename_all(), rebar_app_info:t()) -> {rebar_app_info:t(), [rebar_app_info:t()], [pkg_dep()]}. diff --git a/src/rebar_prv_lock.erl b/src/rebar_prv_lock.erl index 1de8083..aba5080 100644 --- a/src/rebar_prv_lock.erl +++ b/src/rebar_prv_lock.erl @@ -31,23 +31,17 @@ init(State) -> do(State) -> case rebar_state:get(State, locks, []) of [] -> - AllDeps = rebar_state:get(State, {all_deps, default}, []), + AllDeps = rebar_state:lock(State), Locks = lists:map(fun(Dep) -> Dir = rebar_app_info:dir(Dep), Source = rebar_app_info:source(Dep), %% If source is tuple it is a source dep %% e.g. {git, "git://github.com/ninenines/cowboy.git", "master"} - case Source of - Source when is_tuple(Source) -> - {rebar_app_info:name(Dep) - ,rebar_app_info:original_vsn(Dep) - ,rebar_fetch:lock_source(Dir, Source) - ,rebar_app_info:dep_level(Dep)}; - _Source -> - {rebar_app_info:name(Dep) - ,rebar_app_info:original_vsn(Dep)} - end + {rebar_app_info:name(Dep) + ,rebar_app_info:original_vsn(Dep) + ,rebar_fetch:lock_source(Dir, Source) + ,rebar_app_info:dep_level(Dep)} end, AllDeps), Dir = rebar_state:dir(State), file:write_file(filename:join(Dir, "rebar.lock"), io_lib:format("~p.~n", [Locks])), diff --git a/src/rebar_state.erl b/src/rebar_state.erl index 7b0ac6a..4b2d872 100644 --- a/src/rebar_state.erl +++ b/src/rebar_state.erl @@ -3,6 +3,9 @@ -export([new/0, new/1, new/2, new/3, get/2, get/3, set/3, + lock/1, + lock/2, + current_profile/1, current_profile/2, @@ -15,11 +18,9 @@ create_logic_providers/2, project_apps/1, project_apps/2, + all_deps/1, all_deps/2, deps_names/1, - pkg_deps/1, pkg_deps/2, - src_deps/1, src_deps/2, - src_apps/1, src_apps/2, prepend_hook/3, append_hook/3, hooks/2, providers/1, providers/2, add_provider/2]). @@ -29,15 +30,14 @@ -record(state_t, {dir :: file:name(), opts = dict:new() :: rebar_dict(), + lock = [], current_profile = default :: atom(), command_args = [], command_parsed_args = [], - src_deps = [], - src_apps = [], - pkg_deps = [] :: [rebar_packages:package()], - project_apps = [], + project_apps = [] :: [rebar_app_into:t()], + all_deps = [] :: [rebar_app_into:t()], providers = []}). @@ -99,6 +99,12 @@ current_profile(#state_t{current_profile=Profile}) -> current_profile(State, Profile) -> State#state_t{current_profile=Profile}. +lock(#state_t{lock=Lock}) -> + Lock. + +lock(State=#state_t{lock=Lock}, App) -> + State#state_t{lock=[App | Lock]}. + command_args(#state_t{command_args=CmdArgs}) -> CmdArgs. @@ -151,35 +157,6 @@ deps_names(State) -> Deps = rebar_state:get(State, deps, []), deps_names(Deps). --spec pkg_deps(t()) -> [rebar_packages:package()]. -pkg_deps(#state_t{pkg_deps=PkgDeps}) -> - PkgDeps. - -pkg_deps(State=#state_t{pkg_deps=PkgDeps}, NewPkgDeps) when is_list(PkgDeps) -> - State#state_t{pkg_deps=NewPkgDeps}; -pkg_deps(State=#state_t{pkg_deps=PkgDeps}, PkgDep) -> - State#state_t{pkg_deps=[PkgDep | PkgDeps]}. - -src_deps(#state_t{src_deps=SrcDeps}) -> - SrcDeps. - -src_deps(State=#state_t{src_deps=SrcDeps}, NewSrcDeps) when is_list(SrcDeps) -> - State#state_t{src_deps=NewSrcDeps}; -src_deps(State=#state_t{src_deps=SrcDeps}, SrcDep) -> - Name = rebar_app_info:name(SrcDep), - NewSrcDeps = lists:keystore(Name, 2, SrcDeps, SrcDep), - State#state_t{src_deps=NewSrcDeps}. - -src_apps(#state_t{src_apps=SrcApps}) -> - SrcApps. - -src_apps(State=#state_t{src_apps=_SrcApps}, NewSrcApps) when is_list(NewSrcApps) -> - State#state_t{src_apps=NewSrcApps}; -src_apps(State=#state_t{src_apps=SrcApps}, NewSrcApp) -> - Name = rebar_app_info:name(NewSrcApp), - NewSrcApps = lists:keystore(Name, 2, SrcApps, NewSrcApp), - State#state_t{src_apps=NewSrcApps}. - project_apps(#state_t{project_apps=Apps}) -> Apps. @@ -188,6 +165,12 @@ project_apps(State=#state_t{}, NewApps) when is_list(NewApps) -> project_apps(State=#state_t{project_apps=Apps}, App) -> State#state_t{project_apps=lists:keystore(rebar_app_info:name(App), 2, Apps, App)}. +all_deps(#state_t{all_deps=Apps}) -> + Apps. + +all_deps(State=#state_t{}, NewApps) -> + State#state_t{all_deps=NewApps}. + providers(#state_t{providers=Providers}) -> Providers. |