diff --git a/src/rebar_relx.erl b/src/rebar_relx.erl index 05ef6de4a..f94cd812d 100644 --- a/src/rebar_relx.erl +++ b/src/rebar_relx.erl @@ -241,6 +241,8 @@ app_infos_to_relx(AppInfos, AppType) -> => app_info_to_relx(rebar_app_info:app_to_map(AppInfo), AppType)} end, #{}, AppInfos). +app_info_to_relx(#{vsn := Vsn}=Map, AppType) when is_binary(Vsn) -> + app_info_to_relx(Map#{vsn => binary:bin_to_list(Vsn)}, AppType); app_info_to_relx(#{name := Name, vsn := Vsn, applications := Applications, diff --git a/test/mixplugin_SUITE.erl b/test/mixplugin_SUITE.erl new file mode 100644 index 000000000..1ced40b58 --- /dev/null +++ b/test/mixplugin_SUITE.erl @@ -0,0 +1,54 @@ +%% Test a unusual rebar3 corner case where an Elixir package, built with mix plugin, is released. +%% If done directly, without previous build, the release will fail. +%% Repeat the release, or compile/test before the first release, and the release is successful. +%% +%% First build rebar3 escript used by this test suite. +%% rebar3 escriptize + +-module( mixplugin_SUITE ). + +-export( [initial_release/1, re_release/1] ). + +%% Common test callbacks +-export( [all/0, end_per_suite/1, init_per_suite/1] ). + + +all() -> [initial_release, re_release]. + +end_per_suite( _Config ) -> ok. + +init_per_suite( Config ) -> + Repo = proplists:get_value( data_dir, Config ), + Rm_command = "cd " ++ Repo ++ " && rm -rf _build", + Result = os:cmd( Rm_command ), + ct:pal( "rm -rf _build ~p", [Result] ), + Config. + +%% Test cases + +initial_release( Config ) -> release( Config ). + +re_release( Config ) -> release( Config ). + +%%==================================================================== +%% Internal functions +%%==================================================================== + +%% Find where rebar3 directory is. Where the escript was built. +rebar_escript( {ok, Directory} ) -> + Rebar_directory = filename:join( lists:takewhile(fun rebar_escript_build/1, filename:split(Directory)) ), + filename:join( Rebar_directory, "rebar3" ). + +rebar_escript_build( "_build" ) -> false; +rebar_escript_build( _) -> true. + + +release( Config ) -> + Repo = proplists:get_value( data_dir, Config ), + Rebar = rebar_escript( file:get_cwd() ), + Release_command = "cd " ++ Repo ++ " && " ++ Rebar ++ " release", + + Result = os:cmd( Release_command ), + + ct:pal( "~p release\n~p", [Rebar, Result] ), + [_Release_bin] = filelib:wildcard( filename:join([Repo, "_build", "default", "rel", "*", "bin"]) ). diff --git a/test/mixplugin_SUITE_data/rebar.config b/test/mixplugin_SUITE_data/rebar.config new file mode 100644 index 000000000..50dfc2142 --- /dev/null +++ b/test/mixplugin_SUITE_data/rebar.config @@ -0,0 +1,14 @@ +{erl_opts, [debug_info]}. +{deps, [tzdata, hackney]}. +{plugins, [rebar_mix]}. +{provider_hooks, [ + {pre, [{compile, {mix, find_elixir_libs}}]}, + {post, [{compile, {mix, consolidate_protocols}}]} +]}. +{relx, [{release, { 'test_elixirtz', "0.1.0" }, + [test_elixirtz, hackney]}, + {dev_mode, false}, + {include_erts, false}, + {include_src, false}, + {extended_start_script, true}] +}. diff --git a/test/mixplugin_SUITE_data/src/test_elixirtz.app.src b/test/mixplugin_SUITE_data/src/test_elixirtz.app.src new file mode 100644 index 000000000..e60c5c0aa --- /dev/null +++ b/test/mixplugin_SUITE_data/src/test_elixirtz.app.src @@ -0,0 +1,27 @@ +{application, test_elixirtz, + [{description, "An OTP library"}, + {vsn, "0.1.0"}, + {registered, []}, + {applications, + [kernel, + stdlib, + unicode_util_compat, + idna, + mimerl, + certifi, + syntax_tools, + parse_trans, + ssl_verify_fun, + metrics, + hackney, + compiler, + elixir, + logger, + tzdata + ]}, + {env,[]}, + {modules, []}, + + {licenses, ["Apache 2.0"]}, + {links, []} + ]}. diff --git a/test/mixplugin_SUITE_data/src/test_elixirtz.erl b/test/mixplugin_SUITE_data/src/test_elixirtz.erl new file mode 100644 index 000000000..d71b90c92 --- /dev/null +++ b/test/mixplugin_SUITE_data/src/test_elixirtz.erl @@ -0,0 +1,37 @@ +-module(test_elixirtz). + +-export( [ensure_started/0, local_from_utc/2] ). + + +ensure_started() -> + %% Start hackney as early as possible. + ok = application:ensure_started( unicode_util_compat ), + ok = application:ensure_started( idna ), + ok = application:ensure_started( mimerl ), + ok = application:ensure_started( certifi ), + ok = application:ensure_started( syntax_tools ), + ok = application:ensure_started( parse_trans ), + ok = application:ensure_started( ssl_verify_fun ), + ok = application:ensure_started( metrics ), + ok = application:ensure_started( hackney ), + ok = application:ensure_started( compiler ), + ok = application:ensure_started( elixir ), + ok = application:ensure_started( logger ), + ok = application:ensure_started( tzdata ). + +local_from_utc( Date_time, Time_zone ) -> + Naive_date_time = 'Elixir.NaiveDateTime':'from_erl!'( Date_time ), + Elixir_date_time = 'Elixir.DateTime':'from_naive!'( Naive_date_time, <<"Etc/UTC">> ), + B = binary:list_to_bin( Time_zone ), + {ok, Local} = 'Elixir.DateTime':shift_zone( Elixir_date_time, B, 'Elixir.Tzdata.TimeZoneDatabase' ), + #{std_offset := STD, utc_offset := UTC} = Local, + {'Elixir.NaiveDateTime':to_erl( Local ), local_from_utc_offset( STD + UTC )}. + + +local_from_utc_offset( Seconds ) when Seconds < 0 -> + {$-, local_from_utc_offset_hours_minutes( Seconds * -1 )}; +local_from_utc_offset( Seconds ) -> + {$+, local_from_utc_offset_hours_minutes( Seconds )}. + +local_from_utc_offset_hours_minutes( Seconds ) -> + [Seconds div 3600, (Seconds rem 3600) div 60].