diff options
| -rw-r--r-- | inttest/thooks/fish.erl | 5 | ||||
| -rw-r--r-- | inttest/thooks/rebar.config | 7 | ||||
| -rw-r--r-- | inttest/thooks/thooks_rt.erl | 40 | ||||
| -rw-r--r-- | rebar.config.sample | 9 | ||||
| -rw-r--r-- | src/rebar_core.erl | 18 | 
5 files changed, 78 insertions, 1 deletions
| diff --git a/inttest/thooks/fish.erl b/inttest/thooks/fish.erl new file mode 100644 index 0000000..739cb94 --- /dev/null +++ b/inttest/thooks/fish.erl @@ -0,0 +1,5 @@ +-module(fish). + +-compile(export_all). + +fish() -> fish. diff --git a/inttest/thooks/rebar.config b/inttest/thooks/rebar.config new file mode 100644 index 0000000..6514818 --- /dev/null +++ b/inttest/thooks/rebar.config @@ -0,0 +1,7 @@ +%% pre-scripts +{pre_hooks, [{clean, "echo preclean >> preclean.out"}, +             {compile, "echo precompile >> precompile.out"}]}. + +%% post-scripts +{post_hooks, [{clean, "echo postclean >> postclean.out"}, +              {compile, "echo postcompile >> postcompile.out"}]}. diff --git a/inttest/thooks/thooks_rt.erl b/inttest/thooks/thooks_rt.erl new file mode 100644 index 0000000..52af9f5 --- /dev/null +++ b/inttest/thooks/thooks_rt.erl @@ -0,0 +1,40 @@ +-module(thooks_rt). + +-include_lib("eunit/include/eunit.hrl"). +-compile(export_all). + +files() -> +    [ +     %% dummy lfe files +     {copy, "../../rebar", "rebar"}, +     {copy, "rebar.config", "rebar.config"}, +     {copy, "fish.erl", "src/fish.erl"}, +     {create, "ebin/fish.app", app(fish, [fish])} +    ]. + +run(_Dir) -> +    ?assertMatch({ok, _}, retest_sh:run("./rebar -v clean compile", [])), +    ensure_command_ran_only_once("preclean"), +    ensure_command_ran_only_once("precompile"), +    ensure_command_ran_only_once("postclean"), +    ensure_command_ran_only_once("postcompile"), +    ok. + +ensure_command_ran_only_once(Command) -> +    File = Command ++ ".out", +    ?assert(filelib:is_regular(File)), +    %% ensure that this command only ran once (not for each module) +    {ok, Content} = file:read_file(File), +    ?assertEqual(Command ++ "\n", binary_to_list(Content)). + +%% +%% Generate the contents of a simple .app file +%% +app(Name, Modules) -> +    App = {application, Name, +           [{description, atom_to_list(Name)}, +            {vsn, "1"}, +            {modules, Modules}, +            {registered, []}, +            {applications, [kernel, stdlib]}]}, +    io_lib:format("~p.\n", [App]). diff --git a/rebar.config.sample b/rebar.config.sample index 184c16d..9870017 100644 --- a/rebar.config.sample +++ b/rebar.config.sample @@ -138,3 +138,12 @@  %% Subdirectories?  {sub_dirs, ["dir1", "dir2"]}. + +%% == Pre/Post Command Hooks == + +{pre_hooks, [{clean, "./prepare_package_files.sh"}, +             {compile, "escript generate_headers"}]}. + +{post_hooks, [{clean, "touch file1.out"}, +              {eunit, "touch file2.out"}, +              {compile, "touch postcompile.out"}]}. diff --git a/src/rebar_core.erl b/src/rebar_core.erl index d92af34..3f8068a 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -223,7 +223,7 @@ execute(Command, Modules, Config, ModuleFile) ->      case select_modules(Modules, Command, []) of          [] ->              ?WARN("'~p' command does not apply to directory ~s\n", -                     [Command, rebar_utils:get_cwd()]); +                  [Command, rebar_utils:get_cwd()]);          TargetModules ->              %% Provide some info on where we are @@ -235,9 +235,11 @@ execute(Command, Modules, Config, ModuleFile) ->              erlang:put(operations, erlang:get(operations) + 1),              %% Run the available modules +            apply_hooks(pre_hooks, Config, Command),              case catch(run_modules(TargetModules, Command,                                     Config, ModuleFile)) of                  ok -> +                    apply_hooks(post_hooks, Config, Command),                      ok;                  {error, failed} ->                      ?FAIL; @@ -302,6 +304,20 @@ run_modules([Module | Rest], Command, Config, File) ->              {Module, Error}      end. +apply_hooks(Mode, Config, Command) -> +    case rebar_config:get_local(Config, Mode, []) of +        [] -> +            skip; +        Hooks when is_list(Hooks) -> +            lists:foreach(fun apply_hook/1, +                          [{Command, Hook} || Hook <- Hooks]) +    end. + +apply_hook({Command, {Command, Hook}}) -> +    Msg = lists:flatten(io_lib:format("Command [~p] failed!~n", [Command])), +    rebar_utils:sh(Hook, [{abort_on_error, Msg}]); +apply_hook({Command, {HookCmd, _}}) when Command =/= HookCmd -> +    skip.  acc_modules(Modules, Command, Config, File) ->      acc_modules(select_modules(Modules, Command, []), | 
