-
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
14
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.
+521
−15
Open
Add gleam support to Mix #14262
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
c5b71e3
Add fixture for gleam support
Papipo 30cf420
Add Gleam integration with Mix
Papipo ac74afe
Add support for git dependencies in gleam packages
Papipo 897df15
Exclude gleam tests if gleam is missing
Papipo aa3dca7
Fix deps.compile for gleam
Papipo 5a844b4
Add support for application_start_module
Papipo e5c6cb0
Handle gleam extra_applications
Papipo db283cb
Remove redundant quotes
Papipo 7e9137a
Do not force `app: false` in gleam deps
Papipo 160b669
Generate app file for gleam deps on compilation
Papipo 357fcff
Proper beam compilation and .app file generation
Papipo 39d00ea
Apply suggestions from code review
Papipo bb19f96
Add support for :application option in Compile.App
Papipo 0dee193
Proper handling of deeply nested and dev gleam deps
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, :test])) | ||
|
||
%{ | ||
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
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.