瀏覽代碼

track the parent of umbrella app dependencies

pull/718/head
Tristan Sloughter 9 年之前
父節點
當前提交
cf22c7e941
共有 4 個檔案被更改,包括 92 行新增27 行删除
  1. +56
    -11
      src/rebar_app_discover.erl
  2. +9
    -4
      src/rebar_prv_deps_tree.erl
  3. +17
    -5
      src/rebar_prv_install_deps.erl
  4. +10
    -7
      src/rebar_prv_upgrade.erl

+ 56
- 11
src/rebar_app_discover.erl 查看文件

@ -16,7 +16,31 @@ do(State, LibDirs) ->
Apps = find_apps(Dirs, all),
ProjectDeps = rebar_state:deps_names(State),
DepsDir = rebar_dir:deps_dir(State),
CurrentProfiles = rebar_state:current_profiles(State),
%% There may be a top level src which is an app and there may not
%% Find it here if there is, otherwise define the deps parent as root
TopLevelApp = case ec_lists:find(fun(X) ->
ec_file:real_dir_path(rebar_app_info:dir(X)) =:=
ec_file:real_dir_path(rebar_dir:root_dir(State))
end, Apps) of
{ok, App} ->
rebar_app_info:name(App);
error ->
root
end,
%% Handle top level deps
State1 = lists:foldl(fun(Profile, StateAcc) ->
ProfileDeps = rebar_state:get(StateAcc, {deps, Profile}, []),
ParsedDeps = parse_profile_deps(Profile
,TopLevelApp
,ProfileDeps
,StateAcc),
rebar_state:set(StateAcc, {parsed_deps, Profile}, ParsedDeps)
end, State, lists:reverse(CurrentProfiles)),
%% Handle sub project apps deps
%% Sort apps so we get the same merged deps config everytime
SortedApps = rebar_utils:sort_deps(Apps),
lists:foldl(fun(AppInfo, StateAcc) ->
@ -33,7 +57,7 @@ do(State, LibDirs) ->
?INFO("Ignoring ~s", [Name]),
StateAcc
end
end, State, SortedApps).
end, State1, SortedApps).
format_error({module_list, File}) ->
io_lib:format("Error reading module list from ~p~n", [File]);
@ -51,24 +75,45 @@ merge_deps(AppInfo, State) ->
rebar_state:apply_profiles(
rebar_state:new(reset_hooks(rebar_state:opts(State, Default)), C,
rebar_app_info:dir(AppInfo)), CurrentProfiles), Name),
AppState1 = rebar_state:overrides(AppState, rebar_state:get(AppState, overrides, [])),
rebar_utils:check_min_otp_version(rebar_state:get(AppState, minimum_otp_vsn, undefined)),
rebar_utils:check_blacklisted_otp_versions(rebar_state:get(AppState, blacklisted_otp_vsns, [])),
rebar_utils:check_min_otp_version(rebar_state:get(AppState1, minimum_otp_vsn, undefined)),
rebar_utils:check_blacklisted_otp_versions(rebar_state:get(AppState1, blacklisted_otp_vsns, [])),
AppState1 = rebar_state:set(AppState, artifacts, []),
AppInfo1 = rebar_app_info:state(AppInfo, AppState1),
AppState2 = rebar_state:set(AppState1, artifacts, []),
AppInfo1 = rebar_app_info:state(AppInfo, AppState2),
State1 = lists:foldl(fun(Profile, StateAcc) ->
AppProfDeps = rebar_state:get(AppState, {deps, Profile}, []),
TopLevelProfDeps = rebar_state:get(StateAcc, {deps, Profile}, []),
ProfDeps2 = rebar_utils:tup_dedup(rebar_utils:tup_umerge(
rebar_utils:tup_sort(TopLevelProfDeps)
,rebar_utils:tup_sort(AppProfDeps))),
rebar_state:set(StateAcc, {deps, Profile}, ProfDeps2)
handle_profile(Profile, Name, AppState1, StateAcc)
end, State, lists:reverse(CurrentProfiles)),
{AppInfo1, State1}.
handle_profile(Profile, Name, AppState, State) ->
{TopSrc, TopPkg} = rebar_state:get(State, {parsed_deps, Profile}, {[], []}),
TopLevelProfileDeps = rebar_state:get(State, {deps, Profile}, []),
AppProfileDeps = rebar_state:get(AppState, {deps, Profile}, []),
ProfileDeps2 = rebar_utils:tup_dedup(rebar_utils:tup_umerge(
rebar_utils:tup_sort(TopLevelProfileDeps)
,rebar_utils:tup_sort(AppProfileDeps))),
State1 = rebar_state:set(State, {deps, Profile}, ProfileDeps2),
%% Only deps not also specified in the top level config need
%% to be included in the parsed deps
NewDeps = ProfileDeps2 -- TopLevelProfileDeps,
{ParsedSrc, ParsedPkg} = parse_profile_deps(Profile, Name, NewDeps, State1),
rebar_state:set(State1, {parsed_deps, Profile}, {TopSrc++ParsedSrc, TopPkg++ParsedPkg}).
parse_profile_deps(Profile, Name, Deps, State) ->
DepsDir = rebar_prv_install_deps:profile_dep_dir(State, Profile),
Locks = rebar_state:get(State, {locks, Profile}, []),
rebar_prv_install_deps:parse_deps(Name
,DepsDir
,Deps
,State
,Locks
,1).
project_app_config(AppInfo, State) ->
C = rebar_config:consult(rebar_app_info:dir(AppInfo)),
Dir = rebar_app_info:dir(AppInfo),

