diff options
-rw-r--r-- | test/mock_git_resource.erl | 7 | ||||
-rw-r--r-- | test/rebar_compile_SUITE.erl | 3 | ||||
-rw-r--r-- | test/rebar_deps_SUITE.erl | 31 | ||||
-rw-r--r-- | test/rebar_install_deps_SUITE.erl | 226 | ||||
-rw-r--r-- | test/rebar_plugins_SUITE.erl | 6 | ||||
-rw-r--r-- | test/rebar_profiles_SUITE.erl | 15 | ||||
-rw-r--r-- | test/rebar_test_utils.erl | 79 | ||||
-rw-r--r-- | test/rebar_upgrade_SUITE.erl | 12 |
8 files changed, 287 insertions, 92 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/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 0aaa899..1d5aab8 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -544,7 +544,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">>}, []}]}]), diff --git a/test/rebar_deps_SUITE.erl b/test/rebar_deps_SUITE.erl index bfb6a1f..04018fc 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(), @@ -241,7 +223,8 @@ newly_added_dep(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)}]), + {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(), diff --git a/test/rebar_install_deps_SUITE.erl b/test/rebar_install_deps_SUITE.erl index 4e6c3d9..3fabc56 100644 --- a/test/rebar_install_deps_SUITE.erl +++ b/test/rebar_install_deps_SUITE.erl @@ -4,16 +4,24 @@ -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_circular3, + 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_src_override + ]} + ]. init_per_suite(Config) -> application:start(meck), @@ -26,19 +34,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 +76,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 -> {src, 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 -> {src, N, "0.0.0"} + end || W <- Warnings]. + %% format: %% {Spec, %% [Warning], @@ -131,6 +179,79 @@ 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_circular3) -> + %% Spot the circular dep due to being to low in the deps tree + %% but as a source dep, taking precedence over packages + {[{"B", [{"C", "2", [{"B", []}]}]}, + {"c", "1", [{"d",[]}]}], + [], + {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) -> + {[{"b", [{"d", []}]}, + {"C", [{"D", []}]}], + ["d"], + {ok, ["b", "C", "D"]}}; +mdeps(m_pick_source3) -> + %% The order of declaration is important. + {[{"b", []}, + {"B", []}], + ["B"], + {ok, ["b"]}}; +mdeps(m_pick_source4) -> + {[{"B", []}, + {"b", []}], + ["b"], + {ok, ["B"]}}; +mdeps(m_pick_source5) -> + {[{"B", [{"d", []}]}, + {"C", [{"D", []}]}], + ["d"], + {ok, ["B", "C", "D"]}}; +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_src_override) -> + %% This is all handled in setup_project + {[],[],{ok,[]}}. + + setup_project(fail_conflict, Config0, Deps) -> DepsType = ?config(deps_type, Config0), Config = rebar_test_utils:init_rebar_state( @@ -142,12 +263,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 +279,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,15 +302,30 @@ 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(m_pkg_src_override, Config0, _) -> + Config = rebar_test_utils:init_rebar_state(Config0, "m_pkg_src_override_mixed_"), + AppDir = ?config(apps, Config), + rebar_test_utils:create_app(AppDir, "A", "0.0.0", [kernel, stdlib]), + DefaultDeps = rebar_test_utils:expand_deps(mixed, [{"b", [{"c", []}]}]), + OverrideDeps = rebar_test_utils:expand_deps(mixed, [{"C", []}]), + DefaultTop = rebar_test_utils:top_level_deps(DefaultDeps), + OverrideTop = rebar_test_utils:top_level_deps(OverrideDeps), + RebarConf = rebar_test_utils:create_config( + AppDir, + [{deps, DefaultTop}, + {overrides, [{override, b, [{deps, OverrideTop}]}]}] + ), + {SrcDeps,PkgDeps} = rebar_test_utils:flat_deps(DefaultDeps++OverrideDeps), + mock_git_resource:mock([{deps, SrcDeps}]), + mock_pkg_resource:mock([{pkgdeps, PkgDeps}]), + [{rebarconfig, RebarConf} | Config]; setup_project(Case, Config0, Deps) -> DepsType = ?config(deps_type, Config0), Config = rebar_test_utils:init_rebar_state( @@ -206,12 +336,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() -> @@ -319,6 +446,33 @@ nondefault_pick_highest(Config) -> {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_circular3(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_src_override(Config) -> + %% Detect the invalid override where a package dep's are overriden + %% with source dependencies. We only test with overrides because + %% we trust the package index to be correct there and not introduce + %% that kind of error. + {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)), + rebar_test_utils:run_and_check( + Config, RebarConfig, ["lock"], + {error, {rebar_prv_install_deps, + {package_dep_override, <<"b">>}}} + ). + run(Config) -> {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)), rebar_test_utils:run_and_check( @@ -336,6 +490,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)), 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_test_utils.erl b/test/rebar_test_utils.erl index be52e81..8e00483 100644 --- a/test/rebar_test_utils.erl +++ b/test/rebar_test_utils.erl @@ -2,7 +2,7 @@ -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([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]). -export([create_random_name/1, create_random_vsn/0, write_src_file/2]). @@ -137,24 +137,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 +297,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(), 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), |