123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- -module(mad).
- -export([deps/1]).
- -export([clone_deps/1]).
- -export([compile/1]).
- -export([compile_deps/1]).
- -export([update_path/1]).
- %% read rebar.config file and return the {deps, V}
- deps(RebarFile) ->
- case file:consult(RebarFile) of
- {ok, Conf} ->
- case lists:keyfind(deps, 1, Conf) of
- {deps, Deps} ->
- {ok, Deps};
- _ ->
- {ok, []}
- end;
- Else ->
- Else
- end.
- clone_deps(Deps) ->
- exec("mkdir", ["-p", deps_path()]),
- do_clone_deps(Deps).
- do_clone_deps([]) ->
- ok;
- do_clone_deps([{Name, _, Repo}|T]) ->
- Name1 = atom_to_list(Name),
- {Cmd, Url, Co} = Repo,
- %% branch/tag it should checkout to
- Co1 = case Co of
- {_, V} -> V;
- Else -> Else
- end,
- Name2 = make_dep_name(Name1, Co1),
- %% command options: clone url path/to/dep -b Branch/Tag
- Opts = ["clone", Url, get_path(Name2), "-b", Co1],
- io:format("dependency: ~s~n", [Name1]),
- %% run the command
- exec(Cmd, Opts),
- %% check dependencies of the dependency
- case deps(rebar_config_file(Name2)) of
- {ok, Deps} ->
- do_clone_deps(Deps);
- {error, _} ->
- ok
- end,
- do_clone_deps(T).
- %% compile dependencies and the app
- compile(Dir) ->
- RebarFile = filename:join([Dir, "rebar.config"]),
- case deps(RebarFile) of
- {ok, Deps} ->
- compile_deps(Deps);
- {error, _} ->
- ok
- end,
- compile_app(Dir).
- compile_deps([]) ->
- ok;
- compile_deps([{Name, _, Repo}|T]) ->
- Name1 = atom_to_list(Name),
- {_, _, Co} = Repo,
- %% branch/tag it should checkout to
- Co1 = case Co of
- {_, V} -> V;
- Else -> Else
- end,
- Name2 = make_dep_name(Name1, Co1),
- SrcDir = src(Name2),
- EbinDir = ebin(Name2),
- case file:list_dir(SrcDir) of
- {ok, Files} ->
- exec("mkdir", ["-p", EbinDir]),
- lists:foreach(compile_fun(SrcDir, EbinDir), Files);
- {error, _} -> ok
- end,
- %% check dependencies of the dependency
- case deps(rebar_config_file(Name2)) of
- {ok, Deps} ->
- compile_deps(Deps);
- {error, _} ->
- ok
- end,
- compile_deps(T).
- compile_app(Dir) ->
- SrcDir = filename:join([Dir, "src"]),
- case file:list_dir(SrcDir) of
- {ok, Files} ->
- EbinDir = filename:join([Dir, "ebin"]),
- lists:foreach(compile_fun(SrcDir, EbinDir), Files);
- {error, _} ->
- ok
- end.
- exec(Cmd, Opts) ->
- Opts1 = [concat([" ", X]) || X <- Opts],
- os:cmd(concat([Cmd, concat(Opts1)])).
- concat(L) ->
- lists:concat(L).
- make_dep_name(Name, Suffix) ->
- %% Name-Suffix
- concat([Name, "-", Suffix]).
- home() ->
- %% ~/
- {ok, [[H|_]]} = init:get_argument(home),
- H.
- deps_path() ->
- %% ~/.otp/deps
- filename:join([home(), ".otp", "deps"]).
- get_path(X) ->
- %% ~/.otp/deps/X
- filename:join([deps_path(), X]).
- rebar_config_file(X) ->
- %% ~/.otp/deps/X/rebar.config
- filename:join([get_path(X), "rebar.config"]).
- ebin(X) ->
- %% ~/.otp/deps/X/ebin
- filename:join([get_path(X), "ebin"]).
- src(X) ->
- %% ~/.otp/deps/X/src
- filename:join([get_path(X), "src"]).
- deps_path(Deps) ->
- deps_path(Deps, []).
- deps_path([], Acc) ->
- Acc;
- deps_path([{Name, _, Repo}|T], Acc) ->
- Name1 = atom_to_list(Name),
- {_, _, Co} = Repo,
- %% branch/tag it should checkout to
- Co1 = case Co of
- {_, V} -> V;
- Else -> Else
- end,
- Name2 = make_dep_name(Name1, Co1),
- Acc1 = case deps(rebar_config_file(Name2)) of
- {ok, Deps} ->
- deps_path(Deps, []);
- {error, _} ->
- []
- end,
- deps_path(T, [get_path(Name2)|Acc ++ Acc1]).
- deps_ebin(Deps) ->
- deps_ebin(deps_path(Deps), []).
- deps_ebin([], Acc) ->
- Acc;
- deps_ebin([H|T], Acc) ->
- deps_ebin(T, [filename:join([H, "ebin"])|Acc]).
- %% add application directory (its ebin) and its dependencies to the code path
- update_path(Dir) ->
- Ebin = filename:join([Dir, "ebin"]),
- code:add_path(Ebin),
- RebarFile = filename:join([Dir, "rebar.config"]),
- case deps(RebarFile) of
- {ok, Deps} ->
- code:add_paths(deps_ebin(Deps));
- {error, _} ->
- ok
- end.
- is_app_src(Filename) ->
- Filename =/= filename:rootname(Filename, ".app.src").
- app_src_to_app(Filename) ->
- filename:join([filename:basename(Filename, ".app.src") ++ ".app"]).
- compile_fun(SrcDir, EbinDir) ->
- fun(F) ->
- F1 = filename:join([SrcDir, F]),
- case is_app_src(F1) of
- false ->
- io:format("Compiling ~s~n", [F]),
- compile:file(F1, [{outdir, EbinDir}]);
- true ->
- AppF = app_src_to_app(F1),
- io:format("Writing ebin/~s~n", [AppF]),
- exec("cp", [F1, filename:join([EbinDir, AppF])])
- end
- end.
|