Просмотр исходного кода

Add specs and more tests for mad_compile

Sina Samavati 11 лет назад
Родитель
Сommit
80dec2f0e0

+ 39 - 15
src/mad_compile.erl

@@ -11,10 +11,14 @@
 -export([erl_to_beam/2]).
 -export([is_compiled/2]).
 
--define(COMPILE_OPTS(Inc, Ebin), [report, {i, Inc}, {outdir, Ebin}]).
+-define(COMPILE_OPTS(Inc, Ebin, Opts),
+        [report, {i, Inc}, {outdir, Ebin}] ++ Opts).
+
+-type directory() :: string().
 
 
 %% compile dependencies
+-spec deps(directory(), [mad_deps:dependency()]) -> ok.
 deps(_, []) ->
     ok;
 deps(Cwd, [H|T]) ->
@@ -28,6 +32,7 @@ deps(Cwd, [H|T]) ->
     deps(Cwd, T).
 
 %% compile a dependency
+-spec dep(directory(), string()) -> ok.
 dep(Cwd, Name) ->
     %% check dependencies of the dependency
     DepPath = filename:join([Cwd, "deps", Name]),
@@ -51,12 +56,15 @@ dep(Cwd, Name) ->
         Files ->
             IncDir = mad_utils:include(DepPath),
             EbinDir = mad_utils:ebin(DepPath),
+            code:add_path(EbinDir),
             Opts = mad_utils:get_value(erl_opts, Conf1, []),
             mad_utils:exec("mkdir", ["-p", EbinDir]),
-            lists:foreach(compile_fun(SrcDir, IncDir, EbinDir, Opts), Files),
-            put(Name, compiled)
+            lists:foreach(compile_fun(IncDir, EbinDir, Opts), Files),
+            put(Name, compiled),
+            ok
     end.
 
+-spec app(directory()) -> ok.
 app(Dir) ->
     Conf = mad_utils:rebar_conf(Dir),
     Conf1 = mad_utils:script(Dir, Conf),
@@ -68,38 +76,42 @@ app(Dir) ->
         Files ->
             IncDir = mad_utils:include(Dir),
             EbinDir = mad_utils:ebin(Dir),
+            code:add_path(EbinDir),
             Opts = mad_utils:get_value(erl_opts, Conf1, []),
             mad_utils:exec("mkdir", ["-p", EbinDir]),
-            lists:foreach(compile_fun(SrcDir, IncDir, EbinDir, Opts), Files),
-            code:add_path(EbinDir)
+            lists:foreach(compile_fun(IncDir, EbinDir, Opts), Files),
+            code:add_path(EbinDir),
+            ok
     end.
 
+-spec validate_property({atom(), term()}, term()) -> {atom(), term()}.
 validate_property({modules, _}, Modules) ->
     {modules, Modules};
 validate_property(Else, _) ->
     Else.
 
-compile_fun(SrcDir, IncDir, EbinDir, Opts) ->
-    fun(F) ->
-            code:add_path(EbinDir),
-            F1 = filename:join(SrcDir, F),
-            case is_app_src(F1) of
+-spec compile_fun(directory(), directory(), [compile:option()]) ->
+                         fun((file:name()) -> ok).
+compile_fun(IncDir, EbinDir, Opts) ->
+    fun(File) ->
+            case is_app_src(File) of
                 false ->
-                    Compiled = is_compiled(EbinDir, F1),
+                    Compiled = is_compiled(EbinDir, File),
                     if Compiled =:= false ->
-                            io:format("Compiling ~s~n", [F1]),
-                            compile:file(F1, ?COMPILE_OPTS(IncDir, EbinDir) ++ Opts);
+                            io:format("Compiling ~s~n", [File]),
+                            Opts1 = ?COMPILE_OPTS(IncDir, EbinDir, Opts),
+                            compile:file(File, Opts1);
                        true ->
                             ok
                     end;
                 true ->
                     %% add {modules, [Modules]} to .app file
-                    AppFile = filename:join(EbinDir, app_src_to_app(F1)),
+                    AppFile = filename:join(EbinDir, app_src_to_app(File)),
                     io:format("Writing ~s~n", [AppFile]),
                     BeamFiles = filelib:wildcard("*.beam", EbinDir),
                     Modules = [list_to_atom(filename:basename(X, ".beam"))
                                || X <- BeamFiles],
-                    [Struct|_] = mad_utils:consult(F1),
+                    [Struct|_] = mad_utils:consult(File),
                     {application, AppName, Props} = Struct,
                     Props1 = add_modules_property(Props),
                     Props2 = [validate_property(X, Modules) || X <- Props1],
@@ -108,25 +120,34 @@ compile_fun(SrcDir, IncDir, EbinDir, Opts) ->
             end
     end.
 
+%% find all .erl files in Dir
+-spec erl_files(directory()) -> [file:name()].
 erl_files(Dir) ->
     filelib:fold_files(Dir, ".erl", true, fun(F, Acc) -> [F|Acc] end, []).
 
+%% find all .app.src files in Dir
+-spec app_src_files(directory()) -> [file:name()].
 app_src_files(Dir) ->
     filelib:fold_files(Dir, ".app.src", true, fun(F, Acc) -> [F|Acc] end, []).
 
+-spec is_app_src(file:name()) -> boolean().
 is_app_src(Filename) ->
     Filename =/= filename:rootname(Filename, ".app.src").
 
+-spec app_src_to_app(file:name()) -> file:name().
 app_src_to_app(Filename) ->
     filename:basename(Filename, ".app.src") ++ ".app".
 
