diff options
Diffstat (limited to 'src/rebar_prv_deps_tree.erl')
-rw-r--r-- | src/rebar_prv_deps_tree.erl | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/rebar_prv_deps_tree.erl b/src/rebar_prv_deps_tree.erl new file mode 100644 index 0000000..d429c52 --- /dev/null +++ b/src/rebar_prv_deps_tree.erl @@ -0,0 +1,84 @@ +-module(rebar_prv_deps_tree). + +-behaviour(provider). + +-export([init/1, + do/1, + format_error/1]). + +-include("rebar.hrl"). + +-define(PROVIDER, tree). +-define(DEPS, [lock]). + +-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. +init(State) -> + State1 = rebar_state:add_provider( + State, + providers:create([{name, ?PROVIDER}, + {module, ?MODULE}, + {bare, true}, + {deps, ?DEPS}, + {example, "rebar3 tree"}, + {short_desc, "Print dependency tree."}, + {desc, ""}, + {opts, [{verbose, $v, "verbose", undefined, "Print repo and branch/tag/ref for git and hg deps"}]}])), + {ok, State1}. + +-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. +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, State), + {ok, State}. + +-spec format_error(any()) -> iolist(). +format_error(Reason) -> + io_lib:format("~p", [Reason]). + +%% Internal functions + +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), + Source = rebar_app_info:source(App), + 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++ProjectAppNames), D, Verbose); + error -> + print_children(-1, lists:keysort(1, ProjectAppNames), D, Verbose) + end. + +print_children(_, [], _, _) -> + ok; +print_children(Indent, [{Name, Vsn, Source} | Rest], Dict, Verbose) -> + + [io:format("| ") || _ <- lists:seq(0, Indent, 2)], + io:format("|- "), + io:format("~s-~s (~s)~n", [Name, Vsn, type(Source, Verbose)]), + case dict:find(Name, Dict) of + {ok, Children} -> + print_children(Indent+2, lists:keysort(1, Children), Dict, Verbose), + print_children(Indent, Rest, Dict, Verbose); + error -> + 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, _} -> + "hex package"; + {Other, false} -> + io_lib:format("~s repo", [Other]); + {_, true} -> + io_lib:format("~s", [element(2, Source)]) + end. |