Browse Source

n2o_sample repl running

Maxim Sokhatsky 10 years ago
parent
commit
0664d44ee8

BIN
mad


+ 3 - 5
otp.mk

@@ -1,9 +1,7 @@
-compile: get-deps
-get-deps compile clean:
+compile: deps
+deps compile clean:
 	./mad $@
 escript: compile
 	./build
-ct: get-deps compile
-	rebar ct skip_deps=true verbose=1
 
-.PHONY: get-deps compile escript ct
+.PHONY: deps compile escript

+ 28 - 0
src/compile/mad_app.erl

@@ -0,0 +1,28 @@
+-module(mad_app).
+-compile(export_all).
+
+app_src_to_app(Filename) -> filename:basename(Filename, ".app.src") ++ ".app".
+
+validate_property({modules, _}, Modules) -> {modules, Modules};
+validate_property(Else, _) -> Else.
+
+compile(File,_Inc,Bin,_Opt) ->
+    AppFile = filename:join(Bin, app_src_to_app(File)),
+    Compiled = mad_compile:is_compiled(AppFile, File),
+    if  Compiled =:= false ->
+    io:format("Writing ~s~n", [AppFile]),
+    BeamFiles = filelib:wildcard("*.beam", Bin),
+    Modules = [list_to_atom(filename:basename(X, ".beam")) || X <- BeamFiles],
+    [Struct|_] = mad_utils:consult(File),
+    {application, AppName, Props} = Struct,
+    Props1 = add_modules_property(Props),
+    Props2 = [validate_property(X, Modules) || X <- Props1],
+    Struct1 = {application, AppName, Props2},
+    file:write_file(AppFile, io_lib:format("~p.~n", [Struct1])),
+    ok;
+    true -> ok end.
+
+add_modules_property(Properties) ->
+    case lists:keyfind(modules, 1, Properties) of
+        {modules, _} -> Properties;
+        _ -> Properties ++ [{modules, []}] end.

+ 54 - 0
src/compile/mad_dtl.erl

@@ -0,0 +1,54 @@
+-module(mad_dtl).
+-compile(export_all).
+
+compile(Dir,Config) ->
+    case mad_utils:get_value(erlydtl_opts, Config, []) of
+        [] -> skip;
+         X -> compile_erlydtl_files(validate_erlydtl_opts(Dir,X)) end.
+
+get_kv(K, Opts, Default) ->
+    V = mad_utils:get_value(K, Opts, Default),
+    KV = {K, V},
+    {KV, Opts -- [KV]}.
+
+file_to_beam(Bin, Filename) -> filename:join(Bin, filename:basename(Filename) ++ ".beam").
+
+validate_erlydtl_opts(Cwd, Opts) ->
+    DefaultDocRoot = filename:join("priv", "templates"),
+    {DocRoot, Opts1} = get_kv(doc_root, Opts, DefaultDocRoot),
+    {OutDir, Opts2} = get_kv(out_dir, Opts1, "ebin"),
+    {CompilerOpts, Opts3} = get_kv(compiler_options, Opts2, []),
+    {SourceExt, Opts4} = get_kv(source_ext, Opts3, ".dtl"),
+    {ModuleExt, Opts5} = get_kv(module_ext, Opts4, ""),
+
+    {_, DocRootDir} = DocRoot,
+    DocRoot1 = {doc_root, filename:join(Cwd, DocRootDir)},
+    {_, OutDir1} = OutDir,
+    OutDir2 = {out_dir, filename:join(Cwd, OutDir1)},
+
+    [DocRoot1, OutDir2, CompilerOpts, SourceExt, ModuleExt|Opts5].
+
+module_name(File, Ext, NewExt) ->
+    list_to_atom(filename:basename(File, Ext) ++ NewExt).
+
+compile_erlydtl_files(Opts) ->
+
+    {{_, DocRoot},   Opts1} = get_kv(doc_root,   Opts,  ""),
+    {{_, SourceExt}, Opts2} = get_kv(source_ext, Opts1, ""),
+    {{_, ModuleExt}, Opts3} = get_kv(module_ext, Opts2, ""),
+    {{_, OutDir},        _} = get_kv(out_dir,    Opts3, ""),
+
+    Files = filelib:fold_files(DocRoot, SourceExt, true,
+                               fun(F, Acc) -> [F|Acc] end, []),
+
+    Compile = fun(F) ->
+        ModuleName = module_name(F, SourceExt, ModuleExt),
+        BeamFile = file_to_beam(OutDir, atom_to_list(ModuleName)),
+        Compiled = mad_compile:is_compiled(BeamFile, F),
+        if  Compiled =:= false ->
+            io:format("DTL Compiling ~s~n", [F]),
+            erlydtl:compile(F, ModuleName, Opts3);
+        true -> ok end
+    end,
+
+    lists:foreach(Compile, Files).

