diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | THANKS | 1 | ||||
-rw-r--r-- | priv/templates/app_rebar.config | 2 | ||||
-rw-r--r-- | priv/templates/gitignore | 1 | ||||
-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 | ||||
-rw-r--r-- | test/rebar_hooks_SUITE.erl | 6 |
13 files changed, 144 insertions, 18 deletions
@@ -77,7 +77,7 @@ The rebar3 escript can also extract itself with a run script under the user's ho $ ./rebar3 local install ===> Extracting rebar3 libs to ~/.cache/rebar3/lib... ===> Writing rebar3 run script ~/.cache/rebar3/bin/rebar3... -===> Add to $PATH for use: export PATH=$PATH:~/.cache/rebar3/bin +===> Add to $PATH for use: export PATH=~/.cache/rebar3/bin:$PATH ``` To keep it up to date after you've installed rebar3 this way you can use `rebar3 local upgrade` which @@ -140,3 +140,4 @@ Heinz N. Gies Roberto Aloi Andrew McRobb Drew Varner +Niklas Johansson diff --git a/priv/templates/app_rebar.config b/priv/templates/app_rebar.config index 203ce4a..a3f5b8c 100644 --- a/priv/templates/app_rebar.config +++ b/priv/templates/app_rebar.config @@ -2,6 +2,6 @@ {deps, []}. {shell, [ - % {config, [{config, "config/sys.config"}]}, + % {config, "config/sys.config"}, {apps, [{{name}}]} ]}. diff --git a/priv/templates/gitignore b/priv/templates/gitignore index 40ca652..f1c4554 100644 --- a/priv/templates/gitignore +++ b/priv/templates/gitignore @@ -16,3 +16,4 @@ _build .idea *.iml rebar3.crashdump +*~ @@ -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]), diff --git a/test/rebar_hooks_SUITE.erl b/test/rebar_hooks_SUITE.erl index aae7ea0..29e343f 100644 --- a/test/rebar_hooks_SUITE.erl +++ b/test/rebar_hooks_SUITE.erl @@ -84,7 +84,7 @@ run_hooks_once(Config) -> Name = rebar_test_utils:create_random_name("app1_"), Vsn = rebar_test_utils:create_random_vsn(), - RebarConfig = [{pre_hooks, [{compile, "mkdir $REBAR_ROOT_DIR/blah"}]}], + RebarConfig = [{pre_hooks, [{compile, "mkdir \"$REBAR_ROOT_DIR/blah\""}]}], rebar_test_utils:create_config(AppDir, RebarConfig), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:run_and_check(Config, RebarConfig, ["compile"], {ok, [{app, Name, valid}]}). @@ -96,7 +96,7 @@ run_hooks_once_profiles(Config) -> Name = rebar_test_utils:create_random_name("app1_"), Vsn = rebar_test_utils:create_random_vsn(), - RebarConfig = [{profiles, [{hooks, [{pre_hooks, [{compile, "mkdir $REBAR_ROOT_DIR/blah"}]}]}]}], + RebarConfig = [{profiles, [{hooks, [{pre_hooks, [{compile, "mkdir \"$REBAR_ROOT_DIR/blah\""}]}]}]}], rebar_test_utils:create_config(AppDir, RebarConfig), rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:run_and_check(Config, RebarConfig, ["as", "hooks", "compile"], {ok, [{app, Name, valid}]}). @@ -236,7 +236,7 @@ root_hooks(Config) -> rebar_test_utils:create_app(SubAppsDir, Name, Vsn, [kernel, stdlib]), rebar_test_utils:create_config(SubAppsDir, [{provider_hooks, [{post, [{compile, clean}]}]}]), - RConfFile = rebar_test_utils:create_config(AppDir, [{pre_hooks, [{compile, "mkdir $REBAR_ROOT_DIR/blah"}]}]), + RConfFile = rebar_test_utils:create_config(AppDir, [{pre_hooks, [{compile, "mkdir \"$REBAR_ROOT_DIR/blah\""}]}]), {ok, RConf} = file:consult(RConfFile), %% Build with deps. |