Maxim Sokhatsky 10 лет назад
Родитель
Сommit
8aef035172
5 измененных файлов с 108 добавлено и 42 удалено
  1. BIN
      mad
  2. 3 2
      src/mad.erl
  3. 13 10
      src/mad_bundle.erl
  4. 1 13
      src/mad_plan.erl
  5. 91 17
      src/mad_repl.erl

+ 3 - 2
src/mad.erl

@@ -5,6 +5,7 @@
 
 main([]) -> help();
 main(Params) ->
+    io:format("Bundle: ~p~n\r",[escript:script_name()]),
 
     FP = mad_utils:fold_params(Params),
     io:format("Params: ~p~n\r",[FP]),
@@ -50,8 +51,8 @@ repl(Cwd,ConfigFileName,Config,Params) ->
 
 bundle(Cwd,ConfigFileName,Config,Params) ->
     io:format("Tool Params: ~p~n",[Params]),
-    Name = case Params of [] -> filename:basename(mad_utils:cwd()); E -> E end,
-    mad_bundle:main(Name).
+    Name = case Params of [] -> mad_utils:cwd(); E -> E end,
+    mad_bundle:main(filename:basename(Name)).
 
 help(Reason, Data) -> help(io_lib:format("~s ~p", [Reason, Data])).
 help(Msg) -> io:format("Error: ~s~n~n", [Msg]), help().

+ 13 - 10
src/mad_bundle.erl

@@ -2,16 +2,19 @@
 -compile(export_all).
 
 main(App) ->
-    EmuArgs = "-noshell -noinput -boot start_sasl",
-    Files = files(),
-    escript:create(App, [shebang, {comment, ""}, {emu_args, EmuArgs}, {archive, Files, []}]),
-    ok = file:change_mode(App, 8#764).
+    EmuArgs = "-noshell -noinput",
+    Files = static() ++ beams(),
+    escript:create(App,[shebang,{comment,""},{emu_args,EmuArgs},{archive,Files,[memory]}]),
+    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(["apps", "*", "priv", "templates", "*" ])) ++
-             filelib:wildcard(filename:join(["deps", "*", "ebin", "*"]))].
+static() -> Name = "static.gz",
+    {ok,{File,Bin}} = zip:create(Name,
+        [F || F <- filelib:wildcard("{apps,deps}/*/priv/**"), not filelib:is_dir(F) ],
+        [{compress,all},memory]), [ { Name, Bin } ].
+
+beams() ->
+    [ { filename:basename(F), read_file(F) } || F <-
+        lists:concat([filelib:wildcard(X)||X <- 
+        ["ebin/*","deps/*/ebin/*","apps/*/ebin/*","rels/*/files/sys.config",".applist"]])].

+ 1 - 13
src/mad_plan.erl

@@ -1,25 +1,13 @@
 -module(mad_plan).
 -compile(export_all).
 
-disabled() -> [wx,webtool,ssl,runtime_tools,public_key,observer,inets,asn1,et,eunit,hipe].
-
-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) -> 
-   Res = string:tokens(string:strip(string:strip(AppList,right,$]),left,$[),","),
-   [ list_to_atom(R) || R <-Res ]  -- disabled().
-
 relconfig(Apps) -> {sys, [{lib_dirs,["apps","deps"]}, {rel,"node","1",Apps}, {boot_rel,"node"} ]}.
 
 main(AppList) ->
     Relconfig = relconfig(AppList),
     {ok, Server} = reltool:start_server([{config, Relconfig}]),
     {ok, {release, _Node, _Erts, Apps}} = reltool_server:get_rel(Server, "node"),
-    Ordered = [element(1, A) || A <- Apps] -- disabled(),
+    Ordered = [element(1, A) || A <- Apps] -- mad_repl:disabled(),
     io:format("Ordered: ~p~n",[Ordered]),
     io:format("Applist Generation: ~w~n", [file:write_file(".applist",io_lib:format("~w",[Ordered]))]),
     Ordered.

+ 91 - 17
src/mad_repl.erl

@@ -1,32 +1,106 @@
 -module(mad_repl).
 -compile(export_all).
 
+disabled() -> [wx,webtool,ssl,runtime_tools,public_key,observer,inets,asn1,et,eunit,hipe].
+system() -> [compiler,syntax_tools,sasl,tools,mnesia,reltool,xmerl,crypto,kernel,stdlib].
+
+applist() -> 
+    Name = ".applist",
+    case file:read_file(Name) of
+         {ok,Binary} -> parse_applist(Binary); 
+         {error,Reason} ->
+           case mad_repl:load_file(Name) of
+              <<>> -> main([ list_to_atom(filename:basename(App))
+                || App <- filelib:wildcard("{apps,deps}/*"), filelib:is_dir(App) ]);
+              Plan -> parse_applist(Plan) end end.
+
+parse_applist(AppList) -> 
+   Res = string:tokens(string:strip(string:strip(binary_to_list(AppList),right,$]),left,$[),","),
+   [ list_to_atom(R) || R <-Res ]  -- disabled().
+
 load_config() ->
    Config = filelib:wildcard("rels/*/files/sys.config"),
