Skip to content

Commit e0a9b4b

Browse files
author
José Valim
committed
Preserve UTF8 encoding in release config files
Closes #9225 Signed-off-by: José Valim <[email protected]>
1 parent eb8121c commit e0a9b4b

File tree

7 files changed

+52
-32
lines changed

7 files changed

+52
-32
lines changed

lib/elixir/lib/config/provider.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,9 @@ defmodule Config.Provider do
220220
end
221221

222222
defp write_config!(config, path) do
223-
contents = :io_lib.format("%% coding: utf-8~n~p.~n", [config])
223+
contents = :io_lib.format("%% coding: utf-8~n~tw.~n", [config])
224224

225-
case File.write(path, contents) do
225+
case File.write(path, contents, [:utf8]) do
226226
:ok ->
227227
:ok
228228

lib/elixir/test/elixir/config/provider_test.exs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ defmodule Config.ProviderTest do
1818

1919
File.rm_rf(@tmp_path)
2020
File.mkdir_p!(@tmp_path)
21-
File.write!(@sys_config, :io_lib.format("~p.~n", [context[:sys_config] || []]))
21+
File.write!(@sys_config, :io_lib.format("~tw.~n", [context[:sys_config] || []]), [:utf8])
2222

2323
on_exit(fn ->
2424
Application.delete_env(@config_app, :config_providers)
@@ -50,14 +50,16 @@ defmodule Config.ProviderTest do
5050
assert config[@config_app] == [config_providers: :booted]
5151
end
5252

53-
test "writes extra config" do
54-
init_and_assert_boot(extra_config: [my_app: [key: :old_value, sys_key: :sys_value]])
55-
assert consult(@sys_config)[:my_app] == [sys_key: :sys_value, key: :value]
53+
@tag sys_config: [my_app: [encoding: {:"£", "£", '£'}]]
54+
test "writes sys_config with encoding" do
55+
init_and_assert_boot()
56+
config = consult(@sys_config)
57+
assert config[:my_app][:encoding] == {:"£", "£", '£'}
5658
end
5759

5860
@tag sys_config: [my_app: [key: :old_value, sys_key: :sys_value, extra_config: :old_value]]
59-
test "overrides sys_config" do
60-
init_and_assert_boot(extra_config: [my_app: [extra_config: :value]])
61+
test "writes extra config with overrides" do
62+
init_and_assert_boot(extra_config: [my_app: [key: :old_extra_value, extra_config: :value]])
6163

6264
assert consult(@sys_config)[:my_app] ==
6365
[sys_key: :sys_value, extra_config: :value, key: :value]

lib/mix/lib/mix/release.ex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,9 @@ defmodule Mix.Release do
349349
path = Path.join(release.version_path, "sys.config")
350350

351351
args = [runtime?, sys_config]
352-
format = "%% coding: utf-8~n%% RUNTIME_CONFIG=~s~n~p.~n"
352+
format = "%% coding: utf-8~n%% RUNTIME_CONFIG=~s~n~tw.~n"
353353
File.mkdir_p!(Path.dirname(path))
354-
File.write!(path, :io_lib.format(format, args))
354+
File.write!(path, :io_lib.format(format, args), [:utf8])
355355

356356
case :file.consult(path) do
357357
{:ok, _} ->
@@ -436,7 +436,7 @@ defmodule Mix.Release do
436436
:ok | {:error, String.t()}
437437
def make_boot_script(release, path, modes, prepend_paths \\ []) do
438438
with {:ok, rel_spec} <- build_release_spec(release, modes) do
439-
File.write!(path <> ".rel", consultable(rel_spec))
439+
File.write!(path <> ".rel", consultable(rel_spec), [:utf8])
440440

441441
sys_path = String.to_charlist(path)
442442

@@ -459,7 +459,7 @@ defmodule Mix.Release do
459459
|> prepend_paths_to_script(prepend_paths)
460460

461461
script = {:script, rel_info, instructions}
462-
File.write!(script_path, consultable(script))
462+
File.write!(script_path, consultable(script), [:utf8])
463463
:ok = :systools.script2boot(sys_path)
464464

465465
{:error, module, info} ->
@@ -576,7 +576,7 @@ defmodule Mix.Release do
576576
end
577577

578578
defp consultable(term) do
579-
:io_lib.format("%% coding: utf-8~n~p.~n", [term])
579+
:io_lib.format("%% coding: utf-8~n~tp.~n", [term])
580580
end
581581

582582
@doc """
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
use Mix.Config
22

33
config :release_test, :static, :was_set
4+
config :release_test, :encoding, {:"£", "£", '£'}

lib/mix/test/fixtures/release_test/lib/release_test.ex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ defmodule ReleaseTest do
1919
static_config: Application.fetch_env(:release_test, :static),
2020
runtime_config: Application.fetch_env(:release_test, :runtime),
2121
sys_config_init: to_string(sys_config),
22-
sys_config_env: System.get_env("RELEASE_SYS_CONFIG")
22+
sys_config_env: System.get_env("RELEASE_SYS_CONFIG"),
23+
encoding: Application.get_env(:release_test, :encoding)
2324
}
2425

2526
path = Path.join(System.get_env("RELEASE_ROOT"), "RELEASE_BOOTED")
26-
File.write!(path, inspect(info))
27+
File.write!(path, :erlang.term_to_binary(info))
2728

2829
if System.get_env("RELEASE_NAME") =~ "permanent" do
2930
Supervisor.start_link([], strategy: :one_for_one)

lib/mix/test/mix/release_test.exs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,14 @@ defmodule Mix.ReleaseTest do
437437
assert contents =~ "[{foo,[{bar,baz}]}]."
438438
end
439439

440+
test "writes sys_config with encoding" do
441+
assert make_sys_config(release([]), [encoding: {:"£", "£", '£'}], "unused/runtime/path") ==
442+
:ok
443+
444+
{:ok, contents} = :file.consult(@sys_config)
445+
assert contents == [[encoding: {:"£", "£", '£'}]]
446+
end
447+
440448
test "writes the given sys_config with config providers" do
441449
release = release(config_providers: @providers)
442450
assert make_sys_config(release, [kernel: [key: :value]], "/foo/bar/bat") == :ok

lib/mix/test/mix/tasks/release_test.exs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,9 @@ defmodule Mix.Tasks.ReleaseTest do
140140
static_config: {:ok, :was_set},
141141
runtime_config: :error,
142142
sys_config_env: sys_config_env,
143-
sys_config_init: sys_config_init
144-
} = wait_until_evaled(Path.join(root, "RELEASE_BOOTED"))
143+
sys_config_init: sys_config_init,
144+
encoding: {:"£", "£", '£'}
145+
} = wait_until_decoded(Path.join(root, "RELEASE_BOOTED"))
145146

146147
if match?({:win32, _}, :os.type()) do
147148
# `RELEAS~1` is the DOS path name (8 character) for the `release_test` directory
@@ -169,6 +170,7 @@ defmodule Mix.Tasks.ReleaseTest do
169170
File.write!("config/releases.exs", """
170171
import Config
171172
config :release_test, :runtime, :was_set
173+
config :release_test, :encoding, {:runtime, :"£", "£", '£'}
172174
""")
173175

174176
root = Path.absname("_build/dev/rel/runtime_config")
@@ -198,8 +200,9 @@ defmodule Mix.Tasks.ReleaseTest do
198200
static_config: {:ok, :was_set},
199201
runtime_config: {:ok, :was_set},
200202
sys_config_env: sys_config_env,
201-
sys_config_init: sys_config_init
202-
} = wait_until_evaled(Path.join(root, "RELEASE_BOOTED"))
203+
sys_config_init: sys_config_init,
204+
encoding: {:runtime, :"£", "£", '£'}
205+
} = wait_until_decoded(Path.join(root, "RELEASE_BOOTED"))
203206

204207
if match?({:win32, _}, :os.type()) do
205208
assert sys_config_env =~ "tmp\\runtime_config-0.1.0"
@@ -250,7 +253,7 @@ defmodule Mix.Tasks.ReleaseTest do
250253
root_dir: root_dir,
251254
static_config: {:ok, :was_set},
252255
runtime_config: :error
253-
} = wait_until_evaled(Path.join(root, "RELEASE_BOOTED"))
256+
} = wait_until_decoded(Path.join(root, "RELEASE_BOOTED"))
254257

255258
if match?({:win32, _}, :os.type()) do
256259
assert String.ends_with?(app_dir, "demo/lib/release_test-0.1.0")
@@ -276,7 +279,7 @@ defmodule Mix.Tasks.ReleaseTest do
276279
script = Path.join(root, "bin/permanent1")
277280

278281
open_port(script, ['start'])
279-
wait_until_evaled(Path.join(root, "RELEASE_BOOTED"))
282+
wait_until_decoded(Path.join(root, "RELEASE_BOOTED"))
280283
assert System.cmd(script, ["rpc", "ReleaseTest.hello_world"]) == {"hello world\n", 0}
281284
assert System.cmd(script, ["stop"]) == {"", 0}
282285

@@ -325,7 +328,7 @@ defmodule Mix.Tasks.ReleaseTest do
325328
release_vsn: "0.1.0",
326329
static_config: {:ok, :was_set},
327330
runtime_config: {:ok, :was_set}
328-
} = wait_until_evaled(Path.join(root, "RELEASE_BOOTED"))
331+
} = wait_until_decoded(Path.join(root, "RELEASE_BOOTED"))
329332
end)
330333
end)
331334
end
@@ -342,22 +345,27 @@ defmodule Mix.Tasks.ReleaseTest do
342345
script = Path.join(root, "bin/permanent2")
343346
open_port(script, ['daemon_iex'])
344347

345-
assert wait_until_evaled(Path.join(root, "RELEASE_BOOTED")) == %{
346-
app_dir: Path.join(root, "lib/release_test-0.1.0"),
348+
assert %{
349+
app_dir: app_dir,
347350
cookie_env: "abcdefghij",
348351
mode: :embedded,
349-
node: :"permanent2@#{@hostname}",
352+
node: release_node("permanent2"),
350353
protocols_consolidated?: true,
351354
release_name: "permanent2",
352355
release_node: "permanent2",
353-
release_root: root,
356+
release_root: ^root,
354357
release_vsn: "0.1.0",
355-
root_dir: :code.root_dir() |> to_string(),
358+
root_dir: root_dir,
356359
static_config: {:ok, :was_set},
357360
runtime_config: :error,
358-
sys_config_env: Path.join(root, "releases/0.1.0/sys"),
359-
sys_config_init: Path.join(root, "releases/0.1.0/sys")
360-
}
361+
sys_config_env: sys_config_env,
362+
sys_config_init: sys_config_init
363+
} = wait_until_decoded(Path.join(root, "RELEASE_BOOTED"))
364+
365+
assert app_dir == Path.join(root, "lib/release_test-0.1.0")
366+
assert root_dir == :code.root_dir() |> to_string()
367+
assert sys_config_env == Path.join(root, "releases/0.1.0/sys")
368+
assert sys_config_init == Path.join(root, "releases/0.1.0/sys")
361369

362370
assert wait_until(fn ->
363371
File.read!(Path.join(root, "tmp/log/erlang.log.1")) =~
@@ -403,8 +411,8 @@ defmodule Mix.Tasks.ReleaseTest do
403411
Port.open({:spawn_executable, to_charlist(command)}, [:hide, args: args])
404412
end
405413

406-
defp wait_until_evaled(file) do
407-
wait_until(fn -> File.exists?(file) && Code.eval_file(file) |> elem(0) end)
414+
defp wait_until_decoded(file) do
415+
wait_until(fn -> File.exists?(file) && file |> File.read!() |> :erlang.binary_to_term() end)
408416
end
409417

410418
defp wait_until(fun) do

0 commit comments

Comments
 (0)