Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

540 linhas
19 KiB

há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message
há 6 anos
support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message
há 6 anos
support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message
há 6 anos
há 9 anos
support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message
há 6 anos
support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message
há 6 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
há 10 anos
support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message
há 6 anos
support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message
há 6 anos
support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message
há 6 anos
support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message
há 6 anos
support for hex v2, multiple repository fetching, private organizations (#1884) * update to hex_core for hex-v2 repo support (#1865) * update to hex_core for hex-v2 repo support This patch adds only single repo hex-v2 support through hex_core. Packages no longer filtered out by buildtool metadata and the package index is updated per-package instead of fetched as one large ets dump. * tell travis to also build hex_core branch * support list of repos for hex packages (#1866) * support list of repos for hex packages repos are defined under the hex key in rebar configs. They can be defined at the top level of a project or globally, but not in profiles and the repos configured in dependencies are also ignored. Searching for packages involves first checking for a match in the local repo index cache, in the order repos are defined. If not found each repo is checked through the hex api for any known versions of the package and the first repo with a version that fits the constraint is used. * add {repos, replace, []} for overriding the global & default repos * add hex auth handling for repos (#1874) auth token are kept in a hex.config file that is modified by the rebar3 hex plugin. Repo names that have a : separating a parent and child are considered organizations. The parent repo's auth will be included with the child. So an organization named hexpm:rebar3_test will include any hexpm auth tokens found in the rebar3_test organization's configuration. * move packages to top level of of hexpm cache dir (#1876) * move packages to top level of of hexpm cache dir * append organization name to parent's repo_url when parsing repos * only eval config scripts and apply overrides once per app (#1879) * only eval config scripts and apply overrides once per app * move new resource behaviour to rebar_resource_v2 and keep v1 * cleanup use of rebar_resource module and unused functions * cleanup error messages and unused code * when discovering apps support mix packages as unbuilt apps (#1882) * use hex_core tarball unpacking support in pkg resource (#1883) * use hex_core tarball unpacking support in pkg resource * ignore etag if package doesn't exist and delete if checksum fails * add back tests for bad package checksums * improve bad registry checksum error message
há 6 anos
  1. -module(rebar_state).
  2. -export([new/0, new/1, new/2, new/3,
  3. get/2, get/3, set/3,
  4. format_error/1,
  5. has_all_artifacts/1,
  6. code_paths/2, code_paths/3, update_code_paths/3,
  7. opts/1, opts/2,
  8. default/1, default/2,
  9. escript_path/1, escript_path/2,
  10. lock/1, lock/2,
  11. current_profiles/1, current_profiles/2,
  12. command_args/1, command_args/2,
  13. command_parsed_args/1, command_parsed_args/2,
  14. add_to_profile/3, apply_profiles/2,
  15. dir/1, dir/2,
  16. create_logic_providers/2,
  17. current_app/1, current_app/2,
  18. project_apps/1, project_apps/2,
  19. deps_to_build/1, deps_to_build/2,
  20. all_plugin_deps/1, all_plugin_deps/2, update_all_plugin_deps/2,
  21. all_deps/1, all_deps/2, update_all_deps/2, merge_all_deps/2,
  22. all_checkout_deps/1,
  23. namespace/1, namespace/2,
  24. deps_names/1,
  25. to_list/1,
  26. compilers/1, compilers/2,
  27. prepend_compilers/2, append_compilers/2,
  28. project_builders/1, add_project_builder/3,
  29. create_resources/2, set_resources/2,
  30. resources/1, resources/2, add_resource/2,
  31. providers/1, providers/2, add_provider/2,
  32. allow_provider_overrides/1, allow_provider_overrides/2
  33. ]).
  34. -include("rebar.hrl").
  35. -include_lib("providers/include/providers.hrl").
  36. -record(state_t, {dir :: file:name(),
  37. opts = dict:new() :: rebar_dict(),
  38. code_paths = dict:new() :: rebar_dict(),
  39. default = dict:new() :: rebar_dict(),
  40. escript_path :: undefined | file:filename_all(),
  41. lock = [],
  42. current_profiles = [default] :: [atom()],
  43. namespace = default :: atom(),
  44. command_args = [],
  45. command_parsed_args = {[], []},
  46. current_app :: undefined | rebar_app_info:t(),
  47. project_apps = [] :: [rebar_app_info:t()],
  48. deps_to_build = [] :: [rebar_app_info:t()],
  49. all_plugin_deps = [] :: [rebar_app_info:t()],
  50. all_deps = [] :: [rebar_app_info:t()],
  51. compilers = [] :: [module()],
  52. project_builders = [] :: [{rebar_app_info:project_type(), module()}],
  53. resources = [],
  54. providers = [],
  55. allow_provider_overrides = false :: boolean()}).
  56. -export_type([t/0]).
  57. -type t() :: #state_t{}.
  58. -spec new() -> t().
  59. new() ->
  60. BaseState = base_state(dict:new()),
  61. BaseState#state_t{dir = rebar_dir:get_cwd()}.
  62. -spec new(list()) -> t().
  63. new(Config) when is_list(Config) ->
  64. Opts = base_opts(Config),
  65. BaseState = base_state(Opts),
  66. BaseState#state_t{dir=rebar_dir:get_cwd(),
  67. default=Opts}.
  68. -spec new(t() | atom(), list()) -> t().
  69. new(Profile, Config) when is_atom(Profile)
  70. , is_list(Config) ->
  71. Opts = base_opts(Config),
  72. BaseState = base_state(Opts),
  73. BaseState#state_t{dir = rebar_dir:get_cwd(),
  74. current_profiles = [Profile],
  75. default = Opts};
  76. new(ParentState=#state_t{}, Config) ->
  77. %% Load terms from rebar.config, if it exists
  78. Dir = rebar_dir:get_cwd(),
  79. new(ParentState, Config, Dir).
  80. -spec new(t(), list(), file:filename_all()) -> t().
  81. new(ParentState, Config, Dir) ->
  82. new(ParentState, Config, deps_from_config(Dir, Config), Dir).
  83. new(ParentState, Config, Deps, Dir) ->
  84. Opts = ParentState#state_t.opts,
  85. Plugins = proplists:get_value(plugins, Config, []),
  86. ProjectPlugins = proplists:get_value(project_plugins, Config, []),
  87. Terms = Deps++[{{project_plugins, default}, ProjectPlugins}, {{plugins, default}, Plugins} | Config],
  88. true = rebar_config:verify_config_format(Terms),
  89. LocalOpts = dict:from_list(Terms),
  90. NewOpts = rebar_opts:merge_opts(LocalOpts, Opts),
  91. ParentState#state_t{dir=Dir
  92. ,opts=NewOpts
  93. ,default=NewOpts}.
  94. deps_from_config(Dir, Config) ->
  95. case rebar_config:consult_lock_file(filename:join(Dir, ?LOCK_FILE)) of
  96. [] ->
  97. [{{deps, default}, proplists:get_value(deps, Config, [])}];
  98. D ->
  99. %% We want the top level deps only from the lock file.
  100. %% This ensures deterministic overrides for configs.
  101. Deps = [X || X <- D, element(3, X) =:= 0],
  102. [{{locks, default}, D}, {{deps, default}, Deps}]
  103. end.
  104. base_state(Opts) ->
  105. #state_t{opts=Opts}.
  106. base_opts(Config) ->
  107. Deps = proplists:get_value(deps, Config, []),
  108. Plugins = proplists:get_value(plugins, Config, []),
  109. ProjectPlugins = proplists:get_value(project_plugins, Config, []),
  110. Terms = [{{deps, default}, Deps}, {{plugins, default}, Plugins},
  111. {{project_plugins, default}, ProjectPlugins} | Config],
  112. true = rebar_config:verify_config_format(Terms),
  113. dict:from_list(Terms).
  114. get(State, Key) ->
  115. {ok, Value} = dict:find(Key, State#state_t.opts),
  116. Value.
  117. get(State, Key, Default) ->
  118. case dict:find(Key, State#state_t.opts) of
  119. {ok, Value} ->
  120. Value;
  121. error ->
  122. Default
  123. end.
  124. -spec set(t(), any(), any()) -> t().
  125. set(State=#state_t{opts=Opts}, Key, Value) ->
  126. State#state_t{ opts = dict:store(Key, Value, Opts) }.
  127. default(#state_t{default=Opts}) ->
  128. Opts.
  129. default(State, Opts) ->
  130. State#state_t{default=Opts}.
  131. format_error({profile_not_list, Profile, Other}) ->
  132. io_lib:format("Profile config must be a list but for profile '~p' config given as:~n~p", [Profile, Other]).
  133. -spec has_all_artifacts(#state_t{}) -> true | {false, file:filename()}.
  134. has_all_artifacts(State) ->
  135. Artifacts = rebar_state:get(State, artifacts, []),
  136. Dir = rebar_dir:base_dir(State),
  137. all(Dir, Artifacts).
  138. all(_, []) ->
  139. true;
  140. all(Dir, [File|Artifacts]) ->
  141. case filelib:is_regular(filename:join(Dir, File)) of
  142. false ->
  143. ?DEBUG("Missing artifact ~ts", [filename:join(Dir, File)]),
  144. {false, File};
  145. true ->
  146. all(Dir, Artifacts)
  147. end.
  148. -spec code_paths(#state_t{}, atom()) -> [file:filename()].
  149. code_paths(#state_t{code_paths=CodePaths}, Key) ->
  150. case dict:find(Key, CodePaths) of
  151. {ok, CodePath} ->
  152. CodePath;
  153. _ ->
  154. []
  155. end.
  156. -spec code_paths(#state_t{}, atom(), [file:filename()]) -> #state_t{}.
  157. code_paths(State=#state_t{code_paths=CodePaths}, Key, CodePath) ->
  158. State#state_t{code_paths=dict:store(Key, CodePath, CodePaths)}.
  159. -spec update_code_paths(#state_t{}, atom(), [file:filename()]) -> #state_t{}.
  160. update_code_paths(State=#state_t{code_paths=CodePaths}, Key, CodePath) ->
  161. case dict:is_key(Key, CodePaths) of
  162. true ->
  163. State#state_t{code_paths=dict:append_list(Key, CodePath, CodePaths)};
  164. false ->
  165. State#state_t{code_paths=dict:store(Key, CodePath, CodePaths)}
  166. end.
  167. opts(#state_t{opts=Opts}) ->
  168. Opts.
  169. opts(State, Opts) ->
  170. State#state_t{opts=Opts}.
  171. current_profiles(#state_t{current_profiles=Profiles}) ->
  172. Profiles.
  173. current_profiles(State, Profiles) ->
  174. State#state_t{current_profiles=Profiles}.
  175. lock(#state_t{lock=Lock}) ->
  176. Lock.
  177. lock(State=#state_t{}, Apps) when is_list(Apps) ->
  178. State#state_t{lock=Apps};
  179. lock(State=#state_t{lock=Lock}, App) ->
  180. State#state_t{lock=[App | Lock]}.
  181. escript_path(#state_t{escript_path=EscriptPath}) ->
  182. EscriptPath.
  183. escript_path(State, EscriptPath) ->
  184. State#state_t{escript_path=EscriptPath}.
  185. command_args(#state_t{command_args=CmdArgs}) ->
  186. CmdArgs.
  187. command_args(State, CmdArgs) ->
  188. State#state_t{command_args=CmdArgs}.
  189. command_parsed_args(#state_t{command_parsed_args=CmdArgs}) ->
  190. CmdArgs.
  191. command_parsed_args(State, CmdArgs) ->
  192. State#state_t{command_parsed_args=CmdArgs}.
  193. add_to_profile(State, Profile, KVs) when is_atom(Profile), is_list(KVs) ->
  194. Opts = rebar_opts:add_to_profile(opts(State), Profile, KVs),
  195. State#state_t{opts=Opts}.
  196. apply_profiles(State, Profile) when not is_list(Profile) ->
  197. apply_profiles(State, [Profile]);
  198. apply_profiles(State, [default]) ->
  199. State;
  200. apply_profiles(State=#state_t{default = Defaults, current_profiles=CurrentProfiles}, Profiles) ->
  201. ProvidedProfiles = lists:prefix([default|Profiles], CurrentProfiles),
  202. AppliedProfiles = case Profiles of
  203. %% Head of list global profile is special, only for use by rebar3
  204. %% It does not clash if a user does `rebar3 as global...` but when
  205. %% it is the head we must make sure not to prepend `default`
  206. [global | _] ->
  207. Profiles;
  208. _ when ProvidedProfiles ->
  209. deduplicate(CurrentProfiles);
  210. _ ->
  211. deduplicate(CurrentProfiles ++ Profiles)
  212. end,
  213. ConfigProfiles = rebar_state:get(State, profiles, []),
  214. NewOpts =
  215. lists:foldl(fun(default, OptsAcc) ->
  216. OptsAcc;
  217. (Profile, OptsAcc) ->
  218. case proplists:get_value(Profile, ConfigProfiles, []) of
  219. OptsList when is_list(OptsList) ->
  220. ProfileOpts = dict:from_list(OptsList),
  221. rebar_opts:merge_opts(Profile, ProfileOpts, OptsAcc);
  222. Other ->
  223. throw(?PRV_ERROR({profile_not_list, Profile, Other}))
  224. end
  225. end, Defaults, AppliedProfiles),
  226. State#state_t{current_profiles = AppliedProfiles, opts=NewOpts}.
  227. deduplicate(Profiles) ->
  228. do_deduplicate(lists:reverse(Profiles), []).
  229. do_deduplicate([], Acc) ->
  230. Acc;
  231. do_deduplicate([Head | Rest], Acc) ->
  232. case lists:member(Head, Acc) of
  233. true -> do_deduplicate(Rest, Acc);
  234. false -> do_deduplicate(Rest, [Head | Acc])
  235. end.
  236. dir(#state_t{dir=Dir}) ->
  237. Dir.
  238. dir(State=#state_t{}, Dir) ->
  239. State#state_t{dir=filename:absname(Dir)}.
  240. deps_names(Deps) when is_list(Deps) ->
  241. lists:map(fun(Dep) when is_tuple(Dep) ->
  242. rebar_utils:to_binary(element(1, Dep));
  243. (Dep) when is_atom(Dep) ->
  244. rebar_utils:to_binary(Dep)
  245. end, Deps);
  246. deps_names(State) ->
  247. Deps = rebar_state:get(State, deps, []),
  248. deps_names(Deps).
  249. current_app(#state_t{current_app=CurrentApp}) ->
  250. CurrentApp.
  251. current_app(State=#state_t{}, CurrentApp) ->
  252. State#state_t{current_app=CurrentApp}.
  253. project_apps(#state_t{project_apps=Apps}) ->
  254. Apps.
  255. project_apps(State=#state_t{}, NewApps) when is_list(NewApps) ->
  256. State#state_t{project_apps=NewApps};
  257. project_apps(State=#state_t{project_apps=Apps}, App) ->
  258. State#state_t{project_apps=lists:keystore(rebar_app_info:name(App), 2, Apps, App)}.
  259. deps_to_build(#state_t{deps_to_build=Apps}) ->
  260. Apps.
  261. deps_to_build(State=#state_t{deps_to_build=Apps}, NewApps) when is_list(NewApps) ->
  262. State#state_t{deps_to_build=Apps++NewApps};
  263. deps_to_build(State=#state_t{deps_to_build=Apps}, App) ->
  264. State#state_t{deps_to_build=lists:keystore(rebar_app_info:name(App), 2, Apps, App)}.
  265. all_deps(#state_t{all_deps=Apps}) ->
  266. Apps.
  267. all_deps(State=#state_t{}, NewApps) ->
  268. State#state_t{all_deps=NewApps}.
  269. all_checkout_deps(#state_t{all_deps=Apps}) ->
  270. [App || App <- Apps, rebar_app_info:is_checkout(App)].
  271. all_plugin_deps(#state_t{all_plugin_deps=Apps}) ->
  272. Apps.
  273. all_plugin_deps(State=#state_t{}, NewApps) ->
  274. State#state_t{all_plugin_deps=NewApps}.
  275. update_all_plugin_deps(State=#state_t{all_plugin_deps=Apps}, NewApps) ->
  276. State#state_t{all_plugin_deps=Apps++NewApps}.
  277. update_all_deps(State=#state_t{all_deps=Apps}, NewApps) ->
  278. State#state_t{all_deps=Apps++NewApps}.
  279. merge_all_deps(State=#state_t{all_deps=Apps}, UpdatedApps) when is_list(UpdatedApps) ->
  280. State#state_t{all_deps=lists:ukeymerge(2, lists:keysort(2, UpdatedApps), lists:keysort(2, Apps))}.
  281. namespace(#state_t{namespace=Namespace}) ->
  282. Namespace.
  283. namespace(State=#state_t{}, Namespace) ->
  284. State#state_t{namespace=Namespace}.
  285. -spec resources(t()) -> [{rebar_resource_v2:type(), module()}].
  286. resources(#state_t{resources=Resources}) ->
  287. Resources.
  288. -spec set_resources(t(), [{rebar_resource_v2:type(), module()}]) -> t().
  289. set_resources(State, Resources) ->
  290. State#state_t{resources=Resources}.
  291. -spec resources(t(), [{rebar_resource_v2:type(), module()}]) -> t().
  292. resources(State, NewResources) ->
  293. lists:foldl(fun(Resource, StateAcc) ->
  294. add_resource(StateAcc, Resource)
  295. end, State, NewResources).
  296. -spec add_resource(t(), {rebar_resource_v2:type(), module()}) -> t().
  297. add_resource(State=#state_t{resources=Resources}, {ResourceType, ResourceModule}) ->
  298. _ = code:ensure_loaded(ResourceModule),
  299. Resource = case erlang:function_exported(ResourceModule, init, 2) of
  300. true ->
  301. case ResourceModule:init(ResourceType, State) of
  302. {ok, R=#resource{}} ->
  303. R;
  304. _ ->
  305. %% init didn't return a resource
  306. %% must be an old resource
  307. warn_old_resource(ResourceModule),
  308. rebar_resource:new(ResourceType,
  309. ResourceModule,
  310. #{})
  311. end;
  312. false ->
  313. %% no init, must be initial implementation
  314. warn_old_resource(ResourceModule),
  315. rebar_resource:new(ResourceType,
  316. ResourceModule,
  317. #{})
  318. end,
  319. State#state_t{resources=[Resource | Resources]}.
  320. warn_old_resource(ResourceModule) ->
  321. ?WARN("Using custom resource ~s that implements a deprecated api. "
  322. "It should be upgraded to rebar_resource_v2.", [ResourceModule]).
  323. %% @doc get a list of all registered compiler modules, which should implement
  324. %% the `rebar_compiler' behaviour
  325. -spec compilers(t()) -> [module()].
  326. compilers(#state_t{compilers=Compilers}) ->
  327. Compilers.
  328. %% @doc register compiler modules prior to the existing ones. Each compiler
  329. %% module should implement the `rebar_compiler' behaviour. Use this when
  330. %% your custom compiler generates .erl files (or files of another type) and
  331. %% that should run before other compiler modules.
  332. -spec prepend_compilers(t(), [module()]) -> t().
  333. prepend_compilers(State=#state_t{compilers=Compilers}, NewCompilers) ->
  334. State#state_t{compilers=NewCompilers++Compilers}.
  335. %% @doc register compiler modules. Each compiler
  336. %% module should implement the `rebar_compiler' behaviour. Use this when
  337. %% your custom compiler generates binary artifacts and does not have
  338. %% a particular need to run before any other compiler.
  339. -spec append_compilers(t(), [module()]) -> t().
  340. append_compilers(State=#state_t{compilers=Compilers}, NewCompilers) ->
  341. State#state_t{compilers=Compilers++NewCompilers}.
  342. %% @private reset all compiler modules by replacing them by a list of
  343. %% modules that implement the `rebar_compiler' behaviour.
  344. -spec compilers(t(), [module()]) -> t().
  345. compilers(State, Compilers) ->
  346. State#state_t{compilers=Compilers}.
  347. project_builders(#state_t{project_builders=ProjectBuilders}) ->
  348. ProjectBuilders.
  349. add_project_builder(State=#state_t{project_builders=ProjectBuilders}, Type, Module) ->
  350. _ = code:ensure_loaded(Module),
  351. case erlang:function_exported(Module, build, 1) of
  352. true ->
  353. State#state_t{project_builders=[{Type, Module} | ProjectBuilders]};
  354. false ->
  355. ?WARN("Unable to add project builder for type ~s, required function ~s:build/1 not found.",
  356. [Type, Module]),
  357. State
  358. end.
  359. create_resources(Resources, State) ->
  360. lists:foldl(fun(R, StateAcc) ->
  361. add_resource(StateAcc, R)
  362. end, State, Resources).
  363. providers(#state_t{providers=Providers}) ->
  364. Providers.
  365. providers(State, NewProviders) ->
  366. State#state_t{providers=NewProviders}.
  367. allow_provider_overrides(#state_t{allow_provider_overrides=Allow}) ->
  368. Allow.
  369. allow_provider_overrides(State, Allow) ->
  370. State#state_t{allow_provider_overrides=Allow}.
  371. -spec add_provider(t(), providers:t()) -> t().
  372. add_provider(State=#state_t{providers=Providers, allow_provider_overrides=true}, Provider) ->
  373. State#state_t{providers=[Provider | Providers]};
  374. add_provider(State=#state_t{providers=Providers, allow_provider_overrides=false}, Provider) ->
  375. Name = providers:impl(Provider),
  376. Namespace = providers:namespace(Provider),
  377. Module = providers:module(Provider),
  378. case lists:any(fun(P) ->
  379. case {providers:impl(P), providers:namespace(P)} of
  380. {Name, Namespace} ->
  381. ?DEBUG("Not adding provider ~p ~p from module ~p because it already exists from module ~p",
  382. [Namespace, Name, Module, providers:module(P)]),
  383. true;
  384. _ ->
  385. false
  386. end
  387. end, Providers) of
  388. true ->
  389. State;
  390. false ->
  391. State#state_t{providers=[Provider | Providers]}
  392. end.
  393. create_logic_providers(ProviderModules, State0) ->
  394. try
  395. lists:foldl(fun(ProviderMod, StateAcc) ->
  396. case providers:new(ProviderMod, StateAcc) of
  397. {error, {Mod, Error}} ->
  398. ?WARN("~ts", [Mod:format_error(Error)]),
  399. StateAcc;
  400. {error, Reason} ->
  401. ?WARN(Reason++"~n", []),
  402. StateAcc;
  403. {ok, StateAcc1} ->
  404. StateAcc1
  405. end
  406. end, State0, ProviderModules)
  407. catch
  408. ?WITH_STACKTRACE(C,T,S)
  409. ?DEBUG("~p: ~p ~p", [C, T, S]),
  410. ?CRASHDUMP("~p: ~p~n~p~n~n~p", [C, T, S, State0]),
  411. throw({error, "Failed creating providers. Run with DEBUG=1 for stacktrace or consult rebar3.crashdump."})
  412. end.
  413. to_list(#state_t{} = State) ->
  414. Fields = record_info(fields, state_t),
  415. Values = tl(tuple_to_list(State)),
  416. lists:zip(Fields, [reformat(I) || I <- Values]).
  417. reformat({K,V}) when is_list(V) ->
  418. {K, [reformat(I) || I <- V]};
  419. reformat({K,V}) ->
  420. try
  421. {K, [reformat(I) || I <- dict:to_list(V)]}
  422. catch
  423. error:{badrecord,dict} ->
  424. {K,V}
  425. end;
  426. reformat(V) ->
  427. try
  428. [reformat(I) || I <- dict:to_list(V)]
  429. catch
  430. error:{badrecord,dict} ->
  431. V
  432. end.
  433. %% ===================================================================
  434. %% Internal functions
  435. %% ===================================================================