Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

252 lignes
8.7 KiB

il y a 10 ans
il y a 10 ans
il y a 10 ans
il y a 10 ans
il y a 10 ans
il y a 10 ans
  1. %% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
  2. %% ex: ts=4 sw=4 et
  3. %% -------------------------------------------------------------------
  4. %%
  5. %% rebar: Erlang Build Tools
  6. %%
  7. %% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
  8. %%
  9. %% Permission is hereby granted, free of charge, to any person obtaining a copy
  10. %% of this software and associated documentation files (the "Software"), to deal
  11. %% in the Software without restriction, including without limitation the rights
  12. %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. %% copies of the Software, and to permit persons to whom the Software is
  14. %% furnished to do so, subject to the following conditions:
  15. %%
  16. %% The above copyright notice and this permission notice shall be included in
  17. %% all copies or substantial portions of the Software.
  18. %%
  19. %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. %% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. %% THE SOFTWARE.
  26. %% -------------------------------------------------------------------
  27. -module(rebar3).
  28. -export([main/1,
  29. run/2,
  30. global_option_spec_list/0,
  31. init_config/0,
  32. set_options/2,
  33. parse_args/1,
  34. version/0,
  35. log_level/0]).
  36. -include("rebar.hrl").
  37. %% ====================================================================
  38. %% Public API
  39. %% ====================================================================
  40. %% escript Entry point
  41. main(Args) ->
  42. case catch(run(Args)) of
  43. {ok, _State} ->
  44. ok;
  45. rebar_abort ->
  46. erlang:halt(1);
  47. {error, rebar_abort} ->
  48. erlang:halt(1);
  49. {error, {Module, Reason}} ->
  50. case code:which(Module) of
  51. non_existing ->
  52. ?ERROR("Uncaught error in rebar_core. Run with DEBUG=1 to see stacktrace", []),
  53. ?DEBUG("Uncaught error: ~p ~p", [Module, Reason]);
  54. _ ->
  55. ?ERROR(Module:format_error(Reason), [])
  56. end,
  57. erlang:halt(1);
  58. {error, Error} when is_list(Error) ->
  59. ?ERROR(Error, []),
  60. erlang:halt(1);
  61. Error ->
  62. %% Nothing should percolate up from rebar_core;
  63. %% Dump this error to console
  64. ?ERROR("Uncaught error in rebar_core. Run with DEBUG=1 to see stacktrace", []),
  65. ?DEBUG("Uncaught error: ~p", [Error]),
  66. erlang:halt(1)
  67. end.
  68. %% Erlang-API entry point
  69. run(BaseState, Commands) ->
  70. _ = application:load(rebar),
  71. BaseState1 = rebar_state:set(BaseState, task, Commands),
  72. run_aux(BaseState1, [], Commands).
  73. %% ====================================================================
  74. %% Internal functions
  75. %% ====================================================================
  76. run(RawArgs) ->
  77. _ = application:load(rebar),
  78. {GlobalPluginProviders, BaseConfig} = init_config(),
  79. case erlang:system_info(version) of
  80. "6.1" ->
  81. ?WARN("Due to a filelib bug in Erlang 17.1 it is recommended"
  82. "you update to a newer release.", []);
  83. _ ->
  84. ok
  85. end,
  86. {BaseConfig1, _Args1} = set_options(BaseConfig, {[], []}),
  87. run_aux(BaseConfig1, GlobalPluginProviders, RawArgs).
  88. run_aux(State, GlobalPluginProviders, RawArgs) ->
  89. %% Make sure crypto is running
  90. case crypto:start() of
  91. ok -> ok;
  92. {error,{already_started,crypto}} -> ok
  93. end,
  94. application:start(asn1),
  95. application:start(public_key),
  96. application:start(ssl),
  97. inets:start(),
  98. State2 = case os:getenv("REBAR_PROFILE") of
  99. false ->
  100. State;
  101. Profile ->
  102. State1 = rebar_state:apply_profiles(State, [list_to_atom(Profile)]),
  103. rebar_state:default(State1, rebar_state:opts(State1))
  104. end,
  105. %% Process each command, resetting any state between each one
  106. BaseDir = rebar_dir:base_dir(State2),
  107. State3 = rebar_state:set(State2, base_dir,
  108. filename:join(filename:absname(rebar_state:dir(State2)), BaseDir)),
  109. {ok, Providers} = application:get_env(rebar, providers),
  110. {ok, PluginProviders, State4} = rebar_plugins:install(State3),
  111. rebar_core:update_code_path(State4),
  112. AllProviders = Providers++PluginProviders++GlobalPluginProviders,
  113. State5 = rebar_state:create_logic_providers(AllProviders, State4),
  114. {Task, Args} = parse_args(RawArgs),
  115. rebar_core:process_command(rebar_state:command_args(State5, Args), Task).
  116. init_config() ->
  117. %% Initialize logging system
  118. Verbosity = log_level(),
  119. ok = rebar_log:init(command_line, Verbosity),
  120. Config = case os:getenv("REBAR_CONFIG") of
  121. false ->
  122. rebar_config:consult_file(?DEFAULT_CONFIG_FILE);
  123. ConfigFile ->
  124. rebar_config:consult_file(ConfigFile)
  125. end,
  126. Config1 = case rebar_config:consult_file(?LOCK_FILE) of
  127. [D] ->
  128. [{locks, D}, {{deps, default}, D} | Config];
  129. _ ->
  130. Config
  131. end,
  132. %% If $HOME/.rebar3/config exists load and use as global config
  133. Home = rebar_dir:home_dir(),
  134. GlobalConfigFile = filename:join([Home, ?CONFIG_DIR, "config"]),
  135. State = case filelib:is_regular(GlobalConfigFile) of
  136. true ->
  137. ?DEBUG("Load global config file ~p",
  138. [GlobalConfigFile]),
  139. GlobalConfig = rebar_state:new(global, rebar_config:consult_file(GlobalConfigFile)),
  140. {ok, PluginProviders, GlobalConfig1} = rebar_plugins:install(GlobalConfig),
  141. rebar_state:new(GlobalConfig1, Config1);
  142. false ->
  143. PluginProviders = [],
  144. rebar_state:new(Config1)
  145. end,
  146. %% Determine the location of the rebar executable; important for pulling
  147. %% resources out of the escript
  148. State1 = try
  149. ScriptName = filename:absname(escript:script_name()),
  150. rebar_state:escript_path(State, ScriptName)
  151. catch
  152. _:_ ->
  153. State
  154. end,
  155. %% TODO: Do we need this still? I think it may still be used.
  156. %% Initialize vsn cache
  157. {PluginProviders, rebar_state:set(State1, vsn_cache, dict:new())}.
  158. parse_args([]) ->
  159. parse_args(["help"]);
  160. parse_args([H | Rest]) when H =:= "-h"
  161. ; H =:= "--help" ->
  162. parse_args(["help" | Rest]);
  163. parse_args([H | Rest]) when H =:= "-v"
  164. ; H =:= "--version" ->
  165. parse_args(["version" | Rest]);
  166. parse_args([Task | RawRest]) ->
  167. {list_to_atom(Task), RawRest}.
  168. set_options(State, {Options, NonOptArgs}) ->
  169. GlobalDefines = proplists:get_all_values(defines, Options),
  170. State1 = rebar_state:set(State, defines, GlobalDefines),
  171. %% Set global variables based on getopt options
  172. State2 = set_global_flag(State1, Options, force),
  173. Task = proplists:get_value(task, Options, "help"),
  174. {rebar_state:set(State2, task, Task), NonOptArgs}.
  175. %%
  176. %% get log level based on getopt option
  177. %%
  178. log_level() ->
  179. case os:getenv("QUIET") of
  180. false ->
  181. DefaultLevel = rebar_log:default_level(),
  182. case os:getenv("DEBUG") of
  183. false ->
  184. DefaultLevel;
  185. _ ->
  186. DefaultLevel + 3
  187. end;
  188. _ ->
  189. rebar_log:error_level()
  190. end.
  191. %%
  192. %% show version information and halt
  193. %%
  194. version() ->
  195. {ok, Vsn} = application:get_key(rebar, vsn),
  196. ?CONSOLE("rebar ~s on Erlang/OTP ~s Erts ~s",
  197. [Vsn, erlang:system_info(otp_release), erlang:system_info(version)]).
  198. %% TODO: Actually make it 'global'
  199. %%
  200. %% set global flag based on getopt option boolean value
  201. %%
  202. set_global_flag(State, Options, Flag) ->
  203. Value = case proplists:get_bool(Flag, Options) of
  204. true ->
  205. "1";
  206. false ->
  207. "0"
  208. end,
  209. rebar_state:set(State, Flag, Value).
  210. %%
  211. %% options accepted via getopt
  212. %%
  213. global_option_spec_list() ->
  214. [
  215. %% {Name, ShortOpt, LongOpt, ArgSpec, HelpMsg}
  216. {help, $h, "help", undefined, "Print this help."},
  217. {version, $V, "version", undefined, "Show version information."},
  218. %{config, $C, "config", string, "Rebar config file to use."},
  219. {task, undefined, undefined, string, "Task to run."}
  220. ].