浏览代码

refactor install_deps again and rename app_builder to compile

pull/3/head
Tristan Sloughter 10 年前
父节点
当前提交
829d4f2ca5
共有 5 个文件被更改,包括 119 次插入90 次删除
  1. +2
    -2
      ebin/rebar.app
  2. +4
    -8
      src/rebar_app_discover.erl
  3. +5
    -3
      src/rebar_prv_compile.erl
  4. +82
    -61
      src/rebar_prv_install_deps.erl
  5. +26
    -16
      src/rebar_state.erl

+ 2
- 2
ebin/rebar.app 查看文件

@ -22,7 +22,7 @@
rebar_packages,
rebar_prv_deps,
rebar_prv_install_deps,
rebar_prv_app_builder,
rebar_prv_compile,
rebar_prv_app_discovery,
rebar_prv_escripter,
rebar_prv_release,
@ -57,7 +57,7 @@
rebar_prv_install_deps,
rebar_prv_packages,
rebar_erlydtl_compiler,
rebar_prv_app_builder,
rebar_prv_compile,
rebar_prv_app_discovery,
rebar_prv_shell,
rebar_prv_tar,

+ 4
- 8
src/rebar_app_discover.erl 查看文件

@ -7,8 +7,9 @@
do(State, LibDirs) ->
Apps = find_apps(LibDirs, all),
ProjectDeps = rebar_state:deps_names(State),
lists:foldl(fun(AppInfo, StateAcc) ->
rebar_state:apps_to_build(StateAcc, AppInfo)
rebar_state:project_apps(StateAcc, rebar_app_info:deps(AppInfo, ProjectDeps))
end, State, Apps).
-spec all_app_dirs(list(file:name())) -> list(file:name()).
@ -35,15 +36,10 @@ app_dirs(LibDir) ->
"*.app"]),
lists:usort(lists:foldl(fun(Path, Acc) ->
Files = filelib:wildcard(to_list(Path)),
Files = filelib:wildcard(ec_cnv:to_list(Path)),
[app_dir(File) || File <- Files] ++ Acc
end, [], [Path1, Path2, Path3, Path4])).
to_list(S) when is_list(S) ->
S;
to_list(S) when is_binary(S) ->
binary_to_list(S).
find_unbuilt_apps(LibDirs) ->
find_apps(LibDirs, invalid).
@ -149,7 +145,7 @@ get_modules_list(AppFile, AppDetail) ->
ok | {error, Reason::term()}.
has_all_beams(EbinDir, [Module | ModuleList]) ->
BeamFile = filename:join([EbinDir,
list_to_binary(atom_to_list(Module) ++ ".beam")]),
ec_cnv:to_list(Module) ++ ".beam"]),
case filelib:is_file(BeamFile) of
true ->
has_all_beams(EbinDir, ModuleList);

src/rebar_prv_app_builder.erl → src/rebar_prv_compile.erl 查看文件

@ -1,4 +1,4 @@
-module(rebar_prv_app_builder).
-module(rebar_prv_compile).
-behaviour(rebar_provider).
@ -29,10 +29,12 @@ init(State) ->
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | relx:error().
do(State) ->
Apps = rebar_state:apps_to_build(State),
Apps = rebar_state:project_apps(State),
lists:foreach(fun(AppInfo) ->
_AppInfo1 = build(State, AppInfo)
C = rebar_config:consult(rebar_app_info:dir(AppInfo)),
S = rebar_state:new(rebar_state:new(), C, rebar_app_info:dir(AppInfo)),
_AppInfo1 = build(S, AppInfo)
end, Apps),
rebar_lock:create(State),

+ 82
- 61
src/rebar_prv_install_deps.erl 查看文件

