mirror of
https://github.com/correl/rebar.git
synced 2024-11-23 19:19:54 +00:00
improve behaviour of rebar shell
attempt to emulate the behavior of `erl -pa ebin -pa deps/*/ebin` fix error messages and formatting issues of `rebar shell` by shutting down and restarting the user subsystem in a mode more hospitable to the shell than the simple user started when run as an escript. emulate `error_logger` behaviour when the shell is run via `erl` add documentation of the shell command limitations: the erlang interrupt handler is not enabled when running as an escript and there is no interface to re-enable it via erlang code. this means `ctrl-c` will immediately exit the running process unlike when running the shell via `erl`. `ctrl-g` is, however, unaffected the user subsystem is killed and restarted but not supervised. if your code somehow relies on the user subsystem crashing and restarting `rebar shell` may interfere with it's operation
This commit is contained in:
parent
93621d0d0c
commit
89cd24937e
3 changed files with 38 additions and 21 deletions
1
THANKS
1
THANKS
|
@ -123,3 +123,4 @@ Dave Thomas
|
||||||
Evgeniy Khramtsov
|
Evgeniy Khramtsov
|
||||||
YeJun Su
|
YeJun Su
|
||||||
Yuki Ito
|
Yuki Ito
|
||||||
|
alisdair sullivan
|
||||||
|
|
|
@ -409,6 +409,9 @@ qc Test QuickCheck properties
|
||||||
|
|
||||||
xref Run cross reference analysis
|
xref Run cross reference analysis
|
||||||
|
|
||||||
|
shell Start a shell similar to
|
||||||
|
'erl -pa ebin -pa deps/*/ebin'
|
||||||
|
|
||||||
help Show the program options
|
help Show the program options
|
||||||
version Show version information
|
version Show version information
|
||||||
">>,
|
">>,
|
||||||
|
|
|
@ -30,27 +30,40 @@
|
||||||
|
|
||||||
-include("rebar.hrl").
|
-include("rebar.hrl").
|
||||||
|
|
||||||
-export([shell/2]).
|
-export([shell/2, info/2]).
|
||||||
|
|
||||||
|
%% NOTE:
|
||||||
|
%% this is an attempt to replicate `erl -pa ./ebin -pa deps/*/ebin`. it is
|
||||||
|
%% mostly successful but does stop and then restart the user io system to get
|
||||||
|
%% around issues with rebar being an escript and starting in `noshell` mode.
|
||||||
|
%% it also lacks the ctrl-c interrupt handler that `erl` features. ctrl-c will
|
||||||
|
%% immediately kill the script. ctrl-g, however, works fine
|
||||||
|
|
||||||
shell(_Config, _AppFile) ->
|
shell(_Config, _AppFile) ->
|
||||||
?CONSOLE("NOTICE: Using experimental 'shell' command~n", []),
|
|
||||||
%% backwards way to say we only want this executed
|
|
||||||
%% for the "top level" directory
|
|
||||||
case is_deps_dir(rebar_utils:get_cwd()) of
|
|
||||||
false ->
|
|
||||||
true = code:add_pathz(rebar_utils:ebin_dir()),
|
true = code:add_pathz(rebar_utils:ebin_dir()),
|
||||||
|
%% terminate the current user
|
||||||
|
ok = supervisor:terminate_child(kernel_sup, user),
|
||||||
|
%% start a new shell (this also starts a new user under the correct group)
|
||||||
user_drv:start(),
|
user_drv:start(),
|
||||||
|
%% enable error_logger's tty output
|
||||||
|
ok = error_logger:swap_handler(tty),
|
||||||
|
%% disable the simple error_logger (which may have been added multiple
|
||||||
|
%% times). removes at most the error_logger added by init and the
|
||||||
|
%% error_logger added by the tty handler
|
||||||
|
ok = remove_error_handler(3),
|
||||||
%% this call never returns (until user quits shell)
|
%% this call never returns (until user quits shell)
|
||||||
shell:server(false, false);
|
timer:sleep(infinity).
|
||||||
true ->
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
ok.
|
|
||||||
|
|
||||||
is_deps_dir(Dir) ->
|
info(help, shell) ->
|
||||||
case lists:reverse(filename:split(Dir)) of
|
?CONSOLE(
|
||||||
[_, "deps" | _] ->
|
"Start a shell with project and deps preloaded similar to~n"
|
||||||
true;
|
"'erl -pa ebin -pa deps/*/ebin'.~n",
|
||||||
_V ->
|
[]).
|
||||||
false
|
|
||||||
|
remove_error_handler(0) ->
|
||||||
|
?WARN("Unable to remove simple error_logger handler~n", []);
|
||||||
|
remove_error_handler(N) ->
|
||||||
|
case gen_event:delete_handler(error_logger, error_logger, []) of
|
||||||
|
{error, module_not_found} -> ok;
|
||||||
|
{error_logger, _} -> remove_error_handler(N-1)
|
||||||
end.
|
end.
|
Loading…
Reference in a new issue