From e68bbac546e084b4949dc01cbe88c03f6c667139 Mon Sep 17 00:00:00 2001 From: Eric B Merritt Date: Thu, 9 May 2013 16:43:56 -0700 Subject: support a hard distinction between configured releases and realized releases --- src/rcl_prv_assembler.erl | 5 ++- src/rcl_prv_config.erl | 6 +-- src/rcl_prv_discover.erl | 6 +-- src/rcl_prv_overlay.erl | 10 ++--- src/rcl_prv_release.erl | 14 +++---- src/rcl_state.erl | 91 ++++++++++++++++++++++++++------------------- test/rclt_release_SUITE.erl | 18 ++++----- 7 files changed, 83 insertions(+), 67 deletions(-) diff --git a/src/rcl_prv_assembler.erl b/src/rcl_prv_assembler.erl index f40bdc5..204c8bd 100644 --- a/src/rcl_prv_assembler.erl +++ b/src/rcl_prv_assembler.erl @@ -41,8 +41,8 @@ init(State) -> %% looking for OTP Applications -spec do(rcl_state:t()) -> {ok, rcl_state:t()} | relcool:error(). do(State) -> - {RelName, RelVsn} = rcl_state:default_release(State), - Release = rcl_state:get_release(State, RelName, RelVsn), + {RelName, RelVsn} = rcl_state:default_configured_release(State), + Release = rcl_state:get_realized_release(State, RelName, RelVsn), OutputDir = rcl_state:output_dir(State), case create_output_dir(OutputDir) of ok -> @@ -202,6 +202,7 @@ create_release_info(State, Release, OutputDir) -> ReleaseFile = filename:join([ReleaseDir, RelName ++ ".rel"]), ok = ec_file:mkdir_p(ReleaseDir), case rcl_release:metadata(Release) of + State1 = rcl_state:update_realized_release(State0, Release1), {ok, Meta} -> ok = ec_file:write_term(ReleaseFile, Meta), write_bin_file(State, Release, OutputDir, ReleaseDir); diff --git a/src/rcl_prv_config.erl b/src/rcl_prv_config.erl index dfbc321..2bc9851 100644 --- a/src/rcl_prv_config.erl +++ b/src/rcl_prv_config.erl @@ -123,7 +123,7 @@ load_config(ConfigFile, State) -> -spec load_terms(term(), {ok, rcl_state:t()} | relcool:error()) -> {ok, rcl_state:t()} | relcool:error(). load_terms({default_release, RelName, RelVsn}, {ok, State}) -> - {ok, rcl_state:default_release(State, RelName, RelVsn)}; + {ok, rcl_state:default_configured_release(State, RelName, RelVsn)}; load_terms({paths, Paths}, {ok, State}) -> code:add_pathsa([filename:absname(Path) || Path <- Paths]), {ok, State}; @@ -154,7 +154,7 @@ load_terms({release, {RelName, Vsn}, Applications}, {ok, State0}) -> E={error, _} -> E; {ok, Release1} -> - {ok, rcl_state:add_release(State0, Release1)} + {ok, rcl_state:add_configured_release(State0, Release1)} end; load_terms({release, {RelName, Vsn}, {erts, ErtsVsn}, Applications}, {ok, State}) -> @@ -163,7 +163,7 @@ load_terms({release, {RelName, Vsn}, {erts, ErtsVsn}, E={error, _} -> E; {ok, Release1} -> - {ok, rcl_state:add_release(State, Release1)} + {ok, rcl_state:add_configured_release(State, Release1)} end; load_terms({sys_config, SysConfig}, {ok, State}) -> {ok, rcl_state:sys_config(State, filename:absname(SysConfig))}; diff --git a/src/rcl_prv_discover.erl b/src/rcl_prv_discover.erl index 3627787..56085ac 100644 --- a/src/rcl_prv_discover.erl +++ b/src/rcl_prv_discover.erl @@ -48,9 +48,9 @@ do(State0) -> case rcl_rel_discovery:do(State0, LibDirs, AppMeta) of {ok, Releases} -> State1 = rcl_state:available_apps(State0, AppMeta), - {ok, rcl_state:discovered_releases(State1, lists:foldl(fun add/2, - ec_dictionary:new(ec_dict), - Releases))}; + {ok, rcl_state:realized_releases(State1, lists:foldl(fun add/2, + ec_dictionary:new(ec_dict), + Releases))}; Error -> Error end; diff --git a/src/rcl_prv_overlay.erl b/src/rcl_prv_overlay.erl index 40471ea..35e37bf 100644 --- a/src/rcl_prv_overlay.erl +++ b/src/rcl_prv_overlay.erl @@ -43,8 +43,8 @@ init(State) -> %% looking for OTP Applications -spec do(rcl_state:t()) -> {ok, rcl_state:t()} | relcool:error(). do(State) -> - {RelName, RelVsn} = rcl_state:default_release(State), - Release = rcl_state:get_release(State, RelName, RelVsn), + {RelName, RelVsn} = rcl_state:default_configured_release(State), + Release = rcl_state:get_realized_release(State, RelName, RelVsn), case rcl_release:realized(Release) of true -> generate_overlay_vars(State, Release); @@ -202,15 +202,15 @@ generate_state_vars(State) -> {providers, rcl_state:providers(State)}, {sys_config, rcl_state:sys_config(State)}, {root_dir, rcl_state:root_dir(State)}, - {default_release_name, case rcl_state:default_release(State) of + {default_release_name, case rcl_state:default_configured_release(State) of {Name0, _} -> Name0 end}, - {default_release_version, case rcl_state:default_release(State) of + {default_release_version, case rcl_state:default_configured_release(State) of {_, Vsn0} -> Vsn0 end}, - {default_release, case rcl_state:default_release(State) of + {default_release, case rcl_state:default_configured_release(State) of {Name1, undefined} -> erlang:atom_to_list(Name1); {Name1, Vsn1} -> diff --git a/src/rcl_prv_release.erl b/src/rcl_prv_release.erl index eac1f20..d90b492 100644 --- a/src/rcl_prv_release.erl +++ b/src/rcl_prv_release.erl @@ -89,7 +89,7 @@ create_dep_graph(State) -> -spec find_default_release(rcl_state:t(), rcl_depsolver:t()) -> {ok, rcl_state:t()} | relcool:error(). find_default_release(State, DepGraph) -> - case rcl_state:default_release(State) of + case rcl_state:default_configured_release(State) of {undefined, undefined} -> resolve_default_release(State, DepGraph); {RelName, undefined} -> @@ -103,9 +103,9 @@ find_default_release(State, DepGraph) -> resolve_default_release(State0, DepGraph) -> %% Here we will just get the highest versioned release and run that. case lists:sort(fun release_sort/2, - ec_dictionary:to_list(rcl_state:releases(State0))) of + ec_dictionary:to_list(rcl_state:configured_releases(State0))) of [{{RelName, RelVsn}, _} | _] -> - State1 = rcl_state:default_release(State0, RelName, RelVsn), + State1 = rcl_state:default_configured_release(State0, RelName, RelVsn), solve_release(State1, DepGraph, RelName, RelVsn); [] -> ?RCL_ERROR(no_releases_in_system) @@ -113,12 +113,12 @@ resolve_default_release(State0, DepGraph) -> resolve_default_version(State0, DepGraph, RelName) -> %% Here we will just get the lastest version and run that. - AllReleases = ec_dictionary:to_list(rcl_state:releases(State0)), + AllReleases = ec_dictionary:to_list(rcl_state:configured_releases(State0)), SpecificReleases = [Rel || Rel={{PossibleRelName, _}, _} <- AllReleases, PossibleRelName =:= RelName], case lists:sort(fun release_sort/2, SpecificReleases) of [{{RelName, RelVsn}, _} | _] -> - State1 = rcl_state:default_release(State0, RelName, RelVsn), + State1 = rcl_state:default_configured_release(State0, RelName, RelVsn), solve_release(State1, DepGraph, RelName, RelVsn); [] -> ?RCL_ERROR({no_releases_for, RelName}) @@ -143,7 +143,7 @@ solve_release(State0, DepGraph, RelName, RelVsn) -> "Solving Release ~p-~s~n", [RelName, RelVsn]), try - Release = rcl_state:get_release(State0, RelName, RelVsn), + Release = rcl_state:get_configured_release(State0, RelName, RelVsn), Goals = rcl_release:goals(Release), case Goals of [] -> @@ -172,7 +172,7 @@ set_resolved(State, Release0, Pkgs) -> fun() -> rcl_release:format(1, Release1) end), - {ok, rcl_state:update_release(State, Release1)}; + {ok, rcl_state:add_realized_release(State, Release1)}; {error, E} -> ?RCL_ERROR({release_error, E}) end. diff --git a/src/rcl_state.erl b/src/rcl_state.erl index a4f091c..3a91f48 100644 --- a/src/rcl_state.erl +++ b/src/rcl_state.erl @@ -40,14 +40,16 @@ sys_config/2, root_dir/1, root_dir/2, - add_release/2, - get_release/3, - update_release/2, - releases/1, - discovered_releases/1, - discovered_releases/2, - default_release/1, - default_release/3, + add_configured_release/2, + get_configured_release/3, + configured_releases/1, + realized_releases/1, + realized_releases/2, + add_realized_release/2, + get_realized_release/3, + update_realized_release/2, + default_configured_release/1, + default_configured_release/3, available_apps/1, available_apps/2, get/2, @@ -73,12 +75,13 @@ goals=[] :: [rcl_depsolver:constraint()], providers = [] :: [rcl_provider:t()], available_apps = [] :: [rcl_app_info:t()], - default_release :: {rcl_release:name(), rcl_release:vsn()}, + default_configured_release :: {rcl_release:name(), rcl_release:vsn()}, sys_config :: file:filename() | undefined, overrides :: [{AppName::atom(), Directory::file:filename()}], skip_apps = [] :: [AppName::atom()], - releases :: releases(), - discovered_releases :: releases(), + configured_releases :: releases(), + realized_releases :: releases(), + upfrom :: string() | binary() | undefined, config_values :: ec_dictionary:dictionary(Key::atom(), Value::term())}). @@ -112,12 +115,13 @@ new(PropList, Target) caller = proplists:get_value(caller, PropList, api), goals=proplists:get_value(goals, PropList, []), providers = [], - releases=ec_dictionary:new(ec_dict), - discovered_releases=ec_dictionary:new(ec_dict), + configured_releases=ec_dictionary:new(ec_dict), + realized_releases=ec_dictionary:new(ec_dict), config_values=ec_dictionary:new(ec_dict), overrides = proplists:get_value(overrides, PropList, []), root_dir = proplists:get_value(root_dir, PropList, Root), - default_release={proplists:get_value(relname, PropList, undefined), + upfrom = proplists:get_value(upfrom, PropList, undefined), + default_configured_release={proplists:get_value(relname, PropList, undefined), proplists:get_value(relvsn, PropList, undefined)}}, rcl_state:put(create_logic_providers(State0), disable_default_libs, @@ -192,44 +196,55 @@ root_dir(State, RootDir) -> providers(M, NewProviders) -> M#state_t{providers=NewProviders}. --spec add_release(t(), rcl_release:t()) -> t(). -add_release(M=#state_t{releases=Releases}, Release) -> - M#state_t{releases=ec_dictionary:add({rcl_release:name(Release), +-spec add_configured_release(t(), rcl_release:t()) -> t(). +add_configured_release(M=#state_t{configured_releases=Releases}, Release) -> + M#state_t{configured_releases=ec_dictionary:add({rcl_release:name(Release), rcl_release:vsn(Release)}, Release, Releases)}. --spec update_release(t(), rcl_release:t()) -> t(). -update_release(M=#state_t{releases=Releases}, Release) -> - M#state_t{releases=ec_dictionary:add({rcl_release:name(Release), - rcl_release:vsn(Release)}, - Release, - Releases)}. - --spec get_release(t(), rcl_release:name(), rcl_release:vsn()) -> rcl_release:t(). -get_release(#state_t{releases=Releases}, Name, Vsn) -> +-spec get_configured_release(t(), rcl_release:name(), rcl_release:vsn()) -> rcl_release:t(). +get_configured_release(#state_t{configured_releases=Releases}, Name, Vsn) -> ec_dictionary:get({Name, Vsn}, Releases). --spec releases(t()) -> releases(). -releases(#state_t{releases=Releases}) -> +-spec configured_releases(t()) -> releases(). +configured_releases(#state_t{configured_releases=Releases}) -> Releases. --spec discovered_releases(t()) -> releases(). -discovered_releases(#state_t{discovered_releases=Releases}) -> +-spec realized_releases(t()) -> releases(). +realized_releases(#state_t{realized_releases=Releases}) -> Releases. --spec discovered_releases(t(), releases()) -> t(). -discovered_releases(State, Releases) -> - State#state_t{discovered_releases=Releases}. +-spec realized_releases(t(), releases()) -> t(). +realized_releases(State, Releases) -> + State#state_t{realized_releases=Releases}. + +-spec add_realized_release(t(), rcl_release:t()) -> t(). +add_realized_release(State = #state_t{realized_releases=Releases}, Release) -> + NewReleases = ec_dictionary:add({rcl_release:name(Release), rcl_release:vsn(Release)}, + Release, Releases), + State#state_t{realized_releases=NewReleases}. + +-spec get_realized_release(t(), rcl_release:name(), rcl_release:vsn()) -> rcl_release:t(). +get_realized_release(#state_t{realized_releases=Releases}, Name, Vsn) -> + ec_dictionary:get({Name, Vsn}, Releases). + +-spec update_realized_release(t(), rcl_release:t()) -> + t(). +update_realized_release(M=#state_t{realized_releases=Releases}, Release) -> + M#state_t{realized_releases=ec_dictionary:add({rcl_release:name(Release), + rcl_release:vsn(Release)}, + Release, + Releases)}. --spec default_release(t()) -> +-spec default_configured_release(t()) -> {rcl_release:name() | undefined, rcl_release:vsn() | undefined}. -default_release(#state_t{default_release=Def}) -> +default_configured_release(#state_t{default_configured_release=Def}) -> Def. --spec default_release(t(), rcl_release:name(), rcl_release:vsn()) -> t(). -default_release(M, Name, Vsn) -> - M#state_t{default_release={Name, Vsn}}. +-spec default_configured_release(t(), rcl_release:name(), rcl_release:vsn()) -> t(). +default_configured_release(M, Name, Vsn) -> + M#state_t{default_configured_release={Name, Vsn}}. -spec available_apps(t()) -> [rcl_app_info:t()]. available_apps(#state_t{available_apps=Apps}) -> diff --git a/test/rclt_release_SUITE.erl b/test/rclt_release_SUITE.erl index f0446d6..97f564e 100644 --- a/test/rclt_release_SUITE.erl +++ b/test/rclt_release_SUITE.erl @@ -92,7 +92,7 @@ make_release(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)), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:realized_releases(State)), AppSpecs = rcl_release:applications(Release), ?assert(lists:keymember(stdlib, 1, AppSpecs)), ?assert(lists:keymember(kernel, 1, AppSpecs)), @@ -159,7 +159,7 @@ make_scriptless_release(Config) -> ?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)), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:realized_releases(State)), AppSpecs = rcl_release:applications(Release), ?assert(lists:keymember(stdlib, 1, AppSpecs)), ?assert(lists:keymember(kernel, 1, AppSpecs)), @@ -206,7 +206,7 @@ make_overridden_release(Config) -> {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)), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:realized_releases(State)), AppSpecs = rcl_release:applications(Release), ?assert(lists:keymember(stdlib, 1, AppSpecs)), ?assert(lists:keymember(kernel, 1, AppSpecs)), @@ -255,7 +255,7 @@ make_skip_app_release(Config) -> {ok, State} = relcool:do(Cwd, undefined, undefined, [], [LibDir1], 2, OutputDir, [], ConfigFile), - [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:realized_releases(State)), AppSpecs = rcl_release:applications(Release), ?assert(lists:keymember(stdlib, 1, AppSpecs)), ?assert(lists:keymember(kernel, 1, AppSpecs)), @@ -295,7 +295,7 @@ make_implicit_config_release(Config) -> {ok, FooRoot} = file:get_cwd(), {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2, OutputDir, undefined), - [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:realized_releases(State)), ?assert(ec_file:exists(OutputDir)), AppSpecs = rcl_release:applications(Release), ?assert(lists:keymember(stdlib, 1, AppSpecs)), @@ -349,7 +349,7 @@ make_rerun_overridden_release(Config) -> OutputDir, [{OverrideAppName, OverrideAppDir}], ConfigFile), - [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:realized_releases(State)), AppSpecs = rcl_release:applications(Release), ?assert(lists:keymember(stdlib, 1, AppSpecs)), ?assert(lists:keymember(kernel, 1, AppSpecs)), @@ -412,7 +412,7 @@ overlay_release(Config) -> {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2, OutputDir, ConfigFile), - [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:realized_releases(State)), AppSpecs = rcl_release:applications(Release), ?assert(lists:keymember(stdlib, 1, AppSpecs)), ?assert(lists:keymember(kernel, 1, AppSpecs)), @@ -547,7 +547,7 @@ make_depfree_release(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)), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:realized_releases(State)), AppSpecs = rcl_release:applications(Release), ?assert(lists:keymember(stdlib, 1, AppSpecs)), ?assert(lists:keymember(kernel, 1, AppSpecs)). @@ -632,7 +632,7 @@ make_one_app_top_level_release(Config) -> {ok, State} = relcool:do(undefined, undefined, [], [], 2, OutputDir, ConfigFile), ok = file:set_cwd(Cwd), - [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)), + [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:realized_releases(State)), AppSpecs = rcl_release:applications(Release), ?assert(lists:keymember(stdlib, 1, AppSpecs)), ?assert(lists:keymember(kernel, 1, AppSpecs)), -- cgit v1.2.3