-   case Config of
-      [] -> skip;
+   Apps = case Config of
+      [] -> case mad_repl:load_file("sys.config") of
+            <<>> -> [];
+            Bin -> parse(binary_to_list(Bin)) end;
       File ->
-            {ok,[Apps]} = file:consult(File),
-            io:format("Configuration:\n\r",[]),
-            [ begin 
-                io:format("\t~p: ~p\n\r",[App,Cfg]),
-                [ application:set_env(App,K,V) || {K,V} <- Cfg ]
-            end || {App,Cfg} <- Apps ]
-   end.
-
-load_apps([]) -> [ application:start(A) ||A<-mad_plan:applist()];
-load_apps(["applist"]) -> [ application:start(A) ||A<-mad_plan:applist()];
-load_apps(Params) -> [application:ensure_all_started(list_to_atom(A))||A<-Params].
+            case file:consult(File) of
+            {error,_} -> [];
+            {ok,[A]} -> A end
+    end,
+    io:format("Configuration: ~p\n\r",[Apps]),
+    [ begin 
+%        io:format("\t~p: ~p\n\r",[App,Cfg]),
+        [ application:set_env(App,K,V) || {K,V} <- Cfg ],
+        {App,Cfg}
+    end || {App,Cfg} <- Apps ].
+
+load_apps([],Config) -> [ begin
+    case lists:member(A,system()) of
+         true -> application:start(A);
+            _ ->
+                 Cfg = load_config(A),
+                 case Cfg of [] -> application:start(A);
+                              E -> 
+%                 io:format("User Application Start: ~p~n\r",[A]),
+                              application:start(E) end end
+
+    end || A <- applist()];
+load_apps(["applist"],Config) -> load_apps([],Config);
+load_apps(Params,Config) -> [ application:ensure_all_started(list_to_atom(A))||A<-Params].
+
+cwd() -> {ok, Cwd} = file:get_cwd(), Cwd.
 
 main(Params) -> 
     SystemPath = filelib:wildcard(code:root_dir() ++ 
-              "/lib/{compiler,syntax_tools,sasl,tools,mnesia,reltool,xmerl,crypto,kernel,stdlib}-*/ebin"),
+      "/lib/{"++ string:join([atom_to_list(X)||X<-mad_repl:system()],",") ++ "}-*/ebin"),
     UserPath = filelib:wildcard("{apps,deps}/*/ebin"),
     code:set_path(SystemPath++UserPath),
-    io:format("Applications: ~p\n\r",[mad_plan:applist()]),
-    load_config(),
+    code:add_path(filename:join([cwd(),filename:basename(escript:script_name())])),
+    load(),
+    io:format("Applications: ~p\n\r",[applist()]),
+    Config = load_config(),
+
     user_drv:start(),
-    load_apps(Params),
+
+    load_apps(Params,Config),
     case Params of
         ["applist"] -> skip;
         _ ->  timer:sleep(infinity) end.
+
+load() ->
+
+    ets:new(filesystem,[set,named_table,{keypos,1},public]),
+
+    {ok,Sections} = escript:extract(escript:script_name(),[]),
+    [Bin] = [B||{archive,B}<-Sections],
+    unfold_zips(Bin).
+
+unfold_zips(Bin) ->
+    {ok,Unzip} = zip:unzip(Bin,[memory]),
+    [ begin
+%        io:format("Unzip: ~p~n\r",[U]),
+        ets:insert(filesystem,{U,FileBin}),
+        case U of
+            "static.gz" -> unfold_zips(FileBin);
+            _ -> skip end
+      end || {U,FileBin} <- Unzip].
+
+load_file(Name)  ->
+    case ets:lookup(filesystem,Name) of
+        [{Name,Bin}] -> Bin;
+        _ -> <<>> end.
+
+load_config(A) when is_atom(A) -> load_config(atom_to_list(A));
+load_config(A) when is_list(A) ->
+    Name = A ++".app",
+    case ets:lookup(filesystem,Name) of
+        [{Name,Bin}] -> parse(binary_to_list(Bin));
+        _ -> [] end.
+
+parse(String) ->
+    {ok,Tokens,_EndLine} = erl_scan:string(String),
+    {ok,AbsForm} = erl_parse:parse_exprs(Tokens),
+    {value,Value,_Bs} = erl_eval:exprs(AbsForm, erl_eval:new_bindings()),
+    Value.