From 52ca7795feb001f0624ec87e717e3019f8a810bd Mon Sep 17 00:00:00 2001 From: Juhani Rankimies Date: Sun, 5 Dec 2010 02:07:12 +0200 Subject: Unify executable invocation Add flags to rebar_utils:sh to control output and error handling. Replace calls to os:cmd with calls to rebar_utils:sh. --- src/rebar_utils.erl | 106 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 31 deletions(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 98fdbd7..ae27455 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -30,8 +30,7 @@ is_arch/1, get_arch/0, get_os/0, - sh/2, sh/3, - sh_failfast/2, + sh/2, find_files/2, now_str/0, ensure_dir/1, @@ -73,36 +72,49 @@ get_os() -> ArchAtom end. +%% +%% Options = [Option] -- defaults to [use_stdout, abort_on_error] +%% Option = ErrorOption | OutputOption | {cd, string()} | {env, Env} +%% ErrorOption = return_on_error | abort_on_error | {abort_on_error, string()} +%% OutputOption = use_stdout | {use_stdout, bool()} +%% Env = [{string(), Val}] +%% Val = string() | false +%% +sh(Command0, Options0) -> + ?INFO("sh: ~s\n~p\n", [Command0, Options0]), -sh(Command, Env) -> - sh(Command, Env, get_cwd()). + DefaultOptions = [use_stdout, abort_on_error], + Options = lists:map(fun expand_sh_flag/1, + proplists:compact(Options0 ++ DefaultOptions)), -sh(Command0, Env, Dir) -> - ?INFO("sh: ~s\n~p\n", [Command0, Env]), - Command = patch_on_windows(Command0, os:type()), - Port = open_port({spawn, Command}, [{cd, Dir}, {env, Env}, exit_status, {line, 16384}, - use_stdio, stderr_to_stdout]), - case sh_loop(Port) of - ok -> - ok; + ErrorHandler = proplists:get_value(error_handler, Options), + OutputHandler = proplists:get_value(output_handler, Options), + + Command = patch_on_windows(Command0), + PortSettings = proplists:get_all_values(port_settings, Options) ++ + [exit_status, {line, 16384}, use_stdio, stderr_to_stdout, hide], + Port = open_port({spawn, Command}, PortSettings), + + case sh_loop(Port, OutputHandler, []) of + {ok, Output} -> + {ok, Output}; {error, Rc} -> - ?ABORT("~s failed with error: ~w\n", [Command, Rc]) + ErrorHandler(Command, Rc) end. - %% We need a bash shell to execute on windows %% also the port doesn't seem to close from time to time (mingw) -patch_on_windows(Cmd, {win32,nt}) -> - case find_executable("bash") of - false -> Cmd; - Bash -> - Bash ++ " -c \"" ++ Cmd ++ "; echo _port_cmd_status_ $?\" " - end; -patch_on_windows(Command, _) -> - Command. - -sh_failfast(Command, Env) -> - sh(Command, Env). +patch_on_windows(Cmd) -> + case os:type() of + {win32,nt} -> + case find_executable("bash") of + false -> Cmd; + Bash -> + Bash ++ " -c \"" ++ Cmd ++ "; echo _port_cmd_status_ $?\" " + end; + _ -> + Cmd + end. find_files(Dir, Regex) -> filelib:fold_files(Dir, Regex, true, fun(F, Acc) -> [F | Acc] end, []). @@ -162,19 +174,51 @@ match_first([{Regex, MatchValue} | Rest], Val) -> match_first(Rest, Val) end. -sh_loop(Port) -> +expand_sh_flag(return_on_error) -> + {error_handler, + fun(_Command, Rc) -> + {error, Rc} + end}; +expand_sh_flag({abort_on_error, Message}) -> + {error_handler, + fun(_Command, _Rc) -> + ?ABORT(Message, []) + end}; +expand_sh_flag(abort_on_error) -> + {error_handler, + fun(Command, Rc) -> + ?ABORT("~s failed with error: ~w\n", [Command, Rc]) + end}; +expand_sh_flag(use_stdout) -> + {output_handler, + fun(Line, Acc) -> + ?CONSOLE("~s", [Line]), + [Acc | Line] + end}; +expand_sh_flag({use_stdout, false}) -> + {output_handler, + fun(Line, Acc) -> + [Acc | Line] + end}; +expand_sh_flag({cd, Dir}) -> + {port_settings, {cd, Dir}}; +expand_sh_flag({env, Env}) -> + {port_settings, {env, Env}}. + +sh_loop(Port, Fun, Acc) -> receive {Port, {data, {_, "_port_cmd_status_ " ++ Status}}} -> (catch erlang:port_close(Port)), % sigh () for indentation case list_to_integer(Status) of - 0 -> ok; + 0 -> {ok, lists:flatten(Acc)}; Rc -> {error, Rc} end; - {Port, {data, {_, Line}}} -> - ?CONSOLE("~s\n", [Line]), - sh_loop(Port); + {Port, {data, {eol, Line}}} -> + sh_loop(Port, Fun, Fun(Line ++ "\n", Acc)); + {Port, {data, {noeol, Line}}} -> + sh_loop(Port, Fun, Fun(Line, Acc)); {Port, {exit_status, 0}} -> - ok; + {ok, lists:flatten(Acc)}; {Port, {exit_status, Rc}} -> {error, Rc} end. -- cgit v1.1 From 220eec71f6f83e611dad1238c5f5b47d6ef99c22 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Sat, 8 Jan 2011 19:47:17 +0100 Subject: Remove unused fun rebar_utils:get_os/0 --- src/rebar_utils.erl | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index ae27455..7dbb8f7 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -29,7 +29,6 @@ -export([get_cwd/0, is_arch/1, get_arch/0, - get_os/0, sh/2, find_files/2, now_str/0, @@ -63,15 +62,6 @@ get_arch() -> Words = integer_to_list(8 * erlang:system_info(wordsize)), erlang:system_info(system_architecture) ++ "-" ++ Words. -get_os() -> - Arch = erlang:system_info(system_architecture), - case match_first([{"linux", linux}, {"darwin", darwin}], Arch) of - nomatch -> - {unknown, Arch}; - ArchAtom -> - ArchAtom - end. - %% %% Options = [Option] -- defaults to [use_stdout, abort_on_error] %% Option = ErrorOption | OutputOption | {cd, string()} | {env, Env} @@ -164,16 +154,6 @@ find_executable(Name) -> %% Internal functions %% ==================================================================== -match_first([], _Val) -> - nomatch; -match_first([{Regex, MatchValue} | Rest], Val) -> - case re:run(Val, Regex, [{capture, none}]) of - match -> - MatchValue; - nomatch -> - match_first(Rest, Val) - end. - expand_sh_flag(return_on_error) -> {error_handler, fun(_Command, Rc) -> -- cgit v1.1 From 5a371496422a60b6ce6d409d680ea9107eefb019 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Fri, 7 Jan 2011 12:48:22 +0100 Subject: Fix Dialyzer warning --- src/rebar_utils.erl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 7dbb8f7..17fb95a 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -166,9 +166,7 @@ expand_sh_flag({abort_on_error, Message}) -> end}; expand_sh_flag(abort_on_error) -> {error_handler, - fun(Command, Rc) -> - ?ABORT("~s failed with error: ~w\n", [Command, Rc]) - end}; + fun log_and_abort/2}; expand_sh_flag(use_stdout) -> {output_handler, fun(Line, Acc) -> @@ -185,6 +183,10 @@ expand_sh_flag({cd, Dir}) -> expand_sh_flag({env, Env}) -> {port_settings, {env, Env}}. +-spec log_and_abort(string(), integer()) -> no_return(). +log_and_abort(Command, Rc) -> + ?ABORT("~s failed with error: ~w\n", [Command, Rc]). + sh_loop(Port, Fun, Acc) -> receive {Port, {data, {_, "_port_cmd_status_ " ++ Status}}} -> -- cgit v1.1 From 5b05e54cda77d6e45fd6d1cc8ea1dabfafa6bcb1 Mon Sep 17 00:00:00 2001 From: Joseph Wayne Norton Date: Sun, 9 Jan 2011 16:06:51 +0100 Subject: Add otp_release to platform string --- src/rebar_utils.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 17fb95a..f49969a 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -60,7 +60,8 @@ is_arch(ArchRegex) -> get_arch() -> Words = integer_to_list(8 * erlang:system_info(wordsize)), - erlang:system_info(system_architecture) ++ "-" ++ Words. + erlang:system_info(otp_release) ++ "-" + ++ erlang:system_info(system_architecture) ++ "-" ++ Words. %% %% Options = [Option] -- defaults to [use_stdout, abort_on_error] -- cgit v1.1 From e4036cbe56de29be1a4773d459c87700884f17d0 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Sat, 8 Jan 2011 19:09:24 +0100 Subject: Apply Tidier suggestions --- src/rebar_utils.erl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index f49969a..a9ed9a0 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -75,8 +75,8 @@ sh(Command0, Options0) -> ?INFO("sh: ~s\n~p\n", [Command0, Options0]), DefaultOptions = [use_stdout, abort_on_error], - Options = lists:map(fun expand_sh_flag/1, - proplists:compact(Options0 ++ DefaultOptions)), + Options = [expand_sh_flag(V) + || V <- proplists:compact(Options0 ++ DefaultOptions)], ErrorHandler = proplists:get_value(error_handler, Options), OutputHandler = proplists:get_value(output_handler, Options), @@ -87,8 +87,8 @@ sh(Command0, Options0) -> Port = open_port({spawn, Command}, PortSettings), case sh_loop(Port, OutputHandler, []) of - {ok, Output} -> - {ok, Output}; + {ok, _Output} = Ok -> + Ok; {error, Rc} -> ErrorHandler(Command, Rc) end. @@ -179,10 +179,10 @@ expand_sh_flag({use_stdout, false}) -> fun(Line, Acc) -> [Acc | Line] end}; -expand_sh_flag({cd, Dir}) -> - {port_settings, {cd, Dir}}; -expand_sh_flag({env, Env}) -> - {port_settings, {env, Env}}. +expand_sh_flag({cd, _CdArg} = Cd) -> + {port_settings, Cd}; +expand_sh_flag({env, _EnvArg} = Env) -> + {port_settings, Env}. -spec log_and_abort(string(), integer()) -> no_return(). log_and_abort(Command, Rc) -> -- cgit v1.1 From c466076ffb5a1ea4c00d49fefff0dcfbceb58236 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Mon, 31 Jan 2011 17:43:31 +0100 Subject: Clean up emacs file local variables --- src/rebar_utils.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index a9ed9a0..aa324c2 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -1,4 +1,4 @@ -%% -*- tab-width: 4;erlang-indent-level: 4;indent-tabs-mode: nil -*- +%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*- %% ex: ts=4 sw=4 et %% ------------------------------------------------------------------- %% -- cgit v1.1 From 63de05d914f3c2bef6dcfc6cf966400d93c9c80d Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Fri, 28 Jan 2011 16:08:27 +0100 Subject: Clean up code --- src/rebar_utils.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index aa324c2..c8eccc4 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -113,7 +113,7 @@ find_files(Dir, Regex) -> now_str() -> {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:local_time(), lists:flatten(io_lib:format("~4b/~2..0b/~2..0b ~2..0b:~2..0b:~2..0b", - [Year, Month, Day, Hour, Minute, Second])). + [Year, Month, Day, Hour, Minute, Second])). %% TODO: filelib:ensure_dir/1 corrected in R13B04. Remove when we drop %% support for OTP releases older than R13B04. -- cgit v1.1 From 11bf6b4aab33c273f0db94bded8763af68cbc167 Mon Sep 17 00:00:00 2001 From: joewilliams Date: Thu, 10 Feb 2011 13:27:29 -0800 Subject: Add 'generate-appups' command To further support OTP releases I have added support for generating application appup files. These include instructions that systools uses to generate a relup file which contains the low level instructions needed to perform a hot code upgrade. My goal with this module is to produce "good enough" appup files or at least a skeleton to help one get started with something more complex. If an appup file already exists for an application this command will not attempt to create a new one. Usage: $ rebar generate-appups previous_release=/path/to/old/version Generally this command will be run just before 'generate-upgrade'. --- src/rebar_utils.erl | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index c8eccc4..dc7de9b 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -37,7 +37,11 @@ erl_to_mod/1, abort/2, escript_foldl/3, - find_executable/1]). + find_executable/1, + get_reltool_release_info/1, + get_rel_release_info/2, + get_previous_release_path/0, + prop_check/3]). -include("rebar.hrl"). @@ -151,6 +155,42 @@ find_executable(Name) -> "\"" ++ filename:nativename(Path) ++ "\"" end. +%% Get release name and version from a reltool.config +get_reltool_release_info(ReltoolFile) -> + %% expect sys to be the first proplist in reltool.config + case file:consult(ReltoolFile) of + {ok, [{sys, Config}| _]} -> + %% expect the first rel in the proplist to be the one you want + {rel, Name, Ver, _} = proplists:lookup(rel, Config), + {Name, Ver}; + _ -> + ?ABORT("Failed to parse ~s~n", [ReltoolFile]) + end. + +%% Get release name and version from a rel file +get_rel_release_info(Name, Path) -> + [RelFile] = filelib:wildcard(filename:join([Path, "releases", "*", + Name ++ ".rel"])), + [BinDir|_] = re:replace(RelFile, Name ++ "\\.rel", ""), + {ok, [{release, {Name1, Ver}, _, _}]} = + file:consult(filename:join([binary_to_list(BinDir), + Name ++ ".rel"])), + {Name1, Ver}. + +%% Get the previous release path from a global variable +get_previous_release_path() -> + case rebar_config:get_global(previous_release, false) of + false -> + ?ABORT("previous_release=PATH is required to " + "create upgrade package~n", []); + OldVerPath -> + OldVerPath + end. + +%% Helper function for checking values and aborting when needed +prop_check(true, _, _) -> true; +prop_check(false, Msg, Args) -> ?ABORT(Msg, Args). + %% ==================================================================== %% Internal functions %% ==================================================================== -- cgit v1.1 From 4e8dcfbfade08b48fe38bfe041459960b0ff74c3 Mon Sep 17 00:00:00 2001 From: joewilliams Date: Wed, 16 Feb 2011 09:46:40 -0800 Subject: Clean up rebar_appups and rebar_upgrade --- src/rebar_utils.erl | 35 ----------------------------------- 1 file changed, 35 deletions(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index dc7de9b..2822c0f 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -38,9 +38,6 @@ abort/2, escript_foldl/3, find_executable/1, - get_reltool_release_info/1, - get_rel_release_info/2, - get_previous_release_path/0, prop_check/3]). -include("rebar.hrl"). @@ -155,38 +152,6 @@ find_executable(Name) -> "\"" ++ filename:nativename(Path) ++ "\"" end. -%% Get release name and version from a reltool.config -get_reltool_release_info(ReltoolFile) -> - %% expect sys to be the first proplist in reltool.config - case file:consult(ReltoolFile) of - {ok, [{sys, Config}| _]} -> - %% expect the first rel in the proplist to be the one you want - {rel, Name, Ver, _} = proplists:lookup(rel, Config), - {Name, Ver}; - _ -> - ?ABORT("Failed to parse ~s~n", [ReltoolFile]) - end. - -%% Get release name and version from a rel file -get_rel_release_info(Name, Path) -> - [RelFile] = filelib:wildcard(filename:join([Path, "releases", "*", - Name ++ ".rel"])), - [BinDir|_] = re:replace(RelFile, Name ++ "\\.rel", ""), - {ok, [{release, {Name1, Ver}, _, _}]} = - file:consult(filename:join([binary_to_list(BinDir), - Name ++ ".rel"])), - {Name1, Ver}. - -%% Get the previous release path from a global variable -get_previous_release_path() -> - case rebar_config:get_global(previous_release, false) of - false -> - ?ABORT("previous_release=PATH is required to " - "create upgrade package~n", []); - OldVerPath -> - OldVerPath - end. - %% Helper function for checking values and aborting when needed prop_check(true, _, _) -> true; prop_check(false, Msg, Args) -> ?ABORT(Msg, Args). -- cgit v1.1