-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Add gleam support to Mix #14262
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
Open
Papipo
wants to merge
15
commits into
elixir-lang:main
Choose a base branch
from
Papipo:add-gleam-compiler
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+506
−15
Open
Add gleam support to Mix #14262
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
4997e6a
Add fixture for gleam support
Papipo 04eede4
Add Gleam integration with Mix
Papipo edf35ca
Add support for git dependencies in gleam packages
Papipo 94c7624
Exclude gleam tests if gleam is missing
Papipo e81ec1e
Fix deps.compile for gleam
Papipo c595cf6
Add support for application_start_module
Papipo 60f5625
Handle gleam extra_applications
Papipo 047871e
Remove redundant quotes
Papipo cf6018f
Do not force `app: false` in gleam deps
Papipo 3ba141b
Generate app file for gleam deps on compilation
Papipo 6ed5fe7
Proper beam compilation and .app file generation
Papipo 8123710
Apply suggestions from code review
Papipo b75dc61
Add support for :application option in Compile.App
Papipo 638b8a3
Expand gleam deps deps paths
Papipo 2d8c285
Add failing test to verify wrong loadpaths
Papipo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# SPDX-FileCopyrightText: 2021 The Elixir Team | ||
# SPDX-FileCopyrightText: 2012 Plataformatec | ||
|
||
defmodule Mix.Gleam do | ||
# Version that introduced `gleam export package-information` command | ||
@required_gleam_version ">= 1.10.0" | ||
|
||
def load_config(dir) do | ||
File.cd!(dir, fn -> | ||
gleam!(~W(export package-information --out /dev/stdout)) | ||
|> JSON.decode!() | ||
|> Map.fetch!("gleam.toml") | ||
|> parse_config() | ||
end) | ||
end | ||
|
||
def parse_config(json) do | ||
deps = | ||
Map.get(json, "dependencies", %{}) | ||
|> Enum.map(&parse_dep/1) | ||
|
||
dev_deps = | ||
Map.get(json, "dev-dependencies", %{}) | ||
|> Enum.map(&parse_dep(&1, only: :dev)) | ||
|
||
%{ | ||
name: Map.fetch!(json, "name"), | ||
version: Map.fetch!(json, "version"), | ||
deps: deps ++ dev_deps | ||
} | ||
|> maybe_gleam_version(json) | ||
|> maybe_erlang_opts(json["erlang"]) | ||
rescue | ||
KeyError -> | ||
Mix.raise("Command \"gleam export package-information\" unexpected format: \n" <> json) | ||
end | ||
|
||
defp parse_dep({dep, requirement}, opts \\ []) do | ||
dep = String.to_atom(dep) | ||
|
||
spec = | ||
case requirement do | ||
%{"version" => version} -> | ||
{dep, version, opts} | ||
|
||
%{"path" => path} -> | ||
{dep, Keyword.merge(opts, path: Path.expand(path))} | ||
|
||
%{"git" => git, "ref" => ref} -> | ||
{dep, git: git, ref: ref} | ||
|
||
_ -> | ||
Mix.raise("Gleam package #{dep} has unsupported requirement: #{inspect(requirement)}") | ||
end | ||
|
||
case spec do | ||
{dep, version, []} -> {dep, version} | ||
spec -> spec | ||
end | ||
end | ||
|
||
defp maybe_gleam_version(config, json) do | ||
case json["gleam"] do | ||
nil -> config | ||
version -> Map.put(config, :gleam, version) | ||
end | ||
end | ||
|
||
defp maybe_erlang_opts(config, nil), do: config | ||
|
||
defp maybe_erlang_opts(config, opts) do | ||
application = | ||
opts | ||
|> Enum.filter(fn {_, value} -> value != nil end) | ||
|> Enum.map(fn | ||
{"application_start_module", module} when is_binary(module) -> | ||
{:mod, {String.to_atom(module), []}} | ||
|
||
{"extra_applications", applications} when is_list(applications) -> | ||
{:extra_applications, Enum.map(applications, &String.to_atom/1)} | ||
|
||
{key, value} -> | ||
IO.warn("Gleam [erlang] option not supported\n #{key}: #{inspect(value)}") | ||
end) | ||
|
||
Map.put(config, :application, application) | ||
end | ||
|
||
def require!() do | ||
available_version() | ||
|> Version.match?(@required_gleam_version) | ||
end | ||
|
||
defp available_version do | ||
case gleam!(["--version"]) do | ||
"gleam " <> version -> Version.parse!(version) |> Version.to_string() | ||
output -> Mix.raise("Command \"gleam --version\" unexpected format: #{output}") | ||
end | ||
rescue | ||
e in Version.InvalidVersionError -> | ||
Mix.raise("Command \"gleam --version\" invalid version format: #{e.version}") | ||
end | ||
|
||
defp gleam!(args) do | ||
System.cmd("gleam", args) | ||
catch | ||
:error, :enoent -> | ||
Mix.raise( | ||
"The \"gleam\" executable is not available in your PATH. " <> | ||
"Please install it, as one of your dependencies requires it. " | ||
) | ||
else | ||
{response, 0} -> | ||
String.trim(response) | ||
|
||
{response, _} when is_binary(response) -> | ||
Mix.raise("Command \"gleam #{Enum.join(args, " ")}\" failed with reason: #{response}") | ||
|
||
{_, _} -> | ||
Mix.raise("Command \"gleam #{Enum.join(args, " ")}\" failed") | ||
end | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.