summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rebar_prv_as.erl50
-rw-r--r--src/rebar_prv_do.erl1
-rw-r--r--src/rebar_utils.erl4
-rw-r--r--test/rebar_as_SUITE.erl88
4 files changed, 128 insertions, 15 deletions
diff --git a/src/rebar_prv_as.erl b/src/rebar_prv_as.erl
index 1ad22ed..7ac5465 100644
--- a/src/rebar_prv_as.erl
+++ b/src/rebar_prv_as.erl
@@ -32,21 +32,45 @@ init(State) ->
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
- [Profile | Rest] = rebar_state:command_args(State),
- Tasks = args_to_tasks(Rest),
- Profiles = [list_to_atom(X) || X <- string:tokens(Profile, ",")],
- State1 = rebar_state:apply_profiles(State, Profiles),
- lists:foldl(fun(TaskArgs, {ok, StateAcc}) ->
- [TaskStr | Args] = string:tokens(TaskArgs, " "),
- Task = list_to_atom(TaskStr),
- StateAcc1 = rebar_state:set(StateAcc, task, Task),
- StateAcc2 = rebar_state:command_args(StateAcc1, Args),
- rebar_core:process_command(StateAcc2, Task)
- end, {ok, State1}, Tasks).
+ {Profiles, Tasks} = args_to_profiles_and_tasks(rebar_state:command_args(State)),
+ case Profiles of
+ [] ->
+ {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)
+ end.
-spec format_error(any()) -> iolist().
format_error(Reason) ->
io_lib:format("~p", [Reason]).
-args_to_tasks(Args) ->
- [string:strip(T) || T <- string:tokens(string:join(Args, " "), ",")].
+args_to_profiles_and_tasks(Args) ->
+ first_profile(Args).
+
+first_profile([]) -> {[], []};
+first_profile([ProfileList|Rest]) ->
+ case re:split(ProfileList, ",", [{return, list}, {parts, 2}]) of
+ %% profile terminated by comma
+ [P, More] -> profiles([More] ++ Rest, [P]);
+ %% profile not terminated by comma
+ [P] -> comma_or_end(Rest, [P])
+ end.
+
+profiles([], Acc) -> {lists:reverse(Acc), rebar_utils:args_to_tasks([])};
+profiles([ProfileList|Rest], Acc) ->
+ case re:split(ProfileList, ",", [{return, list}, {parts, 2}]) of
+ %% profile terminated by comma
+ [P, More] -> profiles([More] ++ Rest, [P|Acc]);
+ %% profile not terminated by comma
+ [P] -> comma_or_end(Rest, [P|Acc])
+ end.
+
+%% `, foo...`
+comma_or_end([","|Rest], Acc) ->
+ profiles(Rest, Acc);
+%% `,foo...`
+comma_or_end(["," ++ Profile|Rest], Acc) ->
+ profiles([Profile|Rest], Acc);
+comma_or_end(Tasks, Acc) ->
+ {lists:reverse(Acc), rebar_utils:args_to_tasks(Tasks)}.
diff --git a/src/rebar_prv_do.erl b/src/rebar_prv_do.erl
index 8e6ee3a..5ecd987 100644
--- a/src/rebar_prv_do.erl
+++ b/src/rebar_prv_do.erl
@@ -7,6 +7,7 @@
-export([init/1,
do/1,
+ do_tasks/2,
format_error/1]).
-include("rebar.hrl").
diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl
index 0c95c69..1a7bf98 100644
--- a/src/rebar_utils.erl
+++ b/src/rebar_utils.erl
@@ -477,8 +477,8 @@ new_task([], Acc) -> lists:reverse(Acc);
new_task([TaskList|Rest], Acc) ->
case re:split(TaskList, ",", [{return, list}, {parts, 2}]) of
%% `do` consumes all remaining args
- ["do" = Task|RestArgs] ->
- lists:reverse([{Task, RestArgs ++ Rest}|Acc]);
+ ["do" = Task] ->
+ lists:reverse([{Task, Rest}|Acc]);
%% single task terminated by a comma
[Task, ""] -> new_task(Rest, [{Task, []}|Acc]);
%% sequence of two or more tasks
diff --git a/test/rebar_as_SUITE.erl b/test/rebar_as_SUITE.erl
new file mode 100644
index 0000000..5566c98
--- /dev/null
+++ b/test/rebar_as_SUITE.erl
@@ -0,0 +1,88 @@
+-module(rebar_as_SUITE).
+
+-export([suite/0,
+ init_per_suite/1,
+ end_per_suite/1,
+ init_per_testcase/2,
+ all/0,
+ as_basic/1,
+ as_multiple_profiles/1,
+ as_multiple_tasks/1,
+ as_multiple_profiles_multiple_tasks/1,
+ as_comma_placement/1]).
+
+-include_lib("common_test/include/ct.hrl").
+-include_lib("eunit/include/eunit.hrl").
+-include_lib("kernel/include/file.hrl").
+
+suite() -> [].
+
+init_per_suite(Config) -> Config.
+
+end_per_suite(_Config) -> ok.
+
+init_per_testcase(_, Config) ->
+ rebar_test_utils:init_rebar_state(Config, "do_as_").
+
+all() -> [as_basic, as_multiple_profiles, as_multiple_tasks,
+ as_multiple_profiles_multiple_tasks].
+
+as_basic(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("as_basic_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ rebar_test_utils:run_and_check(Config,
+ [],
+ ["as", "default", "compile"],
+ {ok, [{app, Name}]}).
+
+as_multiple_profiles(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("as_multiple_profiles_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ rebar_test_utils:run_and_check(Config,
+ [],
+ ["as", "foo", ",", "bar", "compile"],
+ {ok, [{app, Name}]}).
+
+as_multiple_tasks(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("as_multiple_tasks_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ rebar_test_utils:run_and_check(Config,
+ [],
+ ["as", "foo", "clean", ",", "compile"],
+ {ok, [{app, Name}]}).
+
+as_multiple_profiles_multiple_tasks(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("as_multiple_profiles_multiple_tasks_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ rebar_test_utils:run_and_check(Config,
+ [],
+ ["as", "foo", ",", "bar", "clean", ",", "compile"],
+ {ok, [{app, Name}]}).
+
+as_comma_placement(Config) ->
+ AppDir = ?config(apps, Config),
+
+ Name = rebar_test_utils:create_random_name("do_as_crazy_"),
+ Vsn = rebar_test_utils:create_random_vsn(),
+ rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]),
+
+ rebar_test_utils:run_and_check(Config,
+ [],
+ ["as", "foo,bar", ",", "baz", ",qux", "compile"],
+ {ok, [{app, Name}]}).