From e390e61cf7d678eac21b5eae6b64ee82304efa9a Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 27 Dec 2012 09:45:20 -0500 Subject: remove print statements that got left in And made it through code review!!! --- src/rcl_prv_overlay.erl | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index af914ee..243df99 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -182,10 +182,8 @@ do_overlay(State, OverlayVars) -> Overlays -> handle_errors(State, ec_plists:map(fun(Overlay) -> - io:format("--->Doing ~p~n", [Overlay]), Res = do_individual_overlay(State, OverlayVars, Overlay), - io:format("-->Done ~p~n", [Overlay]), Res end, Overlays)) end. @@ -206,16 +204,12 @@ handle_errors(State, Result) -> {ok, rcl_state:t()} | relcool:error(). do_individual_overlay(State, OverlayVars, {mkdir, Dir}) -> ModuleName = make_template_name("rcl_mkdir_template", Dir), - io:format("compiling to ~p ~n", [ModuleName]), case erlydtl:compile(erlang:iolist_to_binary(Dir), ModuleName) of {ok, ModuleName} -> - io:format("compiled ~n"), case render(ModuleName, OverlayVars) of {ok, IoList} -> - io:format("rendered ~n"), Absolute = filename:absname(filename:join(rcl_state:root_dir(State), erlang:iolist_to_binary(IoList))), - io:format("got ~p ~n", [Absolute]), case rcl_util:mkdir_p(Absolute) of {error, Error} -> ?RCL_ERROR({unable_to_make_dir, Absolute, Error}); @@ -267,7 +261,6 @@ render_template(OverlayVars, FromFile, ToFile) -> Good when Good =:= ok; ok =:= {ok, TemplateName} -> case render(TemplateName, OverlayVars) of {ok, IoData} -> - io:format("Rendering ~p~n", [IoData]), case filelib:ensure_dir(ToFile) of ok -> case file:write_file(ToFile, IoData) of -- cgit v1.2.3 From b87e030af2e3120ea4a6950c9808285897ce7be9 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 27 Dec 2012 10:18:05 -0500 Subject: splint out render and write so we can reuse the render --- src/rcl_prv_overlay.erl | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index 243df99..7e8b369 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -247,38 +247,47 @@ do_individual_overlay(State, OverlayVars, {template, From, To}) -> fun(FromFile) -> file_render_do(State, OverlayVars, To, ToTemplateName, fun(ToFile) -> - render_template(OverlayVars, - erlang:binary_to_list(FromFile), - ToFile) + write_template(OverlayVars, + erlang:binary_to_list(FromFile), + ToFile) end) end). --spec render_template(proplists:proplist(), iolist(), file:name()) -> +-spec render_template(proplists:proplist(), iolist()) -> ok | relcool:error(). -render_template(OverlayVars, FromFile, ToFile) -> - TemplateName = make_template_name("rcl_template_renderer", FromFile), - case erlydtl:compile(FromFile, TemplateName) of +render_template(OverlayVars, Data) -> + TemplateName = make_template_name("rcl_template_renderer", Data), + case erlydtl:compile(Data, TemplateName) of Good when Good =:= ok; ok =:= {ok, TemplateName} -> case render(TemplateName, OverlayVars) of {ok, IoData} -> - case filelib:ensure_dir(ToFile) of + {ok, IoData}; + {error, Reason} -> + ?RCL_ERROR({unable_to_render_template, Data, Reason}) + end; + {error, Reason} -> + ?RCL_ERROR({unable_to_compile_template, Data, Reason}) + end. + +write_template(OverlayVars, FromFile, ToFile) -> + case render_template(OverlayVars, FromFile) of + {ok, IoData} -> + case filelib:ensure_dir(ToFile) of + ok -> + case file:write_file(ToFile, IoData) of ok -> - case file:write_file(ToFile, IoData) of - ok -> - ok; - {error, Reason} -> - ?RCL_ERROR({unable_to_write, ToFile, Reason}) - end; + ok; {error, Reason} -> - ?RCL_ERROR({unable_to_enclosing_dir, ToFile, Reason}) + ?RCL_ERROR({unable_to_write, ToFile, Reason}) end; {error, Reason} -> - ?RCL_ERROR({unable_to_render_template, FromFile, Reason}) + ?RCL_ERROR({unable_to_enclosing_dir, ToFile, Reason}) end; - {error, Reason} -> - ?RCL_ERROR({unable_to_compile_template, FromFile, Reason}) + Error -> + Error end. + -spec file_render_do(rcl_state:t(), proplists:proplist(), iolist(), module(), fun((term()) -> {ok, rcl_state:t()} | relcool:error())) -> {ok, rcl_state:t()} | relcool:error(). -- cgit v1.2.3 From 901f020a4e0e5635b2d242f75ead571830395a06 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 27 Dec 2012 11:54:38 -0500 Subject: suport variables in vars files of overlays --- src/rcl_prv_overlay.erl | 48 +++++++++++++++++++++++++++++++++++++++++++-- test/rclt_release_SUITE.erl | 8 ++++++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index 7e8b369..d7fcc1b 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -112,11 +112,55 @@ get_overlay_vars_from_file(State, OverlayVars) -> read_overlay_vars(State, OverlayVars, FileName) -> case file:consult(FileName) of {ok, Terms} -> - do_overlay(State, OverlayVars ++ Terms); + case render_overlay_vars(OverlayVars, Terms, []) of + {ok, NewTerms} -> + do_overlay(State, NewTerms ++ OverlayVars); + Error -> + Error + end; {error, Reason} -> ?RCL_ERROR({unable_to_read_varsfile, FileName, Reason}) end. +-spec render_overlay_vars(proplists:proplist(), proplists:proplist(), + proplists:proplist()) -> + {ok, proplists:proplist()} | relcool:error(). +render_overlay_vars(OverlayVars, [{Key, Value} | Rest], Acc) + when erlang:is_list(Value) -> + case io_lib:printable_list(Value) of + true -> + case render_template(Acc ++ OverlayVars, erlang:iolist_to_binary(Value)) of + {ok, Data} -> + %% Adding to the end sucks, but ordering needs to be retained + render_overlay_vars(OverlayVars, Rest, Acc ++ [{Key, Data}]); + Error -> + Error + end; + false -> + case render_overlay_vars(Acc ++ OverlayVars, Value, []) of + {ok, NewValue} -> + render_overlay_vars(OverlayVars, Rest, Acc ++ [{Key, NewValue}]); + Error -> + Error + end + end; +render_overlay_vars(OverlayVars, [{Key, Value} | Rest], Acc) + when erlang:is_binary(Value) -> + case render_template(Acc ++ OverlayVars, erlang:iolist_to_binary(Value)) of + {ok, Data} -> + render_overlay_vars(OverlayVars, Rest, Acc ++ [{Key, erlang:iolist_to_binary(Data)}]); + Error -> + Error + end; +render_overlay_vars(OverlayVars, [KeyValue | Rest], Acc) -> + render_overlay_vars(OverlayVars, Rest, Acc ++ KeyValue); +render_overlay_vars(_OverlayVars, [], Acc) -> + {ok, Acc}. + + + + + -spec generate_release_vars(rcl_release:t()) -> proplists:proplist(). generate_release_vars(Release) -> [{erts_vsn, rcl_release:erts(Release)}, @@ -258,7 +302,7 @@ do_individual_overlay(State, OverlayVars, {template, From, To}) -> render_template(OverlayVars, Data) -> TemplateName = make_template_name("rcl_template_renderer", Data), case erlydtl:compile(Data, TemplateName) of - Good when Good =:= ok; ok =:= {ok, TemplateName} -> + Good when Good =:= ok; Good =:= {ok, TemplateName} -> case render(TemplateName, OverlayVars) of {ok, IoData} -> {ok, IoData}; diff --git a/test/rclt_release_SUITE.erl b/test/rclt_release_SUITE.erl index f4f0ecc..890a24b 100644 --- a/test/rclt_release_SUITE.erl +++ b/test/rclt_release_SUITE.erl @@ -269,6 +269,7 @@ overlay_release(Config) -> VarsFile = filename:join([LibDir1, "vars.config"]), write_config(VarsFile, [{yahoo, "yahoo"}, {yahoo2, [{foo, "bar"}]}, + {yahoo3, [{bar, "{{yahoo}}/{{yahoo2.foo}}"}]}, {foo_dir, "foodir"}]), TemplateFile = filename:join([LibDir1, "test_template"]), @@ -358,7 +359,9 @@ overlay_release(Config) -> ?assertEqual("bar", proplists:get_value(yahoo2_foo, TemplateData)), ?assertEqual("foodir", - proplists:get_value(foo_dir, TemplateData)). + proplists:get_value(foo_dir, TemplateData)), + ?assertEqual("yahoo/bar", + proplists:get_value(yahoo3, TemplateData)). %%%=================================================================== %%% Helper Functions @@ -436,4 +439,5 @@ test_template_contents() -> "{default_release, \"{{default_release}}\"}.\n" "{yahoo, \"{{yahoo}}\"}.\n" "{yahoo2_foo, \"{{yahoo2.foo}}\"}.\n" - "{foo_dir, \"{{foo_dir}}\"}.\n". + "{foo_dir, \"{{foo_dir}}\"}.\n" + "{yahoo3, \"{{yahoo3.bar}}\"}.\n". -- cgit v1.2.3 From 58a82fd5970aa098826ad65f32cc3dab34fb1da6 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 27 Dec 2012 17:45:32 -0500 Subject: support file->directory copies in overlay --- src/rcl_prv_overlay.erl | 73 ++++++++++++++++++++++++++------------------- test/rclt_release_SUITE.erl | 3 ++ 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index d7fcc1b..aa27bd6 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -28,6 +28,8 @@ do/1, format_error/1]). +-define(DIRECTORY_RE, ".*(\/|\\\\)$"). + -include_lib("relcool/include/relcool.hrl"). %%============================================================================ @@ -153,14 +155,10 @@ render_overlay_vars(OverlayVars, [{Key, Value} | Rest], Acc) Error end; render_overlay_vars(OverlayVars, [KeyValue | Rest], Acc) -> - render_overlay_vars(OverlayVars, Rest, Acc ++ KeyValue); + render_overlay_vars(OverlayVars, Rest, Acc ++ [KeyValue]); render_overlay_vars(_OverlayVars, [], Acc) -> {ok, Acc}. - - - - -spec generate_release_vars(rcl_release:t()) -> proplists:proplist(). generate_release_vars(Release) -> [{erts_vsn, rcl_release:erts(Release)}, @@ -226,9 +224,8 @@ do_overlay(State, OverlayVars) -> Overlays -> handle_errors(State, ec_plists:map(fun(Overlay) -> - Res = do_individual_overlay(State, OverlayVars, - Overlay), - Res + do_individual_overlay(State, OverlayVars, + Overlay) end, Overlays)) end. @@ -252,8 +249,7 @@ do_individual_overlay(State, OverlayVars, {mkdir, Dir}) -> {ok, ModuleName} -> case render(ModuleName, OverlayVars) of {ok, IoList} -> - Absolute = filename:absname(filename:join(rcl_state:root_dir(State), - erlang:iolist_to_binary(IoList))), + Absolute = absolutize(State, IoList), case rcl_util:mkdir_p(Absolute) of {error, Error} -> ?RCL_ERROR({unable_to_make_dir, Absolute, Error}); @@ -269,34 +265,48 @@ do_individual_overlay(State, OverlayVars, {mkdir, Dir}) -> do_individual_overlay(State, OverlayVars, {copy, From, To}) -> FromTemplateName = make_template_name("rcl_copy_from_template", From), ToTemplateName = make_template_name("rcl_copy_to_template", To), - file_render_do(State, OverlayVars, From, FromTemplateName, + file_render_do(OverlayVars, From, FromTemplateName, fun(FromFile) -> - file_render_do(State, OverlayVars, To, ToTemplateName, + file_render_do(OverlayVars, To, ToTemplateName, fun(ToFile) -> - filelib:ensure_dir(ToFile), - case ec_file:copy(FromFile, ToFile) of - ok -> - ok; - {error, Err} -> - ?RCL_ERROR({copy_failed, - FromFile, - ToFile, Err}) - end + copy_to(State, FromFile, ToFile) end) end); do_individual_overlay(State, OverlayVars, {template, From, To}) -> FromTemplateName = make_template_name("rcl_template_from_template", From), ToTemplateName = make_template_name("rcl_template_to_template", To), - file_render_do(State, OverlayVars, From, FromTemplateName, + file_render_do(OverlayVars, From, FromTemplateName, fun(FromFile) -> - file_render_do(State, OverlayVars, To, ToTemplateName, + file_render_do(OverlayVars, To, ToTemplateName, fun(ToFile) -> write_template(OverlayVars, - erlang:binary_to_list(FromFile), - ToFile) + erlang:binary_to_list(absolutize(State, FromFile)), + absolutize(State, ToFile)) end) end). +-spec copy_to(rcl_state:t(), file:name(), file:name()) -> ok | relcool:error(). +copy_to(State, FromFile0, ToFile0) -> + ToFile1 = absolutize(State, ToFile0), + FromFile1 = absolutize(State, FromFile0), + ToFile2 = case re:run(ToFile0, ?DIRECTORY_RE) of + nomatch -> + filelib:ensure_dir(ToFile1), + ToFile1; + _ -> + rcl_util:mkdir_p(ToFile1), + erlang:iolist_to_binary(filename:join(ToFile1, + filename:basename(FromFile1))) + end, + case ec_file:copy(FromFile1, ToFile2) of + ok -> + ok; + {error, Err} -> + ?RCL_ERROR({copy_failed, + FromFile1, + ToFile1, Err}) + end. + -spec render_template(proplists:proplist(), iolist()) -> ok | relcool:error(). render_template(OverlayVars, Data) -> @@ -331,18 +341,15 @@ write_template(OverlayVars, FromFile, ToFile) -> Error end. - --spec file_render_do(rcl_state:t(), proplists:proplist(), iolist(), module(), +-spec file_render_do(proplists:proplist(), iolist(), module(), fun((term()) -> {ok, rcl_state:t()} | relcool:error())) -> {ok, rcl_state:t()} | relcool:error(). -file_render_do(State, OverlayVars, Data, TemplateName, NextAction) -> +file_render_do(OverlayVars, Data, TemplateName, NextAction) -> case erlydtl:compile(erlang:iolist_to_binary(Data), TemplateName) of {ok, TemplateName} -> case render(TemplateName, OverlayVars) of {ok, IoList} -> - Absolute = filename:absname(filename:join(rcl_state:root_dir(State), - erlang:iolist_to_binary(IoList))), - NextAction(Absolute); + NextAction(IoList); {error, Error} -> ?RCL_ERROR({render_failed, Data, Error}) end; @@ -368,3 +375,7 @@ render(ModuleName, OverlayVars) -> _:Reason -> {error, Reason} end. + +absolutize(State, FileName) -> + filename:absname(filename:join(rcl_state:root_dir(State), + erlang:iolist_to_binary(FileName))). diff --git a/test/rclt_release_SUITE.erl b/test/rclt_release_SUITE.erl index 890a24b..06644ee 100644 --- a/test/rclt_release_SUITE.erl +++ b/test/rclt_release_SUITE.erl @@ -260,6 +260,8 @@ overlay_release(Config) -> {overlay, [{mkdir, "{{target_dir}}/fooo"}, {copy, OverlayVars, "{{target_dir}}/{{foo_dir}}/vars.config"}, + {copy, OverlayVars, + "{{target_dir}}/{{yahoo}}/"}, {template, Template, "{{target_dir}}/test_template_resolved"}]}, {release, {foo, "0.0.1"}, @@ -293,6 +295,7 @@ overlay_release(Config) -> ?assert(ec_file:exists(filename:join(OutputDir, "fooo"))), ?assert(ec_file:exists(filename:join([OutputDir, "foodir", "vars.config"]))), + ?assert(ec_file:exists(filename:join([OutputDir, "yahoo", "vars.config"]))), TemplateData = case file:consult(filename:join([OutputDir, test_template_resolved])) of {ok, Details} -> -- cgit v1.2.3 From 8c22ae33056a406fe2baf180d16e3fb090638508 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 28 Dec 2012 10:08:26 -0500 Subject: make overlays synchronous People seem to expect overlays to happen in order. This patch changes overlays such that they happen one at a time. --- src/rcl_prv_overlay.erl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index aa27bd6..160629b 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -223,10 +223,10 @@ do_overlay(State, OverlayVars) -> {ok, State}; Overlays -> handle_errors(State, - ec_plists:map(fun(Overlay) -> - do_individual_overlay(State, OverlayVars, - Overlay) - end, Overlays)) + lists:map(fun(Overlay) -> + do_individual_overlay(State, OverlayVars, + Overlay) + end, Overlays)) end. -spec handle_errors(rcl_state:t(), [ok | relcool:error()]) -> -- cgit v1.2.3 From b5b6cf855b3bceaac76ccd330d64cfeb2b1f4c14 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 28 Dec 2012 10:21:37 -0500 Subject: make directory checking more robust --- src/rcl_prv_overlay.erl | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index 160629b..9670138 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -289,11 +289,11 @@ do_individual_overlay(State, OverlayVars, {template, From, To}) -> copy_to(State, FromFile0, ToFile0) -> ToFile1 = absolutize(State, ToFile0), FromFile1 = absolutize(State, FromFile0), - ToFile2 = case re:run(ToFile0, ?DIRECTORY_RE) of - nomatch -> + ToFile2 = case is_directory(ToFile0, ToFile1) of + false -> filelib:ensure_dir(ToFile1), ToFile1; - _ -> + true -> rcl_util:mkdir_p(ToFile1), erlang:iolist_to_binary(filename:join(ToFile1, filename:basename(FromFile1))) @@ -307,6 +307,16 @@ copy_to(State, FromFile0, ToFile0) -> ToFile1, Err}) end. +-spec is_directory(file:name(), file:name()) -> boolean(). +is_directory(ToFile0, ToFile1) -> + case re:run(ToFile0, ?DIRECTORY_RE) of + nomatch -> + filelib:is_dir(ToFile1); + _ -> + true + end. + + -spec render_template(proplists:proplist(), iolist()) -> ok | relcool:error(). render_template(OverlayVars, Data) -> -- cgit v1.2.3 From ae2e47e811ef113c0e6ab1df2bb66a4917f7ea07 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 28 Dec 2012 11:47:35 -0500 Subject: support the ability to *not* autogenerate start scripts --- src/rcl_prv_assembler.erl | 17 +++++++++++----- test/rclt_release_SUITE.erl | 47 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/rcl_prv_assembler.erl b/src/rcl_prv_assembler.erl index a721b12..61f6dad 100644 --- a/src/rcl_prv_assembler.erl +++ b/src/rcl_prv_assembler.erl @@ -210,11 +210,18 @@ write_bin_file(State, Release, OutputDir, RelDir) -> ErlOpts = rcl_state:get(State, erl_opts, ""), StartFile = bin_file_contents(RelName, RelVsn, rcl_release:erts(Release), - ErlOpts), - ok = file:write_file(VsnRel, StartFile), - ok = file:change_mode(VsnRel, 8#777), - ok = file:write_file(BareRel, StartFile), - ok = file:change_mode(BareRel, 8#777), + ErlOpts), + %% We generate the start script by default, unless the user + %% tells us not too + case rcl_state:get(State, generate_start_script, true) of + false -> + ok; + _ -> + ok = file:write_file(VsnRel, StartFile), + ok = file:change_mode(VsnRel, 8#777), + ok = file:write_file(BareRel, StartFile), + ok = file:change_mode(BareRel, 8#777) + end, copy_or_generate_sys_config_file(State, Release, OutputDir, RelDir). %% @doc copy config/sys.config or generate one to releases/VSN/sys.config diff --git a/test/rclt_release_SUITE.erl b/test/rclt_release_SUITE.erl index 06644ee..848c129 100644 --- a/test/rclt_release_SUITE.erl +++ b/test/rclt_release_SUITE.erl @@ -25,6 +25,7 @@ init_per_testcase/2, all/0, make_release/1, + make_scriptless_release/1, make_overridden_release/1, make_rerun_overridden_release/1, make_implicit_config_release/1, @@ -52,8 +53,9 @@ init_per_testcase(_, Config) -> {state, State} | Config]. all() -> - [make_release, make_overridden_release, make_implicit_config_release, - make_rerun_overridden_release, overlay_release]. + [make_release, make_scriptless_release, make_overridden_release, + make_implicit_config_release, make_rerun_overridden_release, + overlay_release]. make_release(Config) -> LibDir1 = proplists:get_value(lib1, Config), @@ -90,6 +92,46 @@ make_release(Config) -> ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)), ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)). +make_scriptless_release(Config) -> + LibDir1 = proplists:get_value(lib1, Config), + [(fun({Name, Vsn}) -> + create_app(LibDir1, Name, Vsn, [kernel, stdlib], []) + end)(App) + || + App <- + [{create_random_name("lib_app1_"), create_random_vsn()} + || _ <- lists:seq(1, 100)]], + + create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel,non_goal_1], []), + create_app(LibDir1, "lib_dep_1", "0.0.1", [stdlib,kernel], []), + create_app(LibDir1, "goal_app_2", "0.0.1", [stdlib,kernel,goal_app_1,non_goal_2], []), + create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]), + create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []), + + ConfigFile = filename:join([LibDir1, "relcool.config"]), + write_config(ConfigFile, + [{generate_start_script, false}, + {release, {foo, "0.0.1"}, + [goal_app_1, + goal_app_2]}]), + OutputDir = filename:join([proplists:get_value(data_dir, Config), + create_random_name("relcool-output")]), + {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2, + OutputDir, [ConfigFile]), + + ?assert(not ec_file:exists(filename:join([OutputDir, "bin", "foo"]))), + ?assert(not ec_file:exists(filename:join([OutputDir, "bin", "foo-0.0.1"]))), + + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)), + AppSpecs = rcl_release:applications(Release), + ?assert(lists:keymember(stdlib, 1, AppSpecs)), + ?assert(lists:keymember(kernel, 1, AppSpecs)), + ?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)), + ?assert(lists:member({non_goal_2, "0.0.1"}, AppSpecs)), + ?assert(lists:member({goal_app_1, "0.0.1"}, AppSpecs)), + ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)), + ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)). + make_overridden_release(Config) -> DataDir = proplists:get_value(data_dir, Config), @@ -171,7 +213,6 @@ make_implicit_config_release(Config) -> OutputDir, []), [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)), ?assert(ec_file:exists(OutputDir)), - AppSpecs = rcl_release:applications(Release), ?assert(lists:keymember(stdlib, 1, AppSpecs)), ?assert(lists:keymember(kernel, 1, AppSpecs)), -- cgit v1.2.3 From 39ff3c87aa0d6444e5c3d9ae03538d0f212d81e6 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 28 Dec 2012 12:14:29 -0500 Subject: add missing erlydtl to the escript created --- rebar.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rebar.config b/rebar.config index 3561991..8ffc212 100644 --- a/rebar.config +++ b/rebar.config @@ -30,6 +30,6 @@ %% Misc ======================================================================= {escript_incl_apps, - [getopt, erlware_commons]}. + [getopt, erlware_commons, erlydtl]}. {first_files, [rcl_provider]}. -- cgit v1.2.3 From 3e295e146c960252af0008f1f13a7e40bcbdb929 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 28 Dec 2012 13:00:34 -0500 Subject: make sure file permissions are set correctly in overlay template/copy --- src/rcl_prv_overlay.erl | 4 ++++ test/rclt_release_SUITE.erl | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index 9670138..b854650 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -300,6 +300,8 @@ copy_to(State, FromFile0, ToFile0) -> end, case ec_file:copy(FromFile1, ToFile2) of ok -> + {ok, FileInfo} = file:read_file_info(FromFile1), + ok = file:write_file_info(ToFile2, FileInfo), ok; {error, Err} -> ?RCL_ERROR({copy_failed, @@ -340,6 +342,8 @@ write_template(OverlayVars, FromFile, ToFile) -> ok -> case file:write_file(ToFile, IoData) of ok -> + {ok, FileInfo} = file:read_file_info(FromFile), + ok = file:write_file_info(ToFile, FileInfo), ok; {error, Reason} -> ?RCL_ERROR({unable_to_write, ToFile, Reason}) diff --git a/test/rclt_release_SUITE.erl b/test/rclt_release_SUITE.erl index 848c129..593944e 100644 --- a/test/rclt_release_SUITE.erl +++ b/test/rclt_release_SUITE.erl @@ -34,6 +34,7 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). -include_lib("kernel/include/file.hrl"). +-include_lib("kernel/include/file.hrl"). suite() -> [{timetrap,{seconds,30}}]. @@ -317,6 +318,8 @@ overlay_release(Config) -> TemplateFile = filename:join([LibDir1, "test_template"]), ok = file:write_file(TemplateFile, test_template_contents()), + {ok, FileInfo} = file:read_file_info(TemplateFile), + ok = file:write_file_info(TemplateFile, FileInfo#file_info{mode=8#00777}), OutputDir = filename:join([proplists:get_value(data_dir, Config), create_random_name("relcool-output")]), @@ -338,12 +341,14 @@ overlay_release(Config) -> ?assert(ec_file:exists(filename:join([OutputDir, "foodir", "vars.config"]))), ?assert(ec_file:exists(filename:join([OutputDir, "yahoo", "vars.config"]))), - TemplateData = case file:consult(filename:join([OutputDir, test_template_resolved])) of + TemplateData = case file:consult(filename:join([OutputDir, "test_template_resolved"])) of {ok, Details} -> Details; Error -> erlang:throw({failed_to_consult, Error}) end, + {ok, ReadFileInfo} = file:read_file_info(filename:join([OutputDir, "test_template_resolved"])), + ?assertEqual(8#100777, ReadFileInfo#file_info.mode), ?assertEqual(erlang:system_info(version), proplists:get_value(erts_vsn, TemplateData)), -- cgit v1.2.3 From 8cbfdd28679872a1791fee615585aec6c03dd5f9 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 30 Dec 2012 16:59:44 -0500 Subject: support 'to' dirs for mkdirs, templates, and copies being based on output dir --- src/rcl_prv_overlay.erl | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index b854650..0e9781b 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -249,7 +249,9 @@ do_individual_overlay(State, OverlayVars, {mkdir, Dir}) -> {ok, ModuleName} -> case render(ModuleName, OverlayVars) of {ok, IoList} -> - Absolute = absolutize(State, IoList), + Absolute = absolutize(State, + filename:join(rcl_state:output_dir(State), + erlang:iolist_to_binary(IoList))), case rcl_util:mkdir_p(Absolute) of {error, Error} -> ?RCL_ERROR({unable_to_make_dir, Absolute, Error}); @@ -279,15 +281,20 @@ do_individual_overlay(State, OverlayVars, {template, From, To}) -> fun(FromFile) -> file_render_do(OverlayVars, To, ToTemplateName, fun(ToFile) -> + FromFile0 = absolutize(State, + filename:join(rcl_state:output_dir(State), + erlang:iolist_to_binary(FromFile))), + FromFile1 = erlang:binary_to_list(FromFile0), write_template(OverlayVars, - erlang:binary_to_list(absolutize(State, FromFile)), + FromFile1, absolutize(State, ToFile)) end) end). -spec copy_to(rcl_state:t(), file:name(), file:name()) -> ok | relcool:error(). copy_to(State, FromFile0, ToFile0) -> - ToFile1 = absolutize(State, ToFile0), + ToFile1 = absolutize(State, filename:join(rcl_state:output_dir(State), + erlang:iolist_to_binary(ToFile0))), FromFile1 = absolutize(State, FromFile0), ToFile2 = case is_directory(ToFile0, ToFile1) of false -> -- cgit v1.2.3 From 306d584398696d08e3ca26d6864fa71cdcfe4012 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 30 Dec 2012 17:34:25 -0500 Subject: only allow relcool to take a single config --- src/rcl_cmd_args.erl | 13 +++++++++---- src/relcool.erl | 2 +- test/rclt_command_SUITE.erl | 3 +-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/rcl_cmd_args.erl b/src/rcl_cmd_args.erl index dc176be..3bb9f41 100644 --- a/src/rcl_cmd_args.erl +++ b/src/rcl_cmd_args.erl @@ -34,7 +34,8 @@ relcool:error(). args2state({error, Detail}) -> ?RCL_ERROR({opt_parse, Detail}); -args2state({ok, {Opts, Targets}}) -> +args2state({ok, {Opts, Target}}) + when erlang:length(Target) == 0; erlang:length(Target) == 1 -> RelName = proplists:get_value(relname, Opts, undefined), RelVsn = proplists:get_value(relvsn, Opts, undefined), case create_log(Opts, @@ -43,15 +44,19 @@ args2state({ok, {Opts, Targets}}) -> Error = {error, _} -> Error; {ok, CommandLineConfig} -> - case validate_configs(Targets) of + case validate_configs(Target) of Error = {error, _} -> Error; {ok, Configs} -> - {ok, {rcl_state:new(CommandLineConfig, Configs), Configs}} + {ok, rcl_state:new(CommandLineConfig, Configs)} end - end. + end; +args2state({ok, {_Opts, Targets}}) -> + ?RCL_ERROR({invalid_targets, Targets}). -spec format_error(Reason::term()) -> iolist(). +format_error({invalid_targets, Targets}) -> + io_lib:format("One config must be specified! not ~p~n", [Targets]); format_error({opt_parse, {invalid_option, Opt}}) -> io_lib:format("invalid option ~s~n", [Opt]); format_error({opt_parse, Arg}) -> diff --git a/src/relcool.erl b/src/relcool.erl index c6747ca..fb17711 100644 --- a/src/relcool.erl +++ b/src/relcool.erl @@ -43,7 +43,7 @@ main(Args) -> OptSpecList = opt_spec_list(), case rcl_cmd_args:args2state(getopt:parse(OptSpecList, Args)) of - {ok, {State, _Target}} -> + {ok, State} -> run_relcool_process(rcl_state:caller(State, command_line)); Error={error, _} -> report_error(rcl_state:caller(rcl_state:new([], []), diff --git a/test/rclt_command_SUITE.erl b/test/rclt_command_SUITE.erl index 1c6accf..bd99da0 100644 --- a/test/rclt_command_SUITE.erl +++ b/test/rclt_command_SUITE.erl @@ -58,8 +58,7 @@ normal_passing_case(Config) -> RelVsn = "33.222", CmdLine = ["-V", LogLevel, "-g",Goal1,"-g",Goal2, "-l", Lib1, "-l", Lib2, "-n", RelName, "-v", RelVsn, "-o", Outdir], - {ok, {State, Target}} = rcl_cmd_args:args2state(getopt:parse(relcool:opt_spec_list(), CmdLine)), - ?assertMatch([], Target), + {ok, State} = rcl_cmd_args:args2state(getopt:parse(relcool:opt_spec_list(), CmdLine)), ?assertMatch([Lib1, Lib2], rcl_state:lib_dirs(State)), ?assertMatch(Outdir, rcl_state:output_dir(State)), -- cgit v1.2.3 From fbf58da536939dece9a6707b7ff39e12bf377d1c Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 30 Dec 2012 17:59:26 -0500 Subject: fix bug in usage of root dir in prv discover --- src/rcl_prv_discover.erl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rcl_prv_discover.erl b/src/rcl_prv_discover.erl index 0a12d24..6ff50ed 100644 --- a/src/rcl_prv_discover.erl +++ b/src/rcl_prv_discover.erl @@ -123,13 +123,13 @@ add_rebar_deps_dir(State, LibDirs) -> false -> %% Check to see if there is a rebar.config. If so then look for a deps %% dir. If both are there then we add that to the lib dirs. - {ok, Cwd} = file:get_cwd(), + Root = rcl_state:root_dir(State), - RebarConfig = filename:join([Cwd, "rebar.config"]), - DepsDir = filename:join([Cwd, "deps"]), + RebarConfig = filename:join([Root, "rebar.config"]), + DepsDir = filename:join([Root, "deps"]), case filelib:is_regular(RebarConfig) andalso filelib:is_dir(DepsDir) of true -> - add_system_lib_dir(State, [filename:absname(Cwd) | LibDirs]); + add_system_lib_dir(State, [filename:absname(Root) | LibDirs]); false -> add_system_lib_dir(State, LibDirs) end -- cgit v1.2.3 From 78ec90ae6084f44b5379bd4e9eebb79746f4a595 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 30 Dec 2012 19:15:01 -0500 Subject: support only one config file in the system --- src/rcl_prv_config.erl | 14 ++++++------- src/rcl_prv_overlay.erl | 3 ++- src/rcl_state.erl | 48 ++++++++++++--------------------------------- src/relcool.erl | 4 ++-- test/rclt_release_SUITE.erl | 6 +++--- 5 files changed, 26 insertions(+), 49 deletions(-) diff --git a/src/rcl_prv_config.erl b/src/rcl_prv_config.erl index 7ea9a77..f87c467 100644 --- a/src/rcl_prv_config.erl +++ b/src/rcl_prv_config.erl @@ -29,11 +29,11 @@ init(State) -> %% populating the state as a result. -spec do(rcl_state:t()) ->{ok, rcl_state:t()} | relcool:error(). do(State) -> - case rcl_state:config_files(State) of + case rcl_state:config_file(State) of [] -> search_for_dominating_config(State); - ConfigFiles -> - lists:foldl(fun load_config/2, {ok, State}, ConfigFiles) + ConfigFile -> + load_config(ConfigFile, State) end. -spec format_error(Reason::term()) -> iolist(). @@ -63,7 +63,7 @@ search_for_dominating_config(State0) -> %% we need to set the root dir on state as well {ok, RootDir} = parent_dir(Config), State1 = rcl_state:root_dir(State0, RootDir), - load_config(Config, {ok, rcl_state:config_files(State1, [Config])}); + load_config(Config, rcl_state:config_file(State1, Config)); no_config -> {ok, State0} end. @@ -88,11 +88,9 @@ parent_dir([H | T], Acc) -> parent_dir(T, [H | Acc]). --spec load_config(file:filename(), {ok, rcl_state:t()} | relcool:error()) -> +-spec load_config(file:filename(), rcl_state:t()) -> {ok, rcl_state:t()} | relcool:error(). -load_config(_, Err = {error, _}) -> - Err; -load_config(ConfigFile, {ok, State}) -> +load_config(ConfigFile, State) -> {ok, CurrentCwd} = file:get_cwd(), ok = file:set_cwd(filename:dirname(ConfigFile)), Result = case file:consult(ConfigFile) of diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index 0e9781b..866ace5 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -196,7 +196,7 @@ generate_state_vars(State) -> {goals, [rcl_depsolver:format_constraint(Constraint) || Constraint <- rcl_state:goals(State)]}, {lib_dirs, rcl_state:lib_dirs(State)}, - {config_files, rcl_state:config_files(State)}, + {config_file, rcl_state:config_file(State)}, {providers, rcl_state:providers(State)}, {sys_config, rcl_state:sys_config(State)}, {root_dir, rcl_state:root_dir(State)}, @@ -295,6 +295,7 @@ do_individual_overlay(State, OverlayVars, {template, From, To}) -> copy_to(State, FromFile0, ToFile0) -> ToFile1 = absolutize(State, filename:join(rcl_state:output_dir(State), erlang:iolist_to_binary(ToFile0))), + FromFile1 = absolutize(State, FromFile0), ToFile2 = case is_directory(ToFile0, ToFile1) of false -> diff --git a/src/rcl_state.erl b/src/rcl_state.erl index eb70ecc..28effbd 100644 --- a/src/rcl_state.erl +++ b/src/rcl_state.erl @@ -30,8 +30,8 @@ overrides/1, overrides/2, goals/1, - config_files/1, - config_files/2, + config_file/1, + config_file/2, providers/1, providers/2, sys_config/1, @@ -64,7 +64,7 @@ caller :: caller(), output_dir :: file:name(), lib_dirs=[] :: [file:name()], - config_files=[] :: [file:filename()], + config_file=[] :: file:filename(), goals=[] :: [rcl_depsolver:constraint()], providers = [] :: [rcl_provider:t()], available_apps = [] :: [rcl_app_info:t()], @@ -93,13 +93,13 @@ %%============================================================================ %% @doc Create a new 'log level' for the system -spec new(proplists:proplist(), [file:filename()] | file:filename()) -> t(). -new(PropList, Targets) when erlang:is_list(PropList) -> +new(PropList, Target) when erlang:is_list(PropList) -> {ok, Root} = file:get_cwd(), State0 = #state_t{log = proplists:get_value(log, PropList, rcl_log:new(error)), output_dir=proplists:get_value(output_dir, PropList, ""), - lib_dirs=get_lib_dirs(proplists:get_value(lib_dirs, PropList, [])), - config_files=process_config_files(Targets), + lib_dirs=proplists:get_value(lib_dirs, PropList, ""), + config_file=Target, goals=proplists:get_value(goals, PropList, []), providers = [], releases=ec_dictionary:new(ec_dict), @@ -137,13 +137,13 @@ lib_dirs(#state_t{lib_dirs=LibDir}) -> goals(#state_t{goals=TS}) -> TS. --spec config_files(t()) -> [file:filename()]. -config_files(#state_t{config_files=ConfigFiles}) -> +-spec config_file(t()) -> file:filename(). +config_file(#state_t{config_file=ConfigFiles}) -> ConfigFiles. --spec config_files(t(), [file:filename()]) -> t(). -config_files(State, ConfigFiles) -> - State#state_t{config_files=ConfigFiles}. +-spec config_file(t(), file:filename()) -> t(). +config_file(State, ConfigFiles) -> + State#state_t{config_file=ConfigFiles}. -spec providers(t()) -> [rcl_provider:t()]. providers(#state_t{providers=Providers}) -> @@ -243,15 +243,14 @@ format(Mod) -> -spec format(t(), non_neg_integer()) -> iolist(). format(#state_t{log=LogState, output_dir=OutDir, lib_dirs=LibDirs, caller=Caller, config_values=Values0, - goals=Goals, config_files=ConfigFiles, + goals=Goals, config_file=ConfigFile, providers=Providers}, Indent) -> Values1 = ec_dictionary:to_list(Values0), [rcl_util:indent(Indent), <<"state(">>, erlang:atom_to_list(Caller), <<"):\n">>, rcl_util:indent(Indent + 1), <<"log: ">>, rcl_log:format(LogState), <<",\n">>, - rcl_util:indent(Indent + 1), "config files: \n", - [[rcl_util:indent(Indent + 2), ConfigFile, ",\n"] || ConfigFile <- ConfigFiles], + rcl_util:indent(Indent + 1), "config file: ", ConfigFile, "\n", rcl_util:indent(Indent + 1), "goals: \n", [[rcl_util:indent(Indent + 2), rcl_depsolver:format_constraint(Goal), ",\n"] || Goal <- Goals], rcl_util:indent(Indent + 1), "output_dir: ", OutDir, "\n", @@ -265,15 +264,6 @@ format(#state_t{log=LogState, output_dir=OutDir, lib_dirs=LibDirs, %%%=================================================================== %%% Internal Functions %%%=================================================================== --spec get_lib_dirs([file:name()]) -> [file:name()]. -get_lib_dirs(CmdDirs) -> - case os:getenv("ERL_LIBS") of - false -> - CmdDirs; - EnvString -> - [Lib || Lib <- re:split(EnvString, ":|;"), - filelib:is_dir(Lib)] ++ CmdDirs - end. -spec create_logic_providers(t()) -> t(). create_logic_providers(State0) -> @@ -285,18 +275,6 @@ create_logic_providers(State0) -> State5#state_t{providers=[ConfigProvider, DiscoveryProvider, ReleaseProvider, OverlayProvider, AssemblerProvider]}. - -%% @doc config files can come in as either a single file name or as a list of -%% files. We what to support both where possible. -process_config_files(File = [Char | _]) - when erlang:is_integer(Char) -> - [File]; -process_config_files(Files = [File | _]) - when erlang:is_list(File) -> - Files; -process_config_files([]) -> - []. - %%%=================================================================== %%% Test Functions %%%=================================================================== diff --git a/src/relcool.erl b/src/relcool.erl index fb17711..9babdb2 100644 --- a/src/relcool.erl +++ b/src/relcool.erl @@ -72,7 +72,7 @@ do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Configs) -> %% @param OutputDir - The directory where the release should be built to %% @param Overrides - A list of overrides for the system %% @param Configs - The list of config files for the system -do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Overrides, Configs) -> +do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Overrides, Config) -> State = rcl_state:new([{relname, RelName}, {relvsn, RelVsn}, {goals, Goals}, @@ -80,7 +80,7 @@ do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Overrides, Configs) -> {output_dir, OutputDir}, {lib_dirs, LibDirs}, {log, rcl_log:new(LogLevel)}], - Configs), + Config), run_relcool_process(rcl_state:caller(State, api)). diff --git a/test/rclt_release_SUITE.erl b/test/rclt_release_SUITE.erl index 593944e..bcdf354 100644 --- a/test/rclt_release_SUITE.erl +++ b/test/rclt_release_SUITE.erl @@ -391,7 +391,7 @@ overlay_release(Config) -> ?assertEqual([""], proplists:get_value(goals, TemplateData)), ?assert(proplists:is_defined(lib_dirs, TemplateData)), - ?assert(proplists:is_defined(config_files, TemplateData)), + ?assert(proplists:is_defined(config_file, TemplateData)), ?assertEqual([""], proplists:get_value(goals, TemplateData)), ?assertEqual("undefined", @@ -457,7 +457,7 @@ write_config(Filename, Values) -> test_template_contents() -> "{erts_vsn, \"{{erts_vsn}}\"}.\n" - "{release_erts_version, \"{{release_erts_version}}\"}.\n" + "{release_erts_version, \"{{release_erts_version}}\"}.\n" "{release_name, {{release_name}}}.\n" "{rel_vsn, \"{{release_version}}\"}.\n" "{release_version, \"{{release_version}}\"}.\n" @@ -479,7 +479,7 @@ test_template_contents() -> "{overridden, [{{ overridden|join:\", \" }}]}.\n" "{goals, [\"{{ goals|join:\", \" }}\"]}.\n" "{lib_dirs, [\"{{ lib_dirs|join:\", \" }}\"]}.\n" - "{config_files, [\"{{ config_files|join:\", \" }}\"]}.\n" + "{config_file, \"{{ config_file }}\"}.\n" "{providers, [{{ providers|join:\", \" }}]}.\n" "{sys_config, \"{{sys_config}}\"}.\n" "{root_dir, \"{{root_dir}}\"}.\n" -- cgit v1.2.3 From 7313be05d2805a3cf699e25d160401fd95635e33 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 30 Dec 2012 19:34:34 -0500 Subject: support config relative directories in templates and copy --- src/rcl_prv_overlay.erl | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index 866ace5..e792a4f 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -281,22 +281,27 @@ do_individual_overlay(State, OverlayVars, {template, From, To}) -> fun(FromFile) -> file_render_do(OverlayVars, To, ToTemplateName, fun(ToFile) -> + RelativeRoot = get_relative_root(State), FromFile0 = absolutize(State, - filename:join(rcl_state:output_dir(State), + filename:join(RelativeRoot, erlang:iolist_to_binary(FromFile))), FromFile1 = erlang:binary_to_list(FromFile0), write_template(OverlayVars, FromFile1, - absolutize(State, ToFile)) + absolutize(State, + filename:join(rcl_state:output_dir(State), + erlang:iolist_to_binary(ToFile)))) end) end). -spec copy_to(rcl_state:t(), file:name(), file:name()) -> ok | relcool:error(). copy_to(State, FromFile0, ToFile0) -> + RelativeRoot = get_relative_root(State), ToFile1 = absolutize(State, filename:join(rcl_state:output_dir(State), erlang:iolist_to_binary(ToFile0))), - FromFile1 = absolutize(State, FromFile0), + FromFile1 = absolutize(State, filename:join(RelativeRoot, + erlang:iolist_to_binary(FromFile0))), ToFile2 = case is_directory(ToFile0, ToFile1) of false -> filelib:ensure_dir(ToFile1), @@ -317,6 +322,14 @@ copy_to(State, FromFile0, ToFile0) -> ToFile1, Err}) end. +get_relative_root(State) -> + case rcl_state:config_file(State) of + [] -> + rcl_state:root_dir(State); + Config -> + filename:dirname(Config) + end. + -spec is_directory(file:name(), file:name()) -> boolean(). is_directory(ToFile0, ToFile1) -> case re:run(ToFile0, ?DIRECTORY_RE) of -- cgit v1.2.3 From 60e04b48942a8d2e0d401ae5deb84e4dc61d05f5 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 30 Dec 2012 20:01:39 -0500 Subject: support the ability to specify a root directory --- README.md | 3 +++ src/rcl_cmd_args.erl | 15 ++++++++++++++- src/relcool.erl | 25 +++++++++++++++++++++---- test/rclt_release_SUITE.erl | 8 +++++--- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 30e5c82..99fef81 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ additional specification information for releases. # OPTIONS +-r *STRING*, \--root *STRING* +: Specify the root directory for the project (if different from cwd) + -n *STRING*, \--relname *STRING* : Specify the name for the release that will be generated diff --git a/src/rcl_cmd_args.erl b/src/rcl_cmd_args.erl index 3bb9f41..9d829d3 100644 --- a/src/rcl_cmd_args.erl +++ b/src/rcl_cmd_args.erl @@ -160,9 +160,22 @@ create_lib_dirs(Opts, Acc) -> Error = {error, _} -> Error; ok -> - {ok, [{lib_dirs, [filename:absname(Dir) || Dir <- Dirs]} | Acc]} + create_root_dir(Opts, [{lib_dirs, [filename:absname(Dir) || Dir <- Dirs]} | Acc]) end. +-spec create_root_dir([getopt:option()], rcl_state:cmd_args()) -> + {ok, rcl_state:cmd_args()} | relcool:error(). +create_root_dir(Opts, Acc) -> + Dir = proplists:get_value(root_dir, Opts, undefined), + case Dir of + undefined -> + {ok, Cwd} = file:get_cwd(), + {ok, [{root_dir, Cwd} | Acc]}; + _ -> + {ok, [{root_dir, Dir} | Acc]} + end. + + -spec check_lib_dirs([string()]) -> ok | relcool:error(). check_lib_dirs([]) -> ok; diff --git a/src/relcool.erl b/src/relcool.erl index 9babdb2..f240553 100644 --- a/src/relcool.erl +++ b/src/relcool.erl @@ -23,6 +23,7 @@ -export([main/1, do/7, do/8, + do/9, format_error/1, opt_spec_list/0]). @@ -60,10 +61,25 @@ main(Args) -> %% @param OutputDir - The directory where the release should be built to %% @param Configs - The list of config files for the system do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Configs) -> - do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, [], Configs). + {ok, Cwd} = file:get_cwd(), + do(Cwd, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, [], Configs). %% @doc provides an API to run the Relcool process from erlang applications %% +%% @param RootDir - The root directory for the project +%% @param RelName - The release name to build (maybe `undefined`) +%% @param RelVsn - The release version to build (maybe `undefined`) +%% @param Goals - The release goals for the system in depsolver or Relcool goal +%% format +%% @param LibDirs - The library dirs that should be used for the system +%% @param OutputDir - The directory where the release should be built to +%% @param Configs - The list of config files for the system +do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Configs) -> + do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, [], Configs). + +%% @doc provides an API to run the Relcool process from erlang applications +%% +%% @param RootDir - The root directory for the system %% @param RelName - The release name to build (maybe `undefined`) %% @param RelVsn - The release version to build (maybe `undefined`) %% @param Goals - The release goals for the system in depsolver or Relcool goal @@ -72,13 +88,14 @@ do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Configs) -> %% @param OutputDir - The directory where the release should be built to %% @param Overrides - A list of overrides for the system %% @param Configs - The list of config files for the system -do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Overrides, Config) -> +do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Overrides, Config) -> State = rcl_state:new([{relname, RelName}, {relvsn, RelVsn}, {goals, Goals}, {overrides, Overrides}, {output_dir, OutputDir}, {lib_dirs, LibDirs}, + {root_dir, RootDir}, {log, rcl_log:new(LogLevel)}], Config), run_relcool_process(rcl_state:caller(State, api)). @@ -93,8 +110,8 @@ opt_spec_list() -> "usually the OTP"}, {output_dir, $o, "output-dir", string, "The output directory for the release. This is `./` by default."}, {lib_dir, $l, "lib-dir", string, "Additional dirs that should be searched for OTP Apps"}, - {log_level, $V, "verbose", {integer, 0}, "Verbosity level, maybe between 0 and 2"} - ]. + {log_level, $V, "verbose", {integer, 0}, "Verbosity level, maybe between 0 and 2"}, + {root_dir, $r, "root", string, "The project root directory"}]. -spec format_error(Reason::term()) -> iolist(). format_error({invalid_return_value, Provider, Value}) -> diff --git a/test/rclt_release_SUITE.erl b/test/rclt_release_SUITE.erl index bcdf354..e92772e 100644 --- a/test/rclt_release_SUITE.erl +++ b/test/rclt_release_SUITE.erl @@ -166,7 +166,8 @@ make_overridden_release(Config) -> goal_app_2]}]), OutputDir = filename:join([proplists:get_value(data_dir, Config), create_random_name("relcool-output")]), - {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2, + {ok, Cwd} = file:get_cwd(), + {ok, State} = relcool:do(Cwd, undefined, undefined, [], [LibDir1], 2, OutputDir, [{OverrideAppName, OverrideAppDir}], [ConfigFile]), [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)), @@ -255,12 +256,13 @@ make_rerun_overridden_release(Config) -> goal_app_2]}]), OutputDir = filename:join([proplists:get_value(data_dir, Config), create_random_name("relcool-output")]), - {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2, + {ok, Cwd} = file:get_cwd(), + {ok, State} = relcool:do(Cwd, undefined, undefined, [], [LibDir1], 2, OutputDir, [{OverrideAppName, OverrideAppDir}], [ConfigFile]), %% Now we run it again to see if it failse. - {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2, + {ok, State} = relcool:do(Cwd, undefined, undefined, [], [LibDir1], 2, OutputDir, [{OverrideAppName, OverrideAppDir}], [ConfigFile]), -- cgit v1.2.3 From 059d9f6d28d8f4e963f556401e23eed44fc44b9d Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Mon, 31 Dec 2012 08:56:02 -0600 Subject: use relative root for overlay vars file path --- src/rcl_prv_overlay.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index e792a4f..94b5f3d 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -112,7 +112,9 @@ get_overlay_vars_from_file(State, OverlayVars) -> -spec read_overlay_vars(rcl_state:t(), proplists:proplist(), file:name()) -> {ok, rcl_state:t()} | relcool:error(). read_overlay_vars(State, OverlayVars, FileName) -> - case file:consult(FileName) of + RelativeRoot = get_relative_root(State), + RelativePath = filename:join(RelativeRoot, erlang:iolist_to_binary(FileName)), + case file:consult(RelativePath) of {ok, Terms} -> case render_overlay_vars(OverlayVars, Terms, []) of {ok, NewTerms} -> -- cgit v1.2.3 From a0bd0b37822999f87786d670529624594c82b0a8 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 31 Dec 2012 15:19:18 -0500 Subject: fix bug in goalless configs --- src/rcl_prv_release.erl | 17 ++++++++++++----- test/rclt_release_SUITE.erl | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/rcl_prv_release.erl b/src/rcl_prv_release.erl index 66f4e11..8a86e02 100644 --- a/src/rcl_prv_release.erl +++ b/src/rcl_prv_release.erl @@ -47,6 +47,8 @@ do(State) -> find_default_release(State, DepGraph). -spec format_error(ErrorDetail::term()) -> iolist(). +format_error(no_goals_specified) -> + "No goals specified for this release ~n"; format_error({no_release_name, Vsn}) -> io_lib:format("A target release version was specified (~s) but no name", [Vsn]); format_error({invalid_release_info, Info}) -> @@ -151,11 +153,16 @@ solve_release(State0, DepGraph, RelName, RelVsn) -> try Release = rcl_state:get_release(State0, RelName, RelVsn), Goals = rcl_release:goals(Release), - case rcl_depsolver:solve(DepGraph, Goals) of - {ok, Pkgs} -> - set_resolved(State0, Release, Pkgs); - {error, Error} -> - ?RCL_ERROR({failed_solve, Error}) + case Goals of + [] -> + ?RCL_ERROR(no_goals_specified); + _ -> + case rcl_depsolver:solve(DepGraph, Goals) of + {ok, Pkgs} -> + set_resolved(State0, Release, Pkgs); + {error, Error} -> + ?RCL_ERROR({failed_solve, Error}) + end end catch throw:not_found -> diff --git a/test/rclt_release_SUITE.erl b/test/rclt_release_SUITE.erl index e92772e..baf2fcd 100644 --- a/test/rclt_release_SUITE.erl +++ b/test/rclt_release_SUITE.erl @@ -29,7 +29,8 @@ make_overridden_release/1, make_rerun_overridden_release/1, make_implicit_config_release/1, - overlay_release/1]). + overlay_release/1, + make_goalless_release/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -56,7 +57,7 @@ init_per_testcase(_, Config) -> all() -> [make_release, make_scriptless_release, make_overridden_release, make_implicit_config_release, make_rerun_overridden_release, - overlay_release]. + overlay_release, make_goalless_release]. make_release(Config) -> LibDir1 = proplists:get_value(lib1, Config), @@ -262,7 +263,7 @@ make_rerun_overridden_release(Config) -> [ConfigFile]), %% Now we run it again to see if it failse. - {ok, State} = relcool:do(Cwd, undefined, undefined, [], [LibDir1], 2, + {ok, State} = relcool:do(Cwd,undefined, undefined, [], [LibDir1], 2, OutputDir, [{OverrideAppName, OverrideAppDir}], [ConfigFile]), @@ -414,6 +415,32 @@ overlay_release(Config) -> ?assertEqual("yahoo/bar", proplists:get_value(yahoo3, TemplateData)). +make_goalless_release(Config) -> + LibDir1 = proplists:get_value(lib1, Config), + [(fun({Name, Vsn}) -> + create_app(LibDir1, Name, Vsn, [kernel, stdlib], []) + end)(App) + || + App <- + [{create_random_name("lib_app1_"), create_random_vsn()} + || _ <- lists:seq(1, 100)]], + + create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel,non_goal_1], []), + create_app(LibDir1, "lib_dep_1", "0.0.1", [], []), + create_app(LibDir1, "goal_app_2", "0.0.1", [stdlib,kernel,goal_app_1,non_goal_2], []), + create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]), + create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []), + + ConfigFile = filename:join([LibDir1, "relcool.config"]), + write_config(ConfigFile, + [{release, {foo, "0.0.1"}, + []}]), + OutputDir = filename:join([proplists:get_value(data_dir, Config), + create_random_name("relcool-output")]), + ?assertMatch({error,{rcl_prv_release,no_goals_specified}}, + relcool:do(undefined, undefined, [], [LibDir1], 2, + OutputDir, [ConfigFile])). + %%%=================================================================== %%% Helper Functions %%%=================================================================== -- cgit v1.2.3 From bb1fbe04e7f44b7b88176cc26537541330248a51 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 2 Jan 2013 15:51:26 -0500 Subject: add tests to try and cover unexpected failures --- test/rclt_release_SUITE.erl | 63 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/test/rclt_release_SUITE.erl b/test/rclt_release_SUITE.erl index baf2fcd..9c9c70c 100644 --- a/test/rclt_release_SUITE.erl +++ b/test/rclt_release_SUITE.erl @@ -30,7 +30,9 @@ make_rerun_overridden_release/1, make_implicit_config_release/1, overlay_release/1, - make_goalless_release/1]). + make_goalless_release/1, + make_depfree_release/1, + make_invalid_config_release/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -57,7 +59,8 @@ init_per_testcase(_, Config) -> all() -> [make_release, make_scriptless_release, make_overridden_release, make_implicit_config_release, make_rerun_overridden_release, - overlay_release, make_goalless_release]. + overlay_release, make_goalless_release, make_depfree_release, + make_invalid_config_release]. make_release(Config) -> LibDir1 = proplists:get_value(lib1, Config), @@ -94,6 +97,33 @@ make_release(Config) -> ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)), ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)). +make_invalid_config_release(Config) -> + LibDir1 = proplists:get_value(lib1, Config), + [(fun({Name, Vsn}) -> + create_app(LibDir1, Name, Vsn, [kernel, stdlib], []) + end)(App) + || + App <- + [{create_random_name("lib_app1_"), create_random_vsn()} + || _ <- lists:seq(1, 100)]], + + create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel,non_goal_1], []), + create_app(LibDir1, "lib_dep_1", "0.0.1", [stdlib,kernel], []), + create_app(LibDir1, "goal_app_2", "0.0.1", [stdlib,kernel,goal_app_1,non_goal_2], []), + create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]), + create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []), + + ConfigFile = filename:join([LibDir1, "relcool.config"]), + ok = ec_file:write(ConfigFile, + "{release, {foo, \"0.0.1\"}, + [goal_app_1, + goal_app_2,]}"), + OutputDir = filename:join([proplists:get_value(data_dir, Config), + create_random_name("relcool-output")]), + {error, {rcl_prv_config, + {consult, _, _}}} = relcool:do(undefined, undefined, [], [LibDir1], 2, + OutputDir, [ConfigFile]). + make_scriptless_release(Config) -> LibDir1 = proplists:get_value(lib1, Config), [(fun({Name, Vsn}) -> @@ -441,6 +471,35 @@ make_goalless_release(Config) -> relcool:do(undefined, undefined, [], [LibDir1], 2, OutputDir, [ConfigFile])). +make_depfree_release(Config) -> + LibDir1 = proplists:get_value(lib1, Config), + [(fun({Name, Vsn}) -> + create_app(LibDir1, Name, Vsn, [kernel, stdlib], []) + end)(App) + || + App <- + [{create_random_name("lib_app1_"), create_random_vsn()} + || _ <- lists:seq(1, 100)]], + + create_app(LibDir1, "goal_app_1", "0.0.1", [kernel,stdlib], []), + create_app(LibDir1, "lib_dep_1", "0.0.1", [kernel,stdlib], []), + create_app(LibDir1, "goal_app_2", "0.0.1", [kernel,stdlib], []), + create_app(LibDir1, "non_goal_1", "0.0.1", [kernel,stdlib], []), + create_app(LibDir1, "non_goal_2", "0.0.1", [kernel,stdlib], []), + + ConfigFile = filename:join([LibDir1, "relcool.config"]), + write_config(ConfigFile, + [{release, {foo, "0.0.1"}, + [goal_app_1]}]), + OutputDir = filename:join([proplists:get_value(data_dir, Config), + create_random_name("relcool-output")]), + {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2, + OutputDir, [ConfigFile]), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)), + AppSpecs = rcl_release:applications(Release), + ?assert(lists:keymember(stdlib, 1, AppSpecs)), + ?assert(lists:keymember(kernel, 1, AppSpecs)). + %%%=================================================================== %%% Helper Functions %%%=================================================================== -- cgit v1.2.3 From 344fa86b23205eebc3233cf9c69a8e9e145714ac Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 4 Jan 2013 09:55:22 -0500 Subject: minor format refactoring --- src/rcl_log.erl | 11 ++++++++--- src/relcool.erl | 32 ++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/rcl_log.erl b/src/rcl_log.erl index a5fb43a..a24b1c0 100644 --- a/src/rcl_log.erl +++ b/src/rcl_log.erl @@ -36,6 +36,7 @@ format/1]). -export_type([int_log_level/0, + atom_log_level/0, log_level/0, log_fun/0, t/0]). @@ -46,10 +47,14 @@ %% types %%============================================================================ +-type log_level() :: int_log_level() | atom_log_level(). + -type int_log_level() :: 0..2. + %% Why no warn? because for our purposes there is no difference between error %% and warn --type log_level() :: error | info | debug. +-type atom_log_level() :: error | info | debug. + -opaque t() :: {?MODULE, int_log_level()}. -type log_fun() :: fun(() -> iolist()). @@ -58,7 +63,7 @@ %% API %%============================================================================ %% @doc Create a new 'log level' for the system --spec new(int_log_level() | log_level()) -> t(). +-spec new(log_level()) -> t(). new(LogLevel) when LogLevel >= 0, LogLevel =< 2 -> {?MODULE, LogLevel}; new(AtomLogLevel) @@ -152,7 +157,7 @@ log_level({?MODULE, DetailLogLevel}) -> DetailLogLevel. %% @doc get the current log level as an atom --spec atom_log_level(t()) -> log_level(). +-spec atom_log_level(t()) -> atom_log_level(). atom_log_level({?MODULE, ?RCL_ERROR}) -> error; atom_log_level({?MODULE, ?RCL_INFO}) -> diff --git a/src/relcool.erl b/src/relcool.erl index f240553..9fb9240 100644 --- a/src/relcool.erl +++ b/src/relcool.erl @@ -36,6 +36,7 @@ %%============================================================================ -type error() :: {error, {Module::module(), Reason::term()}}. +-type goal() :: string() | binary() | rcl_depsolver:constraint(). %%============================================================================ %% API @@ -60,9 +61,12 @@ main(Args) -> %% @param LibDirs - The library dirs that should be used for the system %% @param OutputDir - The directory where the release should be built to %% @param Configs - The list of config files for the system -do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Configs) -> +-spec do(atom(), string(), [goal()], [file:name()], rcl_log:log_level(), + [file:name()], file:name()) -> + ok | error() | {ok, rcl_state:t()}. +do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Config) -> {ok, Cwd} = file:get_cwd(), - do(Cwd, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, [], Configs). + do(Cwd, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, [], Config). %% @doc provides an API to run the Relcool process from erlang applications %% @@ -74,6 +78,9 @@ do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Configs) -> %% @param LibDirs - The library dirs that should be used for the system %% @param OutputDir - The directory where the release should be built to %% @param Configs - The list of config files for the system +-spec do(file:name(), atom(), string(), [goal()], [file:name()], + rcl_log:log_level(), [file:name()], file:name()) -> + ok | error() | {ok, rcl_state:t()}. do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Configs) -> do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, [], Configs). @@ -88,6 +95,9 @@ do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Configs) -> %% @param OutputDir - The directory where the release should be built to %% @param Overrides - A list of overrides for the system %% @param Configs - The list of config files for the system +-spec do(file:name(), atom(), string(), [goal()], [file:name()], + rcl_log:log_level(), [file:name()], [{atom(), file:name()}], file:name()) -> + ok | error() | {ok, rcl_state:t()}. do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Overrides, Config) -> State = rcl_state:new([{relname, RelName}, {relvsn, RelVsn}, @@ -104,13 +114,17 @@ do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Overrides, Con -spec opt_spec_list() -> [getopt:option_spec()]. opt_spec_list() -> [ - {relname, $n, "relname", string, "Specify the name for the release that will be generated"}, + {relname, $n, "relname", string, + "Specify the name for the release that will be generated"}, {relvsn, $v, "relvsn", string, "Specify the version for the release"}, - {goals, $g, "goal", string, "Specify a target constraint on the system. These are " - "usually the OTP"}, - {output_dir, $o, "output-dir", string, "The output directory for the release. This is `./` by default."}, - {lib_dir, $l, "lib-dir", string, "Additional dirs that should be searched for OTP Apps"}, - {log_level, $V, "verbose", {integer, 0}, "Verbosity level, maybe between 0 and 2"}, + {goals, $g, "goal", string, + "Specify a target constraint on the system. These are usually the OTP"}, + {output_dir, $o, "output-dir", string, + "The output directory for the release. This is `./` by default."}, + {lib_dir, $l, "lib-dir", string, + "Additional dirs that should be searched for OTP Apps"}, + {log_level, $V, "verbose", {integer, 0}, + "Verbosity level, maybe between 0 and 2"}, {root_dir, $r, "root", string, "The project root directory"}]. -spec format_error(Reason::term()) -> iolist(). @@ -120,7 +134,6 @@ format_error({invalid_return_value, Provider, Value}) -> format_error({error, {Module, Reason}}) -> io_lib:format("~s~n", [Module:format_error(Reason)]). - %%============================================================================ %% internal api %%============================================================================ @@ -187,7 +200,6 @@ run_provider(Provider, {ok, State0}) -> usage() -> getopt:usage(opt_spec_list(), "relcool", "[*release-specification-file*]"). - -spec report_error(rcl_state:t(), error()) -> none() | error(). report_error(State, Error) -> io:format(format_error(Error)), -- cgit v1.2.3 From 3a5cb6adf215e760068c9d3e7a07eb4f971cabf0 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 4 Jan 2013 10:33:54 -0500 Subject: provide the erlang lib dir and cwd as working libraries This happens for every call unless the user passes --disable-default-libs to relcool or {disable_default_libs, true} in the relcool config. --- src/rcl_cmd_args.erl | 9 +++++++-- src/rcl_prv_discover.erl | 29 ++++++++++------------------- src/rcl_state.erl | 4 +++- src/relcool.erl | 6 ++++-- test/rclt_discover_SUITE.erl | 11 +++++------ 5 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/rcl_cmd_args.erl b/src/rcl_cmd_args.erl index 9d829d3..6340201 100644 --- a/src/rcl_cmd_args.erl +++ b/src/rcl_cmd_args.erl @@ -170,11 +170,16 @@ create_root_dir(Opts, Acc) -> case Dir of undefined -> {ok, Cwd} = file:get_cwd(), - {ok, [{root_dir, Cwd} | Acc]}; + create_disable_default_libs(Opts, [{root_dir, Cwd} | Acc]); _ -> - {ok, [{root_dir, Dir} | Acc]} + create_disable_default_libs(Opts, [{root_dir, Dir} | Acc]) end. +-spec create_disable_default_libs([getopt:option()], rcl_state:cmd_args()) -> + {ok, rcl_state:cmd_args()} | relcool:error(). +create_disable_default_libs(Opts, Acc) -> + Def = proplists:get_value(disable_default_libs, Opts, false), + {ok, [{disable_default_libs, Def} | Acc]}. -spec check_lib_dirs([string()]) -> ok | relcool:error(). check_lib_dirs([]) -> diff --git a/src/rcl_prv_discover.erl b/src/rcl_prv_discover.erl index 6ff50ed..4e7ce72 100644 --- a/src/rcl_prv_discover.erl +++ b/src/rcl_prv_discover.erl @@ -112,29 +112,20 @@ setup_overrides(State, AppMetas0) -> get_lib_dirs(State) -> LibDirs0 = rcl_state:lib_dirs(State), - add_rebar_deps_dir(State, LibDirs0). - --spec add_rebar_deps_dir(rcl_state:t(), [file:name()]) -> [file:name()]. -add_rebar_deps_dir(State, LibDirs) -> - ExcludeRebar = rcl_state:get(State, discover_exclude_rebar, false), - case ExcludeRebar of + case rcl_state:get(State, disable_default_libs, false) of true -> - add_system_lib_dir(State, LibDirs); + LibDirs0; false -> - %% Check to see if there is a rebar.config. If so then look for a deps - %% dir. If both are there then we add that to the lib dirs. - Root = rcl_state:root_dir(State), - - RebarConfig = filename:join([Root, "rebar.config"]), - DepsDir = filename:join([Root, "deps"]), - case filelib:is_regular(RebarConfig) andalso filelib:is_dir(DepsDir) of - true -> - add_system_lib_dir(State, [filename:absname(Root) | LibDirs]); - false -> - add_system_lib_dir(State, LibDirs) - end + add_current_dir(State, LibDirs0) end. +-spec add_current_dir(rcl_state:t(), [file:name()]) -> [file:name()]. +add_current_dir(State, LibDirs) -> + %% Check to see if there is a rebar.config. If so then look for a deps + %% dir. If both are there then we add that to the lib dirs. + Root = rcl_state:root_dir(State), + add_system_lib_dir(State, [filename:absname(Root) | LibDirs]). + -spec add_system_lib_dir(rcl_state:t(), [file:name()]) -> [file:name()]. add_system_lib_dir(State, LibDirs) -> ExcludeSystem = rcl_state:get(State, discover_exclude_system, false), diff --git a/src/rcl_state.erl b/src/rcl_state.erl index 28effbd..842b635 100644 --- a/src/rcl_state.erl +++ b/src/rcl_state.erl @@ -108,7 +108,9 @@ new(PropList, Target) when erlang:is_list(PropList) -> root_dir = proplists:get_value(root_dir, PropList, Root), default_release={proplists:get_value(relname, PropList, undefined), proplists:get_value(relvsn, PropList, undefined)}}, - create_logic_providers(State0). + rcl_state:put(create_logic_providers(State0), + disable_default_libs, + proplists:get_value(disable_default_libs, PropList, false)). %% @doc the application overrides for the system -spec overrides(t()) -> [{AppName::atom(), Directory::file:filename()}]. diff --git a/src/relcool.erl b/src/relcool.erl index 9fb9240..a6b30a3 100644 --- a/src/relcool.erl +++ b/src/relcool.erl @@ -113,8 +113,7 @@ do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Overrides, Con -spec opt_spec_list() -> [getopt:option_spec()]. opt_spec_list() -> - [ - {relname, $n, "relname", string, + [{relname, $n, "relname", string, "Specify the name for the release that will be generated"}, {relvsn, $v, "relvsn", string, "Specify the version for the release"}, {goals, $g, "goal", string, @@ -123,6 +122,9 @@ opt_spec_list() -> "The output directory for the release. This is `./` by default."}, {lib_dir, $l, "lib-dir", string, "Additional dirs that should be searched for OTP Apps"}, + {disable_default_libs, undefined, "disable-default-libs", + {boolean, false}, + "Disable the default system added lib dirs (means you must add them all manually"}, {log_level, $V, "verbose", {integer, 0}, "Verbosity level, maybe between 0 and 2"}, {root_dir, $r, "root", string, "The project root directory"}]. diff --git a/test/rclt_discover_SUITE.erl b/test/rclt_discover_SUITE.erl index 63d7841..6b61840 100644 --- a/test/rclt_discover_SUITE.erl +++ b/test/rclt_discover_SUITE.erl @@ -62,8 +62,8 @@ normal_case(Config) -> end)(App) || App <- - [{create_random_name("lib_app1_"), create_random_vsn()} - || _ <- lists:seq(1, 100)]], + [{create_random_name("lib_app1_"), create_random_vsn()} + || _ <- lists:seq(1, 100)]], LibDir2 = proplists:get_value(lib2, Config), Apps2 = [(fun({Name, Vsn}) -> @@ -71,10 +71,9 @@ normal_case(Config) -> end)(App) || App <- [{create_random_name("lib_app2_"), create_random_vsn()} - || _ <- lists:seq(1, 100)]], - State0 = rcl_state:put(rcl_state:put(proplists:get_value(state, Config), - discover_exclude_rebar, true), - discover_exclude_system, true), + || _ <- lists:seq(1, 100)]], + State0 = rcl_state:put(proplists:get_value(state, Config), + disable_default_libs, true), {DiscoverProvider, {ok, State1}} = rcl_provider:new(rcl_prv_discover, State0), {ok, State2} = rcl_provider:do(DiscoverProvider, State1), lists:foreach(fun(App) -> -- cgit v1.2.3 From 47e700e7ad364dc4d919bc5b16c18e71b4a0892d Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 4 Jan 2013 10:54:21 -0500 Subject: make common_test support explicit The rebar support for common test is very, very buggy and it fails often without common_test failing due to how rebar integrates with common test. This patch takes the responsability for running common test from rebar and runs it directly. --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2e43f9d..1cf2e23 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,11 @@ eunit: compile clean-common-test-data $(REBAR) skip_deps=true eunit ct: compile clean-common-test-data - $(REBAR) skip_deps=true ct + ct_run -pa $(CURDIR)/ebin \ + -pa $(CURDIR)/deps/*/ebin \ + -logdir $(CURDIR)/logs \ + -dir $(CURDIR)/test/ \ + -suite rclt_command_SUITE rclt_discover_SUITE -suite rclt_release_SUITE test: compile eunit ct -- cgit v1.2.3 From f1632c3282d719cd5cbb46299f4f0557653ba50f Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 4 Jan 2013 11:02:46 -0500 Subject: change the default log level to info This makes it a bit more comforting to the user (and me as well). With this the user sees a short description of the release. --- src/relcool.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/relcool.erl b/src/relcool.erl index a6b30a3..974b19f 100644 --- a/src/relcool.erl +++ b/src/relcool.erl @@ -125,7 +125,7 @@ opt_spec_list() -> {disable_default_libs, undefined, "disable-default-libs", {boolean, false}, "Disable the default system added lib dirs (means you must add them all manually"}, - {log_level, $V, "verbose", {integer, 0}, + {log_level, $V, "verbose", {integer, 1}, "Verbosity level, maybe between 0 and 2"}, {root_dir, $r, "root", string, "The project root directory"}]. -- cgit v1.2.3