+ 16 - 0
src/compile/mad_erl.erl

@@ -0,0 +1,16 @@
+-module(mad_erl).
+-compile(export_all).
+-define(COMPILE_OPTS(Inc, Ebin, Opts), [report, {i, Inc}, {outdir, Ebin}] ++ Opts).
+
+erl_to_beam(Bin, F) -> filename:join(Bin, filename:basename(F, ".erl") ++ ".beam").
+
+compile(File,Inc,Bin,Opt) ->
+    BeamFile = erl_to_beam(Bin, File),
+    Compiled = mad_compile:is_compiled(BeamFile, File),
+    if  Compiled =:= false ->
+        io:format("Compiling ~s~n", [File]),
+        Opts1 = ?COMPILE_OPTS(Inc, Bin, Opt),
+        compile:file(File, Opts1),
+        ok;
+    true -> ok end.
+

+ 25 - 0
src/compile/mad_port.erl

@@ -0,0 +1,25 @@
+-module(mad_port).
+-compile(export_all).
+
+replace_env(String, []) -> String;
+replace_env(String, [{K,V}|Env]) ->
+   replace_env(re:replace(String, K, V, [global, {return, list}]),Env).
+
+compile(Dir,Config) ->
+    case mad_utils:get_value(port_specs, Config, []) of
+        [] -> skip;
+         X -> compile_port(Dir,X,Config) end.
+
+compile_port(Dir,Specs,Config) ->
+    {_,System} = os:type(),
+    filelib:ensure_dir(Dir ++ "/priv/"),
+    Env = [ {Var,Val} || {System,Var,Val} <- mad_utils:get_value(port_env, Config, []) ],
+    [ begin 
+           Template = string:join(filelib:wildcard(Dir ++ "/" ++ Files)," ") 
+              ++ " CFLAGS LDFLAGS -o " ++ Dir ++ "/" ++ Out,
+       Args = string:strip(replace_env(Template,Env),both,32),
+       {Atom,Status,Report} = sh:run("cc",string:tokens(Args," "),binary,Dir,Env),
+       case Status == 0 of
+          true -> skip;
+          false -> io:format("Port Compilation Error: ~p",[Report]) end
+      end || {System,Out,Files} <- Specs].

+ 11 - 0
src/compile/mad_script.erl

@@ -0,0 +1,11 @@
+-module(mad_script).
+-compile(export_all).
+
+script(ConfigFile, Conf, Name) ->
+    File = ConfigFile ++ ".script",
+    Filename = filename:basename(File),
+    case file:script(File, [{'CONFIG', Conf}, {'SCRIPT', File}]) of
+        {ok, {error,_}} -> Conf;
+        {ok, Out} -> Out;
+        {error, _} -> Conf
+    end.

+ 12 - 0
src/compile/mad_yecc.erl

@@ -0,0 +1,12 @@
+-module(mad_yecc).
+-compile(export_all).
+
+yrl_to_erl(F) -> filename:join(filename:dirname(F),filename:basename(F, ".yrl")) ++ ".erl".
+
+compile(File,Inc,Bin,Opt) ->
+    ErlFile = yrl_to_erl(File),
+    Compiled = mad_compile:is_compiled(ErlFile,File),
+    if Compiled == false ->
+        yecc:file(File),
+        mad_erl:compile(ErlFile,Inc,Bin,Opt); true -> ok end.
+

+ 14 - 21
src/mad.erl

@@ -10,7 +10,7 @@ main(Params) ->
     ConfigFile = "rebar.config",
     ConfigFileAbs = filename:join(Cwd, ConfigFile),
     Conf = mad_utils:consult(ConfigFileAbs),
-    Conf1 = mad_utils:script(ConfigFileAbs, Conf, ""),
+    Conf1 = mad_script:script(ConfigFileAbs, Conf, ""),
 
     %% rebar should create deps dir in deps_dir only, this is not a list
     DepsDir = filename:join([mad_utils:get_value(deps_dir, Conf1, ["deps"]),"*","ebin"]),
