From 8cfb4df3e055b4f1e323273faf9b5157994a583a Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sat, 7 Mar 2015 15:44:32 -0500 Subject: Fix namespace regressions This adds some more convolution to command parsing, unfortunately, but makes some cases clearer (`rebar3 as as as as` is no longer valid). It unfortunately disallows using $REBAR_PROFILE along with `as` in a rebar command. --- src/rebar_core.erl | 38 ++++++++++++++++++++++++++++++++++---- test/rebar_namespace_SUITE.erl | 24 ++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/rebar_core.erl b/src/rebar_core.erl index 36c428d..ab90961 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -74,7 +74,21 @@ process_command(State, Command) -> %% properly exist for non-default namespaces outside of %% dynamic dispatch calls for namespaces. do(TargetProviders, rebar_state:namespace(State, default)); - Command when Command =:= do; Command =:= as -> + Command when Command =:= as, Namespace =:= undefined -> + %% Because of the possible forms such as: + %% 'rebar3 as profile task`, `rebar3 as profile do task` + %% and `rebar3 as profile namespace task`, we can only know + %% whether we're in the first 'as' or a namespace 'as' by + %% looking at profiles (as makes them non-default). + %% The namespace 'as' is banned. It also makes it impossible + %% to have both $REBAR_PROFILE set and use 'as' in a command + case rebar_state:current_profiles(State) of + [default] -> + do([{default, hd(TargetProviders)} | tl(TargetProviders)], State); + _ -> + {error, "Namespace 'as' is forbidden"} + end; + Command when Command =:= do -> do(TargetProviders, State); _ -> Profiles = providers:profiles(CommandProvider), @@ -83,7 +97,12 @@ process_command(State, Command) -> case getopt:parse(Opts, rebar_state:command_args(State1)) of {ok, Args} -> State2 = rebar_state:command_parsed_args(State1, Args), - do(TargetProviders, State2); + case Namespace of + undefined -> % we're executing commands, set the default namespace + do(TargetProviders, rebar_state:namespace(State2, default)); + _ -> + do(TargetProviders, State2) + end; {error, {invalid_option, Option}} -> {error, io_lib:format("Invalid option ~s on task ~p", [Option, Command])} end @@ -94,8 +113,19 @@ process_command(State, Command) -> do([], State) -> {ok, State}; do([ProviderName | Rest], State) -> - Provider = providers:get_provider(ProviderName - ,rebar_state:providers(State)), + %% Special providers like 'as', 'do' or some hooks may be passed + %% as a tuple {Namespace, Name}, otherwise not. Handle them + %% on a per-need basis. + Provider = case ProviderName of + {Namespace, Name} -> + providers:get_provider(Name + ,rebar_state:providers(State) + ,Namespace); + _ -> + providers:get_provider(ProviderName + ,rebar_state:providers(State) + ,rebar_state:namespace(State)) + end, case providers:do(Provider, State) of {ok, State1} -> do(Rest, State1); diff --git a/test/rebar_namespace_SUITE.erl b/test/rebar_namespace_SUITE.erl index 40b7238..3a55573 100644 --- a/test/rebar_namespace_SUITE.erl +++ b/test/rebar_namespace_SUITE.erl @@ -5,7 +5,8 @@ all() -> [implicit_compile, default_compile, do_compile, as_default_compile, as_do_compile, - notfound, do_notfound, default_notfound, ns_notfound]. + notfound, do_notfound, default_notfound, ns_notfound, ns_found, + as_ns_invalid]. init_per_testcase(Case, Config0) -> Config = rebar_test_utils:init_rebar_state(Config0), @@ -77,6 +78,22 @@ ns_notfound(Config) -> [fakecommand, ns])} ). +ns_found(Config) -> + Command = ["ns", "fake_provider"], + rebar_test_utils:run_and_check( + add_fake_ns_provider(Config), [], Command, + {ok, []} + ). + +as_ns_invalid(Config) -> + %% The as namespace is not valid + Command = ["as", "profile", "as", "task"], + rebar_test_utils:run_and_check( + add_fake_ns_provider(Config), [], Command, + {error, "Namespace 'as' is forbidden"} + ). + + %%% Helpers %%% add_fake_ns_provider(Config) -> State = ?config(state, Config), @@ -84,10 +101,13 @@ add_fake_ns_provider(Config) -> State, providers:create( [{name, fake_provider}, - {module, fake_provider}, + {module, ?MODULE}, {namespace, ns}, {deps, []}, {opts, []}] ) ), [{state, State1} | Config]. + +%% callback for the test suite. +do(State) -> {ok, State}. -- cgit v1.1