summaryrefslogtreecommitdiff
path: root/src/rebar_prv_install_deps.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rebar_prv_install_deps.erl')
-rw-r--r--src/rebar_prv_install_deps.erl239
1 files changed, 119 insertions, 120 deletions
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index b590d03..11a4250 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -37,6 +37,8 @@
-export([handle_deps_as_profile/4,
parse_deps/5,
+ parse_deps/6,
+ profile_dep_dir/2,
find_cycles/1,
cull_compile/2]).
@@ -125,11 +127,15 @@ handle_deps_as_profile(Profile, State, Deps, Upgrade) ->
DepsDir = profile_dep_dir(State, Profile),
{SrcDeps, PkgDeps} = parse_deps(DepsDir, Deps, State, Locks, Level),
AllSrcProfileDeps = [{Profile, SrcDeps, Locks, Level}],
- AllPkgProfileDeps = [{Profile, Locks, PkgDeps, Level}],
+ AllPkgProfileDeps = case PkgDeps of
+ [] ->
+ [];
+ _ ->
+ [{Profile, Level, PkgDeps}]
+ end,
{AllApps, PkgDeps1, Seen, State1} = handle_profile_level(AllSrcProfileDeps, AllPkgProfileDeps, Locks, sets:new(), Upgrade, State),
- handle_profile_pkg_level(PkgDeps1, AllApps, Seen, Upgrade, State1).
-
+ handle_profile_pkg_level(PkgDeps1, AllApps, Seen, Upgrade, [], State1).
%% ===================================================================
%% Internal functions
@@ -139,19 +145,21 @@ handle_deps_as_profile(Profile, State, Deps, Upgrade) ->
deps_per_profile(Profiles, Upgrade, State) ->
Level = 0,
{AllProfileDeps, PkgDeps} = lists:foldl(fun(Profile, {SrcAcc, PkgAcc}) ->
- {Src, Pkg} = parse_profile_deps(State, Profile, Level),
- {[Src | SrcAcc], [Pkg | PkgAcc]}
+ case parse_profile_deps(State, Profile, Level) of
+ {Src, {_, _, []}} ->
+ {[Src | SrcAcc], PkgAcc};
+ {Src, Pkg} ->
+ {[Src | SrcAcc], [Pkg | PkgAcc]}
+ end
end, {[], []}, Profiles),
{AllApps, PkgDeps1, Seen, State1} = handle_profile_level(AllProfileDeps, PkgDeps, [], sets:new(), Upgrade, State),
-
- handle_profile_pkg_level(PkgDeps1, AllApps, Seen, Upgrade, State1).
+ Locks = rebar_state:get(State, {locks, default}, []),
+ handle_profile_pkg_level(PkgDeps1, AllApps, Seen, Upgrade, Locks, State1).
parse_profile_deps(State, Profile, Level) ->
- DepsDir = profile_dep_dir(State, Profile),
Locks = rebar_state:get(State, {locks, Profile}, []),
- Deps = rebar_state:get(State, {deps, Profile}, []),
- {SrcDeps, PkgDeps} = parse_deps(DepsDir, Deps, State, Locks, Level),
- {{Profile, SrcDeps, Locks, Level}, {Profile, Locks, PkgDeps, Level}}.
+ {SrcDeps, PkgDeps} = rebar_state:get(State, {parsed_deps, Profile}, {[], []}),
+ {{Profile, SrcDeps, Locks, Level}, {Profile, Level, PkgDeps}}.
%% Level-order traversal of all dependencies, across profiles.
%% If profiles x,y,z are present, then the traversal will go:
@@ -166,28 +174,37 @@ handle_profile_level([{Profile, SrcDeps, Locks, Level} | Rest], PkgDeps, SrcApps
[] -> Rest;
_ -> Rest ++ [{Profile, SrcDeps1, Locks1, Level+1}]
end,
- handle_profile_level(SrcDeps2, [{Profile, Locks1, PkgDeps1, Level+1} | PkgDeps], SrcApps1++SrcApps, sets:union(Seen, Seen1), Upgrade, State1).
-
-handle_profile_pkg_level(PkgDeps, AllApps, Seen, Upgrade, State) ->
+ handle_profile_level(SrcDeps2, case PkgDeps1 of
+ [] ->
+ PkgDeps;
+ _ ->
+ [{Profile, Level+1, PkgDeps1} | PkgDeps]
+ end, SrcApps1, sets:union(Seen, Seen1), Upgrade, State1).
+
+handle_profile_pkg_level([], AllApps, _Seen, _Upgrade, _Locks, State) ->
+ {AllApps, State};
+handle_profile_pkg_level(PkgDeps, AllApps, Seen, Upgrade, Locks, State) ->
%% Read in package index and dep graph
{Packages, Graph} = rebar_state:packages(State),
Registry = rebar_packages:registry(State),
State1 = rebar_state:packages(rebar_state:registry(State, Registry)
,{Packages, Graph}),
- lists:foldl(fun({_Profile, _, [], _}, {AllAcc, StateAcc}) ->
- {AllAcc, StateAcc};
- ({Profile1, Locks, PkgDeps2, Level}, {AllAcc, StateAcc}) ->
- {Solved, StateAcc2} = update_pkg_deps(Profile1, Packages, PkgDeps2
- ,Graph, Upgrade, Seen, StateAcc, Locks
- ,Level),
-
- AllDeps = lists:ukeymerge(2
- ,lists:ukeysort(2, AllAcc)
- ,lists:ukeysort(2, Solved)),
-
- {AllDeps, StateAcc2}
- end, {AllApps, State1}, PkgDeps).
+ S = case rebar_digraph:cull_deps(Graph, lists:keysort(2, PkgDeps), Seen) of
+ {ok, [], []} ->
+ throw({rebar_digraph, no_solution});
+ {ok, [], Discarded} ->
+ [warn_skip_pkg(Pkg, State) || Pkg <- Discarded, not(pkg_locked(Pkg, Locks))],
+ [];
+ {ok, Solution, []} ->
+ Solution;
+ {ok, Solution, Discarded} ->
+ [warn_skip_pkg(Pkg, State) || Pkg <- Discarded, not(pkg_locked(Pkg, Locks))],
+ Solution
+ end,
+
+ {PkgApps, State2} = update_pkg_deps(S, Packages, Upgrade, Seen, State1, Locks),
+ {AllApps++PkgApps, State2}.
find_cycles(Apps) ->
case rebar_digraph:compile_order(Apps) of
@@ -199,36 +216,17 @@ find_cycles(Apps) ->
cull_compile(TopSortedDeps, ProjectApps) ->
lists:dropwhile(fun not_needs_compile/1, TopSortedDeps -- ProjectApps).
-update_pkg_deps(Profile, Packages, PkgDeps, Graph, Upgrade, Seen, State, Locks, Level) ->
- case PkgDeps of
- [] -> %% No pkg deps
- {[], State};
- PkgDeps ->
- %% Find pkg deps needed
- S = case rebar_digraph:cull_deps(Graph, PkgDeps, Level) of
- {ok, [], _} ->
- throw({rebar_digraph, no_solution});
- {ok, Solution, []} ->
- Solution;
- {ok, Solution, Discarded} ->
- [warn_skip_pkg(Pkg, State) || Pkg <- Discarded, not(pkg_locked(Pkg, Locks))],
- Solution
- end,
- update_pkg_deps(Profile, S, Packages, Upgrade, Seen, State, Locks)
- end.
-
-pkg_locked({Name, _, _}, Locks) ->
+pkg_locked({_, Name, _, _}, Locks) ->
pkg_locked(Name, Locks);
-pkg_locked({Name, _}, Locks) ->
+pkg_locked({_, Name, _}, Locks) ->
pkg_locked(Name, Locks);
pkg_locked(Name, Locks) ->
false =/= lists:keyfind(Name, 1, Locks).
-update_pkg_deps(Profile, Pkgs, Packages, Upgrade, Seen, State, Locks) ->
- %% Create app_info record for each pkg dep
- DepsDir = profile_dep_dir(State, Profile),
+update_pkg_deps(Pkgs, Packages, Upgrade, Seen, State, Locks) ->
{Solved, _, State1}
- = lists:foldl(fun(Pkg, {Acc, SeenAcc, StateAcc}) ->
+ = lists:foldl(fun({Profile, Pkg}, {Acc, SeenAcc, StateAcc}) ->
+ DepsDir = profile_dep_dir(State, Profile),
handle_pkg_dep(Profile, Pkg, Packages, Upgrade, DepsDir, Acc, SeenAcc, Locks, StateAcc)
end, {[], Seen, State}, Pkgs),
{Solved, State1}.
@@ -236,14 +234,19 @@ update_pkg_deps(Profile, Pkgs, Packages, Upgrade, Seen, State, Locks) ->
handle_pkg_dep(Profile, Pkg, Packages, Upgrade, DepsDir, Fetched, Seen, Locks, State) ->
IsLock = pkg_locked(Pkg, Locks),
AppInfo = package_to_app(DepsDir, Packages, Pkg, IsLock, State),
- Deps = rebar_app_info:deps(AppInfo),
- Level = rebar_app_info:dep_level(AppInfo),
- {NewSeen, NewState} = maybe_lock(Profile, AppInfo, Seen, State, Level),
- {_, AppInfo1} = maybe_fetch(AppInfo, Profile, Upgrade, Seen, NewState),
- {AppInfo2, _, _, _, _} =
- handle_dep(NewState, Profile, DepsDir, AppInfo1, Locks, Level),
- AppInfo3 = rebar_app_info:deps(AppInfo2, Deps),
- {[AppInfo3 | Fetched], NewSeen, NewState}.
+ case sets:is_element(rebar_app_info:name(AppInfo), Seen) of
+ true ->
+ {Fetched, Seen, State};
+ false ->
+ Deps = rebar_app_info:deps(AppInfo),
+ Level = rebar_app_info:dep_level(AppInfo),
+ {NewSeen, NewState} = maybe_lock(Profile, AppInfo, Seen, State, Level),
+ {_, AppInfo1} = maybe_fetch(AppInfo, Profile, Upgrade, Seen, NewState),
+ {AppInfo2, _, _, _, _} =
+ handle_dep(NewState, Profile, DepsDir, AppInfo1, Locks, Level),
+ AppInfo3 = rebar_app_info:deps(AppInfo2, Deps),
+ {[AppInfo3 | Fetched], NewSeen, NewState}
+ end.
maybe_lock(Profile, AppInfo, Seen, State, Level) ->
Name = rebar_app_info:name(AppInfo),
@@ -271,7 +274,7 @@ maybe_lock(Profile, AppInfo, Seen, State, Level) ->
{sets:add_element(Name, Seen), State}
end.
-package_to_app(DepsDir, Packages, {Name, Vsn, Level}, IsLock, State) ->
+package_to_app(DepsDir, Packages, {Parent, Name, Vsn, Level}, IsLock, State) ->
case dict:find({Name, Vsn}, Packages) of
error ->
case rebar_packages:check_registry(Name, Vsn, State) of
@@ -282,14 +285,14 @@ package_to_app(DepsDir, Packages, {Name, Vsn, Level}, IsLock, State) ->
end;
{ok, PkgDeps} ->
Source = {pkg, Name, Vsn},
- AppInfo = new_dep(DepsDir, Name, Vsn, Source, IsLock, State),
+ AppInfo = new_dep(root, DepsDir, Name, Vsn, Source, IsLock, State),
AppInfo1 = rebar_app_info:dep_level(rebar_app_info:deps(AppInfo, PkgDeps), Level),
BaseDir = rebar_state:get(State, base_dir, []),
AppState1 = rebar_state:set(rebar_app_info:state(AppInfo1), base_dir, BaseDir),
- rebar_app_info:state(AppInfo1, AppState1)
+ rebar_app_info:parent(rebar_app_info:state(AppInfo1, AppState1), Parent)
end.
--spec update_src_deps(atom(), non_neg_integer(), list(), list(), list(), rebar_state:t(), boolean(), sets:set(binary()), list()) -> {rebar_state:t(), list(), list(), sets:set(binary())}.
+-spec update_src_deps(atom(), non_neg_integer(), list(), list(), list(), rebar_state:t(), boolean(), sets:set(binary()), list()) -> {list(), list(), list(), rebar_state:t(), sets:set(binary()), list()}.
update_src_deps(Profile, Level, SrcDeps, PkgDeps, SrcApps, State, Upgrade, Seen, Locks) ->
lists:foldl(
fun(AppInfo, {SrcDepsAcc, PkgDepsAcc, SrcAppsAcc, StateAcc, SeenAcc, LocksAcc}) ->
@@ -371,14 +374,14 @@ handle_dep(AppInfo, Profile, SrcDeps, PkgDeps, SrcApps, Level, State, Locks) ->
,NewLocks}.
-spec handle_dep(rebar_state:t(), atom(), file:filename_all(), rebar_app_info:t(), list(), integer()) ->
- {rebar_app_info:t(), [rebar_app_info:t()], [pkg_dep()], [integer()]}.
+ {rebar_app_info:t(), [rebar_app_info:t()], [pkg_dep()], [integer()], rebar_state:t()}.
handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) ->
Profiles = rebar_state:current_profiles(State),
Name = rebar_app_info:name(AppInfo),
- C = rebar_config:consult(rebar_app_info:dir(AppInfo)),
-
+ %% Deps may be under a sub project app, find it and use its state if so
S = rebar_app_info:state(AppInfo),
+ C = rebar_config:consult(rebar_app_info:dir(AppInfo)),
S1 = rebar_state:new(S, C, rebar_app_info:dir(AppInfo)),
S2 = rebar_state:apply_overrides(S1, Name),
@@ -399,7 +402,7 @@ handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) ->
NewLocks = [{DepName, Source, LockLevel+Level} ||
{DepName, Source, LockLevel} <- rebar_state:get(S5, {locks, default}, [])],
AppInfo3 = rebar_app_info:deps(AppInfo2, rebar_state:deps_names(Deps)),
- {SrcDeps, PkgDeps} = parse_deps(DepsDir, Deps, S5, Locks, Level+1),
+ {SrcDeps, PkgDeps} = parse_deps(rebar_app_info:name(AppInfo3), DepsDir, Deps, S5, Locks, Level+1),
{AppInfo3, SrcDeps, PkgDeps, Locks++NewLocks, State}.
-spec maybe_fetch(rebar_app_info:t(), atom(), boolean(),
@@ -413,23 +416,22 @@ maybe_fetch(AppInfo, Profile, Upgrade, Seen, State) ->
false ->
case rebar_app_discover:find_app(AppDir, all) of
false ->
- case fetch_app(AppInfo, AppDir, State) of
- true ->
- maybe_symlink_default(State, Profile, AppDir, AppInfo),
- {true, update_app_info(AppDir, AppInfo)};
- Other ->
- {Other, AppInfo}
- end;
+ true = fetch_app(AppInfo, AppDir, State),
+ maybe_symlink_default(State, Profile, AppDir, AppInfo),
+ {true, update_app_info(AppDir, AppInfo)};
{true, AppInfo1} ->
%% Preserve the state we created with overrides
AppState = rebar_app_info:state(AppInfo),
- AppInfo2 = rebar_app_info:state(AppInfo1, AppState),
+ Parent = rebar_app_info:parent(AppInfo),
+ Source = rebar_app_info:source(AppInfo),
+ AppInfo2 = rebar_app_info:parent(rebar_app_info:state(AppInfo1, AppState), Parent),
+ AppInfo3 = rebar_app_info:source(AppInfo2, Source),
case sets:is_element(rebar_app_info:name(AppInfo), Seen) of
true ->
- {false, AppInfo2};
+ {false, AppInfo3};
false ->
- maybe_symlink_default(State, Profile, AppDir, AppInfo2),
- {maybe_upgrade(AppInfo, AppDir, Upgrade, State), AppInfo2}
+ maybe_symlink_default(State, Profile, AppDir, AppInfo3),
+ {maybe_upgrade(AppInfo, AppDir, Upgrade, State), AppInfo3}
end
end
end.
@@ -477,8 +479,11 @@ make_relative_to_root(State, Path) when is_list(Path) ->
Root = rebar_dir:root_dir(State),
rebar_dir:make_relative_path(Path, Root).
--spec parse_deps(binary(), list(), rebar_state:t(), list(), integer()) -> {[rebar_app_info:t()], [pkg_dep()]}.
+-spec parse_deps(binary(), list(), rebar_state:t(), list(), integer()) -> {[rebar_app_info:t()], [tuple()]}.
parse_deps(DepsDir, Deps, State, Locks, Level) ->
+ parse_deps(root, DepsDir, Deps, State, Locks, Level).
+
+parse_deps(Parent, DepsDir, Deps, State, Locks, Level) ->
lists:foldl(fun(Dep, Acc) ->
Name = case Dep of
Dep when is_tuple(Dep) ->
@@ -488,68 +493,69 @@ parse_deps(DepsDir, Deps, State, Locks, Level) ->
end,
case lists:keyfind(ec_cnv:to_binary(Name), 1, Locks) of
false ->
- parse_dep(Dep, Acc, DepsDir, false, State);
+ parse_dep(Parent, Dep, Acc, DepsDir, false, State);
LockedDep ->
LockedLevel = element(3, LockedDep),
case LockedLevel > Level of
true ->
- parse_dep(Dep, Acc, DepsDir, false, State);
+ parse_dep(Parent, Dep, Acc, DepsDir, false, State);
false ->
- parse_dep(LockedDep, Acc, DepsDir, true, State)
+ parse_dep(Parent, LockedDep, Acc, DepsDir, true, State)
end
end
end, {[], []}, Deps).
-parse_dep({Name, Vsn}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_list(Vsn) ->
+parse_dep(Parent, {Name, Vsn}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_list(Vsn) ->
%% Versioned Package dependency
CheckoutsDir = ec_cnv:to_list(rebar_dir:checkouts_dir(State, Name)),
case rebar_app_info:discover(CheckoutsDir) of
{ok, _App} ->
- Dep = new_dep(DepsDir, Name, [], [], IsLock, State),
+ Dep = new_dep(root, DepsDir, Name, [], [], IsLock, State),
{[Dep | SrcDepsAcc], PkgDepsAcc};
not_found ->
- {SrcDepsAcc, [parse_goal(ec_cnv:to_binary(Name)
+ {SrcDepsAcc, [parse_goal(Parent
+ ,ec_cnv:to_binary(Name)
,ec_cnv:to_binary(Vsn)) | PkgDepsAcc]}
end;
-parse_dep(Name, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_atom(Name); is_binary(Name) ->
+parse_dep(Parent, Name, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_atom(Name); is_binary(Name) ->
%% Unversioned package dependency
{PkgName, PkgVsn} = get_package(ec_cnv:to_binary(Name), State),
CheckoutsDir = ec_cnv:to_list(rebar_dir:checkouts_dir(State, Name)),
case rebar_app_info:discover(CheckoutsDir) of
{ok, _App} ->
- Dep = new_dep(DepsDir, Name, [], [], IsLock, State),
+ Dep = new_dep(root, DepsDir, Name, [], [], IsLock, State),
{[Dep | SrcDepsAcc], PkgDepsAcc};
not_found ->
- {SrcDepsAcc, [{PkgName, PkgVsn} | PkgDepsAcc]}
+ {SrcDepsAcc, [{Parent, PkgName, PkgVsn} | PkgDepsAcc]}
end;
-parse_dep({Name, Source}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_tuple(Source) ->
- Dep = new_dep(DepsDir, Name, [], Source, IsLock, State),
+parse_dep(Parent, {Name, Source}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_tuple(Source) ->
+ Dep = new_dep(Parent, DepsDir, Name, [], Source, IsLock, State),
{[Dep | SrcDepsAcc], PkgDepsAcc};
-parse_dep({Name, _Vsn, Source}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_tuple(Source) ->
- Dep = new_dep(DepsDir, Name, [], Source, IsLock, State),
+parse_dep(Parent, {Name, _Vsn, Source}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_tuple(Source) ->
+ Dep = new_dep(Parent, DepsDir, Name, [], Source, IsLock, State),
{[Dep | SrcDepsAcc], PkgDepsAcc};
-parse_dep({Name, _Vsn, Source, Opts}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_tuple(Source) ->
+parse_dep(Parent, {Name, _Vsn, Source, Opts}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_tuple(Source) ->
?WARN("Dependency option list ~p in ~p is not supported and will be ignored", [Opts, Name]),
- Dep = new_dep(DepsDir, Name, [], Source, IsLock, State),
+ Dep = new_dep(Parent, DepsDir, Name, [], Source, IsLock, State),
{[Dep | SrcDepsAcc], PkgDepsAcc};
-parse_dep({_Name, {pkg, Name, Vsn}, Level}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_integer(Level) ->
+parse_dep(Parent, {_Name, {pkg, Name, Vsn}, Level}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_integer(Level) ->
CheckoutsDir = ec_cnv:to_list(rebar_dir:checkouts_dir(State, Name)),
case rebar_app_info:discover(CheckoutsDir) of
{ok, _App} ->
- Dep = new_dep(DepsDir, Name, [], [], IsLock, State),
+ Dep = new_dep(root, DepsDir, Name, [], [], IsLock, State),
{[Dep | SrcDepsAcc], PkgDepsAcc};
not_found ->
- {SrcDepsAcc, [{Name, Vsn} | PkgDepsAcc]}
+ {SrcDepsAcc, [{Parent, Name, Vsn} | PkgDepsAcc]}
end;
-parse_dep({Name, Source, Level}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_tuple(Source)
- , is_integer(Level) ->
- Dep = new_dep(DepsDir, Name, [], Source, IsLock, State),
+parse_dep(Parent, {Name, Source, Level}, {SrcDepsAcc, PkgDepsAcc}, DepsDir, IsLock, State) when is_tuple(Source)
+ , is_integer(Level) ->
+ Dep = new_dep(Parent, DepsDir, Name, [], Source, IsLock, State),
{[Dep | SrcDepsAcc], PkgDepsAcc};
-parse_dep(Dep, _, _, _, _) ->
+parse_dep(_, Dep, _, _, _, _) ->
throw(?PRV_ERROR({parse_dep, Dep})).
-new_dep(DepsDir, Name, Vsn, Source, IsLock, State) ->
+new_dep(Parent, DepsDir, Name, Vsn, Source, IsLock, State) ->
CheckoutsDir = ec_cnv:to_list(rebar_dir:checkouts_dir(State, Name)),
{ok, Dep} = case rebar_app_info:discover(CheckoutsDir) of
{ok, App} ->
@@ -570,30 +576,28 @@ new_dep(DepsDir, Name, Vsn, Source, IsLock, State) ->
ParentOverrides = rebar_state:overrides(State),
Dep1 = rebar_app_info:state(Dep,
rebar_state:overrides(S, ParentOverrides++Overrides)),
- rebar_app_info:is_lock(rebar_app_info:source(Dep1, Source), IsLock).
+ AppInfo = rebar_app_info:is_lock(rebar_app_info:source(Dep1, Source), IsLock),
+ rebar_app_info:parent(AppInfo, Parent).
fetch_app(AppInfo, AppDir, State) ->
?INFO("Fetching ~s (~p)", [rebar_app_info:name(AppInfo), rebar_app_info:source(AppInfo)]),
Source = rebar_app_info:source(AppInfo),
- case rebar_fetch:download_source(AppDir, Source, State) of
- true ->
- true;
- Error ->
- throw(Error)
- end.
+ true = rebar_fetch:download_source(AppDir, Source, State).
%% This is called after the dep has been downloaded and unpacked, if it hadn't been already.
%% So this is the first time for newly downloaded apps that its .app/.app.src data can
%% be read in an parsed.
update_app_info(AppDir, AppInfo) ->
{ok, Found} = rebar_app_info:discover(AppDir),
+ Parent = rebar_app_info:parent(AppInfo),
+ Source = rebar_app_info:source(AppInfo),
AppDetails = rebar_app_info:app_details(Found),
Applications = proplists:get_value(applications, AppDetails, []),
IncludedApplications = proplists:get_value(included_applications, AppDetails, []),
AppInfo1 = rebar_app_info:applications(
rebar_app_info:app_details(AppInfo, AppDetails),
IncludedApplications++Applications),
- rebar_app_info:valid(AppInfo1, false).
+ rebar_app_info:source(rebar_app_info:parent(rebar_app_info:valid(AppInfo1, false), Parent), Source).
maybe_upgrade(AppInfo, AppDir, Upgrade, State) ->
Source = rebar_app_info:source(AppInfo),
@@ -602,12 +606,7 @@ maybe_upgrade(AppInfo, AppDir, Upgrade, State) ->
case rebar_fetch:needs_update(AppDir, Source, State) of
true ->
?INFO("Upgrading ~s", [rebar_app_info:name(AppInfo)]),
- case rebar_fetch:download_source(AppDir, Source, State) of
- true ->
- true;
- Error ->
- throw(Error)
- end;
+ true = rebar_fetch:download_source(AppDir, Source, State);
false ->
case Upgrade of
true ->
@@ -621,13 +620,13 @@ maybe_upgrade(AppInfo, AppDir, Upgrade, State) ->
false
end.
--spec parse_goal(binary(), binary()) -> pkg_dep().
-parse_goal(Name, Constraint) ->
+-spec parse_goal(binary() | root, binary(), binary()) -> {binary(), binary()} | {binary(), binary(), binary()}.
+parse_goal(Parent, Name, Constraint) ->
case re:run(Constraint, "([^\\d]*)(\\d.*)", [{capture, [1,2], binary}]) of
{match, [<<>>, Vsn]} ->
- {Name, Vsn};
+ {Parent, Name, Vsn};
{match, [Op, Vsn]} ->
- {Name, Vsn, binary_to_atom(Op, utf8)};
+ {Parent, Name, Vsn, binary_to_atom(Op, utf8)};
nomatch ->
throw(?PRV_ERROR({bad_constraint, Name, Constraint}))
end.