-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Add gleam support to Mix #14262
base: main
Are you sure you want to change the base?
Add gleam support to Mix #14262
Conversation
421dc7c
to
0afa895
Compare
@josevalim when working on this I was always thinking of |
It should be possible because we use heroicons, a regular JS package, as a dependency on Phoenix applications. So we could probably support a |
Hello! You shouldn't need to do anything special target-wise as Gleam performs dead code elimination for code that is for other targets.
I would not expect Mix to become a front-end build tool by adding Gleam support. I think the workflow should be the same as it is today etc, with the desired build tool (esbuild, webpack, Adding frontend dependencies to the BEAM application dependency tree would either be wasted work compiling and managing them, or the programmer would need to go through every dependency in the lock file and add configuration to their
There is no such config. A Gleam package doesn't have an explicit target, each function in the public API is available on Erlang, JavaScript, or both, and they get either compiled or eliminated as needed. Whether a package is for Erlang or JavaScript is typically a matter of how the dependant is using them, not a matter of the configuration of the dependency. There is a |
b91ae71
to
c181ecd
Compare
@@ -269,6 +269,15 @@ Enum.each(fixtures, fn fixture -> | |||
File.cp_r!(source, dest) | |||
end) | |||
|
|||
## Set up Gleam fixtures | |||
|
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.
And we should probably skip gleam tests if gleam is not installed, right?
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.
Done. I guess I need to add gleam to CI (although I need to wait until my gleam PR is merged and released).
a18bf89
to
26c8aff
Compare
26c8aff
to
8a7d9fa
Compare
- Add Mix.Gleam module - Add specific gleam binary version requirement - Rely on `gleam export package-info`
- shell_cmd! wasn't handling tuples - Fix documentation
This is an optional value within [erlang] in the gleam.toml file. It will be used for the `mod` value when generating a .app file
8a7d9fa
to
360db23
Compare
I am kind of copypasting this from the Gleam discord in case someone wants to try this out before merging into main: What is this?These changes add first-class support for Gleam in Elixir's Mix, thus allowing gleam path dependencies in What's missing?Probably nothing. Work on the gleam compiler is already merged and work on the Mix side is completed, but there might me rough edges, that's what we need to test. InstructionsMix integration will expect you to have gleam >= 1.10.0 installed and that hasn't been released yet. So:
If you were using UsageAfter running What needs to be tested?
ThanksJust report back with your findings and: thanks :person_bowing: Note: I hope these instructions are enough and correct. Let me know if that's not the case. |
@Papipo thanks for all the work so far! One question: I thought that |
No, gleam is a single binary written in Rust. I don't know if we can provide a hex archive maybe? I don't know how these work. How is rebar installation handled? I know that mix is able to install it locally, but I am not sure what that means exactly. It's still a binary as well, right? |
For Rebar, we have some binaries which we upload to hex.pm, and we version control them every year or so. Although I don't think this will work for Gleam, because people want to upgrade it more frequently, and Rebar is only a build tool, not really a compiler. So I guess we need to be clear we are using the system one and it is up to them to enforce the team uses the same version across the board (which is how we deal with |
In fact the binary is also the LS, so you definitely want to have full control of the version you are using, etc. |
Quoting @lpil on the forums:
Apologies but I am a bit confused. We are using The .app file has things like app name, version, description, registered processes, app environment, and module names. We would need to lift all of this information from the Gleam .toml and make assumptions on how Gleam wants those be used. Worst case scenario, couldn't Gleam support an |
Yes, From @lpil comment over elixirforum I assume the problem are colocated Elixir files within a Gleam project. The Gleam compiler knows nothing about them so any modules they define can't be written in the .app file, I guess. What I have done here is use the Mix task to generate the .app file (and inject the two options gleam.toml supports for the erlang target: Let me know if this looks good or if I should revert it. Thanks. |
Yes, for collocated projects that’s the responsibility of Mix, but for packages I would say that’s Gleam responsibility. Otherwise there is even more we need to understand from Gleam TOML’s and we may need to keep track of it as it evolves. So is there a chance for it to emit an .app file either by default or via a flag? On the plus side, if Rebar wants to integrate Gleam as well, they can reuse it to emit apps too. :) |
b0eda69
to
b70f8fd
Compare
b70f8fd
to
b64f23a
Compare
Apparently this seems to be working fine except that people sometimes need to compile twice . Could this be code path related maybe? It's probably something stupid I missed. |
Can they upload a repo that reproduces the error? Once we move the .app building to |
Hi gang! I'm a bit stuck as to how We could produce a |
I think there is a misunderstanding somewhere, probably on my side, so I will try to break down what I understand is happening here and please correct me if I am wrong.
So because the only thing we call is However, when you say:
It seems Thank you, |
Thanks for the info, I understand better now.
Ah! This is the misunderstanding. Because there's no mapping between Elixir file names and BEAM files, and because Gleam packages commonly contain and use Elixir code, there's no way to for the Gleam compiler to know the names of all the BEAM modules that would need to be listed in the |
I think rebar |
The output of I suspect José will have some guidance on the best approach to creating the .app file. The two options I can immediately see are |
Thanks!
So when consuming a package like |
There's some confusion here due to the Build tools that compile Gleam packages (e.g. the Gleam build tool, Make, Nix, and hopefully Mix soon!) need to compile the Erlang produced by the Gleam compiler + any Elixir files into .BEAM modules and through some means create a The logic for picking a tool is like so:
|
Well put. That highlights precisely the issue here: for compiling dependencies, Mix expects build tools, not compilers. If you look at the file here, the other options are Mix, Rebar and Make, which are all build tools. In a nutshell, Mix uses a build tool to manage dependencies, but it uses compilers to compile your own project. So So this puts us at an impasse because if we use Gleam only as a compiler for dependencies, then we will have to reimplement Gleam's own build tool, as seen in this pull request which already has to parse the .toml file to deal with So I think it would be really important to be able to use Gleam as a build tool. For what is worth, Rebar3 had to add features for it to be compilable by Mix and Mix had to add features for it to be compilable by Rebar3 (most of those features were basically configuring the path things are written to). |
Unless OTP adds new functionality there will be no new additions to the Erlang configuration for Gleam, it purely is a description of the It's unlikely we'll ever have capacity to make a second Rust based Gleam build tool specifically for Mix to use, but even if we did it would produce quite an inferior experience as it would be a BEAM instance starting a Gleam instance starting a BEAM instance. This is a higher overhead than the Gleam build tool's original design where a single Gleam instance created a BEAM instance per-package, which significantly impacted compile times. Mix already has the mechanisms required to compile a directory of Elixir and Erlang, so the only missing piece is how to generate the .app file. Alternatively we could write a Gleam build tool in a single module of Elixir or Erlang, possibly by adapting the Gleam build tool's Erlang and Elixir compile daemon. This would be straightforward and easy, and then it could possibly be vendored in the Mix codebase? Or perhaps it could be supplied via Hex in some way. I am not familiar with the Mix plugin system so I don't know what is possible there. How do either of these options sound to you? |
Oh, this is a very good point. So it seems the current direction is the way to go indeed. Thank you. @Papipo, doesn't this PR then needs to be changed to compile the Erlang source code generated by the Gleam package? Implementation wise, I wonder if perhaps we should drop a Or alternatively, |
Oh! That's a good idea, much easier. I think I would prefer to not have Gleam generate the |
From what I've seen, we could dump the If gleam options there adhere to the expected format (which I hope is the same as Erlang's) we should be good with the former, no? |
Yes, exactly. |
If the root Mix project has a path dependency on a gleam dependency, where should I put this |
oh, that would be a problem with this approach. So maybe, instead of writing the file to disk, you should just push the project data, like we do on It does have one issue though, in that we would have no way to pass application properties (because there is no |
This PR adds support for the gleam language.
gleam.toml
inpath
depsgleam
in deps loader.deps.compile
gleam
binary version (hardcoded to 1.9.0 for now, see below)gleam
binarymain
already but not yet released)Notes:
gleam
binary version requirements are handled automatically when executinggleam compile-package
.gleam export package-info
but I can't know the reason for a bad exit status (maybe the dep path was wrong and the command was run in a dir without agleam.toml
).[erlang]
options set in thegleam.toml
a.app
file is generated in theebin
folder of the dependency. Right now this generated file is very basic, having only thevsn
,applications
(ifextra_applications
was specified) andmod
(ifapplication_start_module
was specified). Not sure if there is room for improvement there (like using a .app.src file instead? I don't know the internals of this).