summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Sloughter <t@crashfast.com>2014-11-22 09:13:10 -0600
committerTristan Sloughter <t@crashfast.com>2014-11-22 20:24:21 -0600
commitaf35d5f0a2c91319fc86c5bb4a9d018658519c4c (patch)
tree81513a265a2710a36a83b69e0758c3fcd0d5b61a
parentf22db1302d710fbf017108852991cd6ac538de17 (diff)
replace rlx_depsolver use with new rebar_digraph
-rw-r--r--src/rebar_digraph.erl77
-rw-r--r--src/rebar_erlc_compiler.erl71
-rw-r--r--src/rebar_packages.erl21
-rw-r--r--src/rebar_prv_install_deps.erl16
-rw-r--r--src/rebar_resource.erl8
-rw-r--r--src/rebar_state.erl4
6 files changed, 113 insertions, 84 deletions
diff --git a/src/rebar_digraph.erl b/src/rebar_digraph.erl
index decc542..1198530 100644
--- a/src/rebar_digraph.erl
+++ b/src/rebar_digraph.erl
@@ -1,86 +1,28 @@
-module(rebar_digraph).
--export([check_graph/2
- ,restore_graph/1
- ,store_graph/3
+-export([restore_graph/1
,solve/2
- ,subgraph/2]).
+ ,subgraph/2
+ ,format_error/1]).
-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(),
+ Graph = digraph:new(),
lists:foreach(fun({V, LastUpdated}) ->
- digraph:add_vertex(G, V, LastUpdated)
+ digraph:add_vertex(Graph, V, LastUpdated)
end, Vs),
lists:foreach(fun({V1, V2}) ->
- digraph:add_edge(G, V1, V2)
+ digraph:add_edge(Graph, 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).
+ Graph.
solve(Graph, Vertices) ->
solve(Graph, Vertices, dict:new()).
solve(_Graph, [], Solution) ->
{_, Vertices} = lists:unzip(dict:to_list(Solution)),
- Vertices;
+ {ok, Vertices};
solve(Graph, Vertices, Solution) ->
{NV, NS} =
lists:foldl(fun(V, {NewVertices, SolutionAcc}) ->
@@ -99,3 +41,6 @@ solve(Graph, Vertices, Solution) ->
subgraph(Graph, Vertices) ->
digraph_utils:subgraph(Graph, Vertices).
+
+format_error(no_solution) ->
+ io_lib:format("No solution for packages found.", []).
diff --git a/src/rebar_erlc_compiler.erl b/src/rebar_erlc_compiler.erl
index 5e7787c..71ee780 100644
--- a/src/rebar_erlc_compiler.erl
+++ b/src/rebar_erlc_compiler.erl
@@ -38,6 +38,14 @@
-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, "^[^._]").
@@ -392,11 +400,20 @@ 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 = rebar_digraph:restore_graph(erlcinfo_file(Config)),
+ G = restore_erlcinfo(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.
@@ -408,7 +425,7 @@ init_erlcinfo(Config, Erls) ->
Updates = [update_erlcinfo(G, Erl, include_path(Erl, Config) ++ Dirs)
|| Erl <- Erls],
Modified = lists:member(modified, Updates),
- ok = rebar_digraph:store_graph(G, erlcinfo_file(Config), Modified),
+ ok = store_erlcinfo(G, Config, Modified),
G.
update_erlcinfo(G, Source, Dirs) ->
@@ -445,6 +462,56 @@ 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 7334365..7308611 100644
--- a/src/rebar_packages.erl
+++ b/src/rebar_packages.erl
@@ -2,9 +2,26 @@
-export([get_packages/1]).
+-export_type([constraint/0]).
+
-include("rebar.hrl").
--spec get_packages(rebar_state:t()) -> {rebar_dict(), rlx_depsolver:t()}.
+-type pkg_name() :: string() | binary() | atom().
+
+-type vsn() :: 'NO_VSN'
+ | ec_semver:semver().
+
+-type constraint_op() ::
+ '=' | gte | '>=' | lte | '<='
+ | gt | '>' | lt | '<' | pes | '~>' | between.
+
+-type constraint() :: pkg_name()
+ | {pkg_name(), vsn()}
+ | {pkg_name(), vsn(), constraint_op()}
+ | {pkg_name(), vsn(), vsn(), between}.
+
+
+-spec get_packages(rebar_state:t()) -> {rebar_dict(), rebar_digraph()}.
get_packages(State) ->
Home = rebar_utils:home_dir(),
RebarDir = rebar_state:get(State, global_rebar_dir, filename:join(Home, ?CONFIG_DIR)),
@@ -17,7 +34,7 @@ get_packages(State) ->
{Dict, rebar_digraph:restore_graph(Graph)}
catch
_:_ ->
- ?ERROR("Bad packages index, try to fix with `rebar update`~n", []),
+ ?ERROR("Bad packages index, try to fix with `rebar update`", []),
{dict:new(), digraph:new()}
end;
false ->
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index 7e41429..81bc71f 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -131,10 +131,12 @@ handle_deps(State, Deps, Update) ->
PkgDeps1 ->
%% Find pkg deps needed
S = case rebar_digraph:solve(Graph, PkgDeps1) of
+ {ok, []} ->
+ throw({rebar_digraph, no_solution});
{ok, Solution} ->
Solution;
- Reason ->
- throw({error, {rlx_depsolver, Reason}})
+ [] ->
+ throw({rebar_digraph, no_solution})
end,
%% Create app_info record for each pkg dep
@@ -156,19 +158,17 @@ handle_deps(State, Deps, Update) ->
%% Internal functions
%% ===================================================================
-package_to_app(DepsDir, Packages, Pkg={_, Vsn}) ->
- Name = ec_cnv:to_binary(rlx_depsolver:dep_pkg(Pkg)),
- FmtVsn = iolist_to_binary(rlx_depsolver:format_version(Vsn)),
- case dict:find({Name, FmtVsn}, Packages) of
+package_to_app(DepsDir, Packages, {Name, Vsn}) ->
+ case dict:find({Name, Vsn}, Packages) of
error ->
[];
{ok, P} ->
PkgDeps = proplists:get_value(<<"deps">>, P, []),
Link = proplists:get_value(<<"link">>, P, ""),
- {ok, AppInfo} = rebar_app_info:new(Name, FmtVsn),
+ {ok, AppInfo} = rebar_app_info:new(Name, Vsn),
AppInfo1 = rebar_app_info:deps(AppInfo, PkgDeps),
AppInfo2 = rebar_app_info:dir(AppInfo1, get_deps_dir(DepsDir, Name)),
- [rebar_app_info:source(AppInfo2, {pkg, Name, FmtVsn, Link})]
+ [rebar_app_info:source(AppInfo2, {pkg, Name, Vsn, Link})]
end.
-spec update_src_deps(integer(), rebar_state:t(), boolean(), sets:set(binary())) ->
diff --git a/src/rebar_resource.erl b/src/rebar_resource.erl
index 5babff7..ee7d2d3 100644
--- a/src/rebar_resource.erl
+++ b/src/rebar_resource.erl
@@ -4,10 +4,10 @@
-export([]).
--export_types([resource/0
- ,type/0
- ,location/0
- ,ref/0]).
+-export_type([resource/0
+ ,type/0
+ ,location/0
+ ,ref/0]).
-type resource() :: {type(), location(), ref()}.
-type type() :: atom().
diff --git a/src/rebar_state.erl b/src/rebar_state.erl
index f39251d..7ed29fa 100644
--- a/src/rebar_state.erl
+++ b/src/rebar_state.erl
@@ -28,7 +28,7 @@
src_deps = [],
src_apps = [],
- pkg_deps = [] :: [rlx_depsolver:constraint()],
+ pkg_deps = [] :: [rebar_packages:constraint()],
project_apps = [],
providers = []}).
@@ -103,7 +103,7 @@ deps_names(State) ->
ec_cnv:to_binary(Dep)
end, Deps).
--spec pkg_deps(t()) -> [rlx_depsolver:constraint()].
+-spec pkg_deps(t()) -> [rebar_packages:constraint()].
pkg_deps(#state_t{pkg_deps=PkgDeps}) ->
PkgDeps.