1 %% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-
2 %%%-------------------------------------------------------------------
3 %%% @author Eric Merritt <ericbmerritt@gmail.com>
4 %%% @copyright (C) 2009-2011 Eric Merritt
6 %%% Provides a means of correctly creating eta pre/post task hooks
7 %%% and executing those hooks that exist.
9 %%%-------------------------------------------------------------------
12 -include_lib("sinan/include/sinan.hrl").
15 -define(CARRIAGE_RETURN
, 13).
18 -export([get_hooks_function
/2,
21 %%%===================================================================
23 %%%===================================================================
25 %% @doc Creats a function that can be used to run build hooks in the system.
26 -spec
get_hooks_function(sin_state:state(),
27 ProjectRoot::string()) -> function().
28 get_hooks_function(State
, ProjectRoot
) ->
29 HooksDir
= filename:join([ProjectRoot
, "_hooks"]),
30 case sin_utils:file_exists(State
, HooksDir
) of
34 gen_build_hooks_function(HooksDir
)
37 %% @doc Format an exception thrown by this module
38 -spec
format_exception(sin_exceptions:exception()) ->
40 format_exception(Exception
) ->
41 sin_exceptions:format_exception(Exception
).
43 %%%===================================================================
44 %%% Internal functions
45 %%%===================================================================
47 %% @doc Generate a function that can be run pre and post task
48 -spec
gen_build_hooks_function(HooksDir::string()) -> function().
49 gen_build_hooks_function(HooksDir
) ->
50 fun(Type
, Task
, Config
, State
) ->
51 do_hook(Config
, State
, Type
, Task
, HooksDir
)
54 %% @doc Setup to run the hook and run it if it exists.
55 -spec
do_hook(sin_config:config(), sin_state:state(),
56 Type::atom(), Task::atom(),
57 HooksDir::string()) -> ok
.
58 do_hook(Config
, State
, Type
, Task
, HooksDir
) when is_atom(Task
) ->
59 HookName
= atom_to_list(Type
) ++ "_" ++ atom_to_list(Task
),
60 HookPath
= filename:join(HooksDir
, HookName
),
61 case sin_utils:file_exists(State
, HookPath
) of
63 sin_log:verbose(Config
, "hook: ~s", [HookName
]),
64 run_hook(Config
, State
, HookPath
, list_to_atom(HookName
));
69 %% @doc Setup the execution environment and run the hook.
70 -spec
run_hook(sin_config:config(), sin_state:state(),
71 HookPath::list(), HookName::atom()) -> ok
.
72 run_hook(Config
, State
, HookPath
, HookName
) ->
73 command(Config
, State
, HookPath
, create_env(State
), HookName
).
75 %% @doc create a minimal env for the hook from the state.
76 -spec
create_env(sin_state:state()) -> Env::[{string(), string()}].
80 erlang:atom_to_list(sin_state:get_value(release
, State
))},
81 {"SIN_RELEASE_VSN", sin_state:get_value(release_vsn
, State
)},
82 {"SIN_BUILD_ROOT", sin_state:get_value(build_root
, State
)},
83 {"SIN_BUILD_DIR", sin_state:get_value(build_dir
, State
)},
84 {"SIN_APPS_DIR", sin_state:get_value(apps_dir
, State
)},
85 {"SIN_RELEASE_DIR", sin_state:get_value(release_dir
, State
)},
86 {"SIN_HOME_DIR", sin_state:get_value(home_dir
, State
)},
87 {"SIN_PROJECT_DIR", sin_state:get_value(project_dir
, State
)}] ++
88 [[{"SIN_" ++ erlang:atom_to_list(Name
) ++
90 {"SIN_" ++ erlang:atom_to_list(Name
) ++
92 #app
{name
=Name
, vsn
=Vsn
, path
=AppDir
}
93 <- sin_state:get_value(project_apps
, [], State
)],
96 %% @doc Given a command an an environment run that command with the environment
97 -spec
command(sin_config:config(), sin_state:state(), Command::list(), Env::list(),
98 HookName::atom()) -> list().
99 command(Config
, State
, Cmd
, Env
, HookName
) ->
101 case sin_sh:sh(Config
, Cmd
, Opt
) of
105 ?
SIN_RAISE(State
, {error_running_hook
, HookName
, Reason
})