Bladeren bron

replace rlx_depsolver use with new rebar_digraph

pull/16/head
Tristan Sloughter 10 jaren geleden
bovenliggende
commit
af35d5f0a2
6 gewijzigde bestanden met toevoegingen van 113 en 84 verwijderingen
  1. +11
    -66
      src/rebar_digraph.erl
  2. +69
    -2
      src/rebar_erlc_compiler.erl
  3. +19
    -2
      src/rebar_packages.erl
  4. +8
    -8
      src/rebar_prv_install_deps.erl
  5. +4
    -4
      src/rebar_resource.erl
  6. +2
    -2
      src/rebar_state.erl

+ 11
- 66
src/rebar_digraph.erl Bestand weergeven

@ -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.", []).

+ 69
- 2
src/rebar_erlc_compiler.erl Bestand weergeven

@ -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

+ 19
- 2
src/rebar_packages.erl Bestand weergeven

@ -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 ->

+ 8
- 8
src/rebar_prv_install_deps.erl Bestand weergeven

@ -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())) ->

+ 4
- 4
src/rebar_resource.erl Bestand weergeven

@ -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().

+ 2
- 2
src/rebar_state.erl Bestand weergeven

@ -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.

Laden…
Annuleren
Opslaan