Pārlūkot izejas kodu

Rebar agent reloads the config file on every run

This allows proper checking of new configurations, deps, or plugins, and
makes sure they are detected during an active shell session.
pull/473/head
Fred Hebert pirms 10 gadiem
vecāks
revīzija
3de325aa49
2 mainītis faili ar 68 papildinājumiem un 35 dzēšanām
  1. +67
    -34
      src/rebar_agent.erl
  2. +1
    -1
      src/rebar_prv_shell.erl

+ 67
- 34
src/rebar_agent.erl Parādīt failu

@ -4,6 +4,8 @@
handle_call/3, handle_cast/2, handle_info/2, handle_call/3, handle_cast/2, handle_info/2,
code_change/3, terminate/2]). code_change/3, terminate/2]).
-include("rebar.hrl").
-record(state, {state, -record(state, {state,
cwd}). cwd}).
@ -16,39 +18,16 @@ do(Command) when is_atom(Command) ->
do(Namespace, Command) when is_atom(Namespace), is_atom(Command) -> do(Namespace, Command) when is_atom(Namespace), is_atom(Command) ->
gen_server:call(?MODULE, {cmd, Namespace, Command}, infinity). gen_server:call(?MODULE, {cmd, Namespace, Command}, infinity).
init(State0) ->
Cwd = file:get_cwd(),
State = rebar_state:update_code_paths(State0, default, code:get_path()),
init(State) ->
{ok, Cwd} = file:get_cwd(),
{ok, #state{state=State, cwd=Cwd}}. {ok, #state{state=State, cwd=Cwd}}.
handle_call({cmd, Command}, _From, State=#state{state=RState, cwd=Cwd}) -> handle_call({cmd, Command}, _From, State=#state{state=RState, cwd=Cwd}) ->
Res = try
case file:get_cwd() of
Cwd ->
case rebar_core:process_command(RState, Command) of
{ok, _} ->
refresh(RState),
ok;
{error, Err} when is_list(Err) ->
refresh(RState),
{error, lists:flatten(Err)};
{error, Err} ->
refresh(RState),
{error, Err}
end;
_ ->
{error, cwd_changed}
end
catch
Type:Reason ->
{error, {Type, Reason}}
end,
{reply, Res, State};
handle_call({cmd, Namespace, Command}, From, State = #state{state=RState}) ->
{reply, Res, _} = handle_call({cmd, Command}, From, State#state{
state = rebar_state:namespace(RState, Namespace)
}),
{reply, Res, State};
{Res, NewRState} = run(default, Command, RState, Cwd),
{reply, Res, State#state{state=NewRState}};
handle_call({cmd, Namespace, Command}, _From, State = #state{state=RState, cwd=Cwd}) ->
{Res, NewRState} = run(Namespace, Command, RState, Cwd),
{reply, Res, State#state{state=NewRState}};
handle_call(_Call, _From, State) -> handle_call(_Call, _From, State) ->
{noreply, State}. {noreply, State}.
@ -64,8 +43,62 @@ code_change(_OldVsn, State, _Extra) ->
terminate(_Reason, _State) -> terminate(_Reason, _State) ->
ok. ok.
refresh(RState) ->
ToRefresh = rebar_state:code_paths(RState, all_deps)
run(Namespace, Command, RState, Cwd) ->
try
case file:get_cwd() of
{ok, Cwd} ->
Args = [atom_to_list(Namespace), atom_to_list(Command)],
CmdState0 = refresh_state(RState, Cwd),
CmdState1 = rebar_state:set(CmdState0, task, atom_to_list(Command)),
CmdState = rebar_state:set(CmdState1, caller, api),
case rebar3:run(CmdState, Args) of
{ok, TmpState} ->
refresh_paths(TmpState),
{ok, CmdState};
{error, Err} when is_list(Err) ->
refresh_paths(CmdState),
{{error, lists:flatten(Err)}, CmdState};
{error, Err} ->
refresh_paths(CmdState),
{{error, Err}, CmdState}
end;
_ ->
{{error, cwd_changed}, RState}
end
catch
Type:Reason ->
?DEBUG("Agent Stacktrace: ~p", [erlang:get_stacktrace()]),
{{error, {Type, Reason}}, RState}
end.
refresh_paths(RState) ->
ToRefresh = (rebar_state:code_paths(RState, all_deps)
%% TODO: add plugin paths here when the other change is merged
++ [filename:join([rebar_app_info:out_dir(App), "test"])
|| App <- rebar_state:project_apps(RState)]
%% make sure to never reload self; halt()s the VM %% make sure to never reload self; halt()s the VM
-- [filename:dirname(code:which(?MODULE))],
rebar_utils:update_code(ToRefresh).
) -- [filename:dirname(code:which(?MODULE))],
%% Similar to rebar_utils:update_code/1, but also forces a reload
%% of used modules.
lists:foreach(fun(Path) ->
Name = filename:basename(Path, "/ebin"),
App = list_to_atom(Name),
application:load(App),
case application:get_key(App, modules) of
undefined ->
code:add_patha(Path),
ok;
{ok, Modules} ->
?DEBUG("reloading ~p from ~s", [Modules, Path]),
code:replace_path(Name, Path),
[begin code:purge(M), code:delete(M), code:load_file(M) end
|| M <- Modules]
end
end, ToRefresh).
refresh_state(RState, _Dir) ->
lists:foldl(
fun(F, State) -> F(State) end,
rebar3:init_config(),
[fun(S) -> rebar_state:current_profiles(S, rebar_state:current_profiles(RState)) end]
).

+ 1
- 1
src/rebar_prv_shell.erl Parādīt failu

@ -82,8 +82,8 @@ shell(State) ->
setup_paths(State), setup_paths(State),
ok = reread_config(State), ok = reread_config(State),
maybe_boot_apps(State), maybe_boot_apps(State),
rebar_agent:start_link(State),
setup_shell(), setup_shell(),
rebar_agent:start_link(State),
%% try to read in sys.config file %% try to read in sys.config file
%% this call never returns (until user quits shell) %% this call never returns (until user quits shell)
timer:sleep(infinity). timer:sleep(infinity).

Notiek ielāde…
Atcelt
Saglabāt