Created
April 4, 2012 18:46
-
-
Save rambocoder/2304656 to your computer and use it in GitHub Desktop.
Windows Support. Updated start-server.bat for ChicaboBoss skeleton, and ChicagoBoss\priv\rebar\boss_rebar.erl with windows support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%%%------------------------------------------------------------------- | |
%%% @author Jose Luis Gordo Romero <[email protected]> | |
%%% @doc Chicago Boss rebar functions, called from boss_plugin | |
%%% Managing compilation/configuration/scripts stuff, the boss way | |
%%% @end | |
%%%------------------------------------------------------------------- | |
-module(boss_rebar). | |
-export([run/4, | |
help/0, | |
help/3, | |
compile/3, | |
compile/4, | |
test_eunit/3, | |
test_functional/3, | |
start_cmd/3, | |
start_dev_cmd/3, | |
stop_cmd/3, | |
reload_cmd/3, | |
boss_config_value/3, | |
boss_config_value/4, | |
boss_load/2, | |
boss_start/1, | |
all_ebin_dirs/2, | |
init_conf/1, | |
init_conf_test/1]). | |
-define(COMMANDS, | |
[{help, "Lists all commands"}, | |
{compile, "Compile (boss way)"}, | |
{test_eunit, "Run src/test/eunit tests"}, | |
{test_functional, "Run src/test/functional tests"}, | |
{start_cmd, "Generates the start shell command"}, | |
{start_dev_cmd, "Generates the start-dev shell command"}, | |
{stop_cmd, "Generates the stop shell command"}, | |
{reload_cmd, "Generates the hot reload shell command"} | |
]). | |
-define(BOSS_TEST_CONFIG, "boss.test.config"). | |
%%-------------------------------------------------------------------- | |
%% @doc run | |
%% @spec run(Command, RebarConf, BossConf, AppFile) -> ok | {error, Reason} | |
%% Rebar Commands Router | |
%% @end | |
%%-------------------------------------------------------------------- | |
run(Command, RebarConf, BossConf, AppFile) when is_list(Command)-> | |
run(list_to_atom(Command), RebarConf, BossConf, AppFile); | |
run(Command, RebarConf, BossConf, AppFile) -> | |
rebar_log:log(debug, "About to run command '~s'~n", [Command]), | |
case lists:keyfind(Command, 1, ?COMMANDS) of | |
false -> | |
{error, command_not_found}; | |
_ -> | |
apply(boss_rebar, Command, [RebarConf, BossConf, AppFile]) | |
end. | |
%%-------------------------------------------------------------------- | |
%% @doc compile | |
%% @spec compile(RebarConf, BossConf, AppFile) -> ok | {error, Reason} | |
%% Chicago Boss compilation, handling all cb special needs | |
%% @end | |
%%-------------------------------------------------------------------- | |
compile(RebarConf, BossConf, AppFile) -> | |
compile(RebarConf, BossConf, AppFile, "ebin"). | |
%%-------------------------------------------------------------------- | |
%% @doc compile | |
%% @spec compile(_RebarConf, _BossConf, AppFile, Dest) -> | |
%% ok | {error, Reason} | |
%% Chicago Boss compilation, handling all cb special needs | |
%% @end | |
%%-------------------------------------------------------------------- | |
compile(_RebarConf, BossConf, AppFile, Dest) -> | |
init_conf(BossConf), | |
boss_load(BossConf, AppFile), | |
AppName = app_name(AppFile), | |
Res = boss_load:load_all_modules_and_emit_app_file(AppName, Dest), | |
rebar_log:log(info, "Chicago Boss compilation of app ~s on ~s (~s)~n", | |
[AppName, Dest, Res]). | |
%%-------------------------------------------------------------------- | |
%% @doc test_eunit | |
%% @spec test_eunit(_RebarConf, _BossConf, AppFile) -> | |
%% ok | {error, Reason} | |
%% Chicago Boss eunit integration | |
%% @end | |
%%-------------------------------------------------------------------- | |
test_eunit(RebarConf, BossConf, AppFile) -> | |
boss_rebar_eunit:eunit(RebarConf, BossConf, AppFile). | |
%%-------------------------------------------------------------------- | |
%% @doc test_functional | |
%% @spec test_functional(_RebarConf, _BossConf, AppFile) -> | |
%% ok | {error, Reason} | |
%% Chicago Boss functionals test | |
%% API: http://www.chicagoboss.org/api-test.html | |
%% @end | |
%%-------------------------------------------------------------------- | |
test_functional(RebarConf, BossConf, AppFile) -> | |
%% Compile, load all boss ebin dir and start boss | |
init_conf_test(BossConf), | |
boss_rebar:compile(RebarConf, BossConf, AppFile), | |
boss_rebar:boss_load(BossConf, AppFile), | |
boss_rebar:boss_start(BossConf), | |
AppName = app_name(AppFile), | |
boss_web_test:start([atom_to_list(AppName)]). | |
%%-------------------------------------------------------------------- | |
%% @doc start_cmd | |
%% @spec start_cmd(RebarConf, BossConf, AppFile) -> | |
%% ok | {error, Reason} | |
%% Generate start shell command (production) | |
%% @end | |
%%-------------------------------------------------------------------- | |
start_cmd(_RebarConf, BossConf, AppFile) -> | |
rebar_log:log(info, "Generating dynamic start command~n", []), | |
EbinDirs = all_ebin_dirs(BossConf, AppFile), | |
MaxProcesses = max_processes(BossConf), | |
SName = sname(BossConf, AppFile), | |
Cookie = cookie(BossConf), | |
io:format("exec erl +K true +P ~B -pa ~s -boot start_sasl -config boss -s boss -setcookie ~s -detached -sname ~s", | |
[MaxProcesses, string:join(EbinDirs, " -pa "), Cookie, SName]), | |
ok. | |
%%-------------------------------------------------------------------- | |
%% @doc start_dev_cmd | |
%% @spec start_dev_cmd(RebarConf, BossConf, AppFile) -> | |
%% ok | {error, Reason} | |
%% Generate start-dev shell command (development) | |
%% @end | |
%%-------------------------------------------------------------------- | |
start_dev_cmd(_RebarConf, BossConf, AppFile) -> | |
rebar_log:log(info, "Generating dynamic start-dev command~n", []), | |
AppName = app_name(AppFile), | |
SName = sname(BossConf, AppFile), | |
case os:type() of | |
false -> EbinDirs = all_ebin_dirs(BossConf, AppFile), | |
io:format("exec erl -pa ~s -boss developing_app ~s -boot start_sasl -config boss -s reloader -s boss -sname ~s", | |
[string:join(EbinDirs, " -pa "), AppName, SName]); | |
{win32, _ } -> EbinDirs = all_ebin_dirs(windows, BossConf, AppFile), | |
Dirs = io_lib:format("~p", [lists:flatten(EbinDirs)]), %EbinDirs come back as a list of lists [[],[],[]] | |
Cmd = io_lib:format("werl -pa ~s -boss developing_app ~s -boot start_sasl -config boss -s reloader -s boss -sname ~s", [string:join(lists:append(EbinDirs), " -pa "), AppName, SName]), | |
io:format("~s~n", [Cmd]) | |
end, | |
ok. | |
%%-------------------------------------------------------------------- | |
%% @doc stop_cmd | |
%% @spec stop_cmd(RebarConf, BossConf, AppFile) -> ok | {error, Reason} | |
%% Generate stop shell command (production) | |
%% @end | |
%%-------------------------------------------------------------------- | |
stop_cmd(_RebarConf, BossConf, AppFile) -> | |
rebar_log:log(info, "Generating dynamic stop command~n", []), | |
SName = sname(BossConf, AppFile), | |
Cookie = cookie(BossConf), | |
StopCommand = io_lib:format("rpc:call('~s', init, stop, []).", [SName]), | |
io:format("erl -noshell -pa ebin -setcookie ~s -sname stopper_~s -eval \"~s\" -s init stop", | |
[Cookie, SName, StopCommand]), | |
ok. | |
%%-------------------------------------------------------------------- | |
%% @doc reload_cmd | |
%% @spec reload_cmd(RebarConf, BossConf, AppFile) -> ok | {error, Reason} | |
%% Generate hot reload shell command (production) | |
%% @end | |
%%-------------------------------------------------------------------- | |
reload_cmd(_RebarConf, BossConf, AppFile) -> | |
rebar_log:log(info, "Generating dynamic reload command~n", []), | |
SName = sname(BossConf, AppFile), | |
Cookie = cookie(BossConf), | |
ReloadCode = io_lib:format("rpc:call('~s', boss_load, reload_all, [])", [SName]), | |
ReloadRoutes = io_lib:format("rpc:call('~s', boss_web, reload_routes, [])", [SName]), | |
ReloadLangs = io_lib:format("rpc:call('~s', boss_web, reload_all_translations, [])", [SName]), | |
io:format("erl -noshell -pa ebin -setcookie ~s -sname reloader_~s -eval \"~s, ~s, ~s.\" -s init stop", | |
[Cookie, SName, ReloadCode, ReloadRoutes, ReloadLangs]), | |
ok. | |
%%-------------------------------------------------------------------- | |
%% @doc help print known commands | |
%% @spec help(_RebarConf, _BossConf, _AppFile) -> Help | |
%% print known commands | |
%% @end | |
%%-------------------------------------------------------------------- | |
help() -> help(true, true, true). | |
help(_RebarConf, _BossConf, _AppFile) -> | |
S = <<" | |
# Chicago Boss rebar commands | |
# ---------------------------------------------------------------------------- | |
# | |
# For init commands (autogenerated) from boss.config, run: | |
# ./init.sh | |
# Compilation | |
compile Compile sources (compat.) | |
boss c=compile Compile sources (called from compile) | |
# Tests | |
eunit [suite=foo] Run src/test/eunit tests (compat.) | |
boss c=test_eunit [suite=foo] Run src/test/eunit tests | |
boss c=test_functional Run src/test/functional tests | |
# Help | |
boss Show this help | |
boss c=help Show this help | |
">>, | |
io:put_chars(S). | |
%%-------------------------------------------------------------------- | |
%% @doc Get Boss config value app, key, default | |
%% @spec boss_config_value(BossConfig, App, Key, Default) -> | |
%% Value | Default | |
%% Searchs in boss config for a given App and Key, | |
%% Don't return an error, return Default | |
%% @end | |
%%-------------------------------------------------------------------- | |
boss_config_value(BossConf, App, Key, Default) -> | |
case boss_config_value(BossConf, App, Key) of | |
{error, _} -> Default; | |
Value -> Value | |
end. | |
%%-------------------------------------------------------------------- | |
%% @doc Get Boss config value app, key | |
%% @spec boss_config_value(BossConfig, App, Key) -> | |
%% Value | {error, Reason} | |
%% Searchs in boss config for a given App and Key | |
%% @end | |
%%-------------------------------------------------------------------- | |
boss_config_value(BossConf, App, Key) -> | |
case lists:keyfind(App, 1, BossConf) of | |
false -> | |
{error, boss_config_app_not_found}; | |
{App, AppConf} -> | |
case lists:keyfind(Key, 1, AppConf) of | |
false -> | |
{error, boss_config_app_setting_not_found}; | |
{Key, KeyConf} -> | |
KeyConf | |
end | |
end. | |
%%-------------------------------------------------------------------- | |
%% @doc Load all boss and app beam code | |
%% @spec boss_load(BossConfig) | |
%% @end | |
%%-------------------------------------------------------------------- | |
boss_load(BossConf, AppFile) -> | |
%% Get all path-defined apps from boss config | |
%% Exclude current boss app if allready loaded | |
AppCurrent = app_name(AppFile), | |
AllDirs = lists:foldl(fun({App, Config}, Dirs) -> | |
case {lists:keyfind(path, 1, Config), AppCurrent =:= App} of | |
{false, _} -> | |
Dirs; | |
{{path, Path}, true} -> | |
case filelib:is_regular(filename:join(["ebin", atom_to_list(App) ++ ".app"])) of | |
true -> Dirs; | |
false -> [Path|Dirs] | |
end; | |
{{path, Path}, _} -> [Path|Dirs] | |
end end, [], lists:reverse(BossConf)), | |
lists:map(fun(Dir) -> | |
lists:map(fun(B) -> | |
F = string:substr(B, 1, string:len(B) - string:len(".beam")), | |
case code:is_loaded(list_to_atom(filename:basename(F))) of | |
false -> | |
code:load_abs(F); | |
{file, _} -> | |
ok | |
end | |
end, rebar_utils:beams(Dir)) | |
end, AllDirs). | |
%%-------------------------------------------------------------------- | |
%% @doc Start the boss app | |
%% @spec boss_start(BossConfig) | |
%% @end | |
%%-------------------------------------------------------------------- | |
boss_start(_BossConf) -> | |
io:format("Starting boss and waiting all apps to initilize...~n"), | |
ok = boss:start(), | |
BossApps = boss_env:get_env(applications, []), | |
timer:sleep(50), | |
boss_start_wait(BossApps), | |
rebar_log:log(info, "All Boss Apps started~n", []), | |
ok. | |
%%-------------------------------------------------------------------- | |
%% @doc Checks that all boss apps (not core) is started | |
%% @spec boss_start_wait(BossApps::list()) | |
%% @end | |
%%-------------------------------------------------------------------- | |
boss_start_wait([]) -> ok; | |
boss_start_wait([App|Rest]) -> | |
CurrentApps = application:which_applications(), | |
case lists:keyfind(App, 1, CurrentApps) of | |
false -> | |
rebar_log:log(info, "Boss App ~p still not started, waiting...~n", [App]), | |
timer:sleep(50), | |
boss_start_wait([App|Rest]); | |
_ -> | |
rebar_log:log(info, "Boss App ~p started~n", [App]), | |
boss_start_wait(Rest) | |
end. | |
%%-------------------------------------------------------------------- | |
%% @doc Start the boss app | |
%% @spec all_ebin_dirs(BossConf, _AppFile) | |
%% Gets all ebin dirs for the apps defined in boss.config | |
%% @end | |
%%-------------------------------------------------------------------- | |
all_ebin_dirs(BossConf, _AppFile) -> | |
lists:foldl(fun({_App, Config}, EbinDirs) -> | |
case lists:keyfind(path, 1, Config) of | |
false -> EbinDirs; | |
{path, Path} -> | |
MainEbin = filename:join([Path, "ebin"]), | |
filelib:ensure_dir(filename:join([MainEbin, "foobar"])), | |
DepsEbin = filename:join([Path, "deps", "*", "ebin"]), | |
[MainEbin, DepsEbin | EbinDirs] | |
end end, [], lists:reverse(BossConf)). | |
all_ebin_dirs(windows, BossConf, _AppFile) -> | |
lists:foldl(fun({_App, Config}, EbinDirs) -> | |
case lists:keyfind(path, 1, Config) of | |
false -> EbinDirs; | |
{path, Path} -> | |
MainEbin = filename:join([Path, "ebin"]), | |
filelib:ensure_dir(filename:join([MainEbin, "foobar"])), | |
%io:format("Path ~p~n", [Path]), | |
DepsEbins = case file:list_dir(Path++"/deps") of | |
{ok, Dirs} -> lists:map(fun(Dir) -> Path ++ "/deps/" ++ Dir ++ "/ebin" end, Dirs); | |
{error, _Reason} -> [] | |
end, | |
%io:format("DepsEbin count: ~s~n", [lists:map(fun(Dir) -> string:concat(" -pa ", Dir) end, lists:flatten(DepsEbins))]), | |
[lists:append([MainEbin] , DepsEbins) | EbinDirs] % DepsEbins is a list, while MainEbin is a string | |
end end, [], lists:reverse(BossConf)). | |
%%-------------------------------------------------------------------- | |
%% @doc Injects the boss.conf configuration to the boss application | |
%% @spec init_conf(BossConf) | |
%% @end | |
%%-------------------------------------------------------------------- | |
init_conf(BossConf) -> | |
lists:map(fun(AppLine) -> | |
{App, AppConf} = AppLine, | |
lists:map(fun({Conf, Val}) -> | |
application:set_env(App, Conf, Val) | |
end, AppConf) | |
end, BossConf). | |
%%-------------------------------------------------------------------- | |
%% @doc Injects the boss.test.conf configuration file if test file exists | |
%% @spec init_conf_test(BossConf) | |
%% @end | |
%%-------------------------------------------------------------------- | |
init_conf_test(BossConf) -> | |
case file:consult(?BOSS_TEST_CONFIG) of | |
{error,enoent} -> | |
io:format("WARNING: ~p not found, using default boss.config.~n", [?BOSS_TEST_CONFIG]), | |
init_conf(BossConf); | |
{ok, [BossTestConfig]} -> | |
init_conf(BossTestConfig) | |
end. | |
%% =================================================================== | |
%% Internal functions | |
%% =================================================================== | |
app_config(AppFile) -> | |
{ok, AppConfig} = file:consult(AppFile), | |
AppConfig. | |
app_name(AppFile) -> | |
[{application, AppName, _}] = app_config(AppFile), | |
AppName. | |
host_name() -> | |
{ok, Host} = inet:gethostname(), | |
Host. | |
sname(BossConf, AppFile) -> | |
boss_config_value(BossConf, boss, vm_name, io_lib:format("~s@~s", [app_name(AppFile), host_name()])). | |
cookie(BossConf) -> | |
boss_config_value(BossConf, boss, vm_cookie, "abc123"). | |
max_processes(BossConf) -> | |
boss_config_value(BossConf, boss, vm_max_processes, 32768). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@ECHO OFF | |
FOR /F "tokens=*" %%i in ('"rebar.cmd boss c=start_dev_cmd ^| findstr werl"') do set myvar=%%i | |
START "Windows Erlang" %myvar% |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@ECHO OFF | |
@echo 1st:%1 2nd:%2 3rd:%3 4th:%4 | |
SET PWD=%cd% | |
SET APPNAME=%3 | |
for %%* in (.) do set PARENTDIR=%%~n* | |
IF /I "%1"=="all" CALL :all | |
IF /I "%1"=="app" IF /I "%2"=="project" IF [%3] NEQ [] CALL :app | |
:: End of main program | |
GOTO End | |
• | |
• | |
:: Sub5 subroutine starts here | |
:all | |
CALL rebar.cmd get-deps | |
CALL rebar.cmd compile | |
:: Unfortunatelly on Windows I could not get erl.exe -eval to do anything complicated | |
REM CALL erl.exe -pa ebin -pa deps/erlydtl/ebin -eval 'erlydtl:compile("src/boss/boss_html_error_template.dtl", boss_html_error_template, [{out_dir, "ebin"}])' -eval 'erlydtl:compile("src/boss/boss_html_doc_template.dtl", boss_html_doc_template, [{out_dir, "ebin"}])' -noshell -s init stop | |
:: End of Sub5 subroutine | |
GOTO :EOF | |
:clean | |
GOTO :EOF | |
:: example how to invoke: windows-make.cmd app PROJECT=awesomenamess | |
:app | |
CALL rebar.cmd create template=skel dest=../%APPNAME% src=../%PARENTDIR% appid=%APPNAME% skip_deps=true | |
GOTO :EOF | |
:End | |
:: End of batch file |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@Kozlov-V: did you figured it out already?, I have the same problem here..