Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

470 řádky
22 KiB

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
před 6 roky
před 10 roky
před 9 roky
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
před 6 roky
před 9 roky
před 10 roky
před 10 roky
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
před 6 roky
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
před 6 roky
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
před 6 roky
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
před 6 roky
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
před 6 roky
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
před 6 roky
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
před 6 roky
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
před 6 roky
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
před 6 roky
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
před 6 roky
  1. %%% @doc utility functions to do the basic discovery of apps
  2. %%% and layout for the project.
  3. -module(rebar_app_discover).
  4. -export([do/2,
  5. format_error/1,
  6. find_unbuilt_apps/1,
  7. find_apps/1,
  8. find_apps/2,
  9. find_apps/4,
  10. find_app/2,
  11. find_app/3]).
  12. -include("rebar.hrl").
  13. -include_lib("providers/include/providers.hrl").
  14. %% @doc from the base directory, find all the applications
  15. %% at the top level and their dependencies based on the configuration
  16. %% and profile information.
  17. -spec do(rebar_state:t(), [file:filename()]) -> rebar_state:t().
  18. do(State, LibDirs) ->
  19. BaseDir = rebar_state:dir(State),
  20. Dirs = [filename:join(BaseDir, LibDir) || LibDir <- LibDirs],
  21. RebarOpts = rebar_state:opts(State),
  22. SrcDirs = rebar_dir:src_dirs(RebarOpts, ["src"]),
  23. Apps = find_apps(Dirs, SrcDirs, all, State),
  24. ProjectDeps = rebar_state:deps_names(State),
  25. DepsDir = rebar_dir:deps_dir(State),
  26. CurrentProfiles = rebar_state:current_profiles(State),
  27. %% There may be a top level src which is an app and there may not
  28. %% Find it here if there is, otherwise define the deps parent as root
  29. TopLevelApp = define_root_app(Apps, State),
  30. %% Handle top level deps
  31. State1 = lists:foldl(fun(Profile, StateAcc) ->
  32. ProfileDeps = rebar_state:get(StateAcc, {deps, Profile}, []),
  33. ProfileDeps2 = rebar_utils:tup_dedup(ProfileDeps),
  34. StateAcc1 = rebar_state:set(StateAcc, {deps, Profile}, ProfileDeps2),
  35. ParsedDeps = parse_profile_deps(Profile
  36. ,TopLevelApp
  37. ,ProfileDeps2
  38. ,rebar_state:opts(StateAcc1)
  39. ,StateAcc1),
  40. rebar_state:set(StateAcc1, {parsed_deps, Profile}, ParsedDeps)
  41. end, State, lists:reverse(CurrentProfiles)),
  42. %% Handle sub project apps deps
  43. %% Sort apps so we get the same merged deps config everytime
  44. SortedApps = rebar_utils:sort_deps(Apps),
  45. lists:foldl(fun(AppInfo, StateAcc) ->
  46. Name = rebar_app_info:name(AppInfo),
  47. case enable(State, AppInfo) of
  48. true ->
  49. {AppInfo1, StateAcc1} = merge_opts(AppInfo, StateAcc),
  50. OutDir = filename:join(DepsDir, Name),
  51. AppInfo2 = rebar_app_info:out_dir(AppInfo1, OutDir),
  52. ProjectDeps1 = lists:delete(Name, ProjectDeps),
  53. rebar_state:project_apps(StateAcc1
  54. ,rebar_app_info:deps(AppInfo2, ProjectDeps1));
  55. false ->
  56. ?INFO("Ignoring ~ts", [Name]),
  57. StateAcc
  58. end
  59. end, State1, SortedApps).
  60. %% @doc checks whether there is an app at the top level (and returns its
  61. %% name) or the 'root' atom in case we're in an umbrella project.
  62. -spec define_root_app([rebar_app_info:t()], rebar_state:t()) ->
  63. root | binary().
  64. define_root_app(Apps, State) ->
  65. RootDir = rebar_dir:root_dir(State),
  66. case ec_lists:find(fun(X) ->
  67. ec_file:real_dir_path(rebar_app_info:dir(X)) =:=
  68. ec_file:real_dir_path(RootDir)
  69. end, Apps) of
  70. {ok, App} ->
  71. rebar_app_info:name(App);
  72. error ->
  73. root
  74. end.
  75. %% @doc formatting errors from the module.
  76. -spec format_error(term()) -> iodata().
  77. format_error({module_list, File}) ->
  78. io_lib:format("Error reading module list from ~p~n", [File]);
  79. format_error({missing_module, Module}) ->
  80. io_lib:format("Module defined in app file missing: ~p~n", [Module]).
  81. %% @doc merges configuration of a project app and the top level state
  82. %% some configuration like erl_opts must be merged into a subapp's opts
  83. %% while plugins and hooks need to be kept defined to only either the
  84. %% top level state or an individual application.
  85. -spec merge_opts(rebar_app_info:t(), rebar_state:t()) ->
  86. {rebar_app_info:t(), rebar_state:t()}.
  87. merge_opts(AppInfo, State) ->
  88. %% These steps make sure that hooks and artifacts are run in the context of
  89. %% the application they are defined at. If an umbrella structure is used and
  90. %% they are defined at the top level they will instead run in the context of
  91. %% the State and at the top level, not as part of an application.
  92. CurrentProfiles = rebar_state:current_profiles(State),
  93. {AppInfo1, State1} = maybe_reset_hooks_plugins(AppInfo, State),
  94. Name = rebar_app_info:name(AppInfo1),
  95. %% We reset the opts here to default so no profiles are applied multiple times
  96. AppInfo2 = rebar_app_info:apply_overrides(rebar_state:get(State1, overrides, []), AppInfo1),
  97. AppInfo3 = rebar_app_info:apply_profiles(AppInfo2, CurrentProfiles),
  98. %% Will throw an exception if checks fail
  99. rebar_app_info:verify_otp_vsn(AppInfo3),
  100. State2 = lists:foldl(fun(Profile, StateAcc) ->
  101. handle_profile(Profile, Name, AppInfo3, StateAcc)
  102. end, State1, lists:reverse(CurrentProfiles)),
  103. {AppInfo3, State2}.
  104. %% @doc Applies a given profile for an app, ensuring the deps
  105. %% match the context it will require.
  106. -spec handle_profile(atom(), binary(), rebar_app_info:t(), rebar_state:t()) ->
  107. rebar_state:t().
  108. handle_profile(Profile, Name, AppInfo, State) ->
  109. TopParsedDeps = rebar_state:get(State, {parsed_deps, Profile}, {[], []}),
  110. TopLevelProfileDeps = rebar_state:get(State, {deps, Profile}, []),
  111. AppProfileDeps = rebar_app_info:get(AppInfo, {deps, Profile}, []),
  112. AppProfileDeps2 = rebar_utils:tup_dedup(AppProfileDeps),
  113. ProfileDeps2 = rebar_utils:tup_dedup(rebar_utils:tup_umerge(TopLevelProfileDeps
  114. ,AppProfileDeps2)),
  115. State1 = rebar_state:set(State, {deps, Profile}, ProfileDeps2),
  116. %% Only deps not also specified in the top level config need
  117. %% to be included in the parsed deps
  118. NewDeps = ProfileDeps2 -- TopLevelProfileDeps,
  119. ParsedDeps = parse_profile_deps(Profile, Name, NewDeps, rebar_app_info:opts(AppInfo), State1),
  120. State2 = rebar_state:set(State1, {deps, Profile}, ProfileDeps2),
  121. rebar_state:set(State2, {parsed_deps, Profile}, TopParsedDeps++ParsedDeps).
  122. %% @doc parses all the known dependencies for a given profile
  123. -spec parse_profile_deps(Profile, Name, Deps, Opts, rebar_state:t()) -> [rebar_app_info:t()] when
  124. Profile :: atom(),
  125. Name :: binary(),
  126. Deps :: [term()], % TODO: refine types
  127. Opts :: term(). % TODO: refine types
  128. parse_profile_deps(Profile, Name, Deps, Opts, State) ->
  129. DepsDir = rebar_prv_install_deps:profile_dep_dir(State, Profile),
  130. Locks = rebar_state:get(State, {locks, Profile}, []),
  131. rebar_app_utils:parse_deps(Name
  132. ,DepsDir
  133. ,Deps
  134. ,rebar_state:opts(State, Opts)
  135. ,Locks
  136. ,1).
  137. %% reset the State hooks if there is a top level application
  138. -spec maybe_reset_hooks_plugins(AppInfo, State) -> {AppInfo, State} when
  139. AppInfo :: rebar_app_info:t(),
  140. State :: rebar_state:t().
  141. maybe_reset_hooks_plugins(AppInfo, State) ->
  142. Dir = rebar_app_info:dir(AppInfo),
  143. CurrentProfiles = rebar_state:current_profiles(State),
  144. case ec_file:real_dir_path(rebar_dir:root_dir(State)) of
  145. Dir ->
  146. Opts = reset_hooks(rebar_state:opts(State), CurrentProfiles),
  147. State1 = rebar_state:opts(State, Opts),
  148. %% set plugins to empty since this is an app at the top level
  149. %% and top level plugins are installed in run_aux
  150. AppInfo1 = rebar_app_info:set(rebar_app_info:set(AppInfo, {plugins,default}, []), plugins, []),
  151. {AppInfo1, State1};
  152. _ ->
  153. %% if not in the top root directory then we need to merge in the
  154. %% default state opts to this subapp's opts
  155. Default = reset_hooks(rebar_state:default(State), CurrentProfiles),
  156. AppInfo1 = rebar_app_info:update_opts(AppInfo, Default),
  157. {AppInfo1, State}
  158. end.
  159. %% @doc make the hooks empty for a given set of options
  160. -spec reset_hooks(Opts, Profiles) ->
  161. Opts when
  162. Opts :: rebar_dict(),
  163. Profiles :: [atom()].
  164. reset_hooks(Opts, CurrentProfiles) ->
  165. AllHooks = [post_hooks, pre_hooks, provider_hooks, artifacts],
  166. Opts1 = lists:foldl(fun(Key, OptsAcc) ->
  167. rebar_opts:set(OptsAcc, Key, [])
  168. end, Opts, AllHooks),
  169. Profiles = rebar_opts:get(Opts1, profiles, []),
  170. Profiles1 = lists:map(fun({P, ProfileOpts}) ->
  171. case lists:member(P, CurrentProfiles) of
  172. true ->
  173. {P, [X || X={Key, _} <- ProfileOpts,
  174. not lists:member(Key, AllHooks)]};
  175. false ->
  176. {P, ProfileOpts}
  177. end
  178. end, Profiles),
  179. rebar_opts:set(Opts1, profiles, Profiles1).
  180. %% @private find the directories for all apps, while detecting their source dirs
  181. %% Returns the app dir with the respective src_dirs for them, in that order,
  182. %% for every app found.
  183. -spec all_app_dirs([file:name()]) -> [{file:name(), [file:name()]}].
  184. all_app_dirs(LibDirs) ->
  185. lists:flatmap(fun(LibDir) ->
  186. {_, SrcDirs} = find_config_src(LibDir, ["src"]),
  187. app_dirs(LibDir, SrcDirs)
  188. end, LibDirs).
  189. %% @private find the directories for all apps based on their source dirs
  190. %% Returns the app dir with the respective src_dirs for them, in that order,
  191. %% for every app found.
  192. -spec all_app_dirs([file:name()], [file:name()]) -> [{file:name(), [file:name()]}].
  193. all_app_dirs(LibDirs, SrcDirs) ->
  194. lists:flatmap(fun(LibDir) -> app_dirs(LibDir, SrcDirs) end, LibDirs).
  195. %% @private find the directories based on the library directories.
  196. %% Returns the app dir with the respective src_dirs for them, in that order,
  197. %% for every app found.
  198. %%
  199. %% The function returns the src directories since they might have been
  200. %% detected in a top-level loop and we want to skip further detection
  201. %% starting now.
  202. -spec app_dirs([file:name()], [file:name()]) -> [{file:name(), [file:name()]}].
  203. app_dirs(LibDir, SrcDirs) ->
  204. Paths = lists:append([
  205. [filename:join([LibDir, SrcDir, "*.app.src"]),
  206. filename:join([LibDir, SrcDir, "*.app.src.script"])]
  207. || SrcDir <- SrcDirs
  208. ]),
  209. EbinPath = filename:join([LibDir, "ebin", "*.app"]),
  210. lists:usort(lists:foldl(fun(Path, Acc) ->
  211. Files = filelib:wildcard(rebar_utils:to_list(Path)),
  212. [{app_dir(File), SrcDirs}
  213. || File <- Files] ++ Acc
  214. end, [], [EbinPath | Paths])).
  215. %% @doc find all apps that haven't been built in a list of directories
  216. -spec find_unbuilt_apps([file:filename_all()]) -> [rebar_app_info:t()].
  217. find_unbuilt_apps(LibDirs) ->
  218. find_apps(LibDirs, invalid).
  219. %% @doc for each directory passed, find all apps that are valid.
  220. %% Returns all the related app info records.
  221. -spec find_apps([file:filename_all()]) -> [rebar_app_info:t()].
  222. find_apps(LibDirs) ->
  223. find_apps(LibDirs, valid).
  224. %% @doc for each directory passed, find all apps according
  225. %% to the validity rule passed in. Returns all the related
  226. %% app info records.
  227. -spec find_apps([file:filename_all()], valid | invalid | all) -> [rebar_app_info:t()].
  228. find_apps(LibDirs, Validate) ->
  229. rebar_utils:filtermap(
  230. fun({AppDir, AppSrcDirs}) ->
  231. find_app(rebar_app_info:new(), AppDir, AppSrcDirs, Validate)
  232. end,
  233. all_app_dirs(LibDirs)
  234. ).
  235. %% @doc for each directory passed, with the configured source directories,
  236. %% find all apps according to the validity rule passed in.
  237. %% Returns all the related app info records.
  238. -spec find_apps([file:filename_all()], [file:filename_all()], valid | invalid | all, rebar_state:t()) -> [rebar_app_info:t()].
  239. find_apps(LibDirs, SrcDirs, Validate, State) ->
  240. rebar_utils:filtermap(
  241. fun({AppDir, AppSrcDirs}) ->
  242. find_app(rebar_app_info:new(), AppDir, AppSrcDirs, Validate, State)
  243. end,
  244. all_app_dirs(LibDirs, SrcDirs)
  245. ).
  246. %% @doc check that a given app in a directory is there, and whether it's
  247. %% valid or not based on the second argument. Returns the related
  248. %% app info record.
  249. -spec find_app(file:filename_all(), valid | invalid | all) -> {true, rebar_app_info:t()} | false.
  250. find_app(AppDir, Validate) ->
  251. {Config, SrcDirs} = find_config_src(AppDir, ["src"]),
  252. AppInfo = rebar_app_info:update_opts(rebar_app_info:new(), dict:new(), Config),
  253. find_app_(AppInfo, AppDir, SrcDirs, Validate).
  254. %% @doc check that a given app in a directory is there, and whether it's
  255. %% valid or not based on the second argument. Returns the related
  256. %% app info record.
  257. -spec find_app(rebar_app_info:t(), file:filename_all(), valid | invalid | all) ->
  258. {true, rebar_app_info:t()} | false.
  259. find_app(AppInfo, AppDir, Validate) ->
  260. %% if no src dir is passed, figure it out from the app info, with a default
  261. %% of src/
  262. AppOpts = rebar_app_info:opts(AppInfo),
  263. SrcDirs = rebar_dir:src_dirs(AppOpts, ["src"]),
  264. find_app_(AppInfo, AppDir, SrcDirs, Validate).
  265. %% @doc check that a given app in a directory is there, and whether it's
  266. %% valid or not based on the second argument. The third argument includes
  267. %% the directories where source files can be located. Returns the related
  268. %% app info record.
  269. -spec find_app(rebar_app_info:t(), file:filename_all(),
  270. [file:filename_all()], valid | invalid | all, rebar_state:t()) ->
  271. {true, rebar_app_info:t()} | false.
  272. find_app(AppInfo, AppDir, SrcDirs, Validate, State) ->
  273. AppInfo1 = case ec_file:real_dir_path(rebar_dir:root_dir(State)) of
  274. AppDir ->
  275. Opts = rebar_state:opts(State),
  276. rebar_app_info:default(rebar_app_info:opts(AppInfo, Opts), Opts);
  277. _ ->
  278. Config = rebar_config:consult(AppDir),
  279. rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), Config)
  280. end,
  281. find_app_(AppInfo1, AppDir, SrcDirs, Validate).
  282. find_app(AppInfo, AppDir, SrcDirs, Validate) ->
  283. Config = rebar_config:consult(AppDir),
  284. AppInfo1 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), Config),
  285. find_app_(AppInfo1, AppDir, SrcDirs, Validate).
  286. -spec find_app_(rebar_app_info:t(), file:filename_all(),
  287. [file:filename_all()], valid | invalid | all) ->
  288. {true, rebar_app_info:t()} | false.
  289. find_app_(AppInfo, AppDir, SrcDirs, Validate) ->
  290. AppFile = filelib:wildcard(filename:join([AppDir, "ebin", "*.app"])),
  291. AppSrcFile = lists:append(
  292. [filelib:wildcard(filename:join([AppDir, SrcDir, "*.app.src"]))
  293. || SrcDir <- SrcDirs]
  294. ),
  295. AppSrcScriptFile = lists:append(
  296. [filelib:wildcard(filename:join([AppDir, SrcDir, "*.app.src.script"]))
  297. || SrcDir <- SrcDirs]
  298. ),
  299. try_handle_app_file(AppInfo, AppFile, AppDir, AppSrcFile, AppSrcScriptFile, Validate).
  300. %% @doc find the directory that an appfile has
  301. -spec app_dir(file:filename()) -> file:filename().
  302. app_dir(AppFile) ->
  303. filename:join(rebar_utils:droplast(filename:split(filename:dirname(AppFile)))).
  304. %% @doc populates an app info record based on an app directory and its
  305. %% app file.
  306. -spec create_app_info(rebar_app_info:t(), file:name(), file:name()) -> rebar_app_info:t().
  307. create_app_info(AppInfo, AppDir, AppFile) ->
  308. [{application, AppName, AppDetails}] = rebar_config:consult_app_file(AppFile),
  309. AppVsn = proplists:get_value(vsn, AppDetails),
  310. Applications = proplists:get_value(applications, AppDetails, []),
  311. IncludedApplications = proplists:get_value(included_applications, AppDetails, []),
  312. AppInfo1 = rebar_app_info:name(
  313. rebar_app_info:original_vsn(
  314. rebar_app_info:dir(AppInfo, AppDir), AppVsn), AppName),
  315. AppInfo2 = rebar_app_info:applications(
  316. rebar_app_info:app_details(AppInfo1, AppDetails),
  317. IncludedApplications++Applications),
  318. Valid = case rebar_app_utils:validate_application_info(AppInfo2) =:= true
  319. andalso rebar_app_info:has_all_artifacts(AppInfo2) =:= true of
  320. true ->
  321. true;
  322. _ ->
  323. false
  324. end,
  325. rebar_app_info:dir(rebar_app_info:valid(AppInfo2, Valid), AppDir).
  326. %% @doc Read in and parse the .app file if it is availabe. Do the same for
  327. %% the .app.src file if it exists.
  328. -spec try_handle_app_file(AppInfo, AppFile, AppDir, AppSrcFile, AppSrcScriptFile, valid | invalid | all) ->
  329. {true, AppInfo} | false when
  330. AppInfo :: rebar_app_info:t(),
  331. AppFile :: file:filename(),
  332. AppDir :: file:filename(),
  333. AppSrcFile :: file:filename(),
  334. AppSrcScriptFile :: file:filename().
  335. try_handle_app_file(AppInfo, [], AppDir, [], AppSrcScriptFile, Validate) ->
  336. try_handle_app_src_file(AppInfo, [], AppDir, AppSrcScriptFile, Validate);
  337. try_handle_app_file(AppInfo, [], AppDir, AppSrcFile, _, Validate) ->
  338. try_handle_app_src_file(AppInfo, [], AppDir, AppSrcFile, Validate);
  339. try_handle_app_file(AppInfo0, [File], AppDir, AppSrcFile, _, Validate) ->
  340. try create_app_info(AppInfo0, AppDir, File) of
  341. AppInfo ->
  342. AppInfo1 = rebar_app_info:app_file(AppInfo, File),
  343. AppInfo2 = case AppSrcFile of
  344. [F] ->
  345. rebar_app_info:app_file_src(AppInfo1, F);
  346. [] ->
  347. %% Set to undefined in case AppInfo previous had a .app.src
  348. rebar_app_info:app_file_src(AppInfo1, undefined);
  349. Other when is_list(Other) ->
  350. throw({error, {multiple_app_files, Other}})
  351. end,
  352. case Validate of
  353. valid ->
  354. case rebar_app_utils:validate_application_info(AppInfo2) of
  355. true ->
  356. {true, AppInfo2};
  357. _ ->
  358. false
  359. end;
  360. invalid ->
  361. case rebar_app_utils:validate_application_info(AppInfo2) of
  362. true ->
  363. false;
  364. _ ->
  365. {true, AppInfo2}
  366. end;
  367. all ->
  368. {true, AppInfo2}
  369. end
  370. catch
  371. throw:{error, {Module, Reason}} ->
  372. ?DEBUG("Falling back to app.src file because .app failed: ~ts", [Module:format_error(Reason)]),
  373. try_handle_app_src_file(AppInfo0, File, AppDir, AppSrcFile, Validate)
  374. end;
  375. try_handle_app_file(_AppInfo, Other, _AppDir, _AppSrcFile, _, _Validate) ->
  376. throw({error, {multiple_app_files, Other}}).
  377. %% @doc Read in the .app.src file if we aren't looking for a valid (already
  378. %% built) app.
  379. -spec try_handle_app_src_file(AppInfo, AppFile, AppDir, AppSrcFile, valid | invalid | all) ->
  380. {true, AppInfo} | false when
  381. AppInfo :: rebar_app_info:t(),
  382. AppFile :: file:filename(),
  383. AppDir :: file:filename(),
  384. AppSrcFile :: file:filename().
  385. try_handle_app_src_file(AppInfo, _, _AppDir, [], _Validate) ->
  386. %% if .app and .app.src are not found check for a mix config file
  387. %% it is assumed a plugin will build the application, including
  388. %% a .app after this step
  389. case filelib:is_file(filename:join(rebar_app_info:dir(AppInfo), "mix.exs")) of
  390. true ->
  391. {true, rebar_app_info:project_type(AppInfo, mix)};
  392. false ->
  393. false
  394. end;
  395. try_handle_app_src_file(_AppInfo, _, _AppDir, _AppSrcFile, valid) ->
  396. false;
  397. try_handle_app_src_file(AppInfo, _, AppDir, [File], Validate) when Validate =:= invalid
  398. ; Validate =:= all ->
  399. AppInfo1 = rebar_app_info:app_file(AppInfo, undefined),
  400. AppInfo2 = create_app_info(AppInfo1, AppDir, File),
  401. case filename:extension(File) of
  402. ".script" ->
  403. {true, rebar_app_info:app_file_src_script(AppInfo2, File)};
  404. _ ->
  405. {true, rebar_app_info:app_file_src(AppInfo2, File)}
  406. end;
  407. try_handle_app_src_file(_AppInfo, _, _AppDir, Other, _Validate) ->
  408. throw({error, {multiple_app_files, Other}}).
  409. %% @doc checks whether the given app is not blacklisted in the config.
  410. -spec enable(rebar_state:t(), rebar_app_info:t()) -> boolean().
  411. enable(State, AppInfo) ->
  412. not lists:member(to_atom(rebar_app_info:name(AppInfo)),
  413. rebar_state:get(State, excluded_apps, [])).
  414. %% @private convert a binary to an atom.
  415. -spec to_atom(binary()) -> atom().
  416. to_atom(Bin) ->
  417. list_to_atom(binary_to_list(Bin)).
  418. %% @private when looking for unknown apps, it's possible they have a
  419. %% rebar.config file specifying non-standard src_dirs. Check for a
  420. %% possible config file and extract src_dirs from it.
  421. find_config_src(AppDir, Default) ->
  422. case rebar_config:consult(AppDir) of
  423. [] ->
  424. {[], Default};
  425. Terms ->
  426. %% TODO: handle profiles I guess, but we don't have that info
  427. {Terms, proplists:get_value(src_dirs, Terms, Default)}
  428. end.