summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rebar_packages.erl32
-rw-r--r--test/rebar_pkg_SUITE.erl16
2 files changed, 41 insertions, 7 deletions
diff --git a/src/rebar_packages.erl b/src/rebar_packages.erl
index 99391ed..c0ed69d 100644
--- a/src/rebar_packages.erl
+++ b/src/rebar_packages.erl
@@ -28,7 +28,17 @@ packages(State) ->
ok;
false ->
?DEBUG("Error loading package index.", []),
- ?ERROR("Bad packages index, try to fix with `rebar3 update`", []),
+ handle_bad_index(State)
+ end.
+
+handle_bad_index(State) ->
+ ?ERROR("Bad packages index. Trying to fix by updating the registry.", []),
+ {ok, State1} = rebar_prv_update:do(State),
+ case load_and_verify_version(State1) of
+ true ->
+ ok;
+ false ->
+ %% Still unable to load after an update, create an empty registry
ets:new(?PACKAGE_TABLE, [named_table, public])
end.
@@ -52,10 +62,24 @@ load_and_verify_version(State) ->
deps(Name, Vsn, State) ->
try
- ?MODULE:verify_table(State),
- ets:lookup_element(?PACKAGE_TABLE, {ec_cnv:to_binary(Name), ec_cnv:to_binary(Vsn)}, 2)
+ deps_(Name, Vsn, State)
+ catch
+ _:_ ->
+ handle_missing_package(Name, Vsn, State)
+ end.
+
+deps_(Name, Vsn, State) ->
+ ?MODULE:verify_table(State),
+ ets:lookup_element(?PACKAGE_TABLE, {ec_cnv:to_binary(Name), ec_cnv:to_binary(Vsn)}, 2).
+
+handle_missing_package(Name, Vsn, State) ->
+ ?INFO("Package ~s-~s not found. Fetching registry updates and trying again...", [Name, Vsn]),
+ {ok, State1} = rebar_prv_update:do(State),
+ try
+ deps_(Name, Vsn, State1)
catch
_:_ ->
+ %% Even after an update the package is still missing, time to error out
throw(?PRV_ERROR({missing_package, ec_cnv:to_binary(Name), ec_cnv:to_binary(Vsn)}))
end.
@@ -143,7 +167,7 @@ handle_single_vsn(Dep, Vsn, Constraint) ->
end.
format_error({missing_package, Package, Version}) ->
- io_lib:format("Package not found in registry: ~s-~s. Try to fix with `rebar3 update`", [Package, Version]).
+ io_lib:format("Package not found in registry: ~s-~s.", [Package, Version]).
verify_table(State) ->
ets:info(?PACKAGE_TABLE, named_table) =:= true orelse load_and_verify_version(State).
diff --git a/test/rebar_pkg_SUITE.erl b/test/rebar_pkg_SUITE.erl
index b3201ad..af6bf42 100644
--- a/test/rebar_pkg_SUITE.erl
+++ b/test/rebar_pkg_SUITE.erl
@@ -20,7 +20,19 @@ init_per_suite(Config) ->
end_per_suite(_Config) ->
application:stop(meck).
-init_per_testcase(pkgs_provider, Config) ->
+init_per_testcase(pkgs_provider=Name, Config) ->
+ %% Need to mock out a registry for this test now because it will try to update it automatically
+ Priv = ?config(priv_dir, Config),
+ Tid = ets:new(registry_table, [public]),
+ ets:insert_new(Tid, []),
+ CacheRoot = filename:join([Priv, "cache", atom_to_list(Name)]),
+ CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]),
+ filelib:ensure_dir(filename:join([CacheDir, "registry"])),
+ ok = ets:tab2file(Tid, filename:join([CacheDir, "registry"])),
+ meck:new(rebar_packages, [passthrough]),
+ meck:expect(rebar_packages, registry_dir, fun(_) -> CacheDir end),
+ meck:expect(rebar_packages, package_dir, fun(_) -> CacheDir end),
+ rebar_prv_update:hex_to_index(rebar_state:new()),
Config;
init_per_testcase(good_uncached=Name, Config0) ->
Config = [{good_cache, false},
@@ -76,8 +88,6 @@ init_per_testcase(bad_disconnect=Name, Config0) ->
meck:expect(httpc, request, fun(_, _, _, _, _) -> {error, econnrefused} end),
Config.
-end_per_testcase(pkgs_provider, Config) ->
- Config;
end_per_testcase(_, Config) ->
unmock_config(Config),
Config.