diff --git a/src/rlx_assemble.erl b/src/rlx_assemble.erl index 70b9f8a2c..f31cdd457 100644 --- a/src/rlx_assemble.erl +++ b/src/rlx_assemble.erl @@ -472,17 +472,42 @@ generate_start_erl_data_file(Release, ReleasesDir) -> %% @doc copy vm.args or generate one to releases/VSN/vm.args -spec copy_or_generate_vmargs_file(rlx_state:t(), rlx_release:t(), file:name()) -> ok. copy_or_generate_vmargs_file(State, Release, RelDir) -> + RootDir = rlx_state:root_dir(State), + + %% default paths to check for the args file + DefaultVmArgsSrcPath = filename:join([RootDir, "config", "vm.args.src"]), + DefaultVmArgsPath = filename:join([RootDir, "config", "vm.args"]), + + %% paths to copy to in the release RelVmargsPath = filename:join([RelDir, "vm.args"]), RelVmargsSrcPath = filename:join([RelDir, "vm.args.src"]), - case rlx_state:vm_args_src(State) of + + VmArgsSrc = rlx_state:vm_args_src(State), + VmArgs = rlx_state:vm_args(State), + + case VmArgsSrc of undefined -> - case rlx_state:vm_args(State) of + case VmArgs of false -> + %% when vm_args_src is not set and vm_args is false, do nothing ok; undefined -> - RelName = erlang:atom_to_list(rlx_release:name(Release)), - unless_exists_write_default(RelVmargsPath, vm_args_file(RelName)); + %% if neither is defined but the files exist at the default paths, include those + case filelib:is_regular(DefaultVmArgsSrcPath) of + false -> + case filelib:is_regular(DefaultVmArgsPath) of + false -> + %% if neither is defined and neither exists then create a default vm.args + RelName = erlang:atom_to_list(rlx_release:name(Release)), + unless_exists_write_default(RelVmargsPath, vm_args_file(RelName)); + true -> + copy_or_symlink_config_file(State, DefaultVmArgsPath, RelVmargsPath) + end; + true -> + copy_or_symlink_config_file(State, DefaultVmArgsSrcPath, RelVmargsSrcPath) + end; ArgsPath -> + %% include the vm_args file if it exists case filelib:is_regular(ArgsPath) of false -> erlang:error(?RLX_ERROR({vmargs_does_not_exist, ArgsPath})); @@ -492,7 +517,7 @@ copy_or_generate_vmargs_file(State, Release, RelDir) -> end; ArgsSrcPath -> %% print a warning if vm_args is also set - case rlx_state:vm_args(State) of + case VmArgs of undefined -> ok; _-> diff --git a/src/rlx_config.erl b/src/rlx_config.erl index 2cb6e85c7..9f12db1c3 100644 --- a/src/rlx_config.erl +++ b/src/rlx_config.erl @@ -86,14 +86,26 @@ load({release, {RelName, Vsn}, Applications, Config}, {ok, State0}) -> {ok, rlx_state:add_configured_release(State0, Release2)}; load({vm_args, false}, {ok, State}) -> {ok, rlx_state:vm_args(State, false)}; +load({vm_args, undefined}, {ok, State}) -> + {ok, rlx_state:vm_args(State, undefined)}; load({vm_args, VmArgs}, {ok, State}) -> {ok, rlx_state:vm_args(State, filename:absname(VmArgs))}; +load({vm_args_src, false}, {ok, State}) -> + {ok, rlx_state:vm_args_src(State, false)}; +load({vm_args_src, undefined}, {ok, State}) -> + {ok, rlx_state:vm_args_src(State, undefined)}; load({vm_args_src, VmArgs}, {ok, State}) -> {ok, rlx_state:vm_args_src(State, filename:absname(VmArgs))}; load({sys_config, false}, {ok, State}) -> {ok, rlx_state:sys_config(State, false)}; +load({sys_config, undefined}, {ok, State}) -> + {ok, rlx_state:sys_config(State, undefined)}; load({sys_config, SysConfig}, {ok, State}) -> {ok, rlx_state:sys_config(State, filename:absname(SysConfig))}; +load({sys_config_src, false}, {ok, State}) -> + {ok, rlx_state:sys_config_src(State, false)}; +load({sys_config_src, undefined}, {ok, State}) -> + {ok, rlx_state:sys_config_src(State, undefined)}; load({sys_config_src, SysConfigSrc}, {ok, State}) -> {ok, rlx_state:sys_config_src(State, filename:absname(SysConfigSrc))}; load({root_dir, Root}, {ok, State}) -> diff --git a/src/rlx_state.erl b/src/rlx_state.erl index 84651ffea..1aa9da247 100644 --- a/src/rlx_state.erl +++ b/src/rlx_state.erl @@ -107,9 +107,9 @@ config_file=[] :: file:filename() | undefined, available_apps=#{} :: #{atom() => rlx_app_info:t()}, vm_args :: file:filename() | false | undefined, - vm_args_src :: file:filename() | undefined, + vm_args_src :: file:filename() | false | undefined, sys_config :: file:filename() | false | undefined, - sys_config_src :: file:filename() | undefined, + sys_config_src :: file:filename() | false | undefined, overrides=[] :: [{AppName::atom(), Directory::file:filename()}], exclude_apps=[] :: [AppName::atom()], exclude_modules=[] :: [{App::atom(), [Module::atom()]}], @@ -229,11 +229,11 @@ vm_args(#state_t{vm_args=VmArgs}) -> vm_args(State, VmArgs) -> State#state_t{vm_args=VmArgs}. --spec vm_args_src(t()) -> file:filename() | undefined. +-spec vm_args_src(t()) -> file:filename() | false | undefined. vm_args_src(#state_t{vm_args_src=VmArgs}) -> VmArgs. --spec vm_args_src(t(), undefined | file:filename()) -> t(). +-spec vm_args_src(t(), undefined | false | file:filename()) -> t(). vm_args_src(State, VmArgs) -> State#state_t{vm_args_src=VmArgs}. @@ -241,15 +241,15 @@ vm_args_src(State, VmArgs) -> sys_config(#state_t{sys_config=SysConfig}) -> SysConfig. --spec sys_config(t(), false | file:filename()) -> t(). +-spec sys_config(t(), false | undefined | file:filename()) -> t(). sys_config(State, SysConfig) -> State#state_t{sys_config=SysConfig}. --spec sys_config_src(t()) -> file:filename() | undefined. +-spec sys_config_src(t()) -> file:filename() | false | undefined. sys_config_src(#state_t{sys_config_src=SysConfigSrc}) -> SysConfigSrc. --spec sys_config_src(t(), file:filename() | undefined) -> t(). +-spec sys_config_src(t(), file:filename() | false | undefined) -> t(). sys_config_src(State, SysConfigSrc) -> State#state_t{sys_config_src=SysConfigSrc}. diff --git a/test/rlx_release_SUITE.erl b/test/rlx_release_SUITE.erl index 0f25fcf84..297f4e796 100644 --- a/test/rlx_release_SUITE.erl +++ b/test/rlx_release_SUITE.erl @@ -37,7 +37,8 @@ groups() -> [make_release, make_config_release, make_release_semver, overlay_release, make_extend_release, make_extend_release_versioned, make_extend_config_release, make_scriptless_release, make_app_type_none_release, include_powershell, - include_unix_powershell_win32, + include_unix_powershell_win32, make_release_with_default_sys_config_vm_args_src, + make_release_with_default_sys_config_vm_args, make_not_included_nodetool_release, make_src_release, make_excluded_src_release, make_exclude_modules_release, make_release_with_sys_config_vm_args_src, make_exclude_app_release, make_overridden_release, make_goalless_release, @@ -72,8 +73,6 @@ init_per_testcase(_, Config) -> [{out_dir, OutputDir} | Config]. end_per_testcase(_, _) -> - %% prevents failures in tests when xref fails to stop - application:stop(xref), ok. make_release(Config) -> @@ -182,6 +181,7 @@ make_extend_release(Config) -> goal_app_2]}, {release, {foo_test, "0.0.1", {extend, foo}}, [goal_app_2]}, + {check_for_undefined_functions, false}, {lib_dirs, [filename:join(LibDir1, "*")]}], {ok, State} = relx:build_release(foo_test, [{root_dir, LibDir1}, {lib_dirs, [LibDir1]}, @@ -983,6 +983,76 @@ make_release_with_sys_config_vm_args_src(Config) -> "vm.args"]))) end. +make_release_with_default_sys_config_vm_args_src(Config) -> + LibDir1 = ?config(lib_dir, Config), + OutputDir = ?config(out_dir, Config), + RootDir = filename:join(LibDir1, "make_release_with_default_sys_config_vm_args_src"), + + %% the .src versions should take precedence and the others are not copied + SysConfig = filename:join([RootDir, "config", "sys.config"]), + rlx_test_utils:write_config(SysConfig, [{this_is_a_test, "yup it is"}]), + + SysConfigSrc = filename:join([RootDir, "config", "sys.config.src"]), + rlx_test_utils:write_config(SysConfigSrc, [{this_is_a_test, "yup it is"}]), + + VmArgs = filename:join([RootDir, "config", "vm.args"]), + rlx_file_utils:write(VmArgs, ""), + + VmArgsSrc = filename:join([RootDir, "config", "vm.args.src"]), + rlx_file_utils:write(VmArgsSrc, ""), + + RelxConfig = [{dev_mode, false}, + {release, {foo, "0.0.1"}, + [goal_app_1, + goal_app_2]}, + {check_for_undefined_functions, false}], + + {ok, State} = relx:build_release(foo, [{root_dir, RootDir}, {lib_dirs, [LibDir1]}, + {output_dir, OutputDir} | RelxConfig]), + + [{{foo, "0.0.1"}, _Release}] = maps:to_list(rlx_state:realized_releases(State)), + + ?assert(filelib:is_file(filename:join([OutputDir, "foo", "releases", "0.0.1", + "sys.config.src"]))), + ?assert(filelib:is_file(filename:join([OutputDir, "foo", "releases", "0.0.1", + "vm.args.src"]))), + + %% check that sys.config and vm.args don't exist because .src was used instead + ?assert(not filelib:is_file(filename:join([OutputDir, "foo", "releases", "0.0.1", + "sys.config"]))), + ?assert(not filelib:is_file(filename:join([OutputDir, "foo", "releases", "0.0.1", + "vm.args"]))), + ok. + +make_release_with_default_sys_config_vm_args(Config) -> + LibDir1 = ?config(lib_dir, Config), + OutputDir = ?config(out_dir, Config), + RootDir = filename:join(LibDir1, "make_release_with_default_sys_config_vm_args"), + + %% no .src versions of the files means these get used + SysConfig = filename:join([RootDir, "config", "sys.config"]), + rlx_test_utils:write_config(SysConfig, [{this_is_a_test, "yup it is"}]), + + VmArgs = filename:join([RootDir, "config", "vm.args"]), + rlx_file_utils:write(VmArgs, ""), + + RelxConfig = [{mode, prod}, + {release, {foo, "0.0.1"}, + [goal_app_1, + goal_app_2]}, + {check_for_undefined_functions, false}], + + {ok, State} = relx:build_release(foo, [{root_dir, RootDir}, {lib_dirs, [LibDir1]}, + {output_dir, OutputDir} | RelxConfig]), + + [{{foo, "0.0.1"}, _Release}] = maps:to_list(rlx_state:realized_releases(State)), + + ?assert(filelib:is_file(filename:join([OutputDir, "foo", "releases", "0.0.1", + "sys.config"]))), + ?assert(filelib:is_file(filename:join([OutputDir, "foo", "releases", "0.0.1", + "vm.args"]))), + ok. + make_prod_mode_release(Config) -> LibDir1 = proplists:get_value(lib_dir, Config), OutputDir = ?config(out_dir, Config),