summaryrefslogtreecommitdiff
path: root/src/rebar_prv_update.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rebar_prv_update.erl')
-rw-r--r--src/rebar_prv_update.erl64
1 files changed, 49 insertions, 15 deletions
diff --git a/src/rebar_prv_update.erl b/src/rebar_prv_update.erl
index 524a684..655e5a3 100644
--- a/src/rebar_prv_update.erl
+++ b/src/rebar_prv_update.erl
@@ -34,18 +34,22 @@ init(State) ->
do(State) ->
?INFO("Updating package index...", []),
try
- Url = url(State),
+ Url = rebar_state:get(State, rebar_packages_cdn, "https://s3.amazonaws.com/s3.hex.pm/registry.ets.gz"),
TmpDir = ec_file:insecure_mkdtemp(),
- TmpFile = filename:join(TmpDir, "packages"),
- Home = rebar_dir:home_dir(),
- PackagesFile = filename:join([Home, ?CONFIG_DIR, "packages"]),
- filelib:ensure_dir(PackagesFile),
- {ok, _RequestId} = httpc:request(get, {Url, [{"Accept", "application/erlang"}]},
- [], [{stream, TmpFile}, {sync, true}]),
- ok = ec_file:copy(TmpFile, PackagesFile)
+ TmpFile = filename:join(TmpDir, "packages.gz"),
+ HexFile = filename:join(TmpDir, "packages"),
+ {ok, _RequestId} = httpc:request(get, {Url, []},
+ [], [{stream, TmpFile}, {sync, true}]),
+ {ok, Data} = file:read_file(TmpFile),
+ Unzipped = zlib:gunzip(Data),
+ ok = file:write_file(HexFile, Unzipped),
+ {Dict, Graph} = hex_to_graph(HexFile),
+ write_registry(Dict, Graph, State),
+ ok
catch
- _:_ ->
- {error, {?MODULE, package_index_write}}
+ E:C ->
+ io:format("E C ~p ~p~n", [E, C]),
+ throw({error, {?MODULE, package_index_write}})
end,
{ok, State}.
@@ -54,9 +58,39 @@ do(State) ->
format_error(package_index_write) ->
"Failed to write package index.".
-url(State) ->
- ErtsVsn = erlang:system_info(version),
+write_registry(Dict, {digraph, Edges, Vertices, Neighbors, _}, State) ->
+ Dir = rebar_dir:global_config_dir(State),
+ RegistryDir = filename:join(Dir, "packages"),
+ filelib:ensure_dir(filename:join(RegistryDir, "dummy")),
+ ets:tab2file(Edges, filename:join(RegistryDir, "edges")),
+ ets:tab2file(Vertices, filename:join(RegistryDir, "vertices")),
+ ets:tab2file(Neighbors, filename:join(RegistryDir, "neighbors")),
+ file:write_file(filename:join(RegistryDir, "dict"), term_to_binary(Dict)).
- Qs = [io_lib:format("~s=~s", [X, Y]) || {X, Y} <- [{"erts", ErtsVsn}]],
- Url = rebar_state:get(State, rebar_packages_url, "http://packages.rebar3.org/packages"),
- Url ++ "?" ++ string:join(Qs, "&").
+hex_to_graph(Filename) ->
+ {ok, T} = ets:file2tab(Filename),
+ Graph = digraph:new(),
+ ets:foldl(fun({Pkg, [Versions]}, ok) when is_binary(Pkg), is_list(Versions) ->
+ lists:foreach(fun(Version) ->
+ digraph:add_vertex(Graph, {Pkg, Version}, 1)
+ end, Versions);
+ (_, ok) ->
+ ok
+ end, ok, T),
+
+ Dict1 = ets:foldl(fun({{Pkg, PkgVsn}, [Deps | _]}, Dict) ->
+ DepsList = lists:foldl(fun([Dep, DepVsn, _, _], DepsListAcc) ->
+ case DepVsn of
+ <<"~> ", Vsn/binary>> ->
+ digraph:add_edge(Graph, {Pkg, PkgVsn}, {Dep, Vsn}),
+ [{Dep, DepVsn} | DepsListAcc];
+ Vsn ->
+ digraph:add_edge(Graph, {Pkg, PkgVsn}, {Dep, Vsn}),
+ [{Dep, Vsn} | DepsListAcc]
+ end
+ end, [], Deps),
+ dict:store({Pkg, PkgVsn}, DepsList, Dict);
+ (_, Dict) ->
+ Dict
+ end, dict:new(), T),
+ {Dict1, Graph}.