Você não pode selecionar mais de 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.

654 linhas
24 KiB

10 anos atrás
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
6 anos atrás
10 anos atrás
10 anos atrás
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
6 anos atrás
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
6 anos atrás
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
6 anos atrás
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
6 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
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
6 anos atrás
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
6 anos atrás
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
6 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
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
6 anos atrás
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
6 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
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
6 anos atrás
10 anos atrás
10 anos atrás
10 anos atrás
  1. -module(rebar_app_info).
  2. -export([new/0,
  3. new/1,
  4. new/2,
  5. new/3,
  6. new/4,
  7. new/5,
  8. update_opts/3,
  9. update_opts/2,
  10. update_opts_deps/2,
  11. discover/1,
  12. name/1,
  13. name/2,
  14. app_file_src/1,
  15. app_file_src/2,
  16. app_file_src_script/1,
  17. app_file_src_script/2,
  18. app_file/1,
  19. app_file/2,
  20. app_details/1,
  21. app_details/2,
  22. parent/1,
  23. parent/2,
  24. original_vsn/1,
  25. original_vsn/2,
  26. priv_dir/1,
  27. applications/1,
  28. applications/2,
  29. profiles/1,
  30. profiles/2,
  31. deps/1,
  32. deps/2,
  33. dep_level/1,
  34. dep_level/2,
  35. dir/1,
  36. dir/2,
  37. out_dir/1,
  38. out_dir/2,
  39. ebin_dir/1,
  40. ebin_dir/2,
  41. default/1,
  42. default/2,
  43. opts/1,
  44. opts/2,
  45. get/2,
  46. get/3,
  47. set/3,
  48. source/1,
  49. source/2,
  50. project_type/1,
  51. project_type/2,
  52. is_lock/1,
  53. is_lock/2,
  54. is_checkout/1,
  55. is_checkout/2,
  56. valid/1,
  57. valid/2,
  58. is_available/1,
  59. is_available/2,
  60. verify_otp_vsn/1,
  61. has_all_artifacts/1,
  62. apply_overrides/2,
  63. add_to_profile/3,
  64. apply_profiles/2,
  65. deduplicate/1,
  66. do_deduplicate/2]).
  67. -include("rebar.hrl").
  68. -include_lib("providers/include/providers.hrl").
  69. -export_type([t/0,
  70. project_type/0]).
  71. -type project_type() :: rebar3 | mix | undefined.
  72. -record(app_info_t, {name :: binary() | undefined,
  73. app_file_src :: file:filename_all() | undefined,
  74. app_file_src_script:: file:filename_all() | undefined,
  75. app_file :: file:filename_all() | undefined,
  76. original_vsn :: binary() | undefined,
  77. parent=root :: binary() | root,
  78. app_details=[] :: list(),
  79. applications=[] :: list(),
  80. deps=[] :: list(),
  81. profiles=[default] :: [atom()],
  82. default=dict:new() :: rebar_dict(),
  83. opts=dict:new() :: rebar_dict(),
  84. dep_level=0 :: integer(),
  85. dir :: file:name(),
  86. out_dir :: file:name(),
  87. ebin_dir :: file:name(),
  88. source :: string() | tuple() | checkout | undefined,
  89. is_lock=false :: boolean(),
  90. is_checkout=false :: boolean(),
  91. valid :: boolean() | undefined,
  92. project_type :: project_type(),
  93. is_available=false :: boolean()}).
  94. %%============================================================================
  95. %% types
  96. %%============================================================================
  97. -type t() :: #app_info_t{}.
  98. %%============================================================================
  99. %% API
  100. %% ============================================================================
  101. %% @doc Build a new, empty, app info value. This is not of a lot of use and you
  102. %% probably wont be doing this much.
  103. -spec new() -> t().
  104. new() ->
  105. #app_info_t{}.
  106. %% @doc Build a new app info value with only the app name set.
  107. -spec new(atom() | binary() | string()) ->
  108. {ok, t()}.
  109. new(AppName) ->
  110. {ok, #app_info_t{name=rebar_utils:to_binary(AppName)}}.
  111. %% @doc Build a new app info value with only the name and version set.
  112. -spec new(atom() | binary() | string(), binary() | string()) ->
  113. {ok, t()}.
  114. new(AppName, Vsn) ->
  115. {ok, #app_info_t{name=rebar_utils:to_binary(AppName),
  116. original_vsn=Vsn}}.
  117. %% @doc build a complete version of the app info with all fields set.
  118. -spec new(atom() | binary() | string(), binary() | string(), file:name()) ->
  119. {ok, t()}.
  120. new(AppName, Vsn, Dir) ->
  121. {ok, #app_info_t{name=rebar_utils:to_binary(AppName),
  122. original_vsn=Vsn,
  123. dir=rebar_utils:to_list(Dir),
  124. out_dir=rebar_utils:to_list(Dir),
  125. ebin_dir=filename:join(rebar_utils:to_list(Dir), "ebin")}}.
  126. %% @doc build a complete version of the app info with all fields set.
  127. -spec new(atom() | binary() | string(), binary() | string(), file:name(), list()) ->
  128. {ok, t()}.
  129. new(AppName, Vsn, Dir, Deps) ->
  130. {ok, #app_info_t{name=rebar_utils:to_binary(AppName),
  131. original_vsn=Vsn,
  132. dir=rebar_utils:to_list(Dir),
  133. out_dir=rebar_utils:to_list(Dir),
  134. ebin_dir=filename:join(rebar_utils:to_list(Dir), "ebin"),
  135. deps=Deps}}.
  136. %% @doc build a complete version of the app info with all fields set.
  137. -spec new(atom() | binary(), atom() | binary() | string(), binary() | string(), file:name(), list()) ->
  138. {ok, t()}.
  139. new(Parent, AppName, Vsn, Dir, Deps) ->
  140. {ok, #app_info_t{name=rebar_utils:to_binary(AppName),
  141. parent=Parent,
  142. original_vsn=Vsn,
  143. dir=rebar_utils:to_list(Dir),
  144. out_dir=rebar_utils:to_list(Dir),
  145. ebin_dir=filename:join(rebar_utils:to_list(Dir), "ebin"),
  146. deps=Deps}}.
  147. %% @doc update the opts based on the contents of a config
  148. %% file for the app
  149. -spec update_opts(t(), rebar_dict(), [any()]) -> t().
  150. update_opts(AppInfo, Opts, Config) ->
  151. LockDeps = case source(AppInfo) of
  152. Tuple when is_tuple(Tuple) andalso element(1, Tuple) =:= pkg ->
  153. %% Deps are set separate for packages
  154. %% instead of making it seem we have no deps
  155. %% don't set anything here.
  156. [];
  157. _ ->
  158. deps_from_config(dir(AppInfo), proplists:get_value(deps, Config, []))
  159. end,
  160. Plugins = proplists:get_value(plugins, Config, []),
  161. Terms = LockDeps++[{{plugins, default}, Plugins} | Config],
  162. true = rebar_config:verify_config_format(Terms),
  163. LocalOpts = dict:from_list(Terms),
  164. NewOpts = rebar_opts:merge_opts(LocalOpts, Opts),
  165. AppInfo#app_info_t{opts=NewOpts,
  166. default=NewOpts}.
  167. %% @doc update current app info opts by merging in a new dict of opts
  168. -spec update_opts(t(), rebar_dict()) -> t().
  169. update_opts(AppInfo=#app_info_t{opts=LocalOpts}, Opts) ->
  170. NewOpts = rebar_opts:merge_opts(LocalOpts, Opts),
  171. AppInfo#app_info_t{opts=NewOpts,
  172. default=NewOpts}.
  173. %% @doc update the opts based on new deps, usually from an app's hex registry metadata
  174. -spec update_opts_deps(t(), [any()]) -> t().
  175. update_opts_deps(AppInfo=#app_info_t{opts=Opts}, Deps) ->
  176. LocalOpts = dict:from_list([{{locks, default}, Deps}, {{deps, default}, Deps}]),
  177. NewOpts = rebar_opts:merge_opts(LocalOpts, Opts),
  178. AppInfo#app_info_t{opts=NewOpts,
  179. default=NewOpts,
  180. deps=Deps}.
  181. %% @private extract the deps for an app in `Dir' based on its config file data
  182. -spec deps_from_config(file:filename(), [any()]) -> [{tuple(), any()}, ...].
  183. deps_from_config(Dir, ConfigDeps) ->
  184. case rebar_config:consult_lock_file(filename:join(Dir, ?LOCK_FILE)) of
  185. [] ->
  186. [{{deps, default}, ConfigDeps}];
  187. D ->
  188. %% We want the top level deps only from the lock file.
  189. %% This ensures deterministic overrides for configs.
  190. Deps = [X || X <- D, element(3, X) =:= 0],
  191. [{{locks, default}, D}, {{deps, default}, Deps}]
  192. end.
  193. %% @doc discover a complete version of the app info with all fields set.
  194. -spec discover(file:filename_all()) -> {ok, t()} | not_found.
  195. discover(Dir) ->
  196. case rebar_app_discover:find_app(Dir, all) of
  197. {true, AppInfo} ->
  198. {ok, AppInfo};
  199. false ->
  200. not_found
  201. end.
  202. %% @doc get the name of the app.
  203. -spec name(t()) -> binary().
  204. name(#app_info_t{name=Name}) ->
  205. Name.
  206. %% @doc set the name of the app.
  207. -spec name(t(), atom() | binary() | string()) -> t().
  208. name(AppInfo=#app_info_t{}, AppName) ->
  209. AppInfo#app_info_t{name=rebar_utils:to_binary(AppName)}.
  210. %% @doc get the dictionary of options for the app.
  211. -spec opts(t()) -> rebar_dict().
  212. opts(#app_info_t{opts=Opts}) ->
  213. Opts.
  214. %% @doc set the dictionary of options for the app.
  215. -spec opts(t(), rebar_dict()) -> t().
  216. opts(AppInfo, Opts) ->
  217. AppInfo#app_info_t{opts=Opts}.
  218. %% @doc get the dictionary of options under the default profile.
  219. %% Represents a root set prior to applying other profiles.
  220. -spec default(t()) -> rebar_dict().
  221. default(#app_info_t{default=Default}) ->
  222. Default.
  223. %% @doc set the dictionary of options under the default profile.
  224. %% Useful when re-applying profile.
  225. -spec default(t(), rebar_dict()) -> t().
  226. default(AppInfo, Default) ->
  227. AppInfo#app_info_t{default=Default}.
  228. %% @doc look up a value in the dictionary of options; fails if
  229. %% the key for it does not exist.
  230. -spec get(t(), term()) -> term().
  231. get(AppInfo, Key) ->
  232. {ok, Value} = dict:find(Key, AppInfo#app_info_t.opts),
  233. Value.
  234. %% @doc look up a value in the dictionary of options; returns
  235. %% a `Default' value otherwise.
  236. -spec get(t(), term(), term()) -> term().
  237. get(AppInfo, Key, Default) ->
  238. case dict:find(Key, AppInfo#app_info_t.opts) of
  239. {ok, Value} ->
  240. Value;
  241. error ->
  242. Default
  243. end.
  244. %% @doc sets a given value in the dictionary of options for the app.
  245. -spec set(t(), any(), any()) -> t().
  246. set(AppInfo=#app_info_t{opts=Opts}, Key, Value) ->
  247. AppInfo#app_info_t{opts = dict:store(Key, Value, Opts)}.
  248. %% @doc finds the .app.src file for an app, if any.
  249. -spec app_file_src(t()) -> file:filename_all() | undefined.
  250. app_file_src(#app_info_t{app_file_src=undefined, dir=Dir, name=Name, opts=Opts}) ->
  251. CandidatePaths = [filename:join([rebar_utils:to_list(Dir), Src, rebar_utils:to_list(Name)++".app.src"])
  252. || Src <- rebar_opts:get(Opts, src_dirs, ["src"])],
  253. case lists:dropwhile(fun(Path) -> not filelib:is_file(Path) end, CandidatePaths) of
  254. [] -> undefined;
  255. [AppFileSrc|_] -> AppFileSrc
  256. end;
  257. app_file_src(#app_info_t{app_file_src=AppFileSrc}) ->
  258. rebar_utils:to_list(AppFileSrc).
  259. %% @doc sets the .app.src file for an app. An app without such a file
  260. %% can explicitly be set with `undefined'.
  261. -spec app_file_src(t(), file:filename_all() | undefined) -> t().
  262. app_file_src(AppInfo=#app_info_t{}, undefined) ->
  263. AppInfo#app_info_t{app_file_src=undefined};
  264. app_file_src(AppInfo=#app_info_t{}, AppFileSrc) ->
  265. AppInfo#app_info_t{app_file_src=rebar_utils:to_list(AppFileSrc)}.
  266. %% @doc finds the .app.src.script file for an app, if any.
  267. -spec app_file_src_script(t()) -> file:filename_all() | undefined.
  268. app_file_src_script(#app_info_t{app_file_src_script=undefined, dir=Dir, name=Name}) ->
  269. AppFileSrcScript = filename:join([rebar_utils:to_list(Dir), "src", rebar_utils:to_list(Name)++".app.src.script"]),
  270. case filelib:is_file(AppFileSrcScript) of
  271. true ->
  272. AppFileSrcScript;
  273. false ->
  274. undefined
  275. end;
  276. app_file_src_script(#app_info_t{app_file_src_script=AppFileSrcScript}) ->
  277. rebar_utils:to_list(AppFileSrcScript).
  278. %% @doc sets the .app.src.script file for an app. An app without such a file
  279. %% can explicitly be set with `undefined'.
  280. -spec app_file_src_script(t(), file:filename_all()) -> t().
  281. app_file_src_script(AppInfo=#app_info_t{}, undefined) ->
  282. AppInfo#app_info_t{app_file_src_script=undefined};
  283. app_file_src_script(AppInfo=#app_info_t{}, AppFileSrcScript) ->
  284. AppInfo#app_info_t{app_file_src_script=rebar_utils:to_list(AppFileSrcScript)}.
  285. %% @doc finds the .app file for an app, if any.
  286. -spec app_file(t()) -> file:filename_all() | undefined.
  287. app_file(#app_info_t{app_file=undefined, out_dir=Dir, name=Name}) ->
  288. AppFile = filename:join([rebar_utils:to_list(Dir), "ebin", rebar_utils:to_list(Name)++".app"]),
  289. case filelib:is_file(AppFile) of
  290. true ->
  291. AppFile;
  292. false ->
  293. undefined
  294. end;
  295. app_file(#app_info_t{app_file=AppFile}) ->
  296. AppFile.
  297. %% @doc sets the .app file for an app.
  298. -spec app_file(t(), file:filename_all() | undefined) -> t().
  299. app_file(AppInfo=#app_info_t{}, AppFile) ->
  300. AppInfo#app_info_t{app_file=AppFile}.
  301. %% @doc returns the information stored in the app's app file,
  302. %% or if none, from the .app.src file.
  303. -spec app_details(t()) -> list().
  304. app_details(AppInfo=#app_info_t{app_details=[]}) ->
  305. case app_file(AppInfo) of
  306. undefined ->
  307. try rebar_config:consult_app_file(app_file_src(AppInfo)) of
  308. [] -> [];
  309. [{application, _Name, AppDetails}] -> AppDetails
  310. catch
  311. _:_ ->
  312. []
  313. end;
  314. AppFile ->
  315. try rebar_file_utils:try_consult(AppFile) of
  316. [] -> [];
  317. [{application, _Name, AppDetails}] -> AppDetails
  318. catch
  319. throw:{error, {Module, Reason}} ->
  320. ?DEBUG("Warning, falling back to .app.src because of: ~ts",
  321. [Module:format_error(Reason)]),
  322. case rebar_config:consult_app_file(app_file_src(AppInfo)) of
  323. [] -> [];
  324. [{application, _Name, AppDetails}] -> AppDetails
  325. end
  326. end
  327. end;
  328. app_details(#app_info_t{app_details=AppDetails}) ->
  329. AppDetails.
  330. %% @doc stores the information that would be returned from the
  331. %% app file, when reading from `app_details/1'.
  332. -spec app_details(t(), list()) -> t().
  333. app_details(AppInfo=#app_info_t{}, AppDetails) ->
  334. AppInfo#app_info_t{app_details=AppDetails}.
  335. %% @doc returns the app's parent in the dep tree.
  336. -spec parent(t()) -> root | binary().
  337. parent(#app_info_t{parent=Parent}) ->
  338. Parent.
  339. %% @doc sets the app's parent.
  340. -spec parent(t(), binary() | root) -> t().
  341. parent(AppInfo=#app_info_t{}, Parent) ->
  342. AppInfo#app_info_t{parent=Parent}.
  343. %% @doc returns the original version of the app (unevaluated if
  344. %% asking for a semver)
  345. -spec original_vsn(t()) -> binary().
  346. original_vsn(#app_info_t{original_vsn=Vsn}) ->
  347. Vsn.
  348. %% @doc stores the original version of the app (unevaluated if
  349. %% asking for a semver)
  350. -spec original_vsn(t(), binary() | string()) -> t().
  351. original_vsn(AppInfo=#app_info_t{}, Vsn) ->
  352. AppInfo#app_info_t{original_vsn=Vsn}.
  353. %% @doc returns the list of applications the app depends on.
  354. -spec applications(t()) -> list().
  355. applications(#app_info_t{applications=Applications}) ->
  356. Applications.
  357. %% @doc sets the list of applications the app depends on.
  358. %% Should be obtained from the app file.
  359. -spec applications(t(), list()) -> t().
  360. applications(AppInfo=#app_info_t{}, Applications) ->
  361. AppInfo#app_info_t{applications=Applications}.
  362. %% @doc returns the list of active profiles
  363. -spec profiles(t()) -> list().
  364. profiles(#app_info_t{profiles=Profiles}) ->
  365. Profiles.
  366. %% @doc sets the list of active profiles
  367. -spec profiles(t(), list()) -> t().
  368. profiles(AppInfo=#app_info_t{}, Profiles) ->
  369. AppInfo#app_info_t{profiles=Profiles}.
  370. %% @doc returns the list of dependencies
  371. -spec deps(t()) -> list().
  372. deps(#app_info_t{deps=Deps}) ->
  373. Deps.
  374. %% @doc sets the list of dependencies.
  375. -spec deps(t(), list()) -> t().
  376. deps(AppInfo=#app_info_t{}, Deps) ->
  377. AppInfo#app_info_t{deps=Deps}.
  378. %% @doc returns the level the app has in the lock files or in the
  379. %% dep tree.
  380. -spec dep_level(t()) -> non_neg_integer().
  381. dep_level(#app_info_t{dep_level=Level}) ->
  382. Level.
  383. %% @doc sets the level the app has in the lock files or in the
  384. %% dep tree.
  385. -spec dep_level(t(), non_neg_integer()) -> t().
  386. dep_level(AppInfo=#app_info_t{}, Level) ->
  387. AppInfo#app_info_t{dep_level=Level}.
  388. %% @doc returns the directory that contains the app.
  389. -spec dir(t()) -> file:name().
  390. dir(#app_info_t{dir=Dir}) ->
  391. Dir.
  392. %% @doc sets the directory that contains the app.
  393. -spec dir(t(), file:name()) -> t().
  394. dir(AppInfo=#app_info_t{out_dir=undefined}, Dir) ->
  395. AppInfo#app_info_t{dir=rebar_utils:to_list(Dir),
  396. out_dir=rebar_utils:to_list(Dir)};
  397. dir(AppInfo=#app_info_t{}, Dir) ->
  398. AppInfo#app_info_t{dir=rebar_utils:to_list(Dir)}.
  399. %% @doc returns the directory where build artifacts for the app
  400. %% should go
  401. -spec out_dir(t()) -> file:name().
  402. out_dir(#app_info_t{out_dir=OutDir}) ->
  403. OutDir.
  404. %% @doc sets the directory where build artifacts for the app
  405. %% should go
  406. -spec out_dir(t(), file:name()) -> t().
  407. out_dir(AppInfo=#app_info_t{}, OutDir) ->
  408. AppInfo#app_info_t{out_dir=rebar_utils:to_list(OutDir),
  409. ebin_dir=filename:join(rebar_utils:to_list(OutDir), "ebin")}.
  410. %% @doc gets the directory where ebin files for the app should go
  411. -spec ebin_dir(t()) -> file:name().
  412. ebin_dir(#app_info_t{ebin_dir=undefined,
  413. out_dir=OutDir}) ->
  414. filename:join(rebar_utils:to_list(OutDir), "ebin");
  415. ebin_dir(#app_info_t{ebin_dir=EbinDir}) ->
  416. EbinDir.
  417. %% @doc sets the directory where beam files should go
  418. -spec ebin_dir(t(), file:name()) -> t().
  419. ebin_dir(AppInfo, EbinDir) ->
  420. AppInfo#app_info_t{ebin_dir=EbinDir}.
  421. %% @doc gets the directory where private files for the app should go
  422. -spec priv_dir(t()) -> file:name().
  423. priv_dir(#app_info_t{out_dir=OutDir}) ->
  424. rebar_utils:to_list(filename:join(OutDir, "priv")).
  425. %% @doc finds the source specification for the app
  426. -spec source(t()) -> string() | tuple().
  427. source(#app_info_t{source=Source}) ->
  428. Source.
  429. %% @doc sets the source specification for the app
  430. -spec source(t(), string() | tuple() | checkout) -> t().
  431. source(AppInfo=#app_info_t{}, Source) ->
  432. AppInfo#app_info_t{source=Source}.
  433. %% @doc returns the lock status for the app
  434. -spec is_lock(t()) -> boolean().
  435. is_lock(#app_info_t{is_lock=IsLock}) ->
  436. IsLock.
  437. %% @doc sets the lock status for the app
  438. -spec is_lock(t(), boolean()) -> t().
  439. is_lock(AppInfo=#app_info_t{}, IsLock) ->
  440. AppInfo#app_info_t{is_lock=IsLock}.
  441. %% @doc returns whether the app is a checkout app or not
  442. -spec is_checkout(t()) -> boolean().
  443. is_checkout(#app_info_t{is_checkout=IsCheckout}) ->
  444. IsCheckout.
  445. %% @doc sets whether the app is a checkout app or not
  446. -spec is_checkout(t(), boolean()) -> t().
  447. is_checkout(AppInfo=#app_info_t{}, IsCheckout) ->
  448. AppInfo#app_info_t{is_checkout=IsCheckout}.
  449. %% @doc returns whether the app source exists in the deps dir
  450. -spec is_available(t()) -> boolean().
  451. is_available(#app_info_t{is_available=IsAvailable}) ->
  452. IsAvailable.
  453. %% @doc sets whether the app's source is available
  454. %% only set if the app's source is found in the expected dep directory
  455. -spec is_available(t(), boolean()) -> t().
  456. is_available(AppInfo=#app_info_t{}, IsAvailable) ->
  457. AppInfo#app_info_t{is_available=IsAvailable}.
  458. %% @doc
  459. -spec project_type(t()) -> atom().
  460. project_type(#app_info_t{project_type=ProjectType}) ->
  461. ProjectType.
  462. %% @doc
  463. -spec project_type(t(), atom()) -> t().
  464. project_type(AppInfo=#app_info_t{}, ProjectType) ->
  465. AppInfo#app_info_t{project_type=ProjectType}.
  466. %% @doc returns whether the app is valid (built) or not
  467. -spec valid(t()) -> boolean().
  468. valid(AppInfo=#app_info_t{valid=undefined}) ->
  469. case rebar_app_utils:validate_application_info(AppInfo) =:= true
  470. andalso has_all_artifacts(AppInfo) =:= true of
  471. true ->
  472. true;
  473. _ ->
  474. false
  475. end;
  476. valid(#app_info_t{valid=Valid}) ->
  477. Valid.
  478. %% @doc sets whether the app is valid (built) or not. If left unset,
  479. %% rebar3 will do the detection of the status itself.
  480. -spec valid(t(), boolean()) -> t().
  481. valid(AppInfo=#app_info_t{}, Valid) ->
  482. AppInfo#app_info_t{valid=Valid}.
  483. %% @doc checks whether the app can be built with the current
  484. %% Erlang/OTP version. If the check fails, the function raises
  485. %% an exception and displays an error.
  486. -spec verify_otp_vsn(t()) -> ok | no_return().
  487. verify_otp_vsn(AppInfo) ->
  488. rebar_utils:check_min_otp_version(rebar_app_info:get(AppInfo, minimum_otp_vsn, undefined)),
  489. rebar_utils:check_blacklisted_otp_versions(rebar_app_info:get(AppInfo, blacklisted_otp_vsns, [])).
  490. %% @doc checks whether all the build artifacts for an app to be considered
  491. %% valid are present.
  492. -spec has_all_artifacts(#app_info_t{}) -> true | {false, file:filename()}.
  493. has_all_artifacts(AppInfo) ->
  494. Artifacts = rebar_app_info:get(AppInfo, artifacts, []),
  495. OutDir = out_dir(AppInfo),
  496. Context = [{base_dir, rebar_app_info:get(AppInfo, base_dir, ?DEFAULT_BASE_DIR)}
  497. ,{profile_dir, rebar_dir:profile_dir(opts(AppInfo), profiles(AppInfo))}
  498. ,{out_dir, OutDir}],
  499. all(OutDir, Context, Artifacts).
  500. %% @private checks that all files/artifacts in the directory are found.
  501. %% Template evaluation must happen and a bbmustache context needs to
  502. %% be provided.
  503. -spec all(file:filename(), term(), [string()]) -> true | {false, string()}.
  504. all(_, _, []) ->
  505. true;
  506. all(Dir, Context, [File|Artifacts]) ->
  507. FilePath = filename:join(Dir, rebar_templater:render(File, Context)),
  508. case filelib:is_regular(FilePath) of
  509. false ->
  510. ?DEBUG("Missing artifact ~ts", [FilePath]),
  511. {false, File};
  512. true ->
  513. all(Dir, Context, Artifacts)
  514. end.
  515. %%%%%
  516. %% @doc given a set of override rules, modify the app info accordingly
  517. -spec apply_overrides(list(), t()) -> t().
  518. apply_overrides(Overrides, AppInfo) ->
  519. Name = binary_to_atom(rebar_app_info:name(AppInfo), utf8),
  520. Opts = rebar_opts:apply_overrides(opts(AppInfo), Name, Overrides),
  521. AppInfo#app_info_t{default=Opts, opts=Opts}.
  522. %% @doc adds a new profile with its own config to the app data
  523. -spec add_to_profile(t(), atom(), [{_,_}]) -> t().
  524. add_to_profile(AppInfo, Profile, KVs) when is_atom(Profile), is_list(KVs) ->
  525. Opts = rebar_opts:add_to_profile(opts(AppInfo), Profile, KVs),
  526. AppInfo#app_info_t{opts=Opts}.
  527. %% @doc applies and merges the profile configuration in the specified order
  528. %% of profiles (or for a single profile) and returns an app info record
  529. %% with the resulting configuration
  530. -spec apply_profiles(t(), atom() | [atom(),...]) -> t().
  531. apply_profiles(AppInfo, Profile) when not is_list(Profile) ->
  532. apply_profiles(AppInfo, [Profile]);
  533. apply_profiles(AppInfo, [default]) ->
  534. AppInfo;
  535. apply_profiles(AppInfo=#app_info_t{default = Defaults, profiles=CurrentProfiles}, Profiles) ->
  536. AppliedProfiles = case Profiles of
  537. %% Head of list global profile is special, only for use by rebar3
  538. %% It does not clash if a user does `rebar3 as global...` but when
  539. %% it is the head we must make sure not to prepend `default`
  540. [global | _] ->
  541. Profiles;
  542. _ ->
  543. deduplicate(CurrentProfiles ++ Profiles)
  544. end,
  545. ConfigProfiles = rebar_app_info:get(AppInfo, profiles, []),
  546. NewOpts =
  547. lists:foldl(fun(default, OptsAcc) ->
  548. OptsAcc;
  549. (Profile, OptsAcc) ->
  550. case proplists:get_value(Profile, ConfigProfiles, []) of
  551. OptsList when is_list(OptsList) ->
  552. ProfileOpts = dict:from_list(OptsList),
  553. rebar_opts:merge_opts(Profile, ProfileOpts, OptsAcc);
  554. Other ->
  555. throw(?PRV_ERROR({profile_not_list, Profile, Other}))
  556. end
  557. end, Defaults, AppliedProfiles),
  558. AppInfo#app_info_t{profiles = AppliedProfiles, opts=NewOpts}.
  559. %% @private drops duplicated profile definitions
  560. -spec deduplicate(list()) -> list().
  561. deduplicate(Profiles) ->
  562. do_deduplicate(lists:reverse(Profiles), []).
  563. %% @private drops duplicated profile definitions
  564. -spec do_deduplicate(list(), list()) -> list().
  565. do_deduplicate([], Acc) ->
  566. Acc;
  567. do_deduplicate([Head | Rest], Acc) ->
  568. case lists:member(Head, Acc) of
  569. true -> do_deduplicate(Rest, Acc);
  570. false -> do_deduplicate(Rest, [Head | Acc])
  571. end.