-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Fix escript archive layout and support priv #13730
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix escript archive layout and support priv #13730
Conversation
escript archive. Currently the expected way of accessing priv files | ||
in an escript is via `:escript.extract/2`. Defaults to `[]`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also be more strict and say that they should not rely on the exact archive layout, instead they should do something like this:
priv_path = :code.priv_dir(:app_name)
escript_path = Path.expand(:escript.script_name())
priv_in_archive = Path.relative_to(priv_path, escript_path)
(Ideally they would use :erl_prim_loader
, but using it with escript is apparently deprecated, because it will change in the future)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FTR the deprecation note for escript + :erl_prim_loader
was added in erlang/otp#8091.
@@ -96,6 +96,28 @@ defmodule Mix.Tasks.EscriptTest do | |||
end | |||
end | |||
|
|||
defmodule EscriptWithPrivs do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is fine to leave this as is, but I think these tests could be written without defining modules. We have a way of pushing updated configuration when we do Mix.Project.push
, which simplify not having to create a bunch of modules.
We should probably refactor this whole test case to use said style, so it could be done later anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean Mix.ProjectStack.post_config/1
? I can refactor in a separate PR :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!!
Co-authored-by: José Valim <[email protected]>
💚 💙 💜 💛 ❤️ |
Escript layout
I noticed that Elixir builds escript archive with all modules, app files and priv files flattened out. Contrarily rebar builds escript with directory layout batching
_build
.The :code documentation states:
From the above it is clear that modules are loaded correctly with a flat structure, however when we deal with multiple applications, this may break other things, for example:
Given this, I would consider the current layout to be a bug, and this PR switches to a
_build
-like layout.With the new layout, the above works as expected:
priv dirs
Currently, all application priv dirs are included in the archive, however reading priv from the archive requires special care (regular file access doesn't work), so in most cases this just unnecessarily inflates the escript size. For example, Phoenix priv dir includes all generator templates, it doesn't make sense to include these in the escript.
I propose a new option
:include_priv_for
to opt-in which privs should be included.Note that this is not a breaking change, because currently
escript.build
docs actually say:Sidenote: due to flattening,
:code.priv_dir/1
does not point to a valid location in the archive. Also, the priv layout is lost, and files could even be lost if there are multiple with the same name. This is to say, even without the above restrictions, I does not really work as expected.For the reference, rebar does not include priv dir (other than for the rebar escript itself, via a private
escript_incl_priv
option).