Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

243 Zeilen
7.8 KiB

vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
vor 10 Jahren
  1. -module(rebar_state).
  2. -export([new/0, new/1, new/2, new/3,
  3. get/2, get/3, set/3,
  4. opts/1,
  5. default/1, default/2,
  6. lock/1, lock/2,
  7. current_profile/1,
  8. current_profile/2,
  9. command_args/1, command_args/2,
  10. command_parsed_args/1, command_parsed_args/2,
  11. apply_profile/2,
  12. dir/1, dir/2,
  13. create_logic_providers/2,
  14. project_apps/1, project_apps/2,
  15. all_deps/1, all_deps/2,
  16. deps_names/1,
  17. prepend_hook/3, append_hook/3, hooks/2,
  18. providers/1, providers/2, add_provider/2]).
  19. -include("rebar.hrl").
  20. -record(state_t, {dir :: file:name(),
  21. opts = dict:new() :: rebar_dict(),
  22. default = dict:new() :: rebar_dict(),
  23. lock = [],
  24. current_profile = default :: atom(),
  25. command_args = [],
  26. command_parsed_args = [],
  27. project_apps = [] :: [rebar_app_into:t()],
  28. all_deps = [] :: [rebar_app_into:t()],
  29. providers = []}).
  30. -export_type([t/0]).
  31. -type t() :: record(state_t).
  32. -spec new() -> t().
  33. new() ->
  34. #state_t{dir = rebar_utils:get_cwd()}.
  35. -spec new(list()) -> t().
  36. new(Config) when is_list(Config) ->
  37. Opts = dict:from_list(Config),
  38. #state_t { dir = rebar_utils:get_cwd(),
  39. default = Opts,
  40. opts = Opts }.
  41. -spec new(t() | atom(), list()) -> t().
  42. new(Profile, Config) when is_atom(Profile)
  43. , is_list(Config) ->
  44. Opts = dict:from_list(Config),
  45. #state_t { dir = rebar_utils:get_cwd(),
  46. current_profile = Profile,
  47. default = Opts,
  48. opts = Opts };
  49. new(ParentState=#state_t{}, Config) ->
  50. %% Load terms from rebar.config, if it exists
  51. Dir = rebar_utils:get_cwd(),
  52. new(ParentState, Config, Dir).
  53. -spec new(t(), list(), file:name()) -> t().
  54. new(ParentState, Config, Dir) ->
  55. Opts = ParentState#state_t.opts,
  56. LocalOpts = case rebar_config:consult_file(?LOCK_FILE) of
  57. [D] ->
  58. dict:from_list([{locks, D} | Config]);
  59. _ ->
  60. dict:from_list(Config)
  61. end,
  62. NewOpts = dict:merge(fun(_Key, Value1, _Value2) ->
  63. Value1
  64. end, LocalOpts, Opts),
  65. ProviderModules = [],
  66. create_logic_providers(ProviderModules
  67. ,ParentState#state_t{dir=Dir
  68. ,opts=NewOpts
  69. ,default=NewOpts}).
  70. get(State, Key) ->
  71. {ok, Value} = dict:find(Key, State#state_t.opts),
  72. Value.
  73. get(State, Key, Default) ->
  74. case dict:find(Key, State#state_t.opts) of
  75. {ok, Value} ->
  76. Value;
  77. error ->
  78. Default
  79. end.
  80. -spec set(t(), any(), any()) -> t().
  81. set(State=#state_t{opts=Opts}, Key, Value) ->
  82. State#state_t{ opts = dict:store(Key, Value, Opts) }.
  83. default(#state_t{default=Opts}) ->
  84. Opts.
  85. default(State, Opts) ->
  86. State#state_t{default=Opts}.
  87. opts(#state_t{opts=Opts}) ->
  88. Opts.
  89. current_profile(#state_t{current_profile=Profile}) ->
  90. Profile.
  91. current_profile(State, Profile) ->
  92. apply_profile(State#state_t{current_profile=Profile}, Profile).
  93. lock(#state_t{lock=Lock}) ->
  94. Lock.
  95. lock(State=#state_t{lock=Lock}, App) ->
  96. State#state_t{lock=[App | Lock]}.
  97. command_args(#state_t{command_args=CmdArgs}) ->
  98. CmdArgs.
  99. command_args(State, CmdArgs) ->
  100. State#state_t{command_args=CmdArgs}.
  101. command_parsed_args(#state_t{command_parsed_args=CmdArgs}) ->
  102. CmdArgs.
  103. command_parsed_args(State, CmdArgs) ->
  104. State#state_t{command_parsed_args=CmdArgs}.
  105. %% Only apply profiles to the default profile
  106. apply_profile(State=#state_t{default=Opts}, Profile) ->
  107. ConfigProfiles = rebar_state:get(State, profiles, []),
  108. Deps = rebar_state:get(State, deps, []),
  109. Opts1 = dict:store({deps, default}, Deps, dict:erase(deps, Opts)),
  110. ProfileOpts = dict:from_list(proplists:get_value(Profile, ConfigProfiles, [])),
  111. State#state_t{opts=merge_opts(Profile, ProfileOpts, Opts1)}.
  112. merge_opts(Profile, Opts1, Opts2) ->
  113. dict:fold(fun(deps, Value, OptsAcc) ->
  114. dict:store({deps, Profile}, Value, OptsAcc);
  115. (Key, Value, OptsAcc) ->
  116. case dict:fetch(Key, Opts2) of
  117. OldValue when is_list(OldValue) ->
  118. case io_lib:printable_list(Value) of
  119. true ->
  120. dict:store(Key, Value, OptsAcc);
  121. false ->
  122. dict:store(Key, lists:keymerge(1, lists:keysort(1, OldValue), lists:keysort(1, Value)), OptsAcc)
  123. end;
  124. _ ->
  125. dict:store(Key, Value, OptsAcc)
  126. end
  127. end, Opts2, Opts1).
  128. dir(#state_t{dir=Dir}) ->
  129. Dir.
  130. dir(State=#state_t{}, Dir) ->
  131. State#state_t{dir=filename:absname(Dir)}.
  132. deps_names(Deps) when is_list(Deps) ->
  133. lists:map(fun(Dep) when is_tuple(Dep) ->
  134. ec_cnv:to_binary(element(1, Dep));
  135. (Dep) when is_atom(Dep) ->
  136. ec_cnv:to_binary(Dep)
  137. end, Deps);
  138. deps_names(State) ->
  139. Deps = rebar_state:get(State, deps, []),
  140. deps_names(Deps).
  141. project_apps(#state_t{project_apps=Apps}) ->
  142. Apps.
  143. project_apps(State=#state_t{}, NewApps) when is_list(NewApps) ->
  144. State#state_t{project_apps=NewApps};
  145. project_apps(State=#state_t{project_apps=Apps}, App) ->
  146. State#state_t{project_apps=lists:keystore(rebar_app_info:name(App), 2, Apps, App)}.
  147. all_deps(#state_t{all_deps=Apps}) ->
  148. Apps.
  149. all_deps(State=#state_t{}, NewApps) ->
  150. State#state_t{all_deps=NewApps}.
  151. providers(#state_t{providers=Providers}) ->
  152. Providers.
  153. providers(State, NewProviders) ->
  154. State#state_t{providers=NewProviders}.
  155. -spec add_provider(t(), providers:t()) -> t().
  156. add_provider(State=#state_t{providers=Providers}, Provider) ->
  157. State#state_t{providers=[Provider | Providers]}.
  158. create_logic_providers(ProviderModules, State0) ->
  159. lists:foldl(fun(ProviderMod, Acc) ->
  160. case providers:new(ProviderMod, Acc) of
  161. {error, Reason} ->
  162. ?ERROR(Reason++"~n", []),
  163. Acc;
  164. {ok, State1} ->
  165. State1
  166. end
  167. end, State0, ProviderModules).
  168. prepend_hook(State=#state_t{providers=Providers}, Target, Hook) ->
  169. State#state_t{providers=add_hook(pre, Providers, Target, Hook)}.
  170. append_hook(State=#state_t{providers=Providers}, Target, Hook) ->
  171. State#state_t{providers=add_hook(post, Providers, Target, Hook)}.
  172. -spec hooks(t(), atom()) -> {[providers:t()], [providers:t()]}.
  173. hooks(_State=#state_t{providers=Providers}, Target) ->
  174. Provider = providers:get_provider(Target, Providers),
  175. providers:hooks(Provider).
  176. %% ===================================================================
  177. %% Internal functions
  178. %% ===================================================================
  179. add_hook(Which, Providers, Target, Hook) ->
  180. Provider = providers:get_provider(Target, Providers),
  181. Hooks = providers:hooks(Provider),
  182. NewHooks = add_hook(Which, Hooks, Hook),
  183. NewProvider = providers:hooks(Provider, NewHooks),
  184. [NewProvider | lists:delete(Provider, Providers)].
  185. add_hook(pre, {PreHooks, PostHooks}, Hook) ->
  186. {[Hook | PreHooks], PostHooks};
  187. add_hook(post, {PreHooks, PostHooks}, Hook) ->
  188. {PreHooks, [Hook | PostHooks]}.