Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get dependency command #2

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/rebar.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@
-define(REBAR_SAVE_CFG, "rebar.config.save").
-define(TIMEOUT, 200000).
-define(RETRY, 10).
-define(FMT_UPDATE, "Update \e[1m\e[32m~p\e[0m from ~200p").
-define(FMT_DOWNLOAD, "Download \e[1m\e[32m~p\e[0m from ~200p").
292 changes: 156 additions & 136 deletions src/deps.erl
Original file line number Diff line number Diff line change
@@ -1,171 +1,191 @@
-module(deps).

-export([
foreach/4,
foreach/5,
foreach/6
]).
-export([foreach/4, foreach/5, foreach/6, deps_list/1, deps_map/1, deps_dir/1]).
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deps_list где то извне используется разве?


-include("rebar.hrl").

-define(ROOT, bfs_root).

-callback do(Dir :: string(), App :: atom(), _VSN, _Source, _Args) ->
{nothing, App :: atom()} |
{ok, App :: atom(), Output :: string()} |
{accum, App :: atom(), Res :: any()} |
{error, App :: atom(), Reason :: string()}.

-spec foreach(Dir :: string(), Module :: module(),
Acc :: any(), Args :: any()) ->
{ok, Res :: any()} | {error, Reason :: any()}.
{nothing, App :: atom()} |
{ok, App :: atom(), Output :: string()} |
{accum, App :: atom(), Res :: any()} |
{error, App :: atom(), Reason :: string()}.

-spec foreach(Dir :: string(), Module :: module(), Acc :: any(), Args :: any()) ->
{ok, Res :: any()} | {error, Reason :: any()}.
foreach(Dir, Module, Acc, Args) ->
foreach(Dir, Module, Acc, Args, false, ?REBAR_CFG).

foreach(Dir, Module, Acc, Args, RebarCfg) ->
foreach(Dir, Module, Acc, Args, false, RebarCfg).

foreach(Dir, Module, Acc, Args, Delay, RebarCfg) ->
ok = file:set_cwd(Dir),
{DepsFldr, DepsList} = case file:consult(RebarCfg) of
{ok, Config} ->
{
proplists:get_value(deps_dir, Config, "deps"),
proplists:get_value(deps, Config, [])
};
{error, enoent} -> {"deps", []}
end,
DepsFldr = deps_dir(RebarCfg),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Так dir или fldr? думаю лучше все же dir чтобы было и слева и справа

DepsList = deps_list(RebarCfg),
DepsFolder = filename:join(Dir, DepsFldr),
bfs_step(Module, DepsFolder, DepsList, Acc, Delay, Args).

-spec bfs_step(Module :: module(), Dir :: string(),
DownloadList :: list({_, _, _, _} | {_, _, _} | {_, _}),
AccResult :: any(), Delay :: boolean(),
Args :: any()) -> {ok, list()} | none.
-spec deps_map(RebarCfg :: string()) -> DepsMap :: map().
deps_map(RebarCfg) ->
DepsList = deps_list(RebarCfg),
lists:foldl(fun ({App, _VSN, Source}, Acc) ->
maps:put(App, Source, Acc);
({App, _VSN, Source, _Raw}, Acc) ->
maps:put(App, Source, Acc)
end,
#{},
DepsList).

-spec deps_list(RebarCfg :: string()) -> DepsList :: list().
deps_list(RebarCfg) ->
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

две очень похожие функции, почти копипаст + дважды читается с диска
Может сделать одну функцию которая оба значения вернет и список приложений и директорию?

case file:consult(RebarCfg) of
{ok, Config} ->
proplists:get_value(deps, Config, []);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

сам по себе список нигде не нужен, везде используется map
так может тут сделать list comprehension + maps:from_list?

{error, enoent} ->
[]
end.

-spec deps_dir(RebarCfg :: string()) -> DepsFldr :: string().
deps_dir(RebarCfg) ->
case file:consult(RebarCfg) of
{ok, Config} ->
proplists:get_value(deps_dir, Config, "deps");
{error, enoent} ->
"deps"
end.

-spec bfs_step(Module :: module(),
Dir :: string(),
DownloadList :: [{_, _, _, _} | {_, _, _} | {_, _}],
AccResult :: any(),
Delay :: boolean(),
Args :: any()) ->
{ok, list()} | none.
bfs_step(Module, Dir, DepsList, AccResult, Delay, Args) ->
{Q, ViewedDeps} = lists:foldl(
fun({App, VSN, Source, [raw]}, {Acc1, Acc2}) ->
{
queue:in({App, VSN, Source}, Acc1),
gb_sets:add(App, Acc2)
};
(A = {App, _, _}, {Acc1, Acc2}) ->
{
queue:in(A, Acc1),
gb_sets:add(App, Acc2)
};
(Drop, Acc) ->
?WARN("Drop ~p", [Drop]),
Acc
end, {queue:new(), gb_sets:new()}, DepsList),
{Q, ViewedDeps} =
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А какие тут функциональные изменения?
если что то не нравится по стилю пожелейте мейнтейнера, отправте отдельным PR ну или хотя бы отдельным комитом внутри

