When an app in umbrella app has alias on test with run somefile.exs, which refers relative path to the app (not to the umbrella root), it works only when running mix test at the app root - not at the umbrella root.
Under apps/inside_app/mix.exs:
def aliases()
test: ["cmd ./shell.sh", "run script.exs", "test"]
end
Here is a script to reproduce it
#!/bin/bash -eux
rm -rf umbrella
mix new --umbrella umbrella
pushd umbrella/apps
mix new inside
popd
pushd umbrella/apps/inside
echo "echo 'hello from cmd'" > hello.sh
chmod +x hello.sh
echo 'IO.puts("hello from run")' > hello.exs
gsed -i -E 's/^ deps: deps\(\)$/ deps: deps(),\n aliases: aliases()/' mix.exs
gsed -i -E 's/^end/ defp aliases, do: [test: ["cmd .\/hello.sh", "run hello.exs", "test"]]\nend/' mix.exs
mix test
popd
pushd umbrella
mix test
popd
Note that this happens from a umbrella phoenix project since the main app (with ecto) has following aliases:
defp aliases do
[
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate", "test"]
]
end
mix test at umbrella root: cmd works but run fails with ** (Mix) No such file: script.exsmix test at the app: both cmd and run worksPlease note that "cmd ./shell.sh" is correctly expanded.
mix test should work with expanding alias, as it runs at the app root.Thanks @chulkilee! It would be awesome if you could provide a small application that reproduces this, as it would make our life easier.
I added a script in the body @josevalim
Hi @chulkilee!
I have actually investigated this about a week ago but I forgot to report back.
This is behaving as expected because the run task always runs at the project that invoked mix. So if you are inside the umbrella, it is the umbrella, if you are a child app, it is the child app. A possible fix for this is to pass the full path:
"mix run #{Path.join(__DIR__, "priv/foo/bar.exs")}"
I have explored some solutions but I don't think we will be able to fix this in any other way without intervention, sorry.
Most helpful comment
Hi @chulkilee!
I have actually investigated this about a week ago but I forgot to report back.
This is behaving as expected because the
runtask always runs at the project that invoked mix. So if you are inside the umbrella, it is the umbrella, if you are a child app, it is the child app. A possible fix for this is to pass the full path:I have explored some solutions but I don't think we will be able to fix this in any other way without intervention, sorry.