Permalink
Fetching contributors…
Cannot retrieve contributors at this time
executable file 121 lines (105 sloc) 4.53 KB
#!/usr/bin/env escript
%% -*- mode:erlang;tab-width:4;erlang-indent-level:4;indent-tabs-mode:nil -*-
%% ex: ft=erlang ts=4 sw=4 et
-include_lib("kernel/include/file.hrl").
main(Args) ->
%% Add ebin/ to our path
true = code:add_path("ebin"),
true = code:add_path("deps/mochiweb/ebin"),
true = code:add_path("deps/jsx/ebin"),
true = code:add_path("deps/idna/ebin"),
true = code:add_path("deps/ssl_verify_hostname/ebin"),
true = code:add_path("deps/hackney/ebin"),
true = code:add_path("deps/oauth/ebin"),
true = code:add_path("deps/couchbeam/ebin"),
Base_name = "erica",
%% Run erica to do proper .app validation and such
erica:main(["compile"] ++ Args),
%% Read the contents of the files in ebin and templates; note that we place
%% all the beam files at the top level of the code archive so that code loading
%% works properly.
Files = load_files("*", "ebin")
++ load_files("*", "deps/mochiweb/ebin")
++ load_files("*", "deps/hackney/ebin")
++ load_files("*", "deps/jsx/ebin")
++ load_files("*", "deps/idna/ebin")
++ load_files("*", "deps/hackney/ebin")
++ load_files("*", "deps/oauth/ebin")
++ load_files("*", "deps/couchbeam/ebin")
++ load_files("priv/templates/*", ".")
++ load_files("priv/web_static/*", ".")
++ load_files("priv/web_templates/*", "."),
%% Write the ez archive with a different name/shebang header per platform
case zip:create("mem", Files, [memory]) of
{ok, {"mem", ZipBin}} ->
%% Archive was successfully created. Prefix that binary with our
%% header and write to "rebar" file
Unix_Header = escript_header(unix),
Unix_Script = <<Unix_Header/binary, ZipBin/binary>>,
write_script(Base_name, Unix_Script),
%% On Windows the shebang is different, and the filename needs a suffix
Windows_Header = escript_header(windows),
Windows_Script = <<Windows_Header/binary, ZipBin/binary>>,
write_script(Base_name ++ ".cmd", Windows_Script);
{error, ZipError} ->
io:format("Failed to construct erica archive: ~p\n", [ZipError]),
halt(1)
end,
%% Add a helpful message
io:format("Congratulations! You now have a self-contained script called '~s'~n"
"in your current working directory. Place this script anywhere "
"in your path\nand you can use, build and push your docs and "
"design docs with erica.\n", [Base_name]).
write_script(Filename, Script) ->
case file:write_file(Filename, Script) of
ok ->
ok;
{error, WriteError} ->
io:format("Failed to write erica script: ~p\n", [WriteError]),
halt(1)
end,
%% Finally, update executable perms for the script
{ok, #file_info{mode = Mode}} = file:read_file_info(Filename),
ok = file:change_mode(Filename, Mode bor 8#00100).
load_files(Wildcard, Dir) ->
lists:foldl(fun(Filename, Acc) ->
case lists:member(Filename, [".", ".."]) of
true ->
Acc;
_ ->
case read_file(Filename, Dir) of
{Filename, Bin} ->
[{Filename, Bin}|Acc];
Bins ->
Bins ++ Acc
end
end
end, [], filelib:wildcard(Wildcard, Dir)).
read_file(Filename, Dir) ->
Filename1 = filename:join(Dir, Filename),
case filelib:is_dir(Filename1) of
true ->
load_files(Filename ++ "/*", Dir);
false ->
{ok, Bin} = file:read_file(filename:join(Dir, Filename)),
{Filename, Bin}
end.
escript_header(Os_Type) ->
Shebang = case Os_Type of
windows ->
%% set local environment so that path is clean on exit
%% prepend path to same directory as script to allow loading DLLs
%% start escript using the same script as entry point and append args
%% on return from escript skip to end of .cmd file
<<"@echo off & ",
"setlocal & ",
"path=%~dp0;%path% & ",
"escript.exe \"%~dpn0.cmd\" %* & ",
"endlocal & ",
"goto :eof\r\n">>;
_ ->
%% must be a unix variant
<<"#!/usr/bin/env escript\n">>
end,
%% Erlang VM args are the same across platforms, and must occur in L2 or L3
<<Shebang/binary, "%%! -pa . -noshell -noinput -sasl errlog_type error\n">>.