diff options
author | simonxu72 <simon.xu72@gmail.com> | 2018-11-13 13:19:13 +0800 |
---|---|---|
committer | simonxu72 <simon.xu72@gmail.com> | 2018-11-13 13:19:13 +0800 |
commit | 4014faf695c3da3a8f0c7aa088cdae0725433d16 (patch) | |
tree | 9601583c4314fd1fdca3c12d657ac54b286f9d21 /src | |
parent | 41d133856bf199034b0eeb0903bedc2071fba7e1 (diff) | |
parent | d0e9a553468424b53aeb9907201d0b4f5aa4fad2 (diff) |
merge from upstream/master
Diffstat (limited to 'src')
-rw-r--r-- | src/r3.erl | 43 | ||||
-rw-r--r-- | src/rebar3.erl | 11 | ||||
-rw-r--r-- | src/rebar_agent.erl | 38 | ||||
-rw-r--r-- | src/rebar_app_discover.erl | 3 | ||||
-rw-r--r-- | src/rebar_git_resource.erl | 17 | ||||
-rw-r--r-- | src/rebar_hg_resource.erl | 19 | ||||
-rw-r--r-- | src/rebar_log.erl | 15 | ||||
-rw-r--r-- | src/rebar_utils.erl | 4 |
8 files changed, 137 insertions, 13 deletions
@@ -1,8 +1,9 @@ %%% @doc external alias for `rebar_agent' for more convenient %%% calls from a shell. -module(r3). --export([do/1, do/2]). +-export([do/1, do/2, async_do/1, async_do/2, break/0, resume/0]). -export(['$handle_undefined_function'/2]). +-include("rebar.hrl"). %% @doc alias for `rebar_agent:do/1' -spec do(atom()) -> ok | {error, term()}. @@ -12,6 +13,46 @@ do(Command) -> rebar_agent:do(Command). -spec do(atom(), atom()) -> ok | {error, term()}. do(Namespace, Command) -> rebar_agent:do(Namespace, Command). +%% @async_doc alias for `rebar_agent:async_do/1' +-spec async_do(atom()) -> ok | {error, term()}. +async_do(Command) -> rebar_agent:async_do(Command). + +%% @async_doc alias for `rebar_agent:async_do/2' +-spec async_do(atom(), atom()) -> ok | {error, term()}. +async_do(Namespace, Command) -> rebar_agent:async_do(Namespace, Command). + +break() -> + case whereis(rebar_agent) of % is the shell running + undefined -> + ok; + Pid -> + {dictionary, Dict} = process_info(Pid, dictionary), + case lists:keyfind(cmd_type, 1, Dict) of + {cmd_type, async} -> + Self = self(), + Ref = make_ref(), + spawn_link(fun() -> + register(r3_breakpoint_handler, self()), + receive + resume -> + Self ! Ref + end + end), + io:format(user, "~n=== BREAK ===~n", []), + receive + Ref -> ok + end; + _ -> + ?DEBUG("ignoring breakpoint since command is not run " + "in async mode", []), + ok + end + end. + +resume() -> + r3_breakpoint_handler ! resume, + ok. + %% @private defer to rebar_agent '$handle_undefined_function'(Cmd, Args) -> rebar_agent:'$handle_undefined_function'(Cmd, Args). diff --git a/src/rebar3.erl b/src/rebar3.erl index 059d530..a490a15 100644 --- a/src/rebar3.erl +++ b/src/rebar3.erl @@ -402,18 +402,21 @@ state_from_global_config(Config, GlobalConfigFile) -> Resources = application:get_env(rebar, resources, []), GlobalConfigThrowAway = rebar_state:create_resources(Resources, GlobalConfigThrowAway0), - GlobalState = case rebar_state:get(GlobalConfigThrowAway, plugins, []) of + Compilers = application:get_env(rebar, compilers, []), + GlobalConfigThrowAway1 = rebar_state:compilers(GlobalConfigThrowAway, Compilers), + + GlobalState = case rebar_state:get(GlobalConfigThrowAway1, plugins, []) of [] -> - GlobalConfigThrowAway; + GlobalConfigThrowAway1; GlobalPluginsToInstall -> rebar_plugins:handle_plugins(global, GlobalPluginsToInstall, - GlobalConfigThrowAway) + GlobalConfigThrowAway1) end, GlobalPlugins = rebar_state:providers(GlobalState), GlobalConfig2 = rebar_state:set(GlobalConfig, plugins, []), GlobalConfig3 = rebar_state:set(GlobalConfig2, {plugins, global}, - rebar_state:get(GlobalConfigThrowAway, plugins, [])), + rebar_state:get(GlobalConfigThrowAway1, plugins, [])), rebar_state:providers(rebar_state:new(GlobalConfig3, Config), GlobalPlugins). -spec test_state(rebar_state:t()) -> [{'extra_src_dirs',[string()]} | {'erl_opts',[any()]}]. diff --git a/src/rebar_agent.erl b/src/rebar_agent.erl index 445ae54..b4734f1 100644 --- a/src/rebar_agent.erl +++ b/src/rebar_agent.erl @@ -1,7 +1,7 @@ %%% @doc Runs a process that holds a rebar3 state and can be used %%% to statefully maintain loaded project state into a running VM. -module(rebar_agent). --export([start_link/1, do/1, do/2]). +-export([start_link/1, do/1, do/2, async_do/1, async_do/2]). -export(['$handle_undefined_function'/2]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -35,6 +35,18 @@ do(Namespace, Command) when is_atom(Namespace), is_atom(Command) -> do(Namespace, Args) when is_atom(Namespace), is_list(Args) -> gen_server:call(?MODULE, {cmd, Namespace, do, Args}, infinity). +-spec async_do(atom()) -> ok | {error, term()}. +async_do(Command) when is_atom(Command) -> + gen_server:cast(?MODULE, {cmd, Command}); +async_do(Args) when is_list(Args) -> + gen_server:cast(?MODULE, {cmd, default, do, Args}). + +-spec async_do(atom(), atom()) -> ok. +async_do(Namespace, Command) when is_atom(Namespace), is_atom(Command) -> + gen_server:cast(?MODULE, {cmd, Namespace, Command}); +async_do(Namespace, Args) when is_atom(Namespace), is_list(Args) -> + gen_server:cast(?MODULE, {cmd, Namespace, do, Args}). + '$handle_undefined_function'(Cmd, [Namespace, Args]) -> gen_server:call(?MODULE, {cmd, Namespace, Cmd, Args}, infinity); '$handle_undefined_function'(Cmd, [Args]) -> @@ -54,20 +66,44 @@ init(State) -> %% @private handle_call({cmd, Command}, _From, State=#state{state=RState, cwd=Cwd}) -> MidState = maybe_show_warning(State), + put(cmd_type, sync), {Res, NewRState} = run(default, Command, "", RState, Cwd), + put(cmd_type, undefined), {reply, Res, MidState#state{state=NewRState}, hibernate}; handle_call({cmd, Namespace, Command}, _From, State = #state{state=RState, cwd=Cwd}) -> MidState = maybe_show_warning(State), + put(cmd_type, sync), {Res, NewRState} = run(Namespace, Command, "", RState, Cwd), + put(cmd_type, undefined), {reply, Res, MidState#state{state=NewRState}, hibernate}; handle_call({cmd, Namespace, Command, Args}, _From, State = #state{state=RState, cwd=Cwd}) -> MidState = maybe_show_warning(State), + put(cmd_type, sync), {Res, NewRState} = run(Namespace, Command, Args, RState, Cwd), + put(cmd_type, undefined), {reply, Res, MidState#state{state=NewRState}, hibernate}; handle_call(_Call, _From, State) -> {noreply, State}. %% @private +handle_cast({cmd, Command}, State=#state{state=RState, cwd=Cwd}) -> + MidState = maybe_show_warning(State), + put(cmd_type, async), + {_, NewRState} = run(default, Command, "", RState, Cwd), + put(cmd_type, undefined), + {noreply, MidState#state{state=NewRState}, hibernate}; +handle_cast({cmd, Namespace, Command}, State = #state{state=RState, cwd=Cwd}) -> + MidState = maybe_show_warning(State), + put(cmd_type, async), + {_, NewRState} = run(Namespace, Command, "", RState, Cwd), + put(cmd_type, undefined), + {noreply, MidState#state{state=NewRState}, hibernate}; +handle_cast({cmd, Namespace, Command, Args}, State = #state{state=RState, cwd=Cwd}) -> + MidState = maybe_show_warning(State), + put(cmd_type, async), + {_, NewRState} = run(Namespace, Command, Args, RState, Cwd), + put(cmd_type, undefined), + {noreply, MidState#state{state=NewRState}, hibernate}; handle_cast(_Cast, State) -> {noreply, State}. diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index 74681c7..21dea29 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -280,7 +280,8 @@ find_apps(LibDirs, SrcDirs, Validate, State) -> -spec find_app(file:filename_all(), valid | invalid | all) -> {true, rebar_app_info:t()} | false. find_app(AppDir, Validate) -> {Config, SrcDirs} = find_config_src(AppDir, ["src"]), - AppInfo = rebar_app_info:update_opts(rebar_app_info:new(), dict:new(), Config), + AppInfo = rebar_app_info:update_opts(rebar_app_info:dir(rebar_app_info:new(), AppDir), + dict:new(), Config), find_app_(AppInfo, AppDir, SrcDirs, Validate). %% @doc check that a given app in a directory is there, and whether it's diff --git a/src/rebar_git_resource.erl b/src/rebar_git_resource.erl index cec7dfc..0ca6627 100644 --- a/src/rebar_git_resource.erl +++ b/src/rebar_git_resource.erl @@ -21,6 +21,7 @@ init(Type, _State) -> {ok, Resource}. lock(AppInfo, _) -> + check_type_support(), lock_(rebar_app_info:dir(AppInfo), rebar_app_info:source(AppInfo)). lock_(AppDir, {git, Url, _}) -> @@ -43,6 +44,7 @@ lock_(AppDir, {git, Url}) -> %% Return true if either the git url or tag/branch/ref is not the same as the currently %% checked out git repo for the dep needs_update(AppInfo, _) -> + check_type_support(), needs_update_(rebar_app_info:dir(AppInfo), rebar_app_info:source(AppInfo)). needs_update_(Dir, {git, Url, {tag, Tag}}) -> @@ -111,6 +113,7 @@ parse_git_url(not_scp, Url) -> end. download(TmpDir, AppInfo, State, _) -> + check_type_support(), case download_(TmpDir, rebar_app_info:source(AppInfo), State) of {ok, _} -> ok; @@ -324,4 +327,18 @@ git_clone_options() -> ?DEBUG("Git clone Option = ~p",[Option]), Option. +check_type_support() -> + case get({is_supported, ?MODULE}) of + true -> + ok; + _ -> + case rebar_utils:sh("git --version", [{return_on_error, true}, + {use_stdout, false}]) of + {error, _} -> + ?ABORT("git not installed", []); + _ -> + put({is_supported, ?MODULE}, true), + ok + end + end. diff --git a/src/rebar_hg_resource.erl b/src/rebar_hg_resource.erl index 21d4b9d..8139d04 100644 --- a/src/rebar_hg_resource.erl +++ b/src/rebar_hg_resource.erl @@ -18,6 +18,7 @@ init(Type, _State) -> {ok, Resource}. lock(AppInfo, _) -> + check_type_support(), lock_(rebar_app_info:dir(AppInfo), rebar_app_info:source(AppInfo)). lock_(AppDir, {hg, Url, _}) -> @@ -61,6 +62,7 @@ needs_update_(Dir, {hg, Url, Ref}) -> not ((LocalRef =:= TargetRef) andalso compare_url(Dir, Url)). download(TmpDir, AppInfo, State, _) -> + check_type_support(), case download_(TmpDir, rebar_app_info:source(AppInfo), State) of {ok, _} -> ok; @@ -110,6 +112,7 @@ download_(Dir, {hg, Url, Rev}, _State) -> [{cd, filename:dirname(Dir)}]). make_vsn(AppInfo, _) -> + check_type_support(), make_vsn_(rebar_app_info:dir(AppInfo)). make_vsn_(Dir) -> @@ -183,3 +186,19 @@ parse_hg_url("http://" ++ HostPath) -> parse_hg_url("https://" ++ HostPath) -> [Host | Path] = rebar_string:lexemes(HostPath, "/"), {Host, filename:rootname(filename:join(Path), ".hg")}. + +check_type_support() -> + case get({is_supported, ?MODULE}) of + true -> + ok; + false -> + case rebar_utils:sh("hg --version", [{return_on_error, true}, + {use_stdout, false}]) of + {error, _} -> + ?ABORT("hg not installed", []); + _ -> + put({is_supported, ?MODULE}, true), + ok + end + end. + diff --git a/src/rebar_log.erl b/src/rebar_log.erl index 9150346..7fc2312 100644 --- a/src/rebar_log.erl +++ b/src/rebar_log.erl @@ -93,11 +93,18 @@ get_level() -> end. log(Level = error, Str, Args) -> - {ok, LogState} = application:get_env(rebar, log), - ec_cmd_log:Level(LogState, lists:flatten(cf:format("~!^~ts~n", [Str])), Args); + case application:get_env(rebar, log) of + {ok, LogState} -> + NewStr = lists:flatten(cf:format("~!^~ts~n", [Str])), + ec_cmd_log:Level( LogState, NewStr, Args); + undefined -> % fallback + io:format(standard_error, Str++"~n", Args) + end; log(Level, Str, Args) -> - {ok, LogState} = application:get_env(rebar, log), - ec_cmd_log:Level(LogState, Str++"~n", Args). + case application:get_env(rebar, log) of + {ok, LogState} -> ec_cmd_log:Level(LogState, Str++"~n", Args); + undefined -> io:format(Str++"~n", Args) + end. crashdump(Str, Args) -> crashdump("rebar3.crashdump", Str, Args). diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 1769b79..11add61 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -156,7 +156,7 @@ sh_send(Command0, String, Options0) -> Options = [expand_sh_flag(V) || V <- proplists:compact(Options0 ++ DefaultOptions)], - Command = lists:flatten(patch_on_windows(Command0, proplists:get_value(env, Options, []))), + Command = lists:flatten(patch_on_windows(Command0, proplists:get_value(env, Options0, []))), PortSettings = proplists:get_all_values(port_settings, Options) ++ [exit_status, {line, 16384}, use_stdio, stderr_to_stdout, hide], Port = open_port({spawn, Command}, PortSettings), @@ -187,7 +187,7 @@ sh(Command0, Options0) -> ErrorHandler = proplists:get_value(error_handler, Options), OutputHandler = proplists:get_value(output_handler, Options), - Command = lists:flatten(patch_on_windows(Command0, proplists:get_value(env, Options, []))), + Command = lists:flatten(patch_on_windows(Command0, proplists:get_value(env, Options0, []))), PortSettings = proplists:get_all_values(port_settings, Options) ++ [exit_status, {line, 16384}, use_stdio, stderr_to_stdout, hide, eof], ?DEBUG("Port Cmd: ~ts\nPort Opts: ~p\n", [Command, PortSettings]), |