-
Notifications
You must be signed in to change notification settings - Fork 3.5k
escript-related mix tasks #2974
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
Conversation
@alco Great work! I would like to suggest though to add the hex functionality in another pull request because I am considering backporting escript install to 1.0.x. I will add some specific comment to the PR overall soon. |
Perfect.
Makes sense! And MIX_HOME would already change it.
Honestly, it is very likely you don't want to install something as an archive. It will break with Elixir version, it is global and therefore has a chance of conflicting with your code, etc. Maybe we should simply not add this functionality to archives? I know they won't be symmetric then... but it will be for good reasons? One final consideration: should we check if the |
@@ -108,7 +108,7 @@ defmodule Mix.Tasks.Escript.Build do | |||
defp escriptize(project, language, force, should_consolidate) do | |||
escript_opts = project[:escript] || [] | |||
|
|||
script_name = to_string(escript_opts[:name] || project[:app]) | |||
script_name = Mix.Escript.escript_name(project) |
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.
Should we allow the -o
option as in archive.build
?
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.
I don't think it's useful for escripts. archive.build
works with non-mix projects according to its docs. Escripts require mix.exs, so it would be simpler to have only one place where the name can be changed – in mix.exs.
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.
Good point, thanks!
Currently there are a few inconveniences related to how archives can be installed. First, the author has to build an archive and put it somewhere online for it to be installable with If In that sense, I see enabling support for packages in I like to have things like |
Right, that's the only reasonable use case. Even though, it can cause issues: what if we have ex_doc installed as an archive and a project list ex_doc as a dependency? Are we currently guaranteeing the package one has higher preference? Furthermore, depending on the order things run, I could end up using both versions like this:
So there are a bunch of issues we should fix before really promoting archives. :( |
Also, thanks for the discussion: ❤️ |
mix escript.install github.com/example/foo # fetches git://github.com/example/example.git | ||
mix escript.install https://github.com/example/foo # fetches https://github.com/example/example.git | ||
mix escript.install --scm=git example.com/foo # fetches git://example.com/example | ||
mix escript.install --scm=git https://example.com/foo # fetches https://example.com/example |
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 should not infer git from a http url. It limits http urls to the git SCM but a lot of SCMs allow using http as transport.
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.
I still vote for the syntax proposed in the mailing list.
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.
In the case of https://example.com/foo.git
above, Git would be inferred from the trailing .git
part.
After some consideration I see the appeal of sticking with your proposal because of its similarity with dep syntax. It doesn't define a few things though. What is your take on these cases?
escript.install ./local_file # ./ is used to distinguish from a hex package
escript.install path/to/local_file # cannot be a hex package, so it can imply a local path
escript.install path path/to/local_repo # ugly
# What about this? Should we forbid fetching remote scripts?
escript.install ??? https://example.com/escript_file
I realize that in the common case hex packages should be preferred, but we still have to define what happens with the other cases.
The ambiguity of supporting a prebuilt escript could be solved with a dedicated task:
escript.install-file local_file
escript.install-file path/to/local_file
escript.install-file http://example.com/escript
# or a flag
escript.install --file local_file
# etc...
It may not be all too important to be able to install prebuilt escripts, but leaving it out makes it feel incomplete.
What do you think, @josevalim, @ericmj ?
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.
If we are going to support prebuilt escripts I prefer these of your proposals:
escript.install ./local_file
escript.install path/to/local_file
escript.install https://example.com/escript_file
The following would build and install a local project (i.e. not a prebuilt file):
escript.install path path/to/local_repo
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.
I like @ericmj's proposal here. With no arguments it means to install prebuilt scripts, if you pass, hex|path|git
, it means installing from a project (which therefore requires building and mix).
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.
I definitely think though we should move this into another discussion, as we can ship prebuilt installation earlier. :)
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.
I like @ericmj's proposal here. With no arguments it means to install prebuilt scripts, if you pass,
hex|path|git
, it means installing from a project (which therefore requires building and mix).
So have we settled on the following syntax?
# this PR
escript.install X # X is a path or a URL to a prebuilt escript file
# future PR
escript.install X Y [Z]
# X is the package type (hex|path|git),
# Y is the package name or URL
# Z would be a version for a Hex package, or a ref for a Git repo
In that case, we can drop the ./
prefix when installing a file from the local directory. It was used to disambiguate from the mix escript.install <hex-package>
syntax.
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.
I definitely like it. @alco, it is not clear if you like it though. Do you?
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.
I like it too. Will push an update tonight.
@josevalim right, archives feel like they haven't been thought out very well. I'm not going to add any changes to them in this PR, but I will probably open another issue for them. |
a8ce248
to
285fb81
Compare
Pushed an update that only implements installation of prebuilt escripts. Did some refactoring, added tests. |
@alco can you please rebase? Let's start work on this front. I have reviewed your changes and they look great, although I would try to unity the installer for both. It seems the only different is the path and that escripts need to call chmod? Thank you! |
I'll rebase later today, there are some conflicts I need to have a closer look at. The differences in installing escripts and archives go beyond just having to call |
I was thinking this routing is the same https://github.com/elixir-lang/elixir/pull/2974/files#diff-2c79c79704bca75ad6388315cad90838R37 up to the |
285fb81
to
842a9b7
Compare
Rebased. The biggest change I had to make during the rebase process was replacing |
@alco awesome! Can you please give a try at unifying both installation approaches? It will be specially important once we start building archives and escripts from git, so the sooner we unify, the best. Also, what if we rename |
@@ -0,0 +1,70 @@ | |||
defmodule Mix.Local.Utils 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.
Shouldn't be mix/local/utils.ex
used as a name for a file?
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 still a valid question.
It's unlikely that I'll have time to work on this before the weekend, sorry. Feel free to take it or I'll get back to you next week. |
@alco oh, no worries at all. I forgot to say but this is not for 1.1, it will be for 1.2 or 1.3, which means we have at least 2 months ahead of us. :) |
OK. Are you planning to include install-from-git and/or install-from-hex in the same version? |
@alco it is your call. but given that we have some time, it would be nice to finally make progress on this (I am aware it stalled mostly due to me being unavailable though, sorry). |
842a9b7
to
e6142e7
Compare
Oh wow, this PR is more than a year old. Time flies X_X Looking into it now. |
The latest Travis build has two issues that look unrelated to the changes in this PR:
and
|
Master is passing. Is it a race condition or something wrong on rebase? |
The rebase was clean, without conflicts. I don't see those errors locally. |
@josevalim I did some unification, still WIP. Will continue tomorrow. |
7075916
to
a662122
Compare
It's green now 🤷. I wasn't able to reproduce the failure |
@josevalim This is ready for review. |
@@ -9,21 +9,6 @@ defmodule Mix.Archive do | |||
""" | |||
|
|||
@doc """ | |||
Returns the archive name based on `app` and `version`. |
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.
This is backwards incompatible. We need to keep it here.
@alco thank you! I have added just one tiny comment, everything else is perfect (and we need to tidy up the FIXMEs in the code). Also, we need to make sure this works on Windows because on Windows you need to use So I think we should likely generate |
The message isn't handled by install() because it raises an exception prior to asking for confirmation.
a662122
to
2b417ae
Compare
@josevalim I have restored I don't have access to a Windows machine at the moment. |
end | ||
|
||
def path_for(:escript) do | ||
Path.join(Mix.Utils.mix_home, "escripts") |
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.
Should we provide MIX_ESCRIPTS
?
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.
Considering we have MIX_ARCHIVES
👍.
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.
This has already been asked and answered here (see the second quote).
|
||
def after_install(dst, _previous) do | ||
File.chmod!(dst, @escript_file_mode) | ||
check_discoverability(dst) |
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.
I would like to check this is actually a escript. Otherwise this command can be used to install any executable and it may be a bad idea.
This PR implements a few additional escript-related mix tasks, outlined in this proposal.
Technical details
mix escript.install
has been added that works similarly tomix archive.install
: it takes a path or a URL to an arbitrary file and puts it under~/.mix/escripts
.mix escript
lists all executable files under~/.mix/escripts
.mix escript.uninstall
removes the file with the given name from~/.mix/escripts
.Additional concerns
TODO
tests
to keep
archive.install
andescript.install
symmetric, both should be able to fetch repositories and hex packages. The package will be fetched into a temporary directory, in the case of an escript it will also fetch dependencies. Then everything is compiled and subsequentlyarchive.install
orescript.install
is called with the resulting archive or escript file. This makes it possible to host mix tasks on hex.pm too.the command-line invocation syntax is just an idea. I have considered lots of alternatives, but would like to hear what the team thinks about it first. We can't really say that it is similar to the dep syntax in mix.exs because that would mean having something like this:
I would much rather have the Mix task infer the source type from the URL given to it. The biggest problem is then to distinguish a local path from the package name.
if we allow both archives and escripts to be fetched from hex.pm, it may be confusing in which way a given package is supposed to be used: as a dependency, as an archive, or as an escript. Perhaps, hex.pm could indicate that visually in some way, or via the project's name.