Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

166 строки
5.9 KiB

10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
  1. -module(rebar_app_discover).
  2. -export([do/2,
  3. find_unbuilt_apps/1,
  4. find_apps/1,
  5. find_apps/2,
  6. find_app/2,
  7. validate_application_info/1]).
  8. do(State, LibDirs) ->
  9. BaseDir = rebar_state:dir(State),
  10. Dirs = [filename:join(BaseDir, LibDir) || LibDir <- LibDirs],
  11. Apps = find_apps(Dirs, all),
  12. ProjectDeps = rebar_state:deps_names(State),
  13. lists:foldl(fun(AppInfo, StateAcc) ->
  14. rebar_state:project_apps(StateAcc, rebar_app_info:deps(AppInfo, ProjectDeps))
  15. end, State, Apps).
  16. -spec all_app_dirs(list(file:name())) -> list(file:name()).
  17. all_app_dirs(LibDirs) ->
  18. lists:flatmap(fun(LibDir) ->
  19. app_dirs(LibDir)
  20. end, LibDirs).
  21. app_dirs(LibDir) ->
  22. Path1 = filename:join([LibDir,
  23. "*",
  24. "src",
  25. "*.app.src"]),
  26. Path2 = filename:join([LibDir,
  27. "src",
  28. "*.app.src"]),
  29. Path3 = filename:join([LibDir,
  30. "*",
  31. "ebin",
  32. "*.app"]),
  33. Path4 = filename:join([LibDir,
  34. "ebin",
  35. "*.app"]),
  36. lists:usort(lists:foldl(fun(Path, Acc) ->
  37. Files = filelib:wildcard(ec_cnv:to_list(Path)),
  38. [app_dir(File) || File <- Files] ++ Acc
  39. end, [], [Path1, Path2, Path3, Path4])).
  40. find_unbuilt_apps(LibDirs) ->
  41. find_apps(LibDirs, invalid).
  42. find_apps(LibDirs) ->
  43. find_apps(LibDirs, valid).
  44. find_apps(LibDirs, Validate) ->
  45. rebar_utils:filtermap(fun(AppDir) ->
  46. find_app(AppDir, Validate)
  47. end, all_app_dirs(LibDirs)).
  48. -spec find_app(list(), boolean()) -> rebar_app_info:t() | false.
  49. find_app(AppDir, Validate) ->
  50. AppFile = filelib:wildcard(filename:join([AppDir, "ebin", "*.app"])),
  51. AppSrcFile = filelib:wildcard(filename:join([AppDir, "src", "*.app.src"])),
  52. case AppFile of
  53. [File] ->
  54. AppInfo = create_app_info(AppDir, File),
  55. AppInfo1 = rebar_app_info:app_file(AppInfo, File),
  56. AppInfo2 = case AppSrcFile of
  57. [F] ->
  58. rebar_app_info:app_file_src(AppInfo1, F);
  59. [] ->
  60. AppInfo1
  61. end,
  62. case Validate of
  63. valid ->
  64. case validate_application_info(AppInfo2) of
  65. true ->
  66. {true, AppInfo2};
  67. false ->
  68. false
  69. end;
  70. invalid ->
  71. case validate_application_info(AppInfo2) of
  72. false ->
  73. {true, AppInfo2};
  74. true ->
  75. false
  76. end;
  77. all ->
  78. {true, AppInfo2}
  79. end;
  80. [] ->
  81. case AppSrcFile of
  82. [File] ->
  83. case Validate of
  84. V when V =:= invalid ; V =:= all ->
  85. AppInfo = create_app_info(AppDir, File),
  86. {true, rebar_app_info:app_file_src(AppInfo, File)};
  87. valid ->
  88. false
  89. end;
  90. [] ->
  91. false
  92. end
  93. end.
  94. app_dir(AppFile) ->
  95. filename:join(rebar_utils:droplast(filename:split(filename:dirname(AppFile)))).
  96. -spec create_app_info(file:name(), file:name()) -> rebar_app_info:t() | error.
  97. create_app_info(AppDir, AppFile) ->
  98. case file:consult(AppFile) of
  99. {ok, [{application, AppName, AppDetails}]} ->
  100. AppVsn = proplists:get_value(vsn, AppDetails),
  101. AbsCwd = filename:absname(rebar_utils:get_cwd()),
  102. {ok, AppInfo} = rebar_app_info:new(AppName, AppVsn, AppDir),
  103. RebarConfig = filename:join(AppDir, "rebar.config"),
  104. AppState = case filelib:is_file(RebarConfig) of
  105. true ->
  106. Terms = rebar_config:consult_file(RebarConfig),
  107. rebar_state:new(Terms);
  108. false ->
  109. rebar_state:new()
  110. end,
  111. AppState1 = rebar_state:set(AppState, base_dir, AbsCwd),
  112. AppInfo1 = rebar_app_info:config(
  113. rebar_app_info:app_details(AppInfo, AppDetails), AppState1),
  114. rebar_app_info:dir(AppInfo1, AppDir);
  115. _ ->
  116. error
  117. end.
  118. -spec validate_application_info(rebar_app_info:t()) -> boolean().
  119. validate_application_info(AppInfo) ->
  120. EbinDir = rebar_app_info:ebin_dir(AppInfo),
  121. AppFile = rebar_app_info:app_file(AppInfo),
  122. AppDetail = rebar_app_info:app_details(AppInfo),
  123. case get_modules_list(AppFile, AppDetail) of
  124. {ok, List} ->
  125. has_all_beams(EbinDir, List);
  126. _Error ->
  127. false
  128. end.
  129. -spec get_modules_list(file:name(), proplists:proplist()) ->
  130. {ok, list()} |
  131. {warning, Reason::term()} |
  132. {error, Reason::term()}.
  133. get_modules_list(AppFile, AppDetail) ->
  134. case proplists:get_value(modules, AppDetail) of
  135. undefined ->
  136. {warning, {invalid_app_file, AppFile}};
  137. ModulesList ->
  138. {ok, ModulesList}
  139. end.
  140. -spec has_all_beams(file:name(), list()) -> boolean().
  141. has_all_beams(EbinDir, [Module | ModuleList]) ->
  142. BeamFile = filename:join([EbinDir,
  143. ec_cnv:to_list(Module) ++ ".beam"]),
  144. case filelib:is_file(BeamFile) of
  145. true ->
  146. has_all_beams(EbinDir, ModuleList);
  147. false ->
  148. false
  149. end;
  150. has_all_beams(_, []) ->
  151. true.