]> granicus.if.org Git - ejabberd/commitdiff
Allow include of simple dependencies (EJAB-1737)(#391)
authorChristophe Romain <christophe.romain@process-one.net>
Wed, 22 Jul 2015 08:48:44 +0000 (10:48 +0200)
committerChristophe Romain <christophe.romain@process-one.net>
Wed, 22 Jul 2015 08:48:44 +0000 (10:48 +0200)
Either contributed module include dependencies this way
  deps/
    dep1/
      src/
      include/
    dep1/
      src/
      include/

Or includes rebar.config or rebar.config.script:
In this case, only git is supported (if git command available)
and ext_mod checkout code in deps directory.

In both case, only basic built procedure is supported. ext_mod
does not do more than bare compilation like this:
erlc -I include src/*erl

src/ext_mod.erl

index bfc448dcfa1164401d6cd7cf594f1910d4630188..070fdf9d3d46a10de6eb928cafa27ced81c43d64 100644 (file)
@@ -445,9 +445,14 @@ compile_and_install(Module, Spec) ->
         true ->
             {ok, Dir} = file:get_cwd(),
             file:set_cwd(SrcDir),
-            Result = case compile(Module, Spec, LibDir) of
-                ok -> install(Module, Spec, LibDir);
-                Error -> Error
+            Result = case compile_deps(Module, Spec, LibDir) of
+                ok ->
+                    case compile(Module, Spec, LibDir) of
+                        ok -> install(Module, Spec, LibDir);
+                        Error -> Error
+                    end;
+                Error ->
+                    Error
             end,
             file:set_cwd(Dir),
             Result;
@@ -459,6 +464,35 @@ compile_and_install(Module, Spec) ->
             end
     end.
 
+compile_deps(_Module, _Spec, DestDir) ->
+    case filelib:is_dir("deps") of
+        true -> ok;
+        false -> fetch_rebar_deps()
+    end,
+    Ebin = filename:join(DestDir, "ebin"),
+    filelib:ensure_dir(filename:join(Ebin, ".")),
+    Result = lists:foldl(fun(Dep, Acc) ->
+                Inc = filename:join(Dep, "include"),
+                Src = filename:join(Dep, "src"),
+                Options = [{outdir, Ebin}, {i, Inc}],
+                [file:copy(App, Ebin) || App <- filelib:wildcard(Src++"/*.app")],
+                Acc++[case compile:file(File, Options) of
+                        {ok, _} -> ok;
+                        {ok, _, _} -> ok;
+                        {ok, _, _, _} -> ok;
+                        error -> {error, {compilation_failed, File}};
+                        Error -> Error
+                    end
+                     || File <- filelib:wildcard(Src++"/*.erl")]
+        end, [], filelib:wildcard("deps/*")),
+    case lists:dropwhile(
+            fun(ok) -> true;
+                (_) -> false
+            end, Result) of
+        [] -> ok;
+        [Error|_] -> Error
+    end.
+
 compile(_Module, _Spec, DestDir) ->
     Ebin = filename:join(DestDir, "ebin"),
     filelib:ensure_dir(filename:join(Ebin, ".")),
@@ -470,6 +504,7 @@ compile(_Module, _Spec, DestDir) ->
     Options = [{outdir, Ebin}, {i, "include"}, {i, EjabInc},
                verbose, report_errors, report_warnings]
               ++ Logger ++ ExtLib,
+    [file:copy(App, Ebin) || App <- filelib:wildcard("src/*.app")],
     Result = [case compile:file(File, Options) of
             {ok, _} -> ok;
             {ok, _, _} -> ok;
@@ -504,6 +539,42 @@ install(Module, Spec, DestDir) ->
         Error -> Error
     end.
 
+%% -- minimalist rebar spec parser, only support git
+
+fetch_rebar_deps() ->
+    case rebar_deps("rebar.config")++rebar_deps("rebar.config.script") of
+        [] ->
+            ok;
+        Deps ->
+            filelib:ensure_dir(filename:join("deps", ".")),
+            lists:foreach(fun({_App, Cmd}) ->
+                        os:cmd("cd deps; "++Cmd++"; cd ..")
+                end, Deps)
+    end.
+rebar_deps(Script) ->
+    case file:script(Script) of
+        {ok, Config} when is_list(Config) ->
+            [rebar_dep(Dep) || Dep <- proplists:get_value(deps, Config, [])];
+        {ok, {deps, Deps}} ->
+            [rebar_dep(Dep) || Dep <- Deps];
+        _ ->
+            []
+    end.
+rebar_dep({App, _, {git, Url}}) ->
+    {App, "git clone "++Url++" "++filename:basename(App)};
+rebar_dep({App, _, {git, Url, {branch, Ref}}}) ->
+    {App, "git clone -n "++Url++" "++filename:basename(App)++
+     "; (cd "++filename:basename(App)++
+     "; git checkout -q origin/"++Ref++")"};
+rebar_dep({App, _, {git, Url, {tag, Ref}}}) ->
+    {App, "git clone -n "++Url++" "++filename:basename(App)++
+     "; (cd "++filename:basename(App)++
+     "; git checkout -q "++Ref++")"};
+rebar_dep({App, _, {git, Url, Ref}}) ->
+    {App, "git clone -n "++Url++" "++filename:basename(App)++
+     "; (cd "++filename:basename(App)++
+     "; git checkout -q "++Ref++")"}.
+
 %% -- YAML spec parser
 
 consult(File) ->