Skip to content

Commit

Permalink
First draft of supporting start module arg for 'rebar3 lfe repl'.
Browse files Browse the repository at this point in the history
  • Loading branch information
oubiwann committed Mar 12, 2024
1 parent 672806f commit 3e655a8
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 31 deletions.
30 changes: 19 additions & 11 deletions src/rebar3_lfe_prv_repl.erl
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@

-define(PROVIDER, repl).
-define(DEPS, [compile]).
-define(DEFAULT_CFG,
#{nobanner => false,
version => rebar3_lfe_repl:lfe_version(),
quit_message => rebar3_lfe_repl:quit_message(),
banner_template => ""
}).
%% ===================================================================
%% Public API
%% ===================================================================
Expand Down Expand Up @@ -72,6 +66,9 @@ opts() ->
{relvsn, $v, "relvsn", string,
"Version of the release to use for the shell "
"session"},
{start_module, $s, "start_module", atom,
"The module to use to override the default shell; "
"must define a start/0."},
{start_clean, undefined, "start_clean", boolean,
"Cancel any applications in the 'apps' list "
"or release."},
Expand All @@ -96,25 +93,34 @@ repl(State) ->
rebar_paths:set_paths([deps, plugins], State),
LfeCfg = rebar_state:get(State, lfe, []),
rebar_api:debug("\t\tLFECfg: ~p", [LfeCfg]),
ReplCfg = make_config(LfeCfg),
ReplOpts = cfg_opts(LfeCfg),
rebar_api:debug("\t\tReplOpts: ~p", [ReplOpts]),
{PluginOpts, _} = rebar_state:command_parsed_args(State),
Overrides = make_opts(PluginOpts),
rebar_api:debug("\t\tOverrides: ~p", [Overrides]),
Opts = maps:merge(ReplOpts, Overrides),
rebar_api:debug("\t\tOpts: ~p", [Opts]),
OTPRelease = erlang:system_info(otp_release),
if OTPRelease >= "26" ->
rebar_api:debug("\t\tRunning newer Erlang ...", []),
ShellArgs = [{shell_args, [{rebar3_lfe_repl,start,[ReplCfg]}]}],
ShellArgs = [{shell_args, [{rebar3_lfe_repl,start,[Opts]}]}],
State1 = rebar_state:set(State, shell, ShellArgs),
shell(State1),
State1;
true ->
ShellArgs = [{shell_args, ['tty_sl -c -e',{rebar3_lfe_repl,start,[ReplCfg]}]}],
ShellArgs = [{shell_args, ['tty_sl -c -e',{rebar3_lfe_repl,start,[Opts]}]}],
rebar_api:debug("\t\tShellArgs config: ~p", [ShellArgs]),
State1 = rebar_state:set(State, shell, ShellArgs),
rebar_api:debug("\t\tCalling underlying rebar3 shell 'do' function ...", []),
rebar_prv_shell:do(State1),
State1
end.

make_config(Parsed) ->
maps:merge(?DEFAULT_CFG, maps:from_list(proplists:get_value(repl, Parsed, []))).
cfg_opts(Parsed) ->
make_opts(proplists:get_value(repl, Parsed, [])).

make_opts(Proplist) ->
maps:from_list(Proplist).

%%% With Erlang 26.0 and rebar3 3.22.1+, the LFE REPL no longer loads. This is
%%% due to the following change combined with the changes in Erlang 26:
Expand Down Expand Up @@ -153,6 +159,7 @@ shell(State) ->
gen_server:enter_loop(rebar_agent, [], GenState, {local, rebar_agent}, hibernate).

setup_shell(ShellArgs) ->
rebar_api:debug("Setting up shell ...", []),
code:ensure_loaded(shell),
case erlang:function_exported(shell, start_interactive, 0) of
false ->
Expand All @@ -179,6 +186,7 @@ setup_shell(ShellArgs) ->

start_interactive(ShellArgs) ->
rebar_api:debug("*** Starting the shell w/Erlang apply ...", []),
rebar_api:debug("(using args: ~p", [ShellArgs]),
apply(shell, start_interactive, ShellArgs).

