mad_deps.erl 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. -module(mad_deps).
  2. -export([repos_path/0]).
  3. -export([path/2]).
  4. -export([clone/2]).
  5. -export([name_and_repo/1]).
  6. -export([checkout_to/1]).
  7. -export([get_publisher/1]).
  8. -define(REPOS_PATH, filename:join([mad_utils:home(), ".mad", "repos"])).
  9. -type directory() :: string().
  10. -type name() :: atom().
  11. -type uri() :: string().
  12. -type version_control() :: git | hg.
  13. -type repo() :: {version_control(), uri(), {branch | tag, string()} | string()}.
  14. -type dependency() :: {name(), string(), repo()}.
  15. -spec repos_path() -> directory().
  16. repos_path() ->
  17. %% ~/.mad/repos
  18. ?REPOS_PATH.
  19. -spec path(string(), string()) -> directory().
  20. path(Publisher, Repo) ->
  21. %% ~/.mad/repos/Publisher/Repo
  22. filename:join([?REPOS_PATH, Publisher, Repo]).
  23. -spec clone(directory(), [dependency()]) -> ok.
  24. clone(_, []) ->
  25. ok;
  26. clone(Cwd, [H|T]) when is_tuple(H) =:= false ->
  27. clone(Cwd, T);
  28. clone(Cwd, [H|T]) ->
  29. {Name, Repo} = name_and_repo(H),
  30. {Cmd, Uri, Co} = case Repo of
  31. V={_, _, _} ->
  32. V;
  33. {_Cmd, _Url, _Co, _} ->
  34. {_Cmd, _Url, _Co}
  35. end,
  36. Cmd1 = atom_to_list(Cmd),
  37. Co1 = checkout_to(Co),
  38. Publisher = get_publisher(Uri),
  39. case get(Name) of
  40. cloned ->
  41. ok;
  42. _ ->
  43. clone_dep(Cwd, Publisher, Name, Cmd1, Uri),
  44. build_dep(Cwd, Publisher, Name, Cmd1, Co1)
  45. end,
  46. clone(Cwd, T).
  47. -spec clone_dep(directory(), string(), string(), string(), uri()) -> ok.
  48. clone_dep(Cwd, Publisher, Name, Cmd, Uri) ->
  49. TrunkPath = path(Publisher, Name),
  50. Opts = ["clone", Uri, TrunkPath],
  51. io:format("dependency: ~s~n", [Name]),
  52. %% clone
  53. mad_utils:exec(Cmd, Opts),
  54. put(Name, cloned),
  55. %% check dependencies of the dependency
  56. Conf = mad_utils:rebar_conf(TrunkPath),
  57. Conf1 = mad_utils:script(TrunkPath, Conf),
  58. clone(Cwd, mad_utils:get_value(deps, Conf1, [])).
  59. %% build dependency based on branch/tag/commit
  60. -spec build_dep(directory(), string(), string(), string(), string()) -> ok.
  61. build_dep(Cwd, Publisher, Name, Cmd, Co) ->
  62. TrunkPath = path(Publisher, Name),
  63. DepPath = filename:join([Cwd, "deps", Name]),
  64. %% get a copy of dependency from trunk
  65. mad_utils:exec("cp", ["-r", TrunkPath, DepPath]),
  66. %% change cwd to the copy of trunk and checkout to Co
  67. ok = file:set_cwd(DepPath),
  68. mad_utils:exec(Cmd, ["checkout", Co]),
  69. ok = file:set_cwd(Cwd).
  70. %% internal
  71. -spec name_and_repo(dependency()) -> {string(), repo()}.
  72. name_and_repo({Name, _, Repo}) ->
  73. {atom_to_list(Name), Repo};
  74. name_and_repo({Name, _, Repo, _}) ->
  75. {atom_to_list(Name), Repo}.
  76. -spec checkout_to(term() | {any(), string}) -> term().
  77. checkout_to({_, V}) -> V;
  78. checkout_to(Else) -> Else.
  79. -spec get_publisher(uri()) -> string().
  80. get_publisher(Uri) ->
  81. S = [{git, 9418}|http_uri:scheme_defaults()],
  82. {ok, {_, _, _, _, Path, _}} = http_uri:parse(Uri, [{scheme_defaults, S}]),
  83. [Publisher|_] = string:tokens(Path, "/"),
  84. Publisher.