summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rebar_digraph.erl101
-rw-r--r--src/rebar_erlc_compiler.erl79
-rw-r--r--src/rebar_packages.erl6
-rw-r--r--src/rebar_prv_install_deps.erl2
-rw-r--r--src/rebar_prv_update.erl4
5 files changed, 109 insertions, 83 deletions
diff --git a/src/rebar_digraph.erl b/src/rebar_digraph.erl
new file mode 100644
index 0000000..decc542
--- /dev/null
+++ b/src/rebar_digraph.erl
@@ -0,0 +1,101 @@
+-module(rebar_digraph).
+
+-export([check_graph/2
+ ,restore_graph/1
+ ,store_graph/3
+ ,solve/2
+ ,subgraph/2]).
+
+-include("rebar.hrl").
+
+check_graph(_File, #graph{vsn=?GRAPH_VSN}) ->
+ ok;
+check_graph(File, #graph{vsn=Vsn}) ->
+ ?ABORT("~s file version is incompatible. expected: ~b got: ~b",
+ [File, ?GRAPH_VSN, Vsn]);
+check_graph(File, _) ->
+ ?ABORT("~s file is invalid. Please delete before next run.",
+ [File]).
+
+restore_graph({Vs, Es}) ->
+ G = digraph:new(),
+ lists:foreach(fun({V, LastUpdated}) ->
+ digraph:add_vertex(G, V, LastUpdated)
+ end, Vs),
+ lists:foreach(fun({V1, V2}) ->
+ digraph:add_edge(G, V1, V2)
+ end, Es),
+ G;
+restore_graph(File) ->
+ G = digraph:new(),
+ case file:read_file(File) of
+ {ok, Data} ->
+ try binary_to_term(Data) of
+ G ->
+ %% ok = check_erlcinfo(Config, Graph),
+ #graph{info=Graph} = G,
+ {Vs, Es} = Graph,
+ lists:foreach(
+ fun({V, LastUpdated}) ->
+ digraph:add_vertex(G, V, LastUpdated)
+ end, Vs),
+ lists:foreach(
+ fun({V1, V2}) ->
+ digraph:add_edge(G, V1, V2)
+ end, Es)
+ catch
+ error:badarg ->
+ ?ERROR(
+ "Failed (binary_to_term) to restore rebar info file."
+ " Discard file.", []),
+ ok
+ end;
+ _Err ->
+ ok
+ end,
+ G.
+
+store_graph(_G, _File, _Modified = false) ->
+ ok;
+store_graph(G, File, _Modified) ->
+ Vs = lists:map(
+ fun(V) ->
+ digraph:vertex(G, V)
+ end, digraph:vertices(G)),
+ Es = lists:flatmap(
+ fun({V, _}) ->
+ lists:map(
+ fun(E) ->
+ {_, V1, V2, _} = digraph:edge(G, E),
+ {V1, V2}
+ end, digraph:out_edges(G, V))
+ end, Vs),
+
+ ok = filelib:ensure_dir(File),
+ Data = term_to_binary(#graph{info={Vs, Es}}, [{compressed, 9}]),
+ file:write_file(File, Data).
+
+solve(Graph, Vertices) ->
+ solve(Graph, Vertices, dict:new()).
+
+solve(_Graph, [], Solution) ->
+ {_, Vertices} = lists:unzip(dict:to_list(Solution)),
+ Vertices;
+solve(Graph, Vertices, Solution) ->
+ {NV, NS} =
+ lists:foldl(fun(V, {NewVertices, SolutionAcc}) ->
+ OutNeighbors = digraph:out_neighbours(Graph, V),
+ lists:foldl(fun({Key, _}=N, {NewVertices1, SolutionAcc1}) ->
+ case dict:is_key(Key, SolutionAcc1) orelse
+ lists:keymember(Key, 1, Vertices) of
+ true ->
+ {NewVertices1, SolutionAcc1};
+ false ->
+ {[N | NewVertices1], dict:store(Key, N, SolutionAcc1)}
+ end
+ end, {NewVertices, SolutionAcc}, OutNeighbors)
+ end, {[], Solution}, Vertices),
+ solve(Graph, NV, NS).
+
+subgraph(Graph, Vertices) ->
+ digraph_utils:subgraph(Graph, Vertices).
diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl
index 1277242..5e7787c 100644
--- a/src/rebar_erlc_compiler.erl
+++ b/src/rebar_erlc_compiler.erl
@@ -38,25 +38,9 @@
-define(ERLCINFO_VSN, 1).
-define(ERLCINFO_FILE, "erlcinfo").
--type erlc_info_v() :: {digraph:vertex(), term()} | 'false'.
--type erlc_info_e() :: {digraph:vertex(), digraph:vertex()}.
--type erlc_info() :: {list(erlc_info_v()), list(erlc_info_e())}.
--record(erlcinfo,
- {
- vsn = ?ERLCINFO_VSN :: pos_integer(),
- info = {[], []} :: erlc_info()
- }).
-define(RE_PREFIX, "^[^._]").
--ifdef(namespaced_types).
-%% digraph:graph() exists starting from Erlang 17.
--type rebar_digraph() :: digraph:graph().
--else.
-%% digraph() has been obsoleted in Erlang 17 and deprecated in 18.
--type rebar_digraph() :: digraph().
--endif.
-
%% ===================================================================
%% Public API
%% ===================================================================
@@ -408,20 +392,11 @@ needs_compile(Source, Target, Parents) ->
lists:any(fun(I) -> TargetLastMod < filelib:last_modified(I) end,
[Source] ++ Parents).
-check_erlcinfo(_Config, #erlcinfo{vsn=?ERLCINFO_VSN}) ->
- ok;
-check_erlcinfo(Config, #erlcinfo{vsn=Vsn}) ->
- ?ABORT("~s file version is incompatible. expected: ~b got: ~b",
- [erlcinfo_file(Config), ?ERLCINFO_VSN, Vsn]);
-check_erlcinfo(Config, _) ->
- ?ABORT("~s file is invalid. Please delete before next run.",
- [erlcinfo_file(Config)]).
-
erlcinfo_file(_Config) ->
filename:join([rebar_utils:get_cwd(), ?CONFIG_DIR, ?ERLCINFO_FILE]).
init_erlcinfo(Config, Erls) ->
- G = restore_erlcinfo(Config),
+ G = rebar_digraph:restore_graph(erlcinfo_file(Config)),
%% Get a unique list of dirs based on the source files' locations.
%% This is used for finding files in sub dirs of the configured
%% src_dirs. For example, src/sub_dir/foo.erl.
@@ -433,7 +408,7 @@ init_erlcinfo(Config, Erls) ->
Updates = [update_erlcinfo(G, Erl, include_path(Erl, Config) ++ Dirs)
|| Erl <- Erls],
Modified = lists:member(modified, Updates),
- ok = store_erlcinfo(G, Config, Modified),
+ ok = rebar_digraph:store_graph(G, erlcinfo_file(Config), Modified),
G.
update_erlcinfo(G, Source, Dirs) ->
@@ -470,56 +445,6 @@ modify_erlcinfo(G, Source, Dirs) ->
digraph:add_edge(G, Source, Incl)
end, AbsIncls).
-restore_erlcinfo(Config) ->
- File = erlcinfo_file(Config),
- G = digraph:new(),
- case file:read_file(File) of
- {ok, Data} ->
- try binary_to_term(Data) of
- Erlcinfo ->
- ok = check_erlcinfo(Config, Erlcinfo),
- #erlcinfo{info=ErlcInfo} = Erlcinfo,
- {Vs, Es} = ErlcInfo,
- lists:foreach(
- fun({V, LastUpdated}) ->
- digraph:add_vertex(G, V, LastUpdated)
- end, Vs),
- lists:foreach(
- fun({V1, V2}) ->
- digraph:add_edge(G, V1, V2)
- end, Es)
- catch
- error:badarg ->
- ?ERROR(
- "Failed (binary_to_term) to restore rebar info file."
- " Discard file.", []),
- ok
- end;
- _Err ->
- ok
- end,
- G.
-
-store_erlcinfo(_G, _Config, _Modified = false) ->
- ok;
-store_erlcinfo(G, Config, _Modified) ->
- Vs = lists:map(
- fun(V) ->
- digraph:vertex(G, V)
- end, digraph:vertices(G)),
- Es = lists:flatmap(
- fun({V, _}) ->
- lists:map(
- fun(E) ->
- {_, V1, V2, _} = digraph:edge(G, E),
- {V1, V2}
- end, digraph:out_edges(G, V))
- end, Vs),
- File = erlcinfo_file(Config),
- ok = filelib:ensure_dir(File),
- Data = term_to_binary(#erlcinfo{info={Vs, Es}}, [{compressed, 9}]),
- file:write_file(File, Data).
-
%% NOTE: If, for example, one of the entries in Files, refers to
%% gen_server.erl, that entry will be dropped. It is dropped because
%% such an entry usually refers to the beam file, and we don't pass a
diff --git a/src/rebar_packages.erl b/src/rebar_packages.erl
index 7974fda..7334365 100644
--- a/src/rebar_packages.erl
+++ b/src/rebar_packages.erl
@@ -14,12 +14,12 @@ get_packages(State) ->
try
{ok, Binary} = file:read_file(PackagesFile),
{Dict, Graph} = binary_to_term(Binary),
- {Dict, Graph}
+ {Dict, rebar_digraph:restore_graph(Graph)}
catch
_:_ ->
?ERROR("Bad packages index, try to fix with `rebar update`~n", []),
- {dict:new(), rlx_depsolver:new_graph()}
+ {dict:new(), digraph:new()}
end;
false ->
- {dict:new(), rlx_depsolver:new_graph()}
+ {dict:new(), digraph:new()}
end.
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index f3c050e..7e41429 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -130,7 +130,7 @@ handle_deps(State, Deps, Update) ->
[];
PkgDeps1 ->
%% Find pkg deps needed
- S = case rlx_depsolver:solve(Graph, PkgDeps1) of
+ S = case rebar_digraph:solve(Graph, PkgDeps1) of
{ok, Solution} ->
Solution;
Reason ->
diff --git a/src/rebar_prv_update.erl b/src/rebar_prv_update.erl
index 4751e05..16987be 100644
--- a/src/rebar_prv_update.erl
+++ b/src/rebar_prv_update.erl
@@ -40,8 +40,8 @@ do(State) ->
Home = rebar_utils:home_dir(),
PackagesFile = filename:join([Home, ?CONFIG_DIR, "packages"]),
filelib:ensure_dir(PackagesFile),
- {ok, _RequestId} = httpc:request(get, {Url, []}, [], [{stream, TmpFile}
- ,{sync, true}]),
+ {ok, _RequestId} = httpc:request(get, {Url, [{"Accept", "application/erlang"}]},
+ [], [{stream, TmpFile}, {sync, true}]),
ok = ec_file:copy(TmpFile, PackagesFile)
catch
_:_ ->