maybe_remove_logger() ->
Expand Down
63 changes: 43 additions & 20 deletions src/rebar3_lfe_repl.erl
Original file line number Diff line number Diff line change
@@ -1,35 +1,51 @@
-module(rebar3_lfe_repl).

-export([start/0, start/1]).
-export([default_opts/0]).

-export([start/0, start/1, start/3]).

-export([lfe_version/0, quit_message/0]).

start(#{nobanner := NoBnr, version := Vsn, quit_message := QuitMsg, banner_template := BnrTmpl}) ->
case BnrTmpl of
"" ->
start(NoBnr, Vsn, QuitMsg);
_ ->
Banner = banner(BnrTmpl, Vsn, QuitMsg),
start(NoBnr, Banner)
end.
-define(DEFAULT_OPTS,
#{start_module => lfe_shell,
nobanner => false,
banner => "",
banner_template => "",
banner_args => [],
%% Legacy k/vs:
version => lfe_version(),
quit_message => quit_message()
}).

default_opts() ->
?DEFAULT_OPTS.

start() ->
Vsn = lfe_version(),
QuitMsg = quit_message(),
start(false, Vsn, QuitMsg).
start(?DEFAULT_OPTS).

start(NoBnr, Vsn, QuitMsg) ->
Banner = banner(Vsn, QuitMsg),
start(NoBnr, Banner).
start(UserOpts) ->
Opts = maps:merge(?DEFAULT_OPTS, UserOpts),
rebar_api:debug("Got opts: ~p", [Opts]),
#{start_module := ReplMod,
nobanner := NoBnr,
banner := Bnr1,
banner_template := BnrTmpl,
banner_args := BnrArgs,
version := Vsn,
quit_message := QuitMsg
} = Opts,
Bnr2 = banner(Bnr1, BnrTmpl, BnrArgs, Vsn, QuitMsg),
start(ReplMod, NoBnr, Bnr2).

start(NoBnr, Bnr) ->
start(ReplMod, NoBnr, Bnr) ->
case NoBnr of
true ->
ok;
_ ->
ok = io:put_chars(erlang:whereis(user), Bnr)
end,
lfe_shell:start().
rebar_api:debug("Calling %s:start ...", [ReplMod]),
ReplMod:start().

%% XXX When the banner functions are public, delete everything below this line:
%% * https://github.com/lfe/lfe/issues/476
Expand All @@ -47,7 +63,7 @@ start(NoBnr, Bnr) ->
%%banner(Vsn) ->
%% banner(Vsn, quit_message()).

banner(Vsn, QuitMsg) ->
banner([Vsn, QuitMsg]) ->
?GRN(" ..-~") ++ ?YLW(".~_") ++ ?GRN("~---..") ++ "\n" ++
?GRN(" ( ") ++ ?YLW("\\\\") ++ ?GRN(" )") ++ " | A Lisp-2+ on the Erlang VM\n" ++
?GRN(" |`-.._") ++ ?YLW("/") ++ ?GRN("_") ++ ?YLW("\\\\") ++ ?GRN("_.-':") ++ " | Type " ++ ?GRN("(help)") ++ " for usage info.\n" ++
Expand All @@ -59,9 +75,16 @@ banner(Vsn, QuitMsg) ->
Vsn ++ " " ++ QuitMsg ++ "\n" ++
?GRN(" `-") ++ ?RED("E") ++ ?GRN("___.-'") ++ "\n\n".
banner(Tmpl, Vsn, QuitMsg) ->
[io_lib:format(Tmpl, [Vsn, QuitMsg])].
banner(Tmpl, Args) ->
[io_lib:format(Tmpl, Args)].
banner("", "", _, Vsn, QuitMsg) ->
banner([Vsn, QuitMsg]);
banner("", BnrTmpl, BnrArgs, _, _) ->
banner(BnrTmpl, BnrArgs);
banner(Bnr, _, _, _, _) ->
Bnr.
quit_message() ->
%% We can update this later to check for env variable settings for
%% shells that require a different control character to abort, such
Expand Down

0 comments on commit 3e655a8

Please sign in to comment.