summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/mock_git_resource.erl7
-rw-r--r--test/mock_pkg_resource.erl49
-rw-r--r--test/rebar_compile_SUITE.erl47
-rw-r--r--test/rebar_deps_SUITE.erl37
-rw-r--r--test/rebar_install_deps_SUITE.erl212
-rw-r--r--test/rebar_pkg_SUITE.erl41
-rw-r--r--test/rebar_pkg_alias_SUITE.erl121
-rw-r--r--test/rebar_plugins_SUITE.erl6
-rw-r--r--test/rebar_profiles_SUITE.erl15
-rw-r--r--test/rebar_release_SUITE.erl33
-rw-r--r--test/rebar_test_utils.erl106
-rw-r--r--test/rebar_upgrade_SUITE.erl12
12 files changed, 543 insertions, 143 deletions
diff --git a/test/mock_git_resource.erl b/test/mock_git_resource.erl
index d8f747b..0f4aff6 100644
--- a/test/mock_git_resource.erl
+++ b/test/mock_git_resource.erl
@@ -20,7 +20,8 @@ mock() -> mock([]).
| {override_vsn, [{App, Vsn}]}
| {deps, [{App, [Dep]}]},
App :: string(),
- Dep :: {App, string(), {git, string()} | {git, string(), term()}},
+ Dep :: {App, string(), {git, string()} | {git, string(), term()}}
+ | {pkg, App, term()},
Vsn :: string().
mock(Opts) ->
meck:new(?MOD, [no_link]),
@@ -46,8 +47,8 @@ mock_lock(_) ->
case Git of
{git, Url, {tag, Ref}} -> {git, Url, {ref, Ref}};
{git, Url, {ref, Ref}} -> {git, Url, {ref, Ref}};
- {git, Url} -> {git, Url, {ref, "fake-ref"}};
- {git, Url, _} -> {git, Url, {ref, "fake-ref"}}
+ {git, Url} -> {git, Url, {ref, "0.0.0"}};
+ {git, Url, _} -> {git, Url, {ref, "0.0.0"}}
end
end).
diff --git a/test/mock_pkg_resource.erl b/test/mock_pkg_resource.erl
index eda863b..4ed8d8e 100644
--- a/test/mock_pkg_resource.erl
+++ b/test/mock_pkg_resource.erl
@@ -111,32 +111,19 @@ mock_pkg_index(Opts) ->
Deps = proplists:get_value(pkgdeps, Opts, []),
Skip = proplists:get_value(not_in_index, Opts, []),
%% Dict: {App, Vsn}: [{<<"link">>, <<>>}, {<<"deps">>, []}]
- %% Digraph: all apps and deps in the index
+ %% Index: all apps and deps in the index
+
Dict = find_parts(Deps, Skip),
- GraphParts = to_graph_parts(Dict),
- Digraph = rebar_digraph:restore_graph(GraphParts),
meck:new(rebar_packages, [passthrough, no_link]),
- meck:expect(rebar_packages, registry,
- fun(_State) -> {ok, to_registry(Deps)} end),
- meck:expect(rebar_packages, get_packages,
- fun(_State) -> {Dict, Digraph} end).
+ meck:expect(rebar_packages, packages,
+ fun(_State) -> to_index(Deps, Dict) end),
+ meck:expect(rebar_packages, load_and_verify_version,
+ fun(_State) -> to_index(Deps, Dict), true end).
%%%%%%%%%%%%%%%
%%% Helpers %%%
%%%%%%%%%%%%%%%
-to_registry(Deps) ->
- Tid = ets:new(registry, []),
- lists:foreach(fun({{Name, Vsn}, _}) ->
- case ets:lookup(Tid, Name) of
- [{_, [Vsns]}] ->
- ets:insert(Tid, {Name, [[Vsn | Vsns]]});
- _ ->
- ets:insert(Tid, {Name, [[Vsn]]})
- end
- end, Deps),
- Tid.
-
all_files(Dir) ->
filelib:wildcard(filename:join([Dir, "**"])).
@@ -156,10 +143,20 @@ find_parts([{AppName, Deps}|Rest], Skip, Acc) ->
find_parts(Rest, Skip, AccNew)
end.
-to_graph_parts(Dict) ->
- LastUpdated = os:timestamp(),
- dict:fold(fun(K,Deps,{Ks,Vs}) ->
- {[{K,LastUpdated}|Ks],
- [{K,{list_to_binary(atom_to_list(DK)), list_to_binary(DV)}}
- || {DK,DV} <- Deps] ++ Vs}
- end, {[],[]}, Dict).
+to_index(AllDeps, Dict) ->
+ catch ets:delete(package_index),
+ ets:new(package_index, [named_table, public]),
+ dict:fold(
+ fun(K, Deps, _) ->
+ DepsList = [{ec_cnv:to_binary(DK), ec_cnv:to_binary(DV)} || {DK, DV} <- Deps],
+ ets:insert(package_index, {K, DepsList, <<"checksum">>})
+ end, ok, Dict),
+ ets:insert(package_index, {package_index_version, 3}),
+ lists:foreach(fun({{Name, Vsn}, _}) ->
+ case ets:lookup(package_index, ec_cnv:to_binary(Name)) of
+ [{_, Vsns}] ->
+ ets:insert(package_index, {ec_cnv:to_binary(Name), [ec_cnv:to_binary(Vsn) | Vsns]});
+ _ ->
+ ets:insert(package_index, {ec_cnv:to_binary(Name), [ec_cnv:to_binary(Vsn)]})
+ end
+ end, AllDeps).
diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl
index 0aaa899..f726943 100644
--- a/test/rebar_compile_SUITE.erl
+++ b/test/rebar_compile_SUITE.erl
@@ -23,7 +23,9 @@
erl_first_files_test/1,
mib_test/1,
only_default_transitive_deps/1,
- clean_all/1]).
+ clean_all/1,
+ override_deps/1,
+ profile_override_deps/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@@ -52,7 +54,7 @@ all() ->
dont_recompile_yrl_or_xrl, delete_beam_if_source_deleted,
deps_in_path, checkout_priority, highest_version_of_pkg_dep,
parse_transform_test, erl_first_files_test, mib_test, only_default_transitive_deps,
- clean_all].
+ clean_all, override_deps, profile_override_deps].
build_basic_app(Config) ->
AppDir = ?config(apps, Config),
@@ -544,7 +546,8 @@ only_default_transitive_deps(Config) ->
GitDeps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}]),
PkgName = rebar_test_utils:create_random_name("pkg1_"),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(GitDeps)},
+ {SrcDeps, _} = rebar_test_utils:flat_deps(GitDeps),
+ mock_git_resource:mock([{deps, SrcDeps},
{config, [{profiles, [{test, [{deps, [list_to_atom(PkgName)]}]}]}]}]),
mock_pkg_resource:mock([{pkgdeps, [{{iolist_to_binary(PkgName), <<"0.1.0">>}, []}]}]),
@@ -590,3 +593,41 @@ clean_all(Config) ->
Config, RConf, ["clean", "--all"],
{ok, [{app, Name, invalid}, {app, DepName, invalid}, {app, PkgName, invalid}]}
).
+
+override_deps(Config) ->
+ mock_git_resource:mock([{deps, [{some_dep, "0.0.1"},{other_dep, "0.0.1"}]}]),
+ Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
+ TopDeps = rebar_test_utils:top_level_deps(Deps),
+
+ RebarConfig = [
+ {deps, TopDeps},
+ {overrides, [
+ {override, some_dep, [
+ {deps, []}
+ ]}
+ ]}
+ ],
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig, ["compile"],
+ {ok, [{dep, "some_dep"},{dep_not_exist, "other_dep"}]}
+ ).
+
+profile_override_deps(Config) ->
+ mock_git_resource:mock([{deps, [{some_dep, "0.0.1"},{other_dep, "0.0.1"}]}]),
+ Deps = rebar_test_utils:expand_deps(git, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]),
+ TopDeps = rebar_test_utils:top_level_deps(Deps),
+
+ RebarConfig = [
+ {deps, TopDeps},
+ {profiles, [{a,
+ [{overrides, [
+ {override, some_dep, [
+ {deps, []}
+ ]}
+ ]}
+ ]}
+ ]}],
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig, ["as", "a", "compile"],
+ {ok, [{dep, "some_dep"},{dep_not_exist, "other_dep"}]}
+ ).
diff --git a/test/rebar_deps_SUITE.erl b/test/rebar_deps_SUITE.erl
index 004d50b..fd86226 100644
--- a/test/rebar_deps_SUITE.erl
+++ b/test/rebar_deps_SUITE.erl
@@ -171,30 +171,11 @@ setup_project(Case, Config0, Deps) ->
rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]),
TopDeps = rebar_test_utils:top_level_deps(Deps),
RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]),
- case DepsType of
- git ->
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}]);
- pkg ->
- mock_pkg_resource:mock([{pkgdeps, flat_pkgdeps(Deps)}])
- end,
+ {SrcDeps, PkgDeps} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}]),
[{rebarconfig, RebarConf} | Config].
-flat_pkgdeps([]) -> [];
-flat_pkgdeps([{{pkg, Name, Vsn}, Deps} | Rest]) ->
- [{{iolist_to_binary(Name),iolist_to_binary(Vsn)}, rebar_test_utils:top_level_deps(Deps)}]
- ++
- flat_pkgdeps(Deps)
- ++
- flat_pkgdeps(Rest).
-
-app_vsn([]) -> [];
-app_vsn([{Source, Deps} | Rest]) ->
- {Name, Vsn} = case Source of
- {pkg, N, V} -> {N,V};
- {N,V,_Ref} -> {N,V}
- end,
- [{Name, Vsn}] ++ app_vsn(Deps) ++ app_vsn(Rest).
-
mock_warnings() ->
%% just let it do its thing, we check warnings through
%% the call log.
@@ -217,7 +198,8 @@ sub_app_deps(Config) ->
Deps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
,{"b", "1.0.0", []}
,{"b", "2.0.0", []}]),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}]),
+ {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
Name = rebar_test_utils:create_random_name("sub_app1_"),
Vsn = rebar_test_utils:create_random_vsn(),
@@ -239,9 +221,10 @@ sub_app_deps(Config) ->
newly_added_dep(Config) ->
AppDir = ?config(apps, Config),
Deps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
- ,{"b", "1.0.0", [{"c", "1.0.0", []}]}
- ,{"c", "2.0.0", []}]),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}]),
+ ,{"b", "1.0.0", [{"c", "1.0.0", []}]}
+ ,{"c", "2.0.0", []}]),
+ {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
Name = rebar_test_utils:create_random_name("app_"),
Vsn = rebar_test_utils:create_random_vsn(),
@@ -314,5 +297,5 @@ in_warnings(git, Warns, NameRaw, VsnRaw) ->
in_warnings(pkg, Warns, NameRaw, VsnRaw) ->
Name = iolist_to_binary(NameRaw),
Vsn = iolist_to_binary(VsnRaw),
- 1 =< length([1 || {_, [AppName, AppVsn]} <- Warns,
+ 1 =< length([1 || {_, [AppName, {pkg, _, AppVsn}]} <- Warns,
AppName =:= Name, AppVsn =:= Vsn]).
diff --git a/test/rebar_install_deps_SUITE.erl b/test/rebar_install_deps_SUITE.erl
index be42e68..b8b70b3 100644
--- a/test/rebar_install_deps_SUITE.erl
+++ b/test/rebar_install_deps_SUITE.erl
@@ -4,16 +4,23 @@
-include_lib("eunit/include/eunit.hrl").
-include_lib("kernel/include/file.hrl").
-all() -> [{group, git}, {group, pkg}].
+all() -> [{group, git}, {group, pkg}, {group, mixed}].
groups() ->
- [{all, [], [flat, pick_highest_left, pick_highest_right,
- pick_smallest1, pick_smallest2,
- circular1, circular2, circular_skip,
- fail_conflict, default_profile, nondefault_profile,
- nondefault_pick_highest]},
- {git, [], [{group, all}]},
- {pkg, [], [{group, all}]}].
+ [{unique, [], [flat, pick_highest_left, pick_highest_right,
+ pick_smallest1, pick_smallest2,
+ circular1, circular2, circular_skip,
+ fail_conflict, default_profile, nondefault_profile,
+ nondefault_pick_highest]},
+ {git, [], [{group, unique}]},
+ {pkg, [], [{group, unique}]},
+ {mixed, [], [
+ m_flat1, m_flat2, m_circular1, m_circular2,
+ m_pick_source1, m_pick_source2, m_pick_source3,
+ m_pick_source4, m_pick_source5, m_source_to_pkg,
+ m_pkg_level1, m_pkg_level2, m_pkg_level3, m_pkg_level3_alpha_order
+ ]}
+ ].
init_per_suite(Config) ->
application:start(meck),
@@ -26,19 +33,33 @@ init_per_group(git, Config) ->
[{deps_type, git} | Config];
init_per_group(pkg, Config) ->
[{deps_type, pkg} | Config];
+init_per_group(mixed, Config) ->
+ [{deps_type, mixed} | Config];
init_per_group(_, Config) ->
Config.
end_per_group(_, Config) ->
Config.
-init_per_testcase(Case, Config) ->
+init_per_testcase(Case, Config) when is_atom(Case) ->
+ DepsType = ?config(deps_type, Config),
+ init_per_testcase({DepsType, Case}, Config);
+init_per_testcase({mixed, Case}, Config) ->
+ {Deps, Warnings, Expect} = mdeps(Case),
+ Expected = case Expect of
+ {ok, List} -> {ok, format_expected_mdeps(List)};
+ Other -> Other
+ end,
+ mock_warnings(),
+ [{expect, Expected},
+ {warnings, format_expected_mixed_warnings(Warnings)}
+ | setup_project(Case, Config, rebar_test_utils:expand_deps(mixed, Deps))];
+init_per_testcase({DepsType, Case}, Config) ->
{Deps, Warnings, Expect} = deps(Case),
Expected = case Expect of
{ok, List} -> {ok, format_expected_deps(List)};
Other -> Other
end,
- DepsType = ?config(deps_type, Config),
mock_warnings(),
[{expect, Expected},
{warnings, Warnings}
@@ -54,6 +75,32 @@ format_expected_deps(Deps) ->
N -> [{dep, N}, {lock, N}]
end || Dep <- Deps]).
+format_expected_mdeps(Deps) ->
+ %% for mixed deps, lowercase is a package, uppercase is source.
+ %% We can't check which was used from the dep, but the lock contains
+ %% the type and we can use that information.
+ lists:append([
+ case Dep of
+ {N,V} when hd(N) >= $a, hd(N) =< $z ->
+ UN = string:to_upper(N),
+ [{dep, UN, V}, {lock, pkg, UN, V}];
+ {N,V} when hd(N) >= $A, hd(N) =< $Z ->
+ [{dep, N, V}, {lock, src, N, V}];
+ N when hd(N) >= $a, hd(N) =< $z ->
+ UN = string:to_upper(N),
+ [{dep, UN}, {lock, pkg, UN, "0.0.0"}];
+ N when hd(N) >= $A, hd(N) =< $Z ->
+ [{dep, N}, {lock, src, N, "0.0.0"}]
+ end || Dep <- Deps]).
+
+format_expected_mixed_warnings(Warnings) ->
+ [case W of
+ {N, Vsn} when hd(N) >= $a, hd(N) =< $z -> {pkg, string:to_upper(N), Vsn};
+ {N, Vsn} when hd(N) >= $A, hd(N) =< $Z -> {git, N, Vsn};
+ N when hd(N) >= $a, hd(N) =< $z -> {pkg, string:to_upper(N), "0.0.0"};
+ N when hd(N) >= $A, hd(N) =< $Z -> {git, N, "0.0.0"}
+ end || W <- Warnings].
+
%% format:
%% {Spec,
%% [Warning],
@@ -131,6 +178,78 @@ deps(nondefault_pick_highest) ->
%% This is all handled in setup_project
{[],[],{ok,[]}}.
+%% format:
+%% Same as `deps/1' except "A" is a source dep
+%% and "a" is a package dep.
+mdeps(m_flat1) ->
+ {[{"c", []},
+ {"B", []}],
+ [],
+ {ok, ["B","c"]}};
+mdeps(m_flat2) ->
+ {[{"B", []},
+ {"c", []}],
+ [],
+ {ok, ["B","c"]}};
+mdeps(m_circular1) ->
+ {[{"b", [{"a",[]}]}], % "A" is the top app
+ [],
+ {error, {rebar_prv_install_deps, {cycles, [[<<"A">>,<<"B">>]]}}}};
+mdeps(m_circular2) ->
+ {[{"B", [{"c", [{"b", []}]}]}],
+ [],
+ {error, {rebar_prv_install_deps, {cycles, [[<<"B">>,<<"C">>]]}}}};
+mdeps(m_pick_source1) ->
+ {[{"B", [{"D", []}]},
+ {"c", [{"d", []}]}],
+ ["d"],
+ {ok, ["B", "c", "D"]}};
+mdeps(m_pick_source2) ->
+ %% The order of declaration is important.
+ {[{"b", []},
+ {"B", []}],
+ [],
+ {ok, ["b"]}};
+mdeps(m_pick_source3) ->
+ {[{"B", []},
+ {"b", []}],
+ [],
+ {ok, ["B"]}};
+mdeps(m_pick_source4) ->
+ {[{"b", [{"d", "1", []}]},
+ {"C", [{"D", "1", []}]}],
+ [{"D", "1"}],
+ {ok, ["b", "C", {"d", "1"}]}};
+mdeps(m_pick_source5) ->
+ {[{"B", [{"d", "1", []}]},
+ {"C", [{"D", "1", []}]}],
+ [{"D", "1"}],
+ {ok, ["B", "C", {"d", "1"}]}};
+mdeps(m_source_to_pkg) ->
+ {[{"B", [{"c",[{"d", []}]}]}],
+ [],
+ {ok, ["B", "c", "d"]}};
+mdeps(m_pkg_level1) ->
+ {[{"B", [{"D", [{"e", "2", []}]}]},
+ {"C", [{"e", "1", []}]}],
+ [{"e","2"}],
+ {ok, ["B","C","D",{"e","1"}]}};
+mdeps(m_pkg_level2) ->
+ {[{"B", [{"e", "1", []}]},
+ {"C", [{"D", [{"e", "2", []}]}]}],
+ [{"e","2"}],
+ {ok, ["B","C","D",{"e","1"}]}};
+mdeps(m_pkg_level3_alpha_order) ->
+ {[{"B", [{"d", [{"f", "1", []}]}]},
+ {"C", [{"E", [{"f", "2", []}]}]}],
+ [{"f","2"}],
+ {ok, ["B","C","d","E",{"f","1"}]}};
+mdeps(m_pkg_level3) ->
+ {[{"B", [{"d", [{"f", "1", []}]}]},
+ {"C", [{"E", [{"G", [{"f", "2", []}]}]}]}],
+ [{"f","2"}],
+ {ok, ["B","C","d","E","G",{"f","1"}]}}.
+
setup_project(fail_conflict, Config0, Deps) ->
DepsType = ?config(deps_type, Config0),
Config = rebar_test_utils:init_rebar_state(
@@ -142,12 +261,9 @@ setup_project(fail_conflict, Config0, Deps) ->
TopDeps = rebar_test_utils:top_level_deps(Deps),
RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps},
{deps_error_on_conflict, true}]),
- case DepsType of
- git ->
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}]);
- pkg ->
- mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Deps)}])
- end,
+ {SrcDeps, PkgDeps} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}]),
[{rebarconfig, RebarConf} | Config];
setup_project(nondefault_profile, Config0, Deps) ->
DepsType = ?config(deps_type, Config0),
@@ -161,12 +277,9 @@ setup_project(nondefault_profile, Config0, Deps) ->
RebarConf = rebar_test_utils:create_config(AppDir, [{profiles, [
{nondef, [{deps, TopDeps}]}
]}]),
- case DepsType of
- git ->
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}]);
- pkg ->
- mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Deps)}])
- end,
+ {SrcDeps, PkgDeps} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}]),
[{rebarconfig, RebarConf} | Config];
setup_project(nondefault_pick_highest, Config0, _) ->
DepsType = ?config(deps_type, Config0),
@@ -187,13 +300,11 @@ setup_project(nondefault_pick_highest, Config0, _) ->
),
case DepsType of
git ->
- mock_git_resource:mock(
- [{deps, rebar_test_utils:flat_deps(DefaultDeps ++ ProfileDeps)}]
- );
+ {SrcDeps, _} = rebar_test_utils:flat_deps(DefaultDeps++ProfileDeps),
+ mock_git_resource:mock([{deps, SrcDeps}]);
pkg ->
- mock_pkg_resource:mock(
- [{pkgdeps, rebar_test_utils:flat_pkgdeps(DefaultDeps ++ ProfileDeps)}]
- )
+ {_, PkgDeps} = rebar_test_utils:flat_deps(DefaultDeps++ProfileDeps),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}])
end,
[{rebarconfig, RebarConf} | Config];
setup_project(Case, Config0, Deps) ->
@@ -206,12 +317,9 @@ setup_project(Case, Config0, Deps) ->
rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]),
TopDeps = rebar_test_utils:top_level_deps(Deps),
RebarConf = rebar_test_utils:create_config(AppDir, [{deps, TopDeps}]),
- case DepsType of
- git ->
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}]);
- pkg ->
- mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Deps)}])
- end,
+ {SrcDeps, PkgDeps} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}]),
[{rebarconfig, RebarConf} | Config].
mock_warnings() ->
@@ -241,6 +349,9 @@ default_profile(Config) ->
AppDir = ?config(apps, Config),
{ok, Apps} = Expect = ?config(expect, Config),
rebar_test_utils:run_and_check(
+ Config, RebarConfig, ["lock"], Expect
+ ),
+ rebar_test_utils:run_and_check(
Config, RebarConfig, ["as", "profile", "lock"], Expect
),
check_warnings(error_calls(), ?config(warnings, Config), ?config(deps_type, Config)),
@@ -253,6 +364,9 @@ default_profile(Config) ->
|| {dep, App} <- Apps],
%% A second run to another profile also links default to the right spot
rebar_test_utils:run_and_check(
+ Config, RebarConfig, ["lock"], Expect
+ ),
+ rebar_test_utils:run_and_check(
Config, RebarConfig, ["as", "other", "lock"], Expect
),
[?assertMatch({ok, #file_info{type=directory}}, % somehow symlinks return dirs
@@ -296,10 +410,13 @@ nondefault_profile(Config) ->
nondefault_pick_highest(Config) ->
{ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
- %AppDir = ?config(apps, Config),
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig, ["lock"],
+ {ok, [{dep, "B"}, {lock, "B"}, {lock, "C", "1"}, {dep, "C", "1"}], "default"}
+ ),
rebar_test_utils:run_and_check(
Config, RebarConfig, ["as", "nondef", "lock"],
- {ok, [{dep, "B"}, {lock, "B"}, {dep, "C", "2"}], "nondef"}
+ {ok, [{dep, "B"}, {lock, "B"}, {lock, "C", "1"}, {dep, "C", "2"}], "nondef"}
),
rebar_test_utils:run_and_check(
Config, RebarConfig, ["lock"],
@@ -307,9 +424,24 @@ nondefault_pick_highest(Config) ->
),
rebar_test_utils:run_and_check(
Config, RebarConfig, ["as", "nondef", "lock"],
- {ok, [{dep, "B"}, {lock, "B"}, {dep, "C", "2"}], "nondef"}
+ {ok, [{dep, "B"}, {lock, "B"}, {lock, "C", "1"}, {dep, "C", "2"}], "nondef"}
).
+m_flat1(Config) -> run(Config).
+m_flat2(Config) -> run(Config).
+m_circular1(Config) -> run(Config).
+m_circular2(Config) -> run(Config).
+m_pick_source1(Config) -> run(Config).
+m_pick_source2(Config) -> run(Config).
+m_pick_source3(Config) -> run(Config).
+m_pick_source4(Config) -> run(Config).
+m_pick_source5(Config) -> run(Config).
+m_source_to_pkg(Config) -> run(Config).
+m_pkg_level1(Config) -> run(Config).
+m_pkg_level2(Config) -> run(Config).
+m_pkg_level3(Config) -> run(Config).
+m_pkg_level3_alpha_order(Config) -> run(Config).
+
run(Config) ->
{ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
rebar_test_utils:run_and_check(
@@ -327,6 +459,10 @@ error_calls() ->
check_warnings(_, [], _) ->
ok;
+check_warnings(Warns, [{Type, Name, Vsn} | Rest], mixed) ->
+ ct:pal("Checking for warning ~p in ~p", [{Name,Vsn},Warns]),
+ ?assert(in_warnings(Type, Warns, Name, Vsn)),
+ check_warnings(Warns, Rest, mixed);
check_warnings(Warns, [{Name, Vsn} | Rest], Type) ->
ct:pal("Checking for warning ~p in ~p", [{Name,Vsn},Warns]),
?assert(in_warnings(Type, Warns, Name, Vsn)),
@@ -339,5 +475,5 @@ in_warnings(git, Warns, NameRaw, VsnRaw) ->
in_warnings(pkg, Warns, NameRaw, VsnRaw) ->
Name = iolist_to_binary(NameRaw),
Vsn = iolist_to_binary(VsnRaw),
- 1 =< length([1 || {_, [AppName, AppVsn]} <- Warns,
+ 1 =< length([1 || {_, [AppName, {pkg, _, AppVsn}]} <- Warns,
AppName =:= Name, AppVsn =:= Vsn]).
diff --git a/test/rebar_pkg_SUITE.erl b/test/rebar_pkg_SUITE.erl
index 85bd6f0..b3201ad 100644
--- a/test/rebar_pkg_SUITE.erl
+++ b/test/rebar_pkg_SUITE.erl
@@ -11,7 +11,7 @@
-define(good_checksum, <<"1C6CE379D191FBAB41B7905075E0BF87CBBE23C77CECE775C5A0B786B2244C35">>).
all() -> [good_uncached, good_cached, badindexchk, badpkg,
- bad_to_good, good_disconnect, bad_disconnect].
+ bad_to_good, good_disconnect, bad_disconnect, pkgs_provider].
init_per_suite(Config) ->
application:start(meck),
@@ -20,6 +20,8 @@ init_per_suite(Config) ->
end_per_suite(_Config) ->
application:stop(meck).
+init_per_testcase(pkgs_provider, Config) ->
+ Config;
init_per_testcase(good_uncached=Name, Config0) ->
Config = [{good_cache, false},
{pkg, {<<"goodpkg">>, <<"1.0.0">>}}
@@ -74,6 +76,8 @@ 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.
@@ -148,9 +152,15 @@ bad_disconnect(Config) ->
Tmp = ?config(tmp_dir, Config),
{Pkg,Vsn} = ?config(pkg, Config),
State = ?config(state, Config),
- ?assertEqual(request_failed,
+ ?assertEqual({fetch_fail, Pkg, Vsn},
rebar_pkg_resource:download(Tmp, {pkg, Pkg, Vsn}, State)).
+pkgs_provider(Config) ->
+ Config1 = rebar_test_utils:init_rebar_state(Config),
+ rebar_test_utils:run_and_check(
+ Config1, [], ["pkgs"],
+ {ok, []}
+ ).
%%%%%%%%%%%%%%%
%%% Helpers %%%
@@ -159,25 +169,34 @@ mock_config(Name, Config) ->
Priv = ?config(priv_dir, Config),
CacheRoot = filename:join([Priv, "cache", atom_to_list(Name)]),
TmpDir = filename:join([Priv, "tmp", atom_to_list(Name)]),
- T = ets:new(fake_registry, [public]),
- ets:insert_new(T, [
- {{<<"badindexchk">>,<<"1.0.0">>}, [[], ?bad_checksum]},
- {{<<"goodpkg">>,<<"1.0.0">>}, [[], ?good_checksum]},
- {{<<"badpkg">>,<<"1.0.0">>}, [[], ?good_checksum]}
+ Tid = ets:new(registry_table, [public]),
+ ets:insert_new(Tid, [
+ {<<"badindexchk">>,[[<<"1.0.0">>]]},
+ {<<"goodpkg">>,[[<<"1.0.0">>]]},
+ {<<"badpkg">>,[[<<"1.0.0">>]]},
+ {{<<"badindexchk">>,<<"1.0.0">>}, [[], ?bad_checksum, [<<"rebar3">>]]},
+ {{<<"goodpkg">>,<<"1.0.0">>}, [[], ?good_checksum, [<<"rebar3">>]]},
+ {{<<"badpkg">>,<<"1.0.0">>}, [[], ?good_checksum, [<<"rebar3">>]]}
]),
CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]),
filelib:ensure_dir(filename:join([CacheDir, "registry"])),
- ok = ets:tab2file(T, filename:join([CacheDir, "registry"])),
+ ok = ets:tab2file(Tid, filename:join([CacheDir, "registry"])),
+
%% The state returns us a fake registry
meck:new(rebar_state, [passthrough]),
- meck:expect(rebar_state, registry,
- fun(_State) -> {ok, fake_registry} end),
meck:expect(rebar_state, get,
fun(_State, rebar_packages_cdn, _Default) ->
"http://test.com/"
end),
+
meck:new(rebar_dir, [passthrough]),
meck:expect(rebar_dir, global_cache_dir, fun(_) -> CacheRoot end),
+
+ 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()),
+
%% Cache fetches are mocked -- we assume the server and clients are
%% correctly used.
GoodCache = ?config(good_cache, Config),
@@ -194,7 +213,7 @@ mock_config(Name, Config) ->
[{cache_root, CacheRoot},
{cache_dir, CacheDir},
{tmp_dir, TmpDir},
- {mock_table, T} | Config].
+ {mock_table, Tid} | Config].
unmock_config(Config) ->
meck:unload(),
diff --git a/test/rebar_pkg_alias_SUITE.erl b/test/rebar_pkg_alias_SUITE.erl
new file mode 100644
index 0000000..f7fa5d4
--- /dev/null
+++ b/test/rebar_pkg_alias_SUITE.erl
@@ -0,0 +1,121 @@
+-module(rebar_pkg_alias_SUITE).
+-compile(export_all).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("eunit/include/eunit.hrl").
+-include_lib("kernel/include/file.hrl").
+
+all() -> [same_alias, diff_alias, diff_alias_vsn].
+
+%% {uuid, {pkg, uuid}} = uuid
+%% {uuid, {pkg, alias}} = uuid on disk
+%% another run should yield the same lock file without error
+init_per_suite(Config) ->
+ mock_config(?MODULE, Config).
+
+end_per_suite(Config) ->
+ unmock_config(Config).
+
+init_per_testcase(same_alias, Config0) ->
+ Config = rebar_test_utils:init_rebar_state(Config0,"same_alias_"),
+ AppDir = ?config(apps, Config),
+ rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]),
+ RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [{fakelib, {pkg, fakelib}}]}]),
+ [{rebarconfig, RebarConf} | Config];
+init_per_testcase(diff_alias, Config0) ->
+ Config = rebar_test_utils:init_rebar_state(Config0,"diff_alias_"),
+ AppDir = ?config(apps, Config),
+ rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]),
+ RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [{fakelib, {pkg, goodpkg}}]}]),
+ [{rebarconfig, RebarConf} | Config];
+init_per_testcase(diff_alias_vsn, Config0) ->
+ Config = rebar_test_utils:init_rebar_state(Config0,"diff_alias_vsn_"),
+ AppDir = ?config(apps, Config),
+ rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]),
+ RebarConf = rebar_test_utils:create_config(AppDir, [{deps, [{fakelib, "1.0.0", {pkg, goodpkg}}]}]),
+ [{rebarconfig, RebarConf} | Config].
+
+end_per_testcase(_, Config) ->
+ Config.
+
+same_alias(Config) ->
+ {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig, ["lock"],
+ {ok, [{lock, "fakelib"}, {dep, "fakelib"}]}
+ ).
+
+diff_alias(Config) ->
+ %% even though the dep is 'fakelib' aliased as 'goodpkg' all
+ %% internal records use 'fakelib' as a value. Just make sure
+ %% the lock actually maintains the proper source as 'goodpkg'
+ AppDir = ?config(apps, Config),
+ Lockfile = filename:join([AppDir, "rebar.lock"]),
+ {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)),
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig, ["lock"],
+ {ok, [{lock, "fakelib"},{dep, "fakelib"}]}
+ ),
+ {ok, [LockData]} = file:consult(Lockfile),
+ ?assert(lists:any(fun({<<"fakelib">>,{pkg,<<"goodpkg">>,_},_}) -> true
+ ; (_) -> false end, LockData)),
+ %% An second run yields the same
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig, ["lock"],
+ {ok, [{lock, "fakelib"},{dep, "fakelib"}]}
+ ),
+ {ok, [LockData]} = file:consult(Lockfile),
+ %% So does an upgrade
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig, ["upgrade"],
+ {ok, [{lock, "fakelib"},{dep, "fakelib"}]}
+ ),
+ {ok, [LockData]} = file:consult(Lockfile).
+
+diff_alias_vsn(Config) -> diff_alias(Config).
+
+mock_config(Name, Config) ->
+ Priv = ?config(priv_dir, Config),
+ AppDir = filename:join([Priv, "fakelib"]),
+ CacheRoot = filename:join([Priv, "cache", atom_to_list(Name)]),
+ TmpDir = filename:join([Priv, "tmp", atom_to_list(Name)]),
+ CacheDir = filename:join([CacheRoot, "hex", "com", "test", "packages"]),
+ filelib:ensure_dir(filename:join([CacheDir, "registry"])),
+ rebar_test_utils:create_app(AppDir, "fakelib", "1.0.0", [kernel, stdlib]),
+ {Chk,Etag} = rebar_test_utils:package_app(AppDir, CacheDir, "fakelib-1.0.0"),
+ {Chk,Etag} = rebar_test_utils:package_app(AppDir, CacheDir, "goodpkg-1.0.0"),
+
+ Tid = ets:new(registry_table, [public]),
+ ets:insert_new(Tid, [
+ {<<"fakelib">>,[[<<"1.0.0">>]]},
+ {<<"goodpkg">>,[[<<"1.0.0">>]]},
+ {{<<"fakelib">>,<<"1.0.0">>}, [[], Chk, [<<"rebar3">>]]},
+ {{<<"goodpkg">>,<<"1.0.0">>}, [[], Chk, [<<"rebar3">>]]}
+ ]),
+ ok = ets:tab2file(Tid, filename:join([CacheDir, "registry"])),
+ ets:delete(Tid),
+ %% The state returns us a fake registry
+ meck:new(rebar_dir, [passthrough, no_link]),
+ meck:expect(rebar_dir, global_cache_dir, fun(_) -> CacheRoot end),
+
+ meck:new(rebar_packages, [passthrough, no_link]),
+ 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()),
+
+ %% Cache fetches are mocked -- we assume the server and clients are
+ %% correctly used.
+ meck:new(httpc, [passthrough, unsticky, no_link]),
+ meck:expect(httpc, request,
+ fun(get, {_Url, _Opts}, _, _, _) ->
+ {ok, {{<<"1.0.0">>, 304, <<"Not Modified">>}, [{"etag", Etag}], <<>>}}
+ end),
+ %% Move all packages to cache
+ NewConf = [{cache_root, CacheRoot},
+ {cache_dir, CacheDir},
+ {tmp_dir, TmpDir},
+ {mock_table, Tid} | Config],
+ NewConf.
+
+unmock_config(Config) ->
+ meck:unload(),
+ Config.
diff --git a/test/rebar_plugins_SUITE.erl b/test/rebar_plugins_SUITE.erl
index adfeafe..5e2c782 100644
--- a/test/rebar_plugins_SUITE.erl
+++ b/test/rebar_plugins_SUITE.erl
@@ -45,7 +45,8 @@ compile_plugins(Config) ->
PluginName = rebar_test_utils:create_random_name("plugin1_"),
Plugins = rebar_test_utils:expand_deps(git, [{PluginName, Vsn, []}]),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Plugins)}]),
+ {SrcDeps, _} = rebar_test_utils:flat_deps(Plugins),
+ mock_git_resource:mock([{deps, SrcDeps}]),
mock_pkg_resource:mock([{pkgdeps, [{{list_to_binary(DepName), list_to_binary(Vsn)}, []}]},
{config, [{plugins, [
@@ -137,7 +138,8 @@ complex_plugins(Config) ->
Deps = rebar_test_utils:expand_deps(git, [{PluginName, Vsn2, [{DepName2, Vsn,
[{DepName3, Vsn, []}]}]}
,{DepName, Vsn, []}]),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}]),
+ {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
RConfFile =
rebar_test_utils:create_config(AppDir,
diff --git a/test/rebar_profiles_SUITE.erl b/test/rebar_profiles_SUITE.erl
index b42df39..41bb535 100644
--- a/test/rebar_profiles_SUITE.erl
+++ b/test/rebar_profiles_SUITE.erl
@@ -57,7 +57,8 @@ profile_new_key(Config) ->
AllDeps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
,{"b", "1.0.0", []}]),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(AllDeps)}]),
+ {SrcDeps, []} = rebar_test_utils:flat_deps(AllDeps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
Name = rebar_test_utils:create_random_name("profile_new_key_"),
Vsn = rebar_test_utils:create_random_vsn(),
@@ -82,7 +83,8 @@ profile_merge_keys(Config) ->
AllDeps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
,{"b", "1.0.0", []}
,{"b", "2.0.0", []}]),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(AllDeps)}]),
+ {SrcDeps, []} = rebar_test_utils:flat_deps(AllDeps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
Name = rebar_test_utils:create_random_name("profile_new_key_"),
Vsn = rebar_test_utils:create_random_vsn(),
@@ -111,7 +113,8 @@ explicit_profile_deduplicate_deps(Config) ->
,{"a", "2.0.0", []}
,{"b", "1.0.0", []}
,{"b", "2.0.0", []}]),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(AllDeps)}]),
+ {SrcDeps, []} = rebar_test_utils:flat_deps(AllDeps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
Name = rebar_test_utils:create_random_name("explicit_profile_deduplicate_deps_"),
Vsn = rebar_test_utils:create_random_vsn(),
@@ -141,7 +144,8 @@ implicit_profile_deduplicate_deps(Config) ->
,{"a", "2.0.0", []}
,{"b", "1.0.0", []}
,{"b", "2.0.0", []}]),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(AllDeps)}]),
+ {SrcDeps, []} = rebar_test_utils:flat_deps(AllDeps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
Name = rebar_test_utils:create_random_name("implicit_profile_deduplicate_deps_"),
Vsn = rebar_test_utils:create_random_vsn(),
@@ -169,7 +173,8 @@ all_deps_code_paths(Config) ->
AllDeps = rebar_test_utils:expand_deps(git, [{"a", "1.0.0", []}
,{"b", "2.0.0", []}]),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(AllDeps)}]),
+ {SrcDeps, []} = rebar_test_utils:flat_deps(AllDeps),
+ mock_git_resource:mock([{deps, SrcDeps}]),
Name = rebar_test_utils:create_random_name("all_deps_code_paths"),
Vsn = rebar_test_utils:create_random_vsn(),
diff --git a/test/rebar_release_SUITE.erl b/test/rebar_release_SUITE.erl
index 1ef0771..f6fe8ff 100644
--- a/test/rebar_release_SUITE.erl
+++ b/test/rebar_release_SUITE.erl
@@ -4,10 +4,11 @@
-include_lib("eunit/include/eunit.hrl").
all() -> [release,
- dev_mode_release,
- profile_dev_mode_override_release,
- tar,
- extend_release].
+ dev_mode_release,
+ profile_dev_mode_override_release,
+ tar,
+ extend_release,
+ user_output_dir].
init_per_testcase(Case, Config0) ->
Config = rebar_test_utils:init_rebar_state(Config0),
@@ -109,3 +110,27 @@ extend_release(Config) ->
["release", "-n", "extended"],
{ok, [{release, extended, Vsn, false}]}
).
+
+user_output_dir(Config) ->
+ AppDir = ?config(apps, Config),
+ Name = ?config(name, Config),
+ ReleaseDir = filename:join(AppDir, "./_rel"),
+ Vsn = "1.0.0",
+
+ {ok, RebarConfig} =
+ file:consult(rebar_test_utils:create_config(AppDir,
+ [{relx, [{release, {list_to_atom(Name), Vsn},
+ [list_to_atom(Name)]},
+ {lib_dirs, [AppDir]},
+ {dev_mode, true}]}])),
+ rebar_test_utils:run_and_check(
+ Config, RebarConfig,
+ ["release", "-o", ReleaseDir],
+ {ok, []}
+ ),
+
+ RelxState = rlx_state:new("", [], []),
+ RelxState1 = rlx_state:base_output_dir(RelxState, ReleaseDir),
+ {ok, RelxState2} = rlx_prv_app_discover:do(RelxState1),
+ {ok, RelxState3} = rlx_prv_rel_discover:do(RelxState2),
+ rlx_state:get_realized_release(RelxState3, list_to_atom(Name), Vsn).
diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl
index be52e81..8d1d408 100644
--- a/test/rebar_test_utils.erl
+++ b/test/rebar_test_utils.erl
@@ -2,8 +2,9 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
-export([init_rebar_state/1, init_rebar_state/2, run_and_check/4]).
--export([expand_deps/2, flat_deps/1, flat_pkgdeps/1, top_level_deps/1]).
--export([create_app/4, create_eunit_app/4, create_empty_app/4, create_config/2]).
+-export([expand_deps/2, flat_deps/1, top_level_deps/1]).
+-export([create_app/4, create_eunit_app/4, create_empty_app/4, create_config/2,
+ package_app/3]).
-export([create_random_name/1, create_random_vsn/0, write_src_file/2]).
%%%%%%%%%%%%%%
@@ -25,7 +26,9 @@ init_rebar_state(Config, Name) ->
ok = ec_file:mkdir_p(CheckoutsDir),
Verbosity = rebar3:log_level(),
rebar_log:init(command_line, Verbosity),
+ GlobalDir = filename:join([DataDir, "cache"]),
State = rebar_state:new([{base_dir, filename:join([AppsDir, "_build"])}
+ ,{global_rebar_dir, GlobalDir}
,{root_dir, AppsDir}]),
[{apps, AppsDir}, {checkouts, CheckoutsDir}, {state, State} | Config].
@@ -137,24 +140,43 @@ expand_deps(pkg, [{Name, Deps} | Rest]) ->
[{Dep, expand_deps(pkg, Deps)} | expand_deps(pkg, Rest)];
expand_deps(pkg, [{Name, Vsn, Deps} | Rest]) ->
Dep = {pkg, Name, Vsn},
- [{Dep, expand_deps(pkg, Deps)} | expand_deps(pkg, Rest)].
-
-flat_deps([]) -> [];
-flat_deps([{{Name,_Vsn,Ref}, Deps} | Rest]) ->
- [{{Name,vsn_from_ref(Ref)}, top_level_deps(Deps)}]
- ++
- flat_deps(Deps)
- ++
- flat_deps(Rest).
-
-flat_pkgdeps([]) -> [];
-flat_pkgdeps([{{pkg, Name, Vsn}, Deps} | Rest]) ->
- [{{iolist_to_binary(Name),iolist_to_binary(Vsn)}, top_level_deps(Deps)}]
- ++
- flat_pkgdeps(Deps)
- ++
- flat_pkgdeps(Rest).
-
+ [{Dep, expand_deps(pkg, Deps)} | expand_deps(pkg, Rest)];
+expand_deps(mixed, [{Name, Deps} | Rest]) ->
+ Dep = if hd(Name) >= $a, hd(Name) =< $z ->
+ {pkg, string:to_upper(Name), "0.0.0"}
+ ; hd(Name) >= $A, hd(Name) =< $Z ->
+ {Name, ".*", {git, "https://example.org/user/"++Name++".git", "master"}}
+ end,
+ [{Dep, expand_deps(mixed, Deps)} | expand_deps(mixed, Rest)];
+expand_deps(mixed, [{Name, Vsn, Deps} | Rest]) ->
+ Dep = if hd(Name) >= $a, hd(Name) =< $z ->
+ {pkg, string:to_upper(Name), Vsn}
+ ; hd(Name) >= $A, hd(Name) =< $Z ->
+ {Name, Vsn, {git, "https://example.org/user/"++Name++".git", {tag, Vsn}}}
+ end,
+ [{Dep, expand_deps(mixed, Deps)} | expand_deps(mixed, Rest)].
+
+%% Source deps can depend on both source and package dependencies;
+%% package deps can only depend on package deps.
+%% For things to work we have to go down the dep tree and find all
+%% lineages of pkg deps and return them, whereas the source deps
+%% can be left as is.
+flat_deps(Deps) -> flat_deps(Deps, [], []).
+
+flat_deps([], Src, Pkg) -> {Src, Pkg};
+flat_deps([{{pkg, Name, Vsn}, PkgDeps} | Rest], Src, Pkg) ->
+ Current = {{iolist_to_binary(Name), iolist_to_binary(Vsn)},
+ top_level_deps(PkgDeps)},
+ {[], FlatPkgDeps} = flat_deps(PkgDeps),
+ flat_deps(Rest,
+ Src,
+ Pkg ++ [Current | FlatPkgDeps]);
+flat_deps([{{Name,_Vsn,Ref}, Deps} | Rest], Src, Pkg) ->
+ Current = {{Name,vsn_from_ref(Ref)}, top_level_deps(Deps)},
+ {FlatDeps, FlatPkgDeps} = flat_deps(Deps),
+ flat_deps(Rest,
+ Src ++ [Current | FlatDeps],
+ Pkg ++ FlatPkgDeps).
vsn_from_ref({git, _, {_, Vsn}}) -> Vsn;
vsn_from_ref({git, _, Vsn}) -> Vsn.
@@ -278,6 +300,28 @@ check_results(AppDir, Expected, ProfileRun) ->
?assertEqual(iolist_to_binary(Vsn),
iolist_to_binary(LockVsn))
end
+ ; ({lock, pkg, Name, Vsn}) ->
+ ct:pal("Pkg Lock Name: ~p, Vsn: ~p", [Name, Vsn]),
+ case lists:keyfind(iolist_to_binary(Name), 1, Locks) of
+ false ->
+ error({lock_not_found, Name});
+ {_LockName, {pkg, _, LockVsn}, _} ->
+ ?assertEqual(iolist_to_binary(Vsn),
+ iolist_to_binary(LockVsn));
+ {_LockName, {_, _, {ref, LockVsn}}, _} ->
+ error({source_lock, {Name, LockVsn}})
+ end
+ ; ({lock, src, Name, Vsn}) ->
+ ct:pal("Src Lock Name: ~p, Vsn: ~p", [Name, Vsn]),
+ case lists:keyfind(iolist_to_binary(Name), 1, Locks) of
+ false ->
+ error({lock_not_found, Name});
+ {_LockName, {pkg, _, LockVsn}, _} ->
+ error({pkg_lock, {Name, LockVsn}});
+ {_LockName, {_, _, {ref, LockVsn}}, _} ->
+ ?assertEqual(iolist_to_binary(Vsn),
+ iolist_to_binary(LockVsn))
+ end
; ({release, Name, Vsn, ExpectedDevMode}) ->
ct:pal("Release: ~p-~s", [Name, Vsn]),
{ok, Cwd} = file:get_cwd(),
@@ -375,3 +419,25 @@ get_app_metadata(Name, Vsn, Deps) ->
{included_applications, []},
{registered, []},
{applications, Deps}]}.
+
+package_app(AppDir, DestDir, PkgName) ->
+ Name = PkgName++".tar",
+ {ok, Fs} = file:list_dir(AppDir),
+ ok = erl_tar:create(filename:join(DestDir, "contents.tar.gz"),
+ lists:zip(Fs, [filename:join(AppDir,F) || F <- Fs]),
+ [compressed]),
+ ok = file:write_file(filename:join(DestDir, "metadata.config"), "who cares"),
+ ok = file:write_file(filename:join(DestDir, "VERSION"), "3"),
+ {ok, Contents} = file:read_file(filename:join(DestDir, "contents.tar.gz")),
+ Blob = <<"3who cares", Contents/binary>>,
+ <<X:256/big-unsigned>> = crypto:hash(sha256, Blob),
+ BinChecksum = list_to_binary(string:to_upper(lists:flatten(io_lib:format("~64.16.0b", [X])))),
+ ok = file:write_file(filename:join(DestDir, "CHECKSUM"), BinChecksum),
+ PkgFiles = ["contents.tar.gz", "VERSION", "metadata.config", "CHECKSUM"],
+ Archive = filename:join(DestDir, Name),
+ ok = erl_tar:create(Archive,
+ lists:zip(PkgFiles, [filename:join(DestDir,F) || F <- PkgFiles])),
+ {ok, BinFull} = file:read_file(Archive),
+ <<E:128/big-unsigned-integer>> = crypto:hash(md5, BinFull),
+ Etag = string:to_lower(lists:flatten(io_lib:format("~32.16.0b", [E]))),
+ {BinChecksum, Etag}.
diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl
index 4ab99c7..54f16da 100644
--- a/test/rebar_upgrade_SUITE.erl
+++ b/test/rebar_upgrade_SUITE.erl
@@ -425,17 +425,21 @@ upgrades(compile_upgrade_parity) ->
mock_deps(git, Deps, Upgrades) ->
catch mock_git_resource:unmock(),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps)}, {upgrade, Upgrades}]);
+ {SrcDeps, _} = rebar_test_utils:flat_deps(Deps),
+ mock_git_resource:mock([{deps, SrcDeps}, {upgrade, Upgrades}]);
mock_deps(pkg, Deps, Upgrades) ->
catch mock_pkg_resource:unmock(),
- mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Deps)}, {upgrade, Upgrades}]).
+ {_, PkgDeps} = rebar_test_utils:flat_deps(Deps),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}, {upgrade, Upgrades}]).
mock_deps(git, OldDeps, Deps, Upgrades) ->
catch mock_git_resource:unmock(),
- mock_git_resource:mock([{deps, rebar_test_utils:flat_deps(Deps++OldDeps)}, {upgrade, Upgrades}]);
+ {SrcDeps, _} = rebar_test_utils:flat_deps(Deps++OldDeps),
+ mock_git_resource:mock([{deps, SrcDeps}, {upgrade, Upgrades}]);
mock_deps(pkg, OldDeps, Deps, Upgrades) ->
catch mock_pkg_resource:unmock(),
- mock_pkg_resource:mock([{pkgdeps, rebar_test_utils:flat_pkgdeps(Deps++OldDeps)}, {upgrade, Upgrades}]).
+ {_, PkgDeps} = rebar_test_utils:flat_deps(Deps++OldDeps),
+ mock_pkg_resource:mock([{pkgdeps, PkgDeps}, {upgrade, Upgrades}]).
normalize_unlocks({App, Locks}) ->
{iolist_to_binary(App),