diff --git a/src/rebar_prv_upgrade.erl b/src/rebar_prv_upgrade.erl index e1d6c6012..63ad951e3 100644 --- a/src/rebar_prv_upgrade.erl +++ b/src/rebar_prv_upgrade.erl @@ -32,12 +32,12 @@ init(State) -> {deps, ?DEPS}, {example, "rebar3 upgrade [cowboy[,ranch]]"}, {short_desc, "Upgrade dependencies."}, - {desc, "Upgrade project dependencies. Mentioning no application " - "will upgrade all dependencies. To upgrade specific dependencies, " + {desc, "Upgrade project dependencies. Use the -a/--all option to " + "upgrade all dependencies. To upgrade specific dependencies, " "their names can be listed in the command."}, - {opts, [ + {opts, [{all, $a, "all", undefined, "Upgrade all dependencies."}, {package, undefined, undefined, string, - "List of packages to upgrade. If not specified, all dependencies are upgraded."} + "List of packages to upgrade."} ]}])), {ok, State1}. @@ -56,7 +56,6 @@ do(State) -> end. do_(State) -> - {Args, _} = rebar_state:command_parsed_args(State), Locks = rebar_state:get(State, {locks, default}, []), %% We have 3 sources of dependencies to upgrade from: %% 1. the top-level rebar.config (in `deps', dep name is an atom) @@ -81,8 +80,12 @@ do_(State) -> ProfileDeps = rebar_state:get(State, {deps, default}, []), Deps = [Dep || Dep <- TopDeps ++ ProfileDeps, % TopDeps > ProfileDeps is_atom(Dep) orelse is_atom(element(1, Dep))], - Names = parse_names(rebar_utils:to_binary(proplists:get_value(package, Args, <<"">>)), Locks), - + Names = case handle_args(State) of + {false, undefined} -> throw(?PRV_ERROR(no_arg)); + {true, _} -> [Name || {Name, _, 0} <- Locks]; + {false, Packages} -> Bin = rebar_utils:to_binary(Packages), + lists:usort(re:split(Bin, <<" *, *">>, [trim, unicode])) + end, DepsDict = deps_dict(rebar_state:all_deps(State)), AltDeps = find_non_default_deps(Deps, State), FilteredNames = cull_default_names_if_profiles(Names, Deps, State), @@ -127,9 +130,17 @@ format_error({transitive_dependency, Name}) -> format_error({checkout_dependency, Name}) -> io_lib:format("Dependency ~ts is a checkout dependency under _checkouts/ and checkouts cannot be upgraded.", [Name]); +format_error(no_arg) -> + "Specify a list of dependencies to upgrade, or --all to upgrade them all"; format_error(Reason) -> io_lib:format("~p", [Reason]). +handle_args(State) -> + {Args, _} = rebar_state:command_parsed_args(State), + All = proplists:get_value(all, Args, false), + Package = proplists:get_value(package, Args), + {All, Package}. + %% fetch updates for package deps that have been unlocked for upgrade update_pkg_deps([], _, _) -> ok; @@ -160,15 +171,6 @@ update_package(Name, RepoConfig, State) -> ok end. -parse_names(Bin, Locks) -> - case lists:usort(re:split(Bin, <<" *, *">>, [trim, unicode])) of - %% Nothing submitted, use *all* apps - [<<"">>] -> [Name || {Name, _, 0} <- Locks]; - [] -> [Name || {Name, _, 0} <- Locks]; - %% Regular options - Other -> Other - end. - %% Find alternative deps in non-default profiles since they may %% need to be passed through (they are never locked) find_non_default_deps(Deps, State) -> diff --git a/test/rebar_pkg_alias_SUITE.erl b/test/rebar_pkg_alias_SUITE.erl index 1d31b2bd9..5ba544de7 100644 --- a/test/rebar_pkg_alias_SUITE.erl +++ b/test/rebar_pkg_alias_SUITE.erl @@ -89,7 +89,7 @@ diff_alias(Config) -> {ok, [{Vsn, LockData}|_]} = file:consult(Lockfile), %% So does an upgrade rebar_test_utils:run_and_check( - Config, RebarConfig, ["upgrade"], + Config, RebarConfig, ["upgrade", "--all"], {ok, [{lock, "fakelib"},{dep, "fakelib"}]} ), {ok, [{Vsn, LockData}|_]} = file:consult(Lockfile). @@ -128,7 +128,7 @@ transitive_alias(Config) -> ?assertNot(filelib:is_dir(PkgName)), %% So does an upgrade rebar_test_utils:run_and_check( - Config, RebarConfig, ["upgrade"], + Config, RebarConfig, ["upgrade", "--all"], {ok, [{lock, "topdep"},{dep, "topdep"}, {lock,"transitive_app"},{dep,"transitive_app"}]} ), diff --git a/test/rebar_upgrade_SUITE.erl b/test/rebar_upgrade_SUITE.erl index 54ff18c0b..f56c4cf2f 100644 --- a/test/rebar_upgrade_SUITE.erl +++ b/test/rebar_upgrade_SUITE.erl @@ -3,7 +3,7 @@ -include_lib("eunit/include/eunit.hrl"). -compile(export_all). -all() -> [{group, git}, {group, pkg}, novsn_pkg]. +all() -> [{group, git}, {group, pkg}, novsn_pkg, upgrade_no_args]. groups() -> [{all, [], [top_a, top_b, top_c, top_d1, top_d2, top_e, @@ -53,6 +53,8 @@ init_per_testcase(novsn_pkg, Config0) -> end}, {expected, {ok, [{dep, "fakeapp", "1.1.0"}, {lock, "fakeapp", "1.1.0"}]}} | Config]; +init_per_testcase(upgrade_no_args, Config0) -> + rebar_test_utils:init_rebar_state(Config0, "upgrade_no_args_"); init_per_testcase(Case, Config) -> DepsType = ?config(deps_type, Config), {Deps, UpDeps, ToUp, Expectations} = upgrades(Case), @@ -543,6 +545,9 @@ mock_deps(pkg, OldDeps, Deps, Upgrades) -> {_, PkgDeps} = rebar_test_utils:flat_deps(Deps++OldDeps), mock_pkg_resource:mock([{pkgdeps, PkgDeps}, {upgrade, Upgrades}]). +normalize_unlocks({[], Locks}) -> + {"--all", + normalize_unlocks_expect(Locks)}; normalize_unlocks({App, Locks}) -> {iolist_to_binary(App), normalize_unlocks_expect(Locks)}; @@ -646,7 +651,7 @@ compile_upgrade_parity(Config) -> Lockfile = filename:join([AppDir, "rebar.lock"]), rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, []}), {ok, CompileLockData1} = file:read_file(Lockfile), - rebar_test_utils:run_and_check(Config, RebarConfig, ["upgrade"], {ok, []}), + rebar_test_utils:run_and_check(Config, RebarConfig, ["upgrade", "--all"], {ok, []}), {ok, UpgradeLockData} = file:read_file(Lockfile), rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, []}), {ok, CompileLockData2} = file:read_file(Lockfile), @@ -781,7 +786,7 @@ novsn_pkg(Config) -> Expectation = ?config(expected, Config), apply(?config(mock_update, Config), []), rebar_test_utils:run_and_check( - Config, RebarConfig, ["upgrade"], Expectation + Config, RebarConfig, ["upgrade", "--all"], Expectation ), ok. @@ -808,3 +813,10 @@ rewrite_locks({ok, Expectations}, Config) -> end, [], Locks), ct:pal("rewriting locks from ~p to~n~p", [Locks, NewLocks]), file:write_file(LockFile, io_lib:format("~p.~n", [NewLocks])). + +upgrade_no_args(Config) -> + try rebar_test_utils:run_and_check(Config, [], ["upgrade"], return) + catch {error, {rebar_prv_upgrade, no_arg}} -> + ok + end, + ok.