- -module(rebar_prv_deps).
-
- -behaviour(provider).
-
- -export([init/1,
- do/1,
- format_error/1]).
-
- -include("rebar.hrl").
-
- -define(PROVIDER, deps).
- -define(DEPS, [app_discovery]).
-
- -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 deps"},
- {short_desc, "List dependencies"},
- {desc, "List dependencies. Those not matching lock files "
- "are followed by an asterisk (*)."},
- {opts, []}])),
- {ok, State1}.
-
- -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
- do(State) ->
- Profiles = rebar_state:current_profiles(State),
- List = [{Profile, rebar_state:get(State, {deps, Profile}, [])}
- || Profile <- Profiles],
- [display(State, Profile, Deps) || {Profile, Deps} <- List],
- {ok, State}.
-
- -spec format_error(any()) -> iolist().
- format_error(Reason) ->
- io_lib:format("~p", [Reason]).
-
- display(State, default, Deps) ->
- NewDeps = merge(Deps, rebar_state:get(State, deps, [])),
- display_deps(State, NewDeps),
- ?CONSOLE("", []);
- display(State, Profile, Deps) ->
- ?CONSOLE("-- ~p --", [Profile]),
- display_deps(State, Deps),
- ?CONSOLE("", []).
-
- merge(Deps, SourceDeps) ->
- merge1(dedup([normalize(Dep) || Dep <- Deps]),
- [normalize(Dep) || Dep <- SourceDeps]).
-
- normalize(Name) when is_binary(Name) ->
- Name;
- normalize(Name) when is_atom(Name) ->
- atom_to_binary(Name, unicode);
- normalize(Dep) when is_tuple(Dep) ->
- Name = element(1, Dep),
- setelement(1, Dep, normalize(Name)).
-
- merge1(Deps, SourceDeps) ->
- Names = [name(Dep) || Dep <- Deps],
- ToAdd = [Dep || Dep <- SourceDeps,
- not lists:member(name(Dep), Names)],
- Deps ++ ToAdd.
-
- %% Keep the latter one as locks come after regular deps in the list.
- %% This is totally not safe as an assumption, but it's what we got.
- %% We do this by comparing the current element and looking if a
- %% similar named one happens later. If so, drop the current one.
- dedup(Deps) -> dedup(Deps, [name(Dep) || Dep <- Deps]).
-
- dedup([], []) -> [];
- dedup([Dep|Deps], [Name|DepNames]) ->
- case lists:member(Name, DepNames) of
- true -> dedup(Deps, DepNames);
- false -> [Dep | dedup(Deps, DepNames)]
- end.
-
- name(T) when is_tuple(T) -> element(1, T);
- name(B) when is_binary(B) -> B.
-
- display_deps(State, Deps) ->
- lists:foreach(fun(Dep) -> display_dep(State, Dep) end, Deps).
-
- %% packages
- display_dep(_State, {Name, Vsn}) when is_list(Vsn) ->
- ?CONSOLE("~ts* (package ~ts)", [rebar_utils:to_binary(Name), rebar_utils:to_binary(Vsn)]);
- display_dep(_State, Name) when is_binary(Name) ->
- ?CONSOLE("~ts* (package)", [Name]);
- display_dep(_State, {Name, Source}) when is_tuple(Source) ->
- ?CONSOLE("~ts* (~ts source)", [rebar_utils:to_binary(Name), type(Source)]);
- display_dep(_State, {Name, _Vsn, Source}) when is_tuple(Source) ->
- ?CONSOLE("~ts* (~ts source)", [rebar_utils:to_binary(Name), type(Source)]);
- display_dep(_State, {Name, _Vsn, Source, _Opts}) when is_tuple(Source) ->
- ?CONSOLE("~ts* (~ts source)", [rebar_utils:to_binary(Name), type(Source)]);
- %% Locked
- display_dep(State, {Name, _Source={pkg, _, Vsn}, Level}) when is_integer(Level) ->
- DepsDir = rebar_dir:deps_dir(State),
- AppDir = filename:join([DepsDir, rebar_utils:to_binary(Name)]),
- {ok, AppInfo} = rebar_app_info:discover(AppDir),
- NeedsUpdate = case rebar_fetch:needs_update(AppInfo, State) of
- true -> "*";
- false -> ""
- end,
- ?CONSOLE("~ts~ts (locked package ~ts)", [Name, NeedsUpdate, Vsn]);
- display_dep(State, {Name, Source, Level}) when is_tuple(Source), is_integer(Level) ->
- DepsDir = rebar_dir:deps_dir(State),
- AppDir = filename:join([DepsDir, rebar_utils:to_binary(Name)]),
- {ok, AppInfo} = rebar_app_info:discover(AppDir),
- NeedsUpdate = case rebar_fetch:needs_update(AppInfo, State) of
- true -> "*";
- false -> ""
- end,
- ?CONSOLE("~ts~ts (locked ~ts source)", [Name, NeedsUpdate, type(Source)]).
-
- type(Source) when is_tuple(Source) -> element(1, Source).
|