From c25fbab1c60836ccbc20225b5a10eea2fb285d48 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 21 Dec 2014 10:30:33 -0500 Subject: Remove profile declarations No longer needed. --- src/rebar_prv_release.erl | 2 +- src/rebar_prv_tar.erl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rebar_prv_release.erl b/src/rebar_prv_release.erl index 295d5b4..d82b428 100644 --- a/src/rebar_prv_release.erl +++ b/src/rebar_prv_release.erl @@ -12,7 +12,7 @@ -include("rebar.hrl"). -define(PROVIDER, release). --define(DEPS, [{compile, default}, compile]). +-define(DEPS, [compile]). %% =================================================================== %% Public API diff --git a/src/rebar_prv_tar.erl b/src/rebar_prv_tar.erl index f9c261f..01fa1ba 100644 --- a/src/rebar_prv_tar.erl +++ b/src/rebar_prv_tar.erl @@ -12,7 +12,7 @@ -include("rebar.hrl"). -define(PROVIDER, tar). --define(DEPS, [{compile, default}, compile]). +-define(DEPS, [compile]). %% =================================================================== %% Public API -- cgit v1.1 From ae54d70e6ce64b97f2d60400b24d1219369617b5 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 21 Dec 2014 11:02:20 -0500 Subject: Add support for namespace-based metacommands And more general namespace support --- rebar.config | 4 ++-- src/rebar_core.erl | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/rebar.config b/rebar.config index 296713a..fd3e53f 100644 --- a/rebar.config +++ b/rebar.config @@ -22,8 +22,8 @@ {git, "https://github.com/erlware/erlware_commons.git", {branch, "master"}}}, {providers, "", - {git, "https://github.com/tsloughter/providers.git", - {tag, "v1.0.0"}}}, + {git, "https://github.com/ferd/providers.git", + {branch, "namespaces"}}}, {erlydtl, ".*", {git, "https://github.com/erlydtl/erlydtl.git", {tag, "0.9.4"}}}, diff --git a/src/rebar_core.erl b/src/rebar_core.erl index eaa546a..96ba426 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -37,8 +37,17 @@ process_command(State, Command) -> Providers = rebar_state:providers(State), TargetProviders = providers:get_target_providers(Command, Providers), case providers:get_provider(Command, Providers) of - not_found -> - {error, io_lib:format("Command ~p not found", [Command])}; + not_found when is_atom(Command) -> + Namespace = Command, + process_command(State, {Namespace, do}); + not_found when is_tuple(Command) -> + case Command of + {default,Cmd} -> + {error, io_lib:format("Command ~p not found", [Cmd])}; + {Namespace,Cmd} -> + {error, io_lib:format("Command ~p not found in namespace ~p", + [Cmd, Namespace])} + end; CommandProvider -> case Command of Command when Command =:= do @@ -62,7 +71,7 @@ process_command(State, Command) -> -spec do([{atom(), atom()}], rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. do([], State) -> {ok, State}; -do([{ProviderName, _} | Rest], State) -> +do([ProviderName | Rest], State) -> Provider = providers:get_provider(ProviderName ,rebar_state:providers(State)), case providers:do(Provider, State) of -- cgit v1.1 From 676f2487adbdef87f3c31d0480e3113f91ca3bff Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 21 Dec 2014 12:53:05 -0500 Subject: Dynamic 'do' provider for namespaces Using a namespace such as 'rebar3 lfe new' will look for the 'new' command in 'lfe' namespace without the need for a 'do' provider to be registered in that namespace. Manually checked that 'rebar3 as command' works, as well with 'default' and 'do'. Test suite still needed. --- src/rebar_core.erl | 44 +++++++++++++++++++++++++++++++------------- src/rebar_state.erl | 8 ++++++++ 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/rebar_core.erl b/src/rebar_core.erl index 96ba426..cfe040a 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -35,23 +35,41 @@ process_command(State, Command) -> %% ? rebar_prv_install_deps:setup_env(State), Providers = rebar_state:providers(State), - TargetProviders = providers:get_target_providers(Command, Providers), - case providers:get_provider(Command, Providers) of - not_found when is_atom(Command) -> - Namespace = Command, - process_command(State, {Namespace, do}); - not_found when is_tuple(Command) -> - case Command of - {default,Cmd} -> - {error, io_lib:format("Command ~p not found", [Cmd])}; - {Namespace,Cmd} -> + 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, + case CommandProvider of + not_found -> + case Namespace of + undefined -> + %% On the first run (Namespace = undefined), we use the + %% unfound command name to be a namespace. + do([{default, do} | TargetProviders], + rebar_state:namespace(State, Command)); + default -> + {error, io_lib:format("Command ~p not found", [Command])}; + _ -> {error, io_lib:format("Command ~p not found in namespace ~p", - [Cmd, Namespace])} + [Command, Namespace])} end; CommandProvider -> case Command of - Command when Command =:= do - ; Command =:= as -> + 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 =:= do; Command =:= as -> do(TargetProviders, State); _ -> Profile = providers:profile(CommandProvider), diff --git a/src/rebar_state.erl b/src/rebar_state.erl index 09becca..657c7d2 100644 --- a/src/rebar_state.erl +++ b/src/rebar_state.erl @@ -23,6 +23,7 @@ project_apps/1, project_apps/2, deps_to_build/1, deps_to_build/2, all_deps/1, all_deps/2, + namespace/1, namespace/2, deps_names/1, @@ -39,6 +40,7 @@ lock = [], current_profiles = [default] :: [atom()], + namespace = undefined :: [atom()], command_args = [], command_parsed_args = [], @@ -220,6 +222,12 @@ all_deps(#state_t{all_deps=Apps}) -> all_deps(State=#state_t{}, NewApps) -> State#state_t{all_deps=NewApps}. +namespace(#state_t{namespace=Namespace}) -> + Namespace. + +namespace(State=#state_t{}, Namespace) -> + State#state_t{namespace=Namespace}. + providers(#state_t{providers=Providers}) -> Providers. -- cgit v1.1 From 73676c80b06bd4a26040b41f42fee8dde536dcac Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 21 Dec 2014 14:47:32 -0500 Subject: Fix up programmatic interface to rebar3 Now supports arbitrary commands --- src/rebar3.erl | 6 +++--- test/rebar_compile_SUITE.erl | 2 +- test/rebar_deps_SUITE.erl | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rebar3.erl b/src/rebar3.erl index b325dc8..d4307f7 100644 --- a/src/rebar3.erl +++ b/src/rebar3.erl @@ -71,10 +71,10 @@ main(Args) -> end. %% Erlang-API entry point -run(BaseState, Command) -> +run(BaseState, Commands) -> _ = application:load(rebar), - BaseState1 = rebar_state:set(BaseState, task, Command), - run_aux(BaseState1, [], [Command]). + BaseState1 = rebar_state:set(BaseState, task, Commands), + run_aux(BaseState1, [], Commands). %% ==================================================================== %% Internal functions diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index 83b868d..03f9c1f 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -33,5 +33,5 @@ build_basic_app(Config) -> Vsn = rebar_test_utils:create_random_vsn(), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), - rebar_test_utils:run_and_check(Config, [], "compile", {ok, [{app, Name}]}). + rebar_test_utils:run_and_check(Config, [], ["compile"], {ok, [{app, Name}]}). diff --git a/test/rebar_deps_SUITE.erl b/test/rebar_deps_SUITE.erl index c6f24c0..d67efe4 100644 --- a/test/rebar_deps_SUITE.erl +++ b/test/rebar_deps_SUITE.erl @@ -195,7 +195,7 @@ circular_skip(Config) -> run(Config). run(Config) -> {ok, RebarConfig} = file:consult(?config(rebarconfig, Config)), rebar_test_utils:run_and_check( - Config, RebarConfig, "install_deps", ?config(expect, Config) + Config, RebarConfig, ["install_deps"], ?config(expect, Config) ), check_warnings(warning_calls(), ?config(warnings, Config), ?config(deps_type, Config)). -- cgit v1.1 From 54a41ca6c4fb819aa5adf4883f51d0c785a56be3 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 21 Dec 2014 14:47:55 -0500 Subject: Tests and fixes for namespaces --- src/rebar_core.erl | 9 +++- test/rebar_namespace_SUITE.erl | 93 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 test/rebar_namespace_SUITE.erl diff --git a/src/rebar_core.erl b/src/rebar_core.erl index cfe040a..c3a8951 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -54,8 +54,13 @@ process_command(State, Command) -> undefined -> %% On the first run (Namespace = undefined), we use the %% unfound command name to be a namespace. - do([{default, do} | TargetProviders], - rebar_state:namespace(State, Command)); + 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])}; _ -> diff --git a/test/rebar_namespace_SUITE.erl b/test/rebar_namespace_SUITE.erl new file mode 100644 index 0000000..40b7238 --- /dev/null +++ b/test/rebar_namespace_SUITE.erl @@ -0,0 +1,93 @@ +-module(rebar_namespace_SUITE). +-compile(export_all). +-include_lib("common_test/include/ct.hrl"). +-include_lib("eunit/include/eunit.hrl"). + +all() -> [implicit_compile, default_compile, do_compile, + as_default_compile, as_do_compile, + notfound, do_notfound, default_notfound, ns_notfound]. + +init_per_testcase(Case, Config0) -> + Config = rebar_test_utils:init_rebar_state(Config0), + AppDir = ?config(apps, Config), + Name = rebar_test_utils:create_random_name("app1_"++atom_to_list(Case)), + Vsn = rebar_test_utils:create_random_vsn(), + rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), + [{name, Name} | Config]. + +end_per_testcase(_, Config) -> + Config. + +implicit_compile(Config) -> + Name = ?config(name, Config), + rebar_test_utils:run_and_check(Config, [], + ["compile"], + {ok, [{app, Name}]}). + +default_compile(Config) -> + Name = ?config(name, Config), + rebar_test_utils:run_and_check(Config, [], + ["default","compile"], + {ok, [{app, Name}]}). + +do_compile(Config) -> + Name = ?config(name, Config), + rebar_test_utils:run_and_check(Config, [], + ["do", "compile"], + {ok, [{app, Name}]}). + +as_default_compile(Config) -> + Name = ?config(name, Config), + rebar_test_utils:run_and_check(Config, [], + ["as", "prod", "default", "compile"], + {ok, [{app, Name}]}). + +as_do_compile(Config) -> + Name = ?config(name, Config), + rebar_test_utils:run_and_check(Config, [], + ["as", "prod", "do", "compile"], + {ok, [{app, Name}]}). + +notfound(Config) -> + Command = ["fakecommand"], + rebar_test_utils:run_and_check( + Config, [], Command, + {error, io_lib:format("Command ~p not found", [fakecommand])} + ). + +do_notfound(Config) -> + Command = ["do", "fakecommand"], + rebar_test_utils:run_and_check( + Config, [], Command, + {error, io_lib:format("Command ~p not found", [fakecommand])} + ). + +default_notfound(Config) -> + Command = ["default", "fakecommand"], + rebar_test_utils:run_and_check( + Config, [], Command, + {error, io_lib:format("Command ~p not found", [fakecommand])} + ). + +ns_notfound(Config) -> + Command = ["ns", "fakecommand"], + rebar_test_utils:run_and_check( + add_fake_ns_provider(Config), [], Command, + {error, io_lib:format("Command ~p not found in namespace ~p", + [fakecommand, ns])} + ). + +%%% Helpers %%% +add_fake_ns_provider(Config) -> + State = ?config(state, Config), + State1 = rebar_state:add_provider( + State, + providers:create( + [{name, fake_provider}, + {module, fake_provider}, + {namespace, ns}, + {deps, []}, + {opts, []}] + ) + ), + [{state, State1} | Config]. -- cgit v1.1