summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Sloughter <t@crashfast.com>2014-11-29 11:06:43 -0600
committerTristan Sloughter <t@crashfast.com>2014-11-29 15:29:33 -0600
commitbdd5d902d9e66cd466a86c94d9484e68d637f888 (patch)
tree4514ba8152342c71e442807ab81f7af6920eb077
parent14cb6803e0a0742613cd4e476c5db0e5a1b134e7 (diff)
fix lock provider to work anytime it is run
-rw-r--r--src/rebar_base_compiler.erl9
-rw-r--r--src/rebar_fetch.erl66
-rw-r--r--src/rebar_plugins.erl2
-rw-r--r--src/rebar_prv_install_deps.erl144
-rw-r--r--src/rebar_prv_lock.erl16
-rw-r--r--src/rebar_state.erl55
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.