+ 9
- 4
src/rebar_prv_deps_tree.erl 查看文件

@ -29,7 +29,7 @@ init(State) ->
do(State) ->
{Args, _} = rebar_state:command_parsed_args(State),
Verbose = proplists:get_value(verbose, Args, false),
print_deps_tree(rebar_state:all_deps(State), Verbose),
print_deps_tree(rebar_state:all_deps(State), Verbose, State),
{ok, State}.
-spec format_error(any()) -> iolist().
@ -38,7 +38,7 @@ format_error(Reason) ->
%% Internal functions
print_deps_tree(SrcDeps, Verbose) ->
print_deps_tree(SrcDeps, Verbose, State) ->
D = lists:foldl(fun(App, Dict) ->
Name = rebar_app_info:name(App),
Vsn = rebar_app_info:original_vsn(App),
@ -46,11 +46,14 @@ print_deps_tree(SrcDeps, Verbose) ->
Parent = rebar_app_info:parent(App),
dict:append_list(Parent, [{Name, Vsn, Source}], Dict)
end, dict:new(), SrcDeps),
ProjectAppNames = [{rebar_app_info:name(App)
,rebar_app_info:original_vsn(App)
,project} || App <- rebar_state:project_apps(State)],
case dict:find(root, D) of
{ok, Children} ->
print_children(-1, lists:keysort(1, Children), D, Verbose);
print_children(-1, lists:keysort(1, Children++ProjectAppNames), D, Verbose);
error ->
none
print_children(-n>1, lists:keysort(1, ProjectAppNames), D, Verbose)
end.
print_children(_, [], _, _) ->
@ -68,6 +71,8 @@ print_children(Indent, [{Name, Vsn, Source} | Rest], Dict, Verbose) ->
print_children(Indent, Rest, Dict, Verbose)
end.
type(project, _) ->
"project app";
type(Source, Verbose) when is_tuple(Source) ->
case {element(1, Source), Verbose} of
{pkg, _} ->

+ 17
- 5
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]).
@ -155,10 +157,11 @@ deps_per_profile(Profiles, Upgrade, State) ->
handle_profile_pkg_level(PkgDeps1, AllApps, Seen, Upgrade, Locks, State1).
parse_profile_deps(State, Profile, Level) ->
DepsDir = profile_dep_dir(State, Profile),
%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),
%Deps = rebar_state:get(State, {deps, Profile}, []),
%{SrcDeps, PkgDeps} = parse_deps(DepsDir, Deps, State, Locks, 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.
@ -373,12 +376,21 @@ handle_dep(AppInfo, Profile, SrcDeps, PkgDeps, SrcApps, Level, State, Locks) ->
-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_state:t()}.
handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) ->
Parent = rebar_app_info:parent(AppInfo),
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 = case ec_lists:find(fun(X) ->
Parent =:= rebar_app_info:name(X)
end, rebar_state:project_apps(State)) of
{ok, ParentApp} ->
rebar_app_info:state(ParentApp);
error ->
rebar_app_info:state(AppInfo)
end,
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),

+ 10
- 7
src/rebar_prv_upgrade.erl 查看文件

@ -53,18 +53,21 @@ do(State) ->
{Locks0, _Unlocks0} ->
Deps0 = top_level_deps(Deps, Locks),
State1 = rebar_state:set(State, {deps, default}, Deps0),
State2 = rebar_state:set(State1, {locks, default}, Locks0),
State3 = rebar_state:set(State2, upgrade, true),
UpdatedLocks = [L || L <- rebar_state:lock(State3),
DepsDir = rebar_prv_install_deps:profile_dep_dir(State, default),
D = rebar_prv_install_deps:parse_deps(root, DepsDir, Deps0, State1, Locks0, 0),
State2 = rebar_state:set(State1, {parsed_deps, default}, D),
State3 = rebar_state:set(State2, {locks, default}, Locks0),
State4 = rebar_state:set(State3, upgrade, true),
UpdatedLocks = [L || L <- rebar_state:lock(State4),
lists:keymember(rebar_app_info:name(L), 1, Locks0)],
Res = rebar_prv_install_deps:do(rebar_state:lock(State3, UpdatedLocks)),
Res = rebar_prv_install_deps:do(rebar_state:lock(State4, UpdatedLocks)),
case Res of
{ok, State4} ->
{ok, State5} ->
rebar_utils:info_useless(
[element(1,Lock) || Lock <- Locks],
[rebar_app_info:name(App) || App <- rebar_state:lock(State4)]
[rebar_app_info:name(App) || App <- rebar_state:lock(State5)]
),
rebar_prv_lock:do(State4);
rebar_prv_lock:do(State5);
_ ->
Res
end

Loading…
取消
儲存