Bläddra i källkod

Merge pull request #268 from ferd/refactor-as-namespace-conflicts

Fix #267, refactor as/do/namespace interactions
pull/270/head
Fred Hebert 10 år sedan
förälder
incheckning
6e337e022c
3 ändrade filer med 50 tillägg och 53 borttagningar
  1. +1
    -1
      src/rebar3.erl
  2. +38
    -51
      src/rebar_core.erl
  3. +11
    -1
      src/rebar_prv_as.erl

+ 1
- 1
src/rebar3.erl Visa fil

@ -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

+ 38
- 51
src/rebar_core.erl Visa fil

@ -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

+ 11
- 1
src/rebar_prv_as.erl Visa fil

@ -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().

Laddar…
Avbryt
Spara