mad_deps.erl 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. -module(mad_deps).
  2. -copyright('Sina Samavati').
  3. -compile(export_all).
  4. pull(F) ->
  5. io:format("==> up: ~p~n", [F]),
  6. {_,Status,Message} = sh:run(io_lib:format("git -C ~p pull",[F])),
  7. case Status of
  8. 0 -> false;
  9. _ -> case binary:match(Message,[<<"Aborting">>,<<"timed out">>]) of
  10. nomatch -> false;
  11. _ -> io:format("~s",[binary_to_list(Message)]), true end end.
  12. up(Params) ->
  13. List = case Params of
  14. [] -> [ F || F <- mad_repl:wildcards(["deps/*"]), filelib:is_dir(F) ];
  15. Apps -> [ "deps/" ++ A || A <- Apps ] end ++ ["."],
  16. lists:any(fun(X) -> X end, [ pull(F) || F <- List ]).
  17. fetch(_, _Config, _, []) -> ok;
  18. fetch(Cwd, Config, ConfigFile, [H|T]) when is_tuple(H) =:= false -> fetch(Cwd, Config, ConfigFile, T);
  19. fetch(Cwd, Config, ConfigFile, [H|T]) ->
  20. {Name, Repo} = name_and_repo(H),
  21. case get(Name) of
  22. fetched -> ok;
  23. _ ->
  24. {Cmd, Uri, Co} = case Repo of
  25. V={_, _, _} -> V;
  26. {_Cmd, _Url, _Co, _} -> {_Cmd, _Url, _Co};
  27. {_Cmd, _Url} -> {_Cmd, _Url, "master"}
  28. end,
  29. Cmd1 = atom_to_list(Cmd),
  30. Cache = mad_utils:get_value(cache, Config, deps_fetch),
  31. fetch_dep(Cwd, Config, ConfigFile, Name, Cmd1, Uri, Co, Cache)
  32. end,
  33. fetch(Cwd, Config, ConfigFile, T).
  34. git_clone(Uri,Fast,TrunkPath,Rev) ->
  35. {["git clone ",Fast,Uri," ",TrunkPath," && cd ",TrunkPath," && git checkout \"",Rev,"\"" ],Rev}.
  36. fetch_dep(Cwd, Config, ConfigFile, Name, Cmd, Uri, Co, Cache) ->
  37. TrunkPath = case Cache of
  38. deps_fetch -> filename:join([mad_utils:get_value(deps_dir,Config,"deps"),Name]);
  39. Dir -> filename:join([Dir,get_publisher(Uri),Name]) end,
  40. io:format("==> dependency: ~p tag: ~p~n\r", [Uri,Co]),
  41. % TODO: add "git clone --depth=1" option by @rillian
  42. Fast = case mad_utils:get_value(fetch_speed,Config,[]) of
  43. "fast_master" -> " --depth=1 ";
  44. _ -> "" end,
  45. {R,Co1} = case Co of
  46. X when is_list(X) -> git_clone(Uri,Fast,TrunkPath,X);
  47. {_,Rev} -> git_clone(Uri,Fast,TrunkPath,Rev);
  48. Master -> {["git clone ",Fast,Uri," ",TrunkPath],lists:concat([Master])} end,
  49. os:cmd(R),
  50. put(Name, fetched),
  51. %% check dependencies of the dependency
  52. TrunkConfigFile = filename:join(TrunkPath, ConfigFile),
  53. Conf = mad_utils:consult(TrunkConfigFile),
  54. Conf1 = mad_utils:script(TrunkConfigFile, Conf, Name),
  55. fetch(Cwd, Config, ConfigFile, mad_utils:get_value(deps, Conf1, [])),
  56. case Cache of
  57. deps_fetch -> skip;
  58. CacheDir -> build_dep(Cwd, Config, ConfigFile, get_publisher(Uri), Name, Cmd, Co1, CacheDir) end.
  59. %% build dependency based on branch/tag/commit
  60. build_dep(Cwd, Conf, _ConfFile, Publisher, Name, _Cmd, _Co, Dir) ->
  61. TrunkPath = filename:join([Dir, Publisher, Name]),
  62. DepsDir = filename:join([mad_utils:get_value(deps_dir, Conf, ["deps"]),Name]),
  63. os:cmd(["cp -r ", TrunkPath, " ", DepsDir]),
  64. ok = file:set_cwd(DepsDir),
  65. ok = file:set_cwd(Cwd).
  66. %% internal
  67. name_and_repo({Name, _, Repo}) when is_list(Name) -> {Name, Repo};
  68. name_and_repo({Name, _, Repo, _}) when is_list(Name) -> {Name, Repo};
  69. name_and_repo({Name, _, Repo}) -> {atom_to_list(Name), Repo};
  70. name_and_repo({Name, _, Repo, _}) -> {atom_to_list(Name), Repo};
  71. name_and_repo({Name, Version}) when is_list(Name) -> {Name, Version};
  72. name_and_repo({Name, Version}) -> {atom_to_list(Name), Version};
  73. name_and_repo(Name) -> {Name,Name}.
  74. get_publisher(Uri) ->
  75. case http_uri:parse(Uri, [{scheme_defaults,
  76. [{git, 9418}|http_uri:scheme_defaults()]}]) of
  77. {ok, {_, _, _, _, Path, _}} -> hd(string:tokens(Path,"/"));
  78. _ -> case string:tokens(Uri,":/") of
  79. [_Server,Publisher,_Repo] -> Publisher;
  80. _ -> exit(error) end end.