mad_deps.erl 4.6 KB

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