lists:foldl(fun ({App, VSN, Source, [raw]}, {Acc1, Acc2}) ->
{queue:in({App, VSN, Source}, Acc1), gb_sets:add(App, Acc2)};
(A = {App, _, _}, {Acc1, Acc2}) ->
{queue:in(A, Acc1), gb_sets:add(App, Acc2)};
(Drop, Acc) ->
?WARN("Drop ~p", [Drop]),
Acc
end,
{queue:new(), gb_sets:new()},
DepsList),

case lists:member(?ROOT, erlang:registered()) of
true ->
none;
false ->
true = erlang:register(?ROOT, self())
end,
bfs_step(Module, Dir, Q, ViewedDeps, DepsList, gb_sets:new(),
AccResult, Delay, Args).

bfs_step(Module, Dir, Queue, ViewedDeps, DownloadList, DownloadedList,
AccResult, Delay, Args) ->
CorrectDownList = lists:reverse(lists:foldl(
fun(A = {App, VSN, Source}, Acc) ->
spawn(
fun() ->
Delay andalso timer:sleep(100),
?ROOT ! Module:do(Dir, App, VSN, Source, Args)
end),
[A | Acc];
({App, VSN, Source, [raw]}, Acc) ->
spawn(
fun() ->
Delay andalso timer:sleep(100),
?ROOT ! Module:do(Dir, App, VSN, Source, Args)
end),
[{App, VSN, Source} | Acc];
(Drop, Acc) ->
?WARN("Drop ~p", [Drop]),
Acc
end, [], DownloadList)),

{DownL, NewAccResult} = lists:foldl(
fun({_, _, _}, {Acc, AccRes}) ->
receive
{nothing, App} ->
{gb_sets:add(App, Acc), AccRes};
{ok, App, Output} ->
?CONSOLE(Output, []),
{gb_sets:add(App, Acc), AccRes};
{accum, App, Result} when not is_list(AccRes) ->
{
gb_sets:add(App, Acc),
Result
};
{accum, App, Result} ->
{
gb_sets:add(App, Acc),
lists:flatten([Result | AccRes])
};
{error, App, Reason} ->
?ERROR("\e[1m\e[31m~p\e[0m: ~n~p", [App, Reason]),
exit("Error when deps update")
after ?TIMEOUT ->
exit("Timeout when update dep")
end;
(_, Acc) ->
Acc
end, {DownloadedList, AccResult}, CorrectDownList),
bfs_step(Module, Dir, Q, ViewedDeps, DepsList, gb_sets:new(), AccResult, Delay, Args).
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

elvis не запускали?
тут вроде более 80 символов, перечит code style проекта


bfs_step(Module,
Dir,
Queue,
ViewedDeps,
DownloadList,
DownloadedList,
AccResult,
Delay,
Args) ->
CorrectDownList =
lists:reverse(
lists:foldl(fun (A = {App, VSN, Source}, Acc) ->
spawn(fun() ->
Delay andalso timer:sleep(100),
?ROOT ! Module:do(Dir, App, VSN, Source, Args)
end),
[A | Acc];
({App, VSN, Source, [raw]}, Acc) ->
spawn(fun() ->
Delay andalso timer:sleep(100),
?ROOT ! Module:do(Dir, App, VSN, Source, Args)
end),
[{App, VSN, Source} | Acc];
(Drop, Acc) ->
?WARN("Drop ~p", [Drop]),
Acc
end,
[],
DownloadList)),

{DownL, NewAccResult} =
lists:foldl(fun ({_, _, _}, {Acc, AccRes}) ->
receive
{nothing, App} ->
{gb_sets:add(App, Acc), AccRes};
{ok, App, Output} ->
?CONSOLE(Output, []),
{gb_sets:add(App, Acc), AccRes};
{accum, App, Result} when not is_list(AccRes) ->
{gb_sets:add(App, Acc), Result};
{accum, App, Result} ->
{gb_sets:add(App, Acc), lists:flatten([Result | AccRes])};
{error, App, Reason} ->
?ERROR("\e[1m\e[31m~p\e[0m: ~n~p", [App, Reason]),
exit("Error when deps update")
after ?TIMEOUT ->
exit("Timeout when update dep")
end;
(_, Acc) ->
Acc
end,
{DownloadedList, AccResult},
CorrectDownList),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тоже кусок без изменений как я понял?


Size1 = gb_sets:size(DownL),
Size2 = gb_sets:size(DownloadedList),
(Size1 - 5 > Size2) andalso Delay
andalso ?CONSOLE("Prepare ~p deps", [Size1]),
Size1 - 5 > Size2 andalso Delay andalso ?CONSOLE("Prepare ~p deps", [Size1]),

case queue:out(Queue) of
{{value, {App, _Vsn, _Source}}, Q} ->
AppDir = filename:join([Dir, App, ?REBAR_CFG]),
Child = try
case file:consult(AppDir) of
{ok, Config} -> proplists:get_value(deps, Config, []);
{error, enoent} -> []
end
catch
_:E ->
?ERROR("Error when file ~s consult: ~p", [AppDir, E]),
throw(E)
end,


