diff --git a/lib/mix/lib/mix/tasks/release.init.ex b/lib/mix/lib/mix/tasks/release.init.ex index d0df7f22c54..811c9b69293 100644 --- a/lib/mix/lib/mix/tasks/release.init.ex +++ b/lib/mix/lib/mix/tasks/release.init.ex @@ -87,8 +87,17 @@ defmodule Mix.Tasks.Release.Init do #!/bin/sh set -e - SELF=$(readlink "$0" || true) - if [ -z "$SELF" ]; then SELF="$0"; fi + readlink_f () { + cd "$(dirname "$1")" > /dev/null + filename="$(basename "$1")" + if [ -h "$filename" ]; then + readlink_f "$(readlink "$filename")" + else + echo "$(pwd -P)/$filename" + fi + } + + SELF=$(readlink_f "$0") RELEASE_ROOT="$(CDPATH='' cd "$(dirname "$SELF")/.." && pwd -P)" export RELEASE_ROOT RELEASE_NAME="${RELEASE_NAME:-"<%= @release.name %>"}" diff --git a/lib/mix/test/mix/tasks/release_test.exs b/lib/mix/test/mix/tasks/release_test.exs index 5adaa70b561..35baa1d2709 100644 --- a/lib/mix/test/mix/tasks/release_test.exs +++ b/lib/mix/test/mix/tasks/release_test.exs @@ -786,6 +786,40 @@ defmodule Mix.Tasks.ReleaseTest do end) end + @tag :unix + test "works properly with an absolute symlink to release" do + in_fixture("release_test", fn -> + Mix.Project.in_project(:release_test, ".", fn _ -> + Mix.Task.run("release") + + File.ln_s!( + Path.absname("_build/#{Mix.env()}/rel/release_test/bin/release_test"), + Path.absname("release_test") + ) + + script = Path.absname("release_test") + {hello_world, 0} = System.cmd(script, ["eval", "IO.puts :hello_world"]) + assert String.trim_trailing(hello_world) == "hello_world" + end) + end) + end + + @tag :unix + test "works properly with a relative symlink to release" do + in_fixture("release_test", fn -> + Mix.Project.in_project(:release_test, ".", fn _ -> + Mix.Task.run("release") + + File.mkdir!("bin") + File.ln_s!("../_build/#{Mix.env()}/rel/release_test/bin/release_test", "bin/release_test") + + script = Path.absname("bin/release_test") + {hello_world, 0} = System.cmd(script, ["eval", "IO.puts :hello_world"]) + assert String.trim_trailing(hello_world) == "hello_world" + end) + end) + end + defp open_port(command, args, env \\ []) do env = for {k, v} <- env, do: {to_charlist(k), to_charlist(v)} Port.open({:spawn_executable, to_charlist(command)}, [:hide, args: args, env: env])