summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2015-03-13 13:44:29 -0400
committerFred Hebert <mononcqc@ferd.ca>2015-03-13 13:44:29 -0400
commit6e337e022c3c4521ee84121845305b494127aaf2 (patch)
tree9a86e20747f700c3abb3d3c0f6d494ced1b352df
parent639b1094cf4ae4c49c085baa28326cfee50f7765 (diff)
parentad18970cd7bbcffd4d868ab1a9372f4e883a1728 (diff)
Merge pull request #268 from ferd/refactor-as-namespace-conflicts
Fix #267, refactor as/do/namespace interactions
-rw-r--r--src/rebar3.erl2
-rw-r--r--src/rebar_core.erl89
-rw-r--r--src/rebar_prv_as.erl12
3 files changed, 50 insertions, 53 deletions
diff --git a/src/rebar3.erl b/src/rebar3.erl
index cb02daa..d80773b 100644
--- a/src/rebar3.erl
+++ b/src/rebar3.erl
@@ -133,7 +133,7 @@ run_aux(State, GlobalPluginProviders, RawArgs) ->
{Task, Args} = parse_args(RawArgs),
- rebar_core:process_command(rebar_state:command_args(State6, Args), Task).
+ rebar_core:init_command(rebar_state:command_args(State6, Args), Task).
init_config() ->
%% Initialize logging system
diff --git a/src/rebar_core.erl b/src/rebar_core.erl
index 12cd1fc..db82766 100644
--- a/src/rebar_core.erl
+++ b/src/rebar_core.erl
@@ -26,69 +26,61 @@
%% -------------------------------------------------------------------
-module(rebar_core).
--export([process_command/2]).
+-export([init_command/2, process_namespace/2, process_command/2]).
-include("rebar.hrl").
+init_command(State, do) ->
+ process_command(rebar_state:namespace(State, default), do);
+init_command(State, as) ->
+ process_command(rebar_state:namespace(State, default), as);
+init_command(State, Command) ->
+ case process_namespace(State, Command) of
+ {ok, State1, Command1} ->
+ process_command(State1, Command1);
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+process_namespace(_State, as) ->
+ {error, "Namespace 'as' is forbidden"};
+process_namespace(State, Command) ->
+ Providers = rebar_state:providers(State),
+ CommandProvider = providers:get_provider(Command, Providers, default),
+ case CommandProvider of
+ not_found ->
+ case providers:get_providers_by_namespace(Command, Providers) of
+ [] ->
+ {error, io_lib:format("Command ~p not found", [Command])};
+ _ ->
+ %% Replay 'do' as a command of that namespace
+ {ok, rebar_state:namespace(State, Command), do}
+ end;
+ _ ->
+ {ok, rebar_state:namespace(State, default), Command}
+ end.
+
-spec process_command(rebar_state:t(), atom()) -> {ok, rebar_state:t()} | {error, string()}.
process_command(State, Command) ->
%% ? rebar_prv_install_deps:setup_env(State),
Providers = rebar_state:providers(State),
Namespace = rebar_state:namespace(State),
- {TargetProviders, CommandProvider} =
- case Namespace of
- undefined ->
- %% undefined namespace means 'default', but on the first run;
- %% it is used as an implicit counter for the first vs. subsequent
- %% runs.
- {providers:get_target_providers(Command, Providers, default),
- providers:get_provider(Command, Providers, default)};
- _ ->
- {providers:get_target_providers(Command, Providers, Namespace),
- providers:get_provider(Command, Providers, Namespace)}
- end,
-
+ TargetProviders = providers:get_target_providers(Command, Providers, Namespace),
+ CommandProvider = providers:get_provider(Command, Providers, Namespace),
case CommandProvider of
- not_found ->
+ not_found when Command =/= do ->
case Namespace of
- undefined ->
- %% On the first run (Namespace = undefined), we use the
- %% unfound command name to be a namespace.
- case providers:get_providers_by_namespace(Command, Providers) of
- [] ->
- {error, io_lib:format("Command ~p not found", [Command])};
- _ ->
- do([{default, do} | TargetProviders],
- rebar_state:namespace(State, Command))
- end;
default ->
{error, io_lib:format("Command ~p not found", [Command])};
_ ->
{error, io_lib:format("Command ~p not found in namespace ~p",
[Command, Namespace])}
end;
+ not_found when Command =:= do, Namespace =/= default ->
+ do([{default, do} | TargetProviders], State);
CommandProvider ->
case Command of
- Command when Command =:= do, Namespace =:= undefined ->
- %% We're definitely in the default namespace. 'do' doesn't
- %% properly exist for non-default namespaces outside of
- %% dynamic dispatch calls for namespaces.
- do(TargetProviders, rebar_state:namespace(State, default));
- 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(TargetProviders, State);
- _ ->
- {error, "Namespace 'as' is forbidden"}
- end;
- Command when Command =:= do ->
+ do ->
do(TargetProviders, State);
_ ->
Profiles = providers:profiles(CommandProvider),
@@ -97,12 +89,7 @@ process_command(State, Command) ->
case getopt:parse(Opts, rebar_state:command_args(State1)) of
{ok, Args} ->
State2 = rebar_state:command_parsed_args(State1, Args),
- case Namespace of
- undefined -> % we're executing commands, set the default namespace
- do(TargetProviders, rebar_state:namespace(State2, default));
- _ ->
- do(TargetProviders, State2)
- end;
+ do(TargetProviders, State2);
{error, {invalid_option, Option}} ->
{error, io_lib:format("Invalid option ~s on task ~p", [Option, Command])}
end
diff --git a/src/rebar_prv_as.erl b/src/rebar_prv_as.erl
index beee00d..6e3825f 100644
--- a/src/rebar_prv_as.erl
+++ b/src/rebar_prv_as.erl
@@ -38,7 +38,17 @@ do(State) ->
{error, "At least one profile must be specified when using `as`"};
_ ->
State1 = rebar_state:apply_profiles(State, [list_to_atom(X) || X <- Profiles]),
- rebar_prv_do:do_tasks(Tasks, State1)
+ {FirstTask, FirstTaskArgs} = hd(Tasks),
+ FirstTaskAtom = list_to_atom(FirstTask),
+ case rebar_core:process_namespace(State1, FirstTaskAtom) of
+ {ok, State2, NewTask} ->
+ rebar_prv_do:do_tasks(
+ [{atom_to_list(NewTask),FirstTaskArgs}|tl(Tasks)],
+ State2
+ );
+ {error, Reason} ->
+ {error, Reason}
+ end
end.
-spec format_error(any()) -> iolist().