@@ -21,12 +21,12 @@ main(Params) ->
     LibDirs = mad_utils:lib_dirs(Cwd, Conf),
     code:add_paths(LibDirs),
 
-    Fun = fun(F) -> Name = list_to_atom(F), ?MODULE:Name(Cwd, ConfigFile, Conf1) end,
+    Fun = fun(F) -> Name = list_to_atom(F), ?MODULE:Name(Cwd, ConfigFile, Conf1,Params) end,
     lists:foreach(Fun, Params).
 
 %% fetch dependencies
-'get-deps'(Cwd, ConfigFile, Conf) ->
-    case get_value(deps, Conf, []) of
+deps(Cwd, ConfigFile, Conf, Params) ->
+    case mad_utils:get_value(deps, Conf, []) of
         [] -> ok;
         Deps ->
             Cache = mad_utils:get_value(deps_dir, Conf, deps_fetch),
@@ -39,27 +39,20 @@ main(Params) ->
     end.
 
 %% compile dependencies and the app
-compile(Cwd, ConfigFile, Conf) ->
-    'compile-deps'(Cwd, ConfigFile, Conf),
-    'compile-apps'(Cwd, ConfigFile, Conf).
+compile(Cwd, ConfigFile, Conf, Params) ->
+    mad_compile:'compile-deps'(Cwd, ConfigFile, Conf),
+    mad_compile:'compile-apps'(Cwd, ConfigFile, Conf).
 
-'compile-apps'(Cwd, ConfigFile, Conf) ->
-    Dirs = mad_utils:sub_dirs(Cwd, ConfigFile, Conf),
-    case Dirs of
-        [] -> mad_compile:dep(Cwd, Conf, ConfigFile, Cwd);
-        Apps -> mad_compile:deps(Cwd, Conf, ConfigFile, Apps) end.
+%% reltool apps resolving
+plan(Cwd,ConfigFileName,Config,Params) ->
+    mad_plan:main(mad_plan:applist()).
 
-'compile-deps'(Cwd, ConfigFile, Conf) ->
-    mad_compile:deps(Cwd, Conf, ConfigFile, get_value(deps, Conf, [])).
-
-get_value(Key, Opts, Default) ->
-    case lists:keyfind(Key, 1, Opts) of
-        {Key, Value} -> Value;
-        _ -> Default end.
+repl(Cwd,ConfigFileName,Config,Params) ->
+    mad_console:main(Params).
 
 help(Reason, Data) -> help(io_lib:format("~s ~p", [Reason, Data])).
 help(Msg) -> io:format("Error: ~s~n~n", [Msg]), help().
 help() ->
-    io:format("Manage Deps~n"),
-    io:format("mad get-deps compile~n"),
+    io:format("SRC VXZ MAD Build Tool version 1.0~n"),
+    io:format("mad deps compile plan start stop repl attach release ~n"),
     halt().

+ 4 - 0
src/mad_attach.erl

@@ -0,0 +1,4 @@
+-module(mad_attach).
+-compile(export_all).
+
+%	to_erl $(RUN_DIR)/

+ 20 - 131
src/mad_compile.erl

@@ -1,7 +1,6 @@
 -module(mad_compile).
 -copyright('Sina Samavati').
 -compile(export_all).
--define(COMPILE_OPTS(Inc, Ebin, Opts), [report, {i, Inc}, {outdir, Ebin}] ++ Opts).
 
 %% compile dependencies
 deps(_, _, _, []) -> ok;
@@ -20,7 +19,7 @@ dep(Cwd, _Conf, ConfigFile, Name) ->
     DepPath = filename:join([Cwd, DepsDir, Name]),
     DepConfigFile = filename:join(DepPath, ConfigFile),
     Conf = mad_utils:consult(DepConfigFile),
-    Conf1 = mad_utils:script(DepConfigFile, Conf, Name),
+    Conf1 = mad_script:script(DepConfigFile, Conf, Name),
     deps(Cwd, Conf, ConfigFile, mad_utils:get_value(deps, Conf1, [])),
 
     %% add lib_dirs to path
@@ -28,7 +27,10 @@ dep(Cwd, _Conf, ConfigFile, Name) ->
     code:add_paths(LibDirs),
 
     SrcDir = filename:join([mad_utils:src(DepPath)]),
