Skip to content

Commit d124344

Browse files
authored
Merge pull request #116 from arpunk/14-add-config-to-repl
[#14] Add `--config` flag for the REPL
2 parents e9673d2 + f15784a commit d124344

File tree

2 files changed

+62
-7
lines changed

2 files changed

+62
-7
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@ by running for example:
4343
$ rebar3 help clojerl repl
4444
Start a clojerl repl
4545
Usage: rebar3 clojerl repl [--apps <apps>] [--sname <sname>]
46+
[--config <config>]
4647

4748
--apps List of applications that should be started separated by commas
4849
(e.g. --apps app1,app2,app3).
4950
--sname Erlang node name.
51+
--config Path to the config file to load.
5052

5153
### rebar.config options
5254

src/rebar3_clojerl_prv_repl.erl

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
-define(NAMESPACE, clojerl).
77
-define(DEPS, [{?NAMESPACE, compile}]).
88

9+
%% Redefining configuration for these apps can lead to errors.
10+
-define(APP_BLACKLIST, [inets, stdlib, kernel, rebar]).
11+
912
-type opts() :: [{atom(), any()}].
1013

1114
%% =============================================================================
@@ -21,6 +24,9 @@ init(State) ->
2124
, { sname, undefined, "sname", string
2225
, "Erlang node name."
2326
}
27+
, { config, undefined, "config", string
28+
, "Path to the config file to load."
29+
}
2430
],
2531
Provider = providers:create([ {namespace, ?NAMESPACE}
2632
, {name, ?PROVIDER}
@@ -29,7 +35,7 @@ init(State) ->
2935
, {deps, ?DEPS}
3036
, { example
3137
, "rebar3 clojerl repl "
32-
"--sname foo --apps bar,baz"
38+
"--sname foo --apps bar,baz --config sys.config"
3339
}
3440
, {opts, Opts}
3541
, {short_desc, "Start a clojerl repl"}
@@ -54,14 +60,17 @@ format_error(Reason) ->
5460
-spec repl(rebar_state:t()) -> ok.
5561
repl(State) ->
5662
maybe_restart_clojerl(),
57-
Bindings = #{<<"#'clojure.core/*compile-files*">> => false},
63+
Bindings = #{<<"#'clojure.core/*compile-files*">> => false},
64+
DepsPaths = rebar_state:code_paths(State, all_deps),
65+
{Opts, _} = rebar_state:command_parsed_args(State),
66+
AppsToStart = read_apps(proplists:get_value(apps, Opts, "")),
5867

59-
DepsPaths = rebar_state:code_paths(State, all_deps),
6068
code:add_pathsa(DepsPaths),
6169

62-
{Opts, _} = rebar_state:command_parsed_args(State),
63-
ok = maybe_start_apps(Opts),
64-
ok = rebar3_clojerl_utils:maybe_set_sname(Opts),
70+
ok = load_apps(AppsToStart),
71+
ok = maybe_apply_config(AppsToStart, State, Opts),
72+
ok = rebar3_clojerl_utils:maybe_set_sname(Opts),
73+
ok = maybe_start_apps(Opts),
6574

6675
try
6776
ok = 'clojerl.Var':push_bindings(Bindings),
@@ -89,7 +98,51 @@ maybe_start_apps(Opts) ->
8998
case proplists:get_value(apps, Opts, undefined) of
9099
undefined -> ok;
91100
AppsStr ->
92-
Apps = [list_to_atom(X) || X <- string:tokens(AppsStr, ",")],
101+
Apps = read_apps(AppsStr),
93102
[application:ensure_all_started(Name) || Name <- Apps],
94103
ok
95104
end.
105+
106+
-spec load_apps([atom()]) -> ok.
107+
load_apps(Apps) ->
108+
[ case application:load(App) of
109+
ok ->
110+
{ok, Ks} = application:get_all_key(App),
111+
%% Load dependencies as well
112+
load_apps(proplists:get_value(applications, Ks));
113+
_ -> error
114+
end
115+
|| App <- Apps
116+
],
117+
ok.
118+
119+
-spec read_config(rebar_state:t(), opts()) -> [[tuple()]] | no_config.
120+
read_config(State, Opts) ->
121+
case proplists:get_value(config, Opts, no_value) of
122+
no_value -> no_config;
123+
Filename when is_list(Filename) ->
124+
rebar_file_utils:consult_config(State, Filename)
125+
end.
126+
127+
-spec read_apps(string()) -> [atom()].
128+
read_apps(AppsStr) ->
129+
[list_to_atom(X) || X <- string:tokens(AppsStr, ",")].
130+
131+
-spec maybe_apply_config([atom()], rebar_state:t(), opts()) -> ok.
132+
maybe_apply_config(AppsToStart, State, Opts) ->
133+
case read_config(State, Opts) of
134+
no_config -> ok;
135+
ConfigList ->
136+
%% Copied from:
137+
%% https://github.com/erlang/rebar3/blob/master/src/rebar_prv_shell.erl
138+
Running = [App || {App, _, _} <- application:which_applications()],
139+
[ application:stop(App)
140+
|| Config <- ConfigList,
141+
{App, _} <- Config,
142+
lists:member(App, Running),
143+
lists:member(App, AppsToStart),
144+
not lists:member(App, ?APP_BLACKLIST)
145+
],
146+
_ = rebar_utils:reread_config(ConfigList, [update_logger]),
147+
ok
148+
end.

0 commit comments

Comments
 (0)