You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
3.2 KiB

10 years ago
10 years ago
  1. %% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-
  2. %% ex: ts=4 sw=4 et
  3. %% -------------------------------------------------------------------
  4. %%
  5. %% rebar: Erlang Build Tools
  6. %%
  7. %% -------------------------------------------------------------------
  8. -module(rebar_fetch).
  9. -export([lock_source/2,
  10. download_source/2,
  11. needs_update/2]).
  12. -export([format_error/1]).
  13. -include("rebar.hrl").
  14. %% map short versions of resources to module names
  15. -define(RESOURCES, [{git, rebar_git_resource}, {pkg, rebar_pkg_resource}]).
  16. -spec lock_source(file:filename_all(), rebar_resource:resource()) ->
  17. rebar_resource:resource() | {error, string()}.
  18. lock_source(AppDir, Source) ->
  19. Module = get_resource_type(Source),
  20. Module:lock(AppDir, Source).
  21. -spec download_source(file:filename_all(), rebar_resource:resource()) -> true | {error, any()}.
  22. download_source(AppDir, Source) ->
  23. try
  24. Module = get_resource_type(Source),
  25. TmpDir = ec_file:insecure_mkdtemp(),
  26. AppDir1 = ec_cnv:to_list(AppDir),
  27. case Module:download(TmpDir, Source) of
  28. {ok, _} ->
  29. ec_file:mkdir_p(AppDir1),
  30. code:del_path(filename:absname(filename:join(AppDir1, "ebin"))),
  31. ec_file:remove(filename:absname(AppDir1), [recursive]),
  32. ok = ec_file:copy(TmpDir, filename:absname(AppDir1), [recursive]),
  33. true;
  34. {tarball, File} ->
  35. ec_file:mkdir_p(AppDir1),
  36. ok = erl_tar:extract(File, [{cwd, TmpDir}
  37. ,compressed]),
  38. BaseName = filename:basename(AppDir1),
  39. [FromDir] = filelib:wildcard(filename:join(TmpDir, BaseName++"-*")),
  40. code:del_path(filename:absname(filename:join(AppDir1, "ebin"))),
  41. ec_file:remove(filename:absname(AppDir1), [recursive]),
  42. ok = ec_file:copy(FromDir, filename:absname(AppDir1), [recursive]),
  43. true
  44. end
  45. catch
  46. _:_ ->
  47. {error, {rebar_fetch, {fetch_fail, Source}}}
  48. end.
  49. -spec needs_update(file:filename_all(), rebar_resource:resource()) -> boolean() | {error, string()}.
  50. needs_update(AppDir, Source) ->
  51. Module = get_resource_type(Source),
  52. try
  53. Module:needs_update(AppDir, Source)
  54. catch
  55. _:_ ->
  56. true
  57. end.
  58. format_error({fetch_fail, Source}) ->
  59. io_lib:format("Failed to fetch and copy dep: ~p", [Source]).
  60. get_resource_type({Type, Location}) ->
  61. find_resource_module(Type, Location);
  62. get_resource_type({Type, Location, _}) ->
  63. find_resource_module(Type, Location);
  64. get_resource_type({Type, _, _, Location}) ->
  65. find_resource_module(Type, Location);
  66. get_resource_type(_) ->
  67. rebar_pkg_resource.
  68. find_resource_module(Type, Location) ->
  69. case lists:keyfind(Type, 1, ?RESOURCES) of
  70. false ->
  71. case code:which(Type) of
  72. non_existing ->
  73. {error, io_lib:format("Cannot handle dependency ~s.~n"
  74. " No module for resource type ~p", [Location, Type])};
  75. _ ->
  76. Type
  77. end;
  78. {Type, Module} ->
  79. Module
  80. end.