-    Files = yrl_files(SrcDir) ++ erl_files(SrcDir) ++ app_src_files(SrcDir),
+
+    Files = files(SrcDir,".yrl") ++ 
+            files(SrcDir,".erl") ++ 
+            files(SrcDir,".app.src"),
 
     case Files of
         [] -> ok;
@@ -43,141 +45,28 @@ dep(Cwd, _Conf, ConfigFile, Name) ->
             Opts = mad_utils:get_value(erl_opts, Conf1, []),
             lists:foreach(compile_fun(IncDir, EbinDir, Opts), Files),
 
-            dtl(DepPath,Conf1),
-            port(DepPath,Conf1),
+            mad_dtl:compile(DepPath,Conf1),
+            mad_port:compile(DepPath,Conf1),
 
             put(Name, compiled),
             ok
     end.
 
+compile_fun(Inc,Bin,Opt) -> fun(File) -> (module(filetype(File))):compile(File,Inc,Bin,Opt) end.
 
-dtl(Dir,Config) ->
-    case mad_utils:get_value(erlydtl_opts, Config, []) of
-        [] -> skip;
-         X -> compile_erlydtl_files(validate_erlydtl_opts(Dir,X)) end.
-
-port(Dir,Config) ->
-    case mad_utils:get_value(port_specs, Config, []) of
-        [] -> skip;
-         X -> compile_port(Dir,X,Config) end.
-
-compile_port(Dir,Specs,Config) ->
-    {_,System} = os:type(),
-    filelib:ensure_dir(Dir ++ "/priv/"),
-    Env = [ {Var,Val} || {System,Var,Val} <- mad_utils:get_value(port_env, Config, []) ],
-    [ begin 
-           Template = string:join(filelib:wildcard(Dir ++ "/" ++ Files)," ") 
-              ++ " CFLAGS LDFLAGS -o " ++ Dir ++ "/" ++ Out,
-       Args = string:strip(replace_env(Template,Env),both,32),
-       {Atom,Status,Report} = sh:run("cc",string:tokens(Args," "),binary,Dir,Env),
-       case Status == 0 of
-          true -> skip;
-          false -> io:format("Port Compilation Error: ~p",[Report]) end
-      end || {System,Out,Files} <- Specs].
-
-replace_env(String, []) -> String;
-replace_env(String, [{K,V}|Env]) ->
-   replace_env(re:replace(String, K, V, [global, {return, list}]),Env).
-
-validate_property({modules, _}, Modules) -> {modules, Modules};
-validate_property(Else, _) -> Else.
+module("erl") -> mad_erl;
+module("yrl") -> mad_yecc;
+module("app.src") -> mad_app.
 
-compile_fun(Inc,Bin,Opt) -> fun(File) -> compile(File,Inc,Bin,Opt,filetype(File)) end.
-filetype(Path) -> "." ++ string:join(tl(string:tokens(filename:basename(Path), ".")), ".").
-
-compile(File,Inc,Bin,Opt,".yrl") ->
-    ErlFile = yrl_to_erl(File),
-    Compiled = is_compiled(ErlFile,File),
-    if Compiled == false ->
-        yecc:file(File),
-        compile(ErlFile,Inc,Bin,Opt,".erl"); true -> ok end;
-compile(File,Inc,Bin,Opt,".erl") ->
-    BeamFile = erl_to_beam(Bin, File),
-    Compiled = is_compiled(BeamFile, File),
-    if  Compiled =:= false ->
-        io:format("Compiling ~s~n", [File]),
-        Opts1 = ?COMPILE_OPTS(Inc, Bin, Opt),
-        compile:file(File, Opts1),
-        ok;
-    true -> ok end;
-compile(File,_Inc,Bin,_Opt,".app.src") ->
-    AppFile = filename:join(Bin, app_src_to_app(File)),
-    Compiled = is_compiled(AppFile, File),
-    if  Compiled =:= false ->
-    io:format("Writing ~s~n", [AppFile]),
-    BeamFiles = filelib:wildcard("*.beam", Bin),
-    Modules = [list_to_atom(filename:basename(X, ".beam")) || X <- BeamFiles],
-    [Struct|_] = mad_utils:consult(File),
-    {application, AppName, Props} = Struct,
-    Props1 = add_modules_property(Props),
-    Props2 = [validate_property(X, Modules) || X <- Props1],
-    Struct1 = {application, AppName, Props2},
-    file:write_file(AppFile, io_lib:format("~p.~n", [Struct1])),
-    ok;
-    true -> ok end;
-compile(File,_Inc,_Bin,_Opt,_) ->
-    io:format("Unknown file type: ~p~n",[File]).
-
-erl_files(Dir) -> filelib:fold_files(Dir, ".erl", true, fun(F, Acc) -> [F|Acc] end, []).
-yrl_files(Dir) -> filelib:fold_files(Dir, ".yrl", true, fun(F, Acc) -> [F|Acc] end, []).
-app_src_files(Dir) -> filelib:fold_files(Dir, ".app.src", false, fun(F, Acc) -> [F|Acc] end, []).
-
-app_src_to_app(Filename) -> filename:basename(Filename, ".app.src") ++ ".app".
-yrl_to_erl(Filename) -> filename:join(filename:dirname(Filename),filename:basename(Filename, ".yrl")) ++ ".erl".
-erl_to_beam(Bin, Filename) -> filename:join(Bin, filename:basename(Filename, ".erl") ++ ".beam").
-file_to_beam(Bin, Filename) -> filename:join(Bin, filename:basename(Filename) ++ ".beam").
+filetype(Path) -> string:join(tl(string:tokens(filename:basename(Path), ".")), ".").
+files(Dir,Ext) -> filelib:fold_files(Dir, Ext, true, fun(F, Acc) -> [F|Acc] end, []).
 is_compiled(BeamFile, File) -> mad_utils:last_modified(BeamFile) >= mad_utils:last_modified(File).