{NewQ, NewS, DownloadL} = lists:foldl(
fun(Item = {Dep, _, _}, {AccQ, AccS, AccD}) ->
case gb_sets:is_member(Dep, AccS) of
false ->
{
queue:in(Item, AccQ),
gb_sets:add(Dep, AccS),
[Item | AccD]
};
true ->
{AccQ, AccS, AccD}
end;
({Dep, A, V, [raw]}, {AccQ, AccS, AccD}) ->
Item = {Dep, A, V},
case gb_sets:is_member(Dep, AccS) of
false ->
{
queue:in(Item, AccQ),
gb_sets:add(Dep, AccS),
[Item | AccD]
};
true ->
{AccQ, AccS, AccD}
end;
(Item, {AccQ, AccS, AccD}) ->
?WARN("Drop ~p", [Item]),
{AccQ, AccS, AccD}
end, {Q, ViewedDeps, []}, Child),
bfs_step(Module, Dir, NewQ, NewS, DownloadL, DownL,
NewAccResult, Delay, Args);
Child =
try
case file:consult(AppDir) of
{ok, Config} ->
proplists:get_value(deps, Config, []);
{error, enoent} ->
[]
end
catch
_:E ->
?ERROR("Error when file ~s consult: ~p", [AppDir, E]),
throw(E)
end,

{NewQ, NewS, DownloadL} =
lists:foldl(fun (Item = {Dep, _, _}, {AccQ, AccS, AccD}) ->
case gb_sets:is_member(Dep, AccS) of
false ->
{queue:in(Item, AccQ),
gb_sets:add(Dep, AccS),
[Item | AccD]};
true ->
{AccQ, AccS, AccD}
end;
({Dep, A, V, [raw]}, {AccQ, AccS, AccD}) ->
Item = {Dep, A, V},
case gb_sets:is_member(Dep, AccS) of
false ->
{queue:in(Item, AccQ),
gb_sets:add(Dep, AccS),
[Item | AccD]};
true ->
{AccQ, AccS, AccD}
end;
(Item, {AccQ, AccS, AccD}) ->
?WARN("Drop ~p", [Item]),
{AccQ, AccS, AccD}
end,
{Q, ViewedDeps, []},
Child),
bfs_step(Module, Dir, NewQ, NewS, DownloadL, DownL, NewAccResult, Delay, Args);
{{value, _}, _} ->
{ok, NewAccResult};
{empty, _} ->
Expand Down
20 changes: 16 additions & 4 deletions src/fd.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,21 @@ main_vrap([WD, A]) when A == "push"; A == "ps" ->
push:all([WD]);
main_vrap([WD, A]) when A == "update"; A == "up" ->
updater:update_all([WD], ?REBAR_CFG, no_fast);
main_vrap([A, "--fast"]) when A == "update"; A == "up" ->
{ok, WD} = file:get_cwd(),
updater:update_all([WD], ?REBAR_CFG, fast);
main_vrap([WD, A, "--fast"]) when A == "update"; A == "up" ->
{ok, WD} = file:get_cwd(),
updater:update_all([WD], ?REBAR_CFG, fast);
main_vrap([A, App]) when A == "update"; A == "up" ->
{ok, WD} = file:get_cwd(),
updater:update_app([WD], App, ?REBAR_CFG, no_fast);
main_vrap([WD, A]) when A == "get"; A == "gt" ->
{ok, WD} = file:get_cwd(),
get:all(WD, no_fast);
main_vrap([WD, A, "--fast"]) when A == "get"; A == "gt" ->
{ok, WD} = file:get_cwd(),
get:all(WD, fast);
main_vrap([A, App]) when A == "get"; A == "gt" ->
{ok, WD} = file:get_cwd(),
get:app(WD, App, no_fast);
main_vrap([WD, A]) when A == "status"; A == "st" ->
checker:checker([WD]);
main_vrap([WD, A]) when A == "log"; A == "lg" ->
Expand Down Expand Up @@ -66,7 +75,8 @@ main_vrap(["help", _]) ->
io:format(
"Usage: fd <command> [path] (fast deps)~n"
"Commands:~n"
" update (up) [--fast] - For update rebar deps. Flag --fast for fetch signle branch.~n"
" update (up) [--fast| APP] - For update rebar deps. Flag --fast for fetch signle branch.~n"
" get (gt) [--fast | APP] - For geting locked rebar deps. If lock file doesn't exist work like update.~n"
" status (st) - Get status rebar deps~n"
" save (sa) - Save deps on current state in rebar.config.save~n"
" load (ld) - For load state from rebar.config.save~n"
Expand All @@ -78,6 +88,8 @@ main_vrap(["help", _]) ->
" push (ps) - For all modificate push~n"
" tag (tg) - list tags~n"
" tag 0.1 --ignore app1 app2 - Create tag 0.1 without ignores app~n"
"~nNotes:~n"
" APP - dependency name. If APP does not exist in rebar.config or rebar.cofnig.save error will be occurred.~n"
);
main_vrap(Args) ->
io:format("Command ~p not recognized.~n", [Args]),
Expand Down
Loading