|
|
@ -56,12 +56,23 @@ init(State) -> |
|
|
|
{short_desc, "Run shell with project apps and deps in path."}, |
|
|
|
{desc, info()}, |
|
|
|
{opts, [{config, undefined, "config", string, |
|
|
|
"Path to the config file to use. Defaults to the " |
|
|
|
"sys_config defined for relx, if present."}, |
|
|
|
"Path to the config file to use. Defaults to " |
|
|
|
"{shell, [{config, File}]} and then the relx " |
|
|
|
"sys.config file if not specified."}, |
|
|
|
{name, undefined, "name", atom, |
|
|
|
"Gives a long name to the node."}, |
|
|
|
{sname, undefined, "sname", atom, |
|
|
|
"Gives a short name to the node."}]} |
|
|
|
"Gives a short name to the node."}, |
|
|
|
{script_file, undefined, "script", string, |
|
|
|
"Path to an escript file to run before " |
|
|
|
"starting the project apps. Defaults to " |
|
|
|
"rebar.config {shell, [{script_file, File}]} " |
|
|
|
"if not specified."}, |
|
|
|
{apps, undefined, "apps", string, |
|
|
|
"A list of apps to boot before starting the " |
|
|
|
"shell. (E.g. --apps app1,app2,app3) Defaults " |
|
|
|
"to rebar.config {shell, [{apps, Apps}]} or " |
|
|
|
"relx apps if not specified."}]} |
|
|
|
]) |
|
|
|
), |
|
|
|
{ok, State1}. |
|
|
@ -86,6 +97,7 @@ shell(State) -> |
|
|
|
setup_name(State), |
|
|
|
setup_paths(State), |
|
|
|
setup_shell(), |
|
|
|
maybe_run_script(State), |
|
|
|
%% apps must be started after the change in shell because otherwise |
|
|
|
%% their application masters never gets the new group leader (held in |
|
|
|
%% their internal state) |
|
|
@ -134,6 +146,51 @@ setup_paths(State) -> |
|
|
|
%% add project app test paths |
|
|
|
ok = add_test_paths(State). |
|
|
|
|
|
|
|
maybe_run_script(State) -> |
|
|
|
case first_value([fun find_script_option/1, |
|
|
|
fun find_script_rebar/1], State) of |
|
|
|
no_value -> |
|
|
|
?DEBUG("No script_file specified.", []), |
|
|
|
ok; |
|
|
|
"none" -> |
|
|
|
?DEBUG("Shell script execution skipped (--script none).", []), |
|
|
|
ok; |
|
|
|
RelFile -> |
|
|
|
File = filename:absname(RelFile), |
|
|
|
try run_script_file(File) |
|
|
|
catch |
|
|
|
C:E -> |
|
|
|
?ABORT("Couldn't run shell escript ~p - ~p:~p~nStack: ~p", |
|
|
|
[File, C, E, erlang:get_stacktrace()]) |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
-spec find_script_option(rebar_state:t()) -> no_value | list(). |
|
|
|
find_script_option(State) -> |
|
|
|
{Opts, _} = rebar_state:command_parsed_args(State), |
|
|
|
debug_get_value(script_file, Opts, no_value, |
|
|
|
"Found script file from command line option."). |
|
|
|
|
|
|
|
-spec find_script_rebar(rebar_state:t()) -> no_value | list(). |
|
|
|
find_script_rebar(State) -> |
|
|
|
Config = rebar_state:get(State, shell, []), |
|
|
|
%% Either a string, or undefined |
|
|
|
debug_get_value(script_file, Config, no_value, |
|
|
|
"Found script file from rebar config file."). |
|
|
|
|
|
|
|
run_script_file(File) -> |
|
|
|
?DEBUG("Extracting escript from ~p", [File]), |
|
|
|
{ok, Script} = escript:extract(File, [compile_source]), |
|
|
|
Beam = proplists:get_value(source, Script), |
|
|
|
Mod = proplists:get_value(module, beam_lib:info(Beam)), |
|
|
|
?DEBUG("Compiled escript as ~p", [Mod]), |
|
|
|
FakeFile = "/fake_path/" ++ atom_to_list(Mod), |
|
|
|
{module, Mod} = code:load_binary(Mod, FakeFile, Beam), |
|
|
|
?DEBUG("Evaling ~p:main([]).", [Mod]), |
|
|
|
Result = Mod:main([]), |
|
|
|
?DEBUG("Result: ~p", [Result]), |
|
|
|
Result. |
|
|
|
|
|
|
|
maybe_boot_apps(State) -> |
|
|
|
case find_apps_to_boot(State) of |
|
|
|
undefined -> |
|
|
@ -172,17 +229,42 @@ check_epmd(_) -> |
|
|
|
|
|
|
|
find_apps_to_boot(State) -> |
|
|
|
%% Try the shell_apps option |
|
|
|
case rebar_state:get(State, shell_apps, undefined) of |
|
|
|
undefined -> |
|
|
|
%% Get to the relx tuple instead |
|
|
|
case lists:keyfind(release, 1, rebar_state:get(State, relx, [])) of |
|
|
|
{_, _, Apps} -> Apps; |
|
|
|
false -> undefined |
|
|
|
end; |
|
|
|
case first_value([fun find_apps_option/1, |
|
|
|
fun find_apps_rebar/1, |
|
|
|
fun find_apps_relx/1], State) of |
|
|
|
no_value -> |
|
|
|
undefined; |
|
|
|
Apps -> |
|
|
|
Apps |
|
|
|
end. |
|
|
|
|
|
|
|
-spec find_apps_option(rebar_state:t()) -> no_value | [atom()]. |
|
|
|
find_apps_option(State) -> |
|
|
|
{Opts, _} = rebar_state:command_parsed_args(State), |
|
|
|
case debug_get_value(apps, Opts, no_value, |
|
|
|
"Found shell apps from command line option.") of |
|
|
|
no_value -> no_value; |
|
|
|
AppsStr -> |
|
|
|
[ list_to_atom(AppStr) |
|
|
|
|| AppStr <- string:tokens(AppsStr, " ,:") ] |
|
|
|
end. |
|
|
|
|
|
|
|
-spec find_apps_rebar(rebar_state:t()) -> no_value | list(). |
|
|
|
find_apps_rebar(State) -> |
|
|
|
ShellOpts = rebar_state:get(State, shell, []), |
|
|
|
debug_get_value(apps, ShellOpts, no_value, |
|
|
|
"Found shell opts from command line option."). |
|
|
|
|
|
|
|
-spec find_apps_relx(rebar_state:t()) -> no_value | list(). |
|
|
|
find_apps_relx(State) -> |
|
|
|
case lists:keyfind(release, 1, rebar_state:get(State, relx, [])) of |
|
|
|
{_, _, Apps} -> |
|
|
|
?DEBUG("Found shell apps from relx.", []), |
|
|
|
Apps; |
|
|
|
false -> |
|
|
|
no_value |
|
|
|
end. |
|
|
|
|
|
|
|
load_apps(Apps) -> |
|
|
|
[case application:load(App) of |
|
|
|
ok -> |
|
|
@ -261,31 +343,51 @@ add_test_paths(State) -> |
|
|
|
% First try the --config flag, then try the relx sys_config |
|
|
|
-spec find_config(rebar_state:t()) -> [tuple()] | no_config. |
|
|
|
find_config(State) -> |
|
|
|
case find_config_option(State) of |
|
|
|
no_config -> |
|
|
|
find_config_relx(State); |
|
|
|
Result -> |
|
|
|
Result |
|
|
|
case first_value([fun find_config_option/1, |
|
|
|
fun find_config_rebar/1, |
|
|
|
fun find_config_relx/1], State) of |
|
|
|
no_value -> |
|
|
|
no_config; |
|
|
|
Filename when is_list(Filename) -> |
|
|
|
consult_config(State, Filename) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec first_value([Fun], State) -> no_value | Value when |
|
|
|
Value :: any(), |
|
|
|
State :: rebar_state:t(), |
|
|
|
Fun :: fun ((State) -> no_value | Value). |
|
|
|
first_value([], _) -> no_value; |
|
|
|
first_value([Fun | Rest], State) -> |
|
|
|
case Fun(State) of |
|
|
|
no_value -> |
|
|
|
first_value(Rest, State); |
|
|
|
Value -> |
|
|
|
Value |
|
|
|
end. |
|
|
|
|
|
|
|
-spec find_config_option(rebar_state:t()) -> [tuple()] | no_config. |
|
|
|
debug_get_value(Key, List, Default, Description) -> |
|
|
|
case proplists:get_value(Key, List, Default) of |
|
|
|
Default -> Default; |
|
|
|
Value -> |
|
|
|
?DEBUG(Description, []), |
|
|
|
Value |
|
|
|
end. |
|
|
|
|
|
|
|
-spec find_config_option(rebar_state:t()) -> Filename::list() | no_value. |
|
|
|
find_config_option(State) -> |
|
|
|
{Opts, _} = rebar_state:command_parsed_args(State), |
|
|
|
case proplists:get_value(config, Opts) of |
|
|
|
undefined -> |
|
|
|
no_config; |
|
|
|
Filename -> |
|
|
|
consult_config(State, Filename) |
|
|
|
end. |
|
|
|
debug_get_value(config, Opts, no_value, |
|
|
|
"Found config from command line option."). |
|
|
|
|
|
|
|
-spec find_config_relx(rebar_state:t()) -> [tuple()] | no_config. |
|
|
|
-spec find_config_rebar(rebar_state:t()) -> [tuple()] | no_value. |
|
|
|
find_config_rebar(State) -> |
|
|
|
debug_get_value(config, rebar_state:get(State, shell, []), no_value, |
|
|
|
"Found config from rebar config file."). |
|
|
|
|
|
|
|
-spec find_config_relx(rebar_state:t()) -> [tuple()] | no_value. |
|
|
|
find_config_relx(State) -> |
|
|
|
case proplists:get_value(sys_config, rebar_state:get(State, relx, [])) of |
|
|
|
undefined -> |
|
|
|
no_config; |
|
|
|
Filename -> |
|
|
|
consult_config(State, Filename) |
|
|
|
end. |
|
|
|
debug_get_value(sys_config, rebar_state:get(State, relx, []), no_value, |
|
|
|
"Found config from relx."). |
|
|
|
|
|
|
|
-spec consult_config(rebar_state:t(), string()) -> [tuple()]. |
|
|
|
consult_config(State, Filename) -> |
|
|
|