-add_modules_property(Properties) ->
-    case lists:keyfind(modules, 1, Properties) of
-        {modules, _} -> Properties;
-        _ -> Properties ++ [{modules, []}] end.
-
-foreach(_, [], _, _) -> ok;
-foreach(Fun, [Dir|T], Config, ConfigFile) ->
-    Fun(Dir, Config, ConfigFile),
-    foreach(Fun, T, Config, ConfigFile).
-
-get_kv(K, Opts, Default) ->
-    V = mad_utils:get_value(K, Opts, Default),
-    KV = {K, V},
-    {KV, Opts -- [KV]}.
-
-validate_erlydtl_opts(Cwd, Opts) ->
-    DefaultDocRoot = filename:join("priv", "templates"),
-    {DocRoot, Opts1} = get_kv(doc_root, Opts, DefaultDocRoot),
-    {OutDir, Opts2} = get_kv(out_dir, Opts1, "ebin"),
-    {CompilerOpts, Opts3} = get_kv(compiler_options, Opts2, []),
-    {SourceExt, Opts4} = get_kv(source_ext, Opts3, ".dtl"),
-    {ModuleExt, Opts5} = get_kv(module_ext, Opts4, ""),
-
-    {_, DocRootDir} = DocRoot,
-    DocRoot1 = {doc_root, filename:join(Cwd, DocRootDir)},
-    {_, OutDir1} = OutDir,
-    OutDir2 = {out_dir, filename:join(Cwd, OutDir1)},
-
-    [DocRoot1, OutDir2, CompilerOpts, SourceExt, ModuleExt|Opts5].
-
-module_name(File, Ext, NewExt) ->
-    list_to_atom(filename:basename(File, Ext) ++ NewExt).
-
-compile_erlydtl_files(Opts) ->
-
-    {{_, DocRoot},   Opts1} = get_kv(doc_root,   Opts,  ""),
-    {{_, SourceExt}, Opts2} = get_kv(source_ext, Opts1, ""),
-    {{_, ModuleExt}, Opts3} = get_kv(module_ext, Opts2, ""),
-    {{_, OutDir},        _} = get_kv(out_dir,    Opts3, ""),
-
-    Files = filelib:fold_files(DocRoot, SourceExt, true,
-                               fun(F, Acc) -> [F|Acc] end, []),
 
-    Compile = fun(F) ->
-        ModuleName = module_name(F, SourceExt, ModuleExt),
-        BeamFile = file_to_beam(OutDir, atom_to_list(ModuleName)),
-        Compiled = is_compiled(BeamFile, F),
-        if  Compiled =:= false ->
-            io:format("DTL Compiling ~s~n", [F]),
-            erlydtl:compile(F, ModuleName, Opts3);
-        true -> ok end
-    end,
+'compile-apps'(Cwd, ConfigFile, Conf) ->
+    Dirs = mad_utils:sub_dirs(Cwd, ConfigFile, Conf),
+    case Dirs of
+        [] -> mad_compile:dep(Cwd, Conf, ConfigFile, Cwd);
+        Apps -> mad_compile:deps(Cwd, Conf, ConfigFile, Apps) end.
 