@ -42,6 +42,11 @@
-define(PROVIDER, install_deps).
-define(DEPS, [app_discovery]).
-type src_dep() :: {atom(), string(), {atom(), string(), string()}}.
-type binary_dep() :: {atom(), binary()} | atom().
-type dep() :: src_dep() | binary_dep().
%% ===================================================================
%% Public API
%% ===================================================================
@ -60,53 +65,9 @@ init(State) ->
-spec do(rebar_state:t()) -> {ok, rebar_state:t()}.
do(State) ->
%% Read in package index and dep graph
{Packages, Graph} = rebar_packages:get_packages(State),
case rebar_state:get(State, locks, []) of
[] ->
case rebar_state:get(State, deps, []) of
[] ->
{ok, State};
Deps ->
%% Split source deps form binary deps, needed to keep backwards compatibility
DepsDir = get_deps_dir(State),
{SrcDeps, Goals} = parse_deps(DepsDir, Deps),
State1 = rebar_state:src_deps(rebar_state:goals(State, Goals), lists:ukeysort(2, SrcDeps)),
State2 = update_src_deps(State1),
case rebar_state:goals(State2) of
[] ->
ProjectApps = lists:map(fun(X) ->
rebar_app_info:deps(X, [rebar_app_info:name(Y) || Y <- SrcDeps])
end, rebar_state:apps_to_build(State2)),
FinalDeps = ProjectApps ++ rebar_state:src_deps(State2),
{ok, Sort} = rebar_topo:sort_apps(FinalDeps),
State3 = rebar_state:apps_to_build(State2, Sort),
{ok, State3};
Goals1 ->
{ok, Solved} = rlx_depsolver:solve(Graph, Goals1),
Final = lists:map(fun({Name, Vsn}) ->
FmtVsn = ec_cnv:to_binary(rlx_depsolver:format_version(Vsn)),
{ok, P} = dict:find({Name, FmtVsn}, Packages),
PkgDeps = proplists:get_value(<<"deps">>, P),
Link = proplists:get_value(<<"link">>, P),
Source = {Name, FmtVsn, Link},
{ok, AppInfo} = rebar_app_info:new(Name, FmtVsn),
AppInfo1 = rebar_app_info:deps(AppInfo, PkgDeps),
AppInfo2 =
rebar_app_info:dir(AppInfo1, get_deps_dir(DepsDir, <<Name/binary, "-", FmtVsn/binary>>)),
AppInfo3 = rebar_app_info:source(AppInfo2, Source),
ok = maybe_fetch(AppInfo3),
AppInfo3
end, Solved),
ProjectApps = lists:map(fun(X) ->
rebar_app_info:deps(X, [rebar_app_info:name(Y) || Y <- SrcDeps] ++ [element(1, G) || G <- Goals1])
end, rebar_state:apps_to_build(State2)),
FinalDeps = ProjectApps ++ rebar_state:src_deps(State2) ++ Final,
{ok, Sort} = rebar_topo:sort_apps(FinalDeps),
State3 = rebar_state:apps_to_build(State2, Sort),
{ok, State3}
end
end;
handle_deps(State, rebar_state:get(State, deps, []));
_Locks ->
{ok, State}
end.
@ -130,10 +91,12 @@ setup_env(State) ->
[{"REBAR_DEPS_DIR", DepsDir}, ERL_LIBS].
-spec get_deps_dir(rebar_state:t()) -> file:filename_all().
get_deps_dir(State) ->
BaseDir = rebar_state:get(State, base_dir, ""),
get_deps_dir(BaseDir, "deps").
-spec get_deps_dir(file:filename_all(), rebar_state:t()) -> file:filename_all().
get_deps_dir(DepsDir, App) ->
filename:join(DepsDir, App).
@ -141,28 +104,84 @@ get_deps_dir(DepsDir, App) ->
%% Internal functions
%% ===================================================================
handle_deps(State, []) ->
{ok, State};
handle_deps(State, Deps) ->
%% Read in package index and dep graph
{Packages, Graph} = rebar_packages:get_packages(State),
ProjectApps = rebar_state:project_apps(State),
%% Split source deps form binary deps, needed to keep backwards compatibility
DepsDir = get_deps_dir(State),
{SrcDeps, BinaryDeps} = parse_deps(DepsDir, Deps),
State1 = rebar_state:src_deps(rebar_state:binary_deps(State, BinaryDeps),
lists:ukeysort(2, SrcDeps)),
%% Fetch transitive src deps
State2 = update_src_deps(State1),
Solved = case rebar_state:binary_deps(State2) of
[] -> %% No binary deps
[];
BinaryDeps1 ->
%% Find binary deps needed
{ok, S} = rlx_depsolver:solve(Graph, BinaryDeps1),
%% Create app_info record for each binary dep
lists:map(fun({Name, Vsn}) ->
AppInfo = package_to_app(DepsDir
,Packages
,Name
,Vsn),
ok = maybe_fetch(AppInfo),
AppInfo
end, S)
end,
FinalDeps = ProjectApps ++ rebar_state:src_deps(State2) ++ Solved,
%% Sort all apps to build order
{ok, Sort} = rebar_topo:sort_apps(FinalDeps),
{ok, rebar_state:project_apps(State2, Sort)}.
-spec package_to_app(file:name(), dict:dict(), binary(), binary()) -> rebar_app_info:t().
package_to_app(DepsDir, Packages, Name, Vsn) ->
FmtVsn = ec_cnv:to_binary(rlx_depsolver:format_version(Vsn)),
{ok, P} = dict:find({Name, FmtVsn}, Packages),
PkgDeps = proplists:get_value(<<"deps">>, P),
Link = proplists:get_value(<<"link">>, P),
{ok, AppInfo} = rebar_app_info:new(Name, FmtVsn),
AppInfo1 = rebar_app_info:deps(AppInfo, PkgDeps),
AppInfo2 =
rebar_app_info:dir(AppInfo1, get_deps_dir(DepsDir, <<Name/binary, "-", FmtVsn/binary>>)),
rebar_app_info:source(AppInfo2, {Name, FmtVsn, Link}).
-spec update_src_deps(rebar_state:t()) -> rebat_state:t().
update_src_deps(State) ->
SrcDeps = rebar_state:src_deps(State),
DepsDir = get_deps_dir(State),
case lists:foldl(fun(AppInfo, {SrcDepsAcc, GoalsAcc}) ->
case lists:foldl(fun(AppInfo, {SrcDepsAcc, BinaryDepsAcc}) ->
ok = maybe_fetch(AppInfo),
{NewSrcDeps, NewGoals} = handle_dep(DepsDir, AppInfo),
{lists:ukeymerge(2, SrcDepsAcc, lists:ukeysort(2, NewSrcDeps)), NewGoals++GoalsAcc}
end, {SrcDeps, rebar_state:goals(State)}, SrcDeps) of
{SrcDeps, NewGoals} ->
rebar_state:goals(State, NewGoals);
{NewSrcDeps, NewGoals} ->
io:format("NEWSRC ~p~n", [NewSrcDeps]),
State1 = rebar_state:src_deps(rebar_state:goals(State, NewGoals), NewSrcDeps),
{AppInfo1, NewSrcDeps, NewBinaryDeps} = handle_dep(DepsDir, AppInfo),
{lists:ukeymerge(2, lists:ukeysort(2, [AppInfo1 | SrcDepsAcc]), lists:ukeysort(2, NewSrcDeps)), NewBinaryDeps++BinaryDepsAcc}
end, {[], rebar_state:binary_deps(State)}, SrcDeps) of
{NewSrcDeps, NewBinaryDeps} when length(SrcDeps) =:= length(NewSrcDeps) ->
rebar_state:src_deps(rebar_state:binary_deps(State, NewBinaryDeps), NewSrcDeps);
{NewSrcDeps, NewBinaryDeps} ->
State1 = rebar_state:src_deps(rebar_state:binary_deps(State, NewBinaryDeps), NewSrcDeps),
update_src_deps(State1)
end.
-spec handle_dep(binary(), rebar_state:t()) -> {[rebar_app_info:t()], [binary_dep()]}.
handle_dep(DepsDir, AppInfo) ->
C = rebar_config:consult(rebar_app_info:dir(AppInfo)),
S = rebar_state:new(rebar_state:new(), C, rebar_app_info:dir(AppInfo)),
Deps = rebar_state:get(S, deps, []),
parse_deps(DepsDir, Deps).
AppInfo1 = rebar_app_info:deps(AppInfo, rebar_state:deps_names(S)),
{SrcDeps, BinaryDeps} = parse_deps(DepsDir, Deps),
{AppInfo1, SrcDeps, BinaryDeps}.
-spec maybe_fetch(rebar_app_info:t()) -> ok.
maybe_fetch(AppInfo) ->
AppDir = rebar_app_info:dir(AppInfo),
case filelib:is_dir(AppDir) of
@ -174,19 +193,21 @@ maybe_fetch(AppInfo) ->
ok
end.
-spec parse_deps(binary(), [dep()]) -> {[rebar_app_info:t()], [binary_dep()]}.
parse_deps(DepsDir, Deps) ->
lists:foldl(fun({Name, Vsn}, {SrcDepsAcc, GoalsAcc}) ->
lists:foldl(fun({Name, Vsn}, {SrcDepsAcc, BinaryDepsAcc}) ->
{SrcDepsAcc, [parse_goal(ec_cnv:to_binary(Name)
,ec_cnv:to_binary(Vsn)) | GoalsAcc]};
(Name, {SrcDepsAcc, GoalsAcc}) when is_atom(Name) ->
{SrcDepsAcc, [ec_cnv:to_binary(Name) | GoalsAcc]};
({Name, _, Source}, {SrcDepsAcc, GoalsAcc}) ->
,ec_cnv:to_binary(Vsn)) | BinaryDepsAcc]};
(Name, {SrcDepsAcc, BinaryDepsAcc}) when is_atom(Name) ->
{SrcDepsAcc, [ec_cnv:to_binary(Name) | BinaryDepsAcc]};
({Name, _, Source}, {SrcDepsAcc, BinaryDepsAcc}) ->
{ok, Dep} = rebar_app_info:new(Name),
Dep1 = rebar_app_info:source(
rebar_app_info:dir(Dep, get_deps_dir(DepsDir, Name)), Source),
{[Dep1 | SrcDepsAcc], GoalsAcc}
{[Dep1 | SrcDepsAcc], BinaryDepsAcc}
end, {[], []}, Deps).
-spec parse_goal(binary(), binary()) -> binary_dep().
parse_goal(Name, Constraint) ->
case re:run(Constraint, "([^\\d]*)(\\d.*)", [{capture, [1,2], binary}]) of
{match, [<<>>, Vsn]} ->

+ 26
- 16
src/rebar_state.erl 查看文件

@ -7,9 +7,10 @@
set_skip_dir/2, is_skip_dir/2, reset_skip_dirs/1,
create_logic_providers/2,
apps_to_build/1, apps_to_build/2,
project_apps/1, project_apps/2,
goals/1, goals/2,
deps_names/1,
binary_deps/1, binary_deps/2,
src_deps/1, src_deps/2,
providers/1, providers/2, add_provider/2]).
@ -33,10 +34,10 @@
command_args = [] :: list(),
src_deps = [] :: [rebar_app_info:t()],
apps = dict:new() :: rebar_dict(),
goals = [],
binary_deps = [],
project_apps = [],
providers = [],
apps_to_build = [],
skip_dirs = new_skip_dirs() :: rebar_dict() }).
-export_type([t/0]).
@ -105,13 +106,22 @@ command_args(#state_t{command_args=CmdArgs}) ->
command_args(State, CmdArgs) ->
State#state_t{command_args=CmdArgs}.
goals(#state_t{goals=Goals}) ->
Goals.
goals(State=#state_t{goals=Goals}, NewGoals) when is_list(Goals) ->
State#state_t{goals=NewGoals};
goals(State=#state_t{goals=Goals}, Goal) ->
State#state_t{goals=[Goal | Goals]}.
deps_names(State) ->
Deps = rebar_state:get(State, deps, []),
lists:map(fun(Dep) when is_tuple(Dep) ->
ec_cnv:to_binary(element(1, Dep));
(Dep) when is_atom(Dep) ->
ec_cnv:to_binary(Dep)
end, Deps).
binary_deps(#state_t{binary_deps=BinaryDeps}) ->
BinaryDeps.
binary_deps(State=#state_t{binary_deps=BinaryDeps}, NewBinaryDeps) when is_list(BinaryDeps) ->
State#state_t{binary_deps=NewBinaryDeps};
binary_deps(State=#state_t{binary_deps=BinaryDeps}, BinaryDep) ->
State#state_t{binary_deps=[BinaryDep | BinaryDeps]}.
src_deps(#state_t{src_deps=SrcDeps}) ->
SrcDeps.
@ -121,13 +131,13 @@ src_deps(State=#state_t{src_deps=SrcDeps}, NewSrcDeps) when is_list(SrcDeps) ->
src_deps(State=#state_t{src_deps=SrcDeps}, SrcDep) ->
State#state_t{src_deps=[SrcDep | SrcDeps]}.
apps_to_build(#state_t{apps_to_build=Apps}) ->
project_apps(#state_t{project_apps=Apps}) ->
Apps.
apps_to_build(State=#state_t{apps_to_build=Apps}, NewApps) when is_list(NewApps) ->
State#state_t{apps_to_build=NewApps};
apps_to_build(State=#state_t{apps_to_build=Apps}, App) ->
State#state_t{apps_to_build=[App | Apps]}.
project_apps(State=#state_t{}, NewApps) when is_list(NewApps) ->
State#state_t{project_apps=NewApps};
project_apps(State=#state_t{project_apps=Apps}, App) ->
State#state_t{project_apps=[App | Apps]}.
providers(#state_t{providers=Providers}) ->
Providers.

正在加载...
取消
保存