+-spec erl_to_beam(directory(), file:name()) -> file:name().
 erl_to_beam(EbinDir, Filename) ->
     filename:join(EbinDir, filename:basename(Filename, ".erl") ++ ".beam").
 
+-spec is_compiled(directory(), file:name()) -> boolean().
 is_compiled(EbinDir, ErlFile) ->
     BeamFile = erl_to_beam(EbinDir, ErlFile),
     mad_utils:last_modified(BeamFile) > mad_utils:last_modified(ErlFile).
 
+-spec add_modules_property([{atom(), term()}]) -> [{atom(), term()}].
 add_modules_property(Properties) ->
     case lists:keyfind(modules, 1, Properties) of
         {modules, _} ->
@@ -135,9 +156,12 @@ add_modules_property(Properties) ->
             Properties ++ [{modules, []}]
     end.
 
+-spec sort([file:name()]) -> [file:name()].
 sort(Files) ->
     sort_by_priority(Files, [], [], []).
 
+-spec sort_by_priority([file:name()], [file:name()], [file:name()], [file:name()])
+                      -> [file:name()].
 sort_by_priority([], High, Medium, Low) ->
     (High ++ Medium) ++ Low;
 sort_by_priority([H|T], High, Medium, Low) ->

+ 1 - 0
src/mad_deps.erl

@@ -15,6 +15,7 @@
 -type version_control() :: git | hg.
 -type repo() :: {version_control(), uri(), {branch | tag, string()} | string()}.
 -type dependency() :: {name(), string(), repo()}.
+-export_type([dependency/0]).
 
 
 -spec repos_path() -> directory().

+ 18 - 3
test/mad_compile_SUITE.erl

@@ -6,8 +6,9 @@
 -export([is_app_src/1]).
 -export([app_src_to_app/1]).
 -export([erl_to_beam/1]).
--export([is_compiled/1]).
 -export([deps/1]).
+-export([app/1]).
+-export([is_compiled/1]).
 
 -import(helper, [get_value/2]).
 
@@ -15,7 +16,7 @@
 all() ->
     [
      erl_files, app_src_files, is_app_src, app_src_to_app, erl_to_beam, deps,
-     is_compiled
+     app, is_compiled
     ].
 
 erl_files(Config) ->
@@ -50,7 +51,21 @@ deps(Config) ->
     ok = application:load(one),
     ok = application:load(two),
     {ok, [one]} = application:get_key(one, modules),
-    {ok, [two]} = application:get_key(two, modules).
+    {ok, [two]} = application:get_key(two, modules),
+
+    ok = one:test_inc_hrl(),
+    ok = one:test_src_hrl(),
+    ok = two:test_inc_hrl(),
+    ok = two:test_src_hrl().
+
+app(Config) ->
+    DataDir = get_value(data_dir, Config),
+    ok = mad_compile:app(DataDir),
+    pong = three:ping(),
+    ok = application:load(three),
+    {ok, [three]} = application:get_key(three, modules),
+    ok = three:test_inc_hrl(),
+    ok = three:test_src_hrl().
 
 is_compiled(Config) ->
     DataDir = get_value(data_dir, Config),

+ 1 - 0
test/mad_compile_SUITE_data/deps/one/include/one_inc.hrl

@@ -0,0 +1 @@
+-define(INC_HRL, ok).

+ 10 - 0
test/mad_compile_SUITE_data/deps/one/src/one.erl

@@ -1,4 +1,14 @@
 -module(one).
+
 -export([ping/0]).
+-export([test_inc_hrl/0]).
+-export([test_src_hrl/0]).
+
+-include("one_src.hrl").
+-include_lib("one_inc.hrl").
 
 ping() -> pong.
+
+test_inc_hrl() -> ?INC_HRL.
+
+test_src_hrl() -> ?SRC_HRL.

+ 1 - 0
test/mad_compile_SUITE_data/deps/one/src/one_src.hrl

@@ -0,0 +1 @@
+-define(SRC_HRL, ok).

+ 1 - 0
test/mad_compile_SUITE_data/deps/two/include/two_inc.hrl

@@ -0,0 +1 @@
+test_inc_hrl() -> ok.

+ 6 - 0
test/mad_compile_SUITE_data/deps/two/src/two.erl

@@ -1,4 +1,10 @@
 -module(two).
+
 -export([ping/0]).
+-export([test_inc_hrl/0]).
+-export([test_src_hrl/0]).
 
 ping() -> pong.
+
+-include_lib("two_inc.hrl").
+-include("two_src.hrl").

+ 1 - 0
test/mad_compile_SUITE_data/deps/two/src/two_src.hrl

@@ -0,0 +1 @@
+test_src_hrl() -> ok.

+ 1 - 0
test/mad_compile_SUITE_data/include/three_inc.hrl

@@ -0,0 +1 @@
+test_inc_hrl() -> ok.

+ 11 - 0
test/mad_compile_SUITE_data/src/three.app.src

@@ -0,0 +1,11 @@
+{application, three,
+ [
+  {description, ""},
+  {vsn, "1"},
+  {registered, []},
+  {applications, [
+                  kernel,
+                  stdlib
+                 ]},
+  {env, []}
+ ]}.

+ 10 - 0
test/mad_compile_SUITE_data/src/three.erl

@@ -0,0 +1,10 @@
+-module(three).
+
+-export([test_inc_hrl/0]).
+-export([test_src_hrl/0]).
+-export([ping/0]).
+
+ping() -> pong.
+
+-include_lib("three_inc.hrl").
+-include("three_src.hrl").

+ 1 - 0
test/mad_compile_SUITE_data/src/three_src.hrl

@@ -0,0 +1 @@
+test_src_hrl() -> ok.