-    lists:foreach(Compile, Files).
+'compile-deps'(Cwd, ConfigFile, Conf) ->
+    mad_compile:deps(Cwd, Conf, ConfigFile, mad_utils:get_value(deps, Conf, [])).

+ 14 - 0
src/mad_console.erl

@@ -0,0 +1,14 @@
+-module(mad_console).
+-compile(export_all).
+
+main(Params) ->
+   Config = filelib:wildcard("rels/*/files/sys.config"),
+   case Config of
+      [] -> skip;
+      File ->
+            {ok,[Apps]} = file:consult(File),
+            [  [ begin
+              io:format("~p : ~p = ~p~n",[App,K,V]),
+              application:set_env(App,K,V) end || {K,V} <- Cfg ]  || {App,Cfg} <- Apps]
+             end,
+   [application:start(A)||A<-mad_plan:applist()], user_drv:start(), timer:sleep(infinity).

+ 28 - 0
src/mad_plan.erl

@@ -0,0 +1,28 @@
+-module(mad_plan).
+-compile(export_all).
+
+applist() ->
+    case file:read_file(".applist") of
+         {ok,Binary} -> parse_applist(binary_to_list(Binary)++"."); 
+         {error,Reason} -> main([ list_to_atom(filename:basename(App))
+                             || App <- filelib:wildcard("{apps,deps}/*")  ] -- ['rebar.config']) end.
+
+parse_applist(AppList) ->
+    {ok,Tokens,_EndLine} = erl_scan:string(AppList),
+    {ok,AbsForm} = erl_parse:parse_exprs(Tokens),
+    {value,Value,_Bs} = erl_eval:exprs(AbsForm, erl_eval:new_bindings()),
+    Value.
+
+relconfig(Apps) ->
+    LibDirs = [Dir || Dir <- ["apps", "deps"], case file:read_file_info(Dir) of {ok, _} -> true; _ -> false end],
+    {sys, [{lib_dirs,LibDirs}, {rel,"node","1",Apps}, {profile, embedded},
+           {boot_rel,"node"}, {app,observer,[{incl_cond,exclude}]} ]}.
+
+main(AppList) ->
+    Relconfig = relconfig(AppList),
+    io:format("Relconfig: ~p",[Relconfig]),
+    {ok, Server} = reltool:start_server([{config, Relconfig}]),
+    {ok, {release, _Node, _Erts, Apps}} = reltool_server:get_rel(Server, "node"),
+    Ordered = [element(1, A) || A <- Apps],
+    io:format("Applist Generation: ~w~n", [file:write_file(".applist",io_lib:format("~w",[Ordered]))]),
+    Ordered.

+ 8 - 0
src/mad_start.erl

@@ -0,0 +1,8 @@
+-module(mad_start).
+-compile(export_all).
+
+main(Params) ->
+    sh:run("run_erl",9).
+
+%	RUN_ERL_LOG_GENERATIONS=1000 RUN_ERL_LOG_MAXSIZE=20000000 \
+%	ERL_LIBS=$(ERL_LIBS) run_erl -daemon $(RUN_DIR)/ $(LOG_DIR)/ "exec $(MAKE) console"

+ 16 - 0
src/mad_tool.erl

@@ -0,0 +1,16 @@
+-module(mad_tool).
+-compile(export_all).
+
+main(App) ->
+    EmuArgs = "-noshell -noinput",
+    Files = files(),
+    escript:create(App, [shebang, {comment, ""}, {emu_args, EmuArgs}, {archive, Files, []}]),
+    ok = file:change_mode(App, 8#764).
+
+read_file(File) -> {ok, Bin} = file:read_file(filename:absname(File)), Bin.
+
+files() ->
+    [{filename:basename(F), read_file(F)}
+     || F <- filelib:wildcard(filename:join("ebin", "*")) ++
+             filelib:wildcard(filename:join(["apps", "*", "ebin", "*"])) ++
+             filelib:wildcard(filename:join(["deps", "*", "ebin", "*"]))].