mad_git.erl 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. -module(mad_git).
  2. -compile(export_all).
  3. deps(_Params) ->
  4. { Cwd, ConfigFile, Conf } = mad_utils:configs(),
  5. case mad_utils:get_value(deps, Conf, []) of
  6. [] -> {ok,[]};
  7. Deps -> file:make_dir(mad_utils:get_value(deps_dir, Conf, ["deps"])),
  8. (mad:profile()):fetch([Cwd, Conf, ConfigFile, Deps]) end.
  9. fetch([Cwd, Conf, ConfigFile, Deps]) -> fetch(Cwd, Conf, ConfigFile, Deps).
  10. fetch(_, _Config, _, []) -> false;
  11. fetch(Cwd, Config, ConfigFile, [H|T]) when is_tuple(H) =:= false -> fetch(Cwd, Config, ConfigFile, T);
  12. fetch(Cwd, Config, ConfigFile, [H|T]) ->
  13. {Name, Repo} = name_and_repo(H),
  14. Res = case get(Name) of
  15. fetched -> {ok,Name};
  16. _ ->
  17. {Cmd, Uri, Co} = case Repo of
  18. V={_, _, _} -> V;
  19. {_Cmd, _Url, _Co, _} -> {_Cmd, _Url, _Co};
  20. {_Cmd, _Url} -> {_Cmd, _Url, "master"};
  21. Url when is_list(Url) -> {git, Url, "master"}
  22. end,
  23. Cmd1 = atom_to_list(Cmd),
  24. Cache = mad_utils:get_value(cache, Config, deps_fetch),
  25. fetch_dep(Cwd, Config, ConfigFile, Name, Cmd1, Uri, Co, Cache)
  26. end,
  27. case Res of
  28. {error,E} -> {error,E};
  29. {ok,_} -> fetch(Cwd, Config, ConfigFile, T) end.
  30. get_repo([]) -> {error,"Repository unspecified."};
  31. get_repo([Name|_]) ->
  32. { Cwd, File, Conf } = mad_utils:configs(),
  33. Res = case string:tokens(Name,"/") of
  34. [Org, Rep] -> {ok,Rep,lists:concat(["https://github.com/",Org,"/",Rep])};
  35. [Rep] -> {ok,Rep,lists:concat(["https://github.com/synrc/",Rep])};
  36. [] -> {error,"Repository invalid."}
  37. end,
  38. case Res of
  39. {error,X} -> {error,X};
  40. {ok,N,Uri} -> fetch_dep(Cwd,Conf,File,N,"git",Uri,[],deps_fetch,[])
  41. end.
  42. git_clone(Uri,Fast,TrunkPath,Rev) when Rev == "head" orelse Rev == "HEAD"
  43. orelse Rev == "master" orelse Rev == [] ->
  44. {["git clone ",Fast,Uri," ",TrunkPath],Rev};
  45. git_clone(Uri,_Fast,TrunkPath,Rev) ->
  46. {["git clone ",Uri," ",TrunkPath,
  47. " && cd ",TrunkPath,
  48. " && git checkout \"",Rev,"\"" ],Rev}.
  49. fetch_dep(Cwd, Config, ConfigFile, Name, Cmd, Uri, Co, Cache) ->
  50. fetch_dep(Cwd, Config, ConfigFile, Name, Cmd, Uri, Co, Cache, deep).
  51. fetch_dep(Cwd, Config, ConfigFile, Name, Cmd, Uri, Co, Cache, Deep) ->
  52. TrunkPath = case Cache of
  53. deps_fetch -> filename:join([mad_utils:get_value(deps_dir,Config,"deps"),Name]);
  54. Dir -> filename:join([Dir,get_publisher(Uri),Name]) end,
  55. mad:info("==> dependency: ~p tag: ~p~n", [Uri,Co]),
  56. Fast = case mad_utils:get_value(fetch_speed,Config,[]) of
  57. fast_master -> " --depth=1 ";
  58. _ -> "" end,
  59. {R,Co1} = case Co of
  60. X when is_list(X) -> git_clone(Uri,Fast,TrunkPath,X);
  61. {_,Rev} -> git_clone(Uri,Fast,TrunkPath,Rev);
  62. Master -> git_clone(Uri,Fast,TrunkPath,Master) end,
  63. %mad:info("Fetch: ~s~n",[R]),
  64. FetchStatus = case filelib:is_dir(TrunkPath) of
  65. true -> {skip,0,list_to_binary("Directory "++TrunkPath++" exists.")};
  66. false -> sh:run(lists:concat(R)) end,
  67. case FetchStatus of
  68. {_,0,_} -> put(Name, fetched),
  69. %% check dependencies of the dependency
  70. TrunkConfigFile = filename:join(TrunkPath, ConfigFile),
  71. Conf = mad_utils:consult(TrunkConfigFile),
  72. Conf1 = mad_utils:script(TrunkConfigFile, Conf, Name),
  73. case Deep of
  74. deep -> fetch(Cwd, Config, ConfigFile, mad_utils:get_value(deps, Conf1, []));
  75. _ -> skip
  76. end,
  77. case Cache of
  78. deps_fetch -> {ok,Name};
  79. CacheDir -> build_dep(Cwd, Config, ConfigFile,
  80. get_publisher(Uri), Name, Cmd, Co1, CacheDir)
  81. end;
  82. {_,_,FetchError} -> {error,FetchError} end.
  83. %% build dependency based on branch/tag/commit
  84. build_dep(Cwd, Conf, _ConfFile, Publisher, Name, _Cmd, _Co, Dir) ->
  85. TrunkPath = filename:join([Dir, Publisher, Name]),
  86. DepsDir = filename:join([mad_utils:get_value(deps_dir, Conf, ["deps"]),Name]),
  87. sh:run(lists:concat(["cp -r ", TrunkPath, " ", DepsDir])),
  88. ok = file:set_cwd(DepsDir),
  89. ok = file:set_cwd(Cwd),
  90. {ok,Name}.
  91. %% internal
  92. name_and_repo(X) -> mad_utils:name_and_repo(X).
  93. get_publisher(Uri) -> case string:tokens(Uri,"@:/") of
  94. [_Proto,_Server,Publisher|_RepoPath] -> Publisher; _ -> core end.
  95. pull(_,[]) -> {ok,[]};
  96. pull(Config,[F|T]) ->
  97. mad:info("==> up: ~p~n", [F]),
  98. {_,Status,Message} = sh:run(lists:concat(["cd ",F," && git pull && cd -"])),
  99. case Status of
  100. 0 -> mad_utils:verbose(Config,Message), pull(Config,T);
  101. _ -> case binary:match(Message,[<<"You are not currently on a branch">>]) of
  102. nomatch -> mad_utils:verbose(Config,Message), {error,Message};
  103. _ -> pull(Config,T) end end.
  104. up(Params) ->
  105. { _Cwd,_ConfigFileName,Config } = mad_utils:configs(),
  106. List = case Params of
  107. [] -> [ F || F <- mad_repl:wildcards(["deps/*"]), filelib:is_dir(F) ];
  108. Apps -> [ "deps/" ++ A || A <- Apps ] end ++ ["."],
  109. pull(Config,List).