Skip to content

Commit

Permalink
Merge pull request #109 from phoenixframework/sd-musl
Browse files Browse the repository at this point in the history
automatically detect musl, allow overriding target
  • Loading branch information
SteffenDE authored Feb 3, 2025
2 parents df61ebc + d675732 commit dd1725a
Showing 1 changed file with 66 additions and 17 deletions.
83 changes: 66 additions & 17 deletions lib/tailwind.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ defmodule Tailwind do
## Tailwind configuration
There are two global configurations for the tailwind application:
There are four global configurations for the tailwind application:
* `:version` - the expected tailwind version
Expand All @@ -35,6 +35,10 @@ defmodule Tailwind do
default, it is automatically downloaded and placed inside
the `_build` directory of your current app
* `:target` - the target architecture for the tailwind executable.
For example `"linux-x64-musl"`. By default, it is automatically detected
based on system information.
Overriding the `:path` is not recommended, as we will automatically
download and manage `tailwind` for you. But in case you can't download
it (for example, GitHub behind a proxy), you may want to
Expand Down Expand Up @@ -108,6 +112,13 @@ defmodule Tailwind do
Application.get_env(:tailwind, :version, latest_version())
end

@doc """
Returns the configured tailwind target. By default, it is automatically detected.
"""
def configured_target do
Application.get_env(:tailwind, :target, target())
end

@doc """
Returns the configuration for the given profile.
Expand Down Expand Up @@ -136,7 +147,7 @@ defmodule Tailwind do
The executable may not be available if it was not yet installed.
"""
def bin_path do
name = "tailwind-#{target()}"
name = "tailwind-#{configured_target()}"

Application.get_env(:tailwind, :path) ||
if Code.ensure_loaded?(Mix.Project) do
Expand Down Expand Up @@ -246,19 +257,45 @@ defmodule Tailwind do
# tailwindcss-windows-x64.exe
defp target do
arch_str = :erlang.system_info(:system_architecture)
[arch | _] = arch_str |> List.to_string() |> String.split("-")

case {:os.type(), arch, :erlang.system_info(:wordsize) * 8} do
{{:win32, _}, _arch, 64} -> "windows-x64.exe"
{{:unix, :darwin}, arch, 64} when arch in ~w(arm aarch64) -> "macos-arm64"
{{:unix, :darwin}, "x86_64", 64} -> "macos-x64"
{{:unix, :freebsd}, "aarch64", 64} -> "freebsd-arm64"
{{:unix, :freebsd}, arch, 64} when arch in ~w(x86_64 amd64) -> "freebsd-x64"
{{:unix, :linux}, "aarch64", 64} -> "linux-arm64"
{{:unix, :linux}, "arm", 32} -> "linux-armv7"
{{:unix, :linux}, "armv7" <> _, 32} -> "linux-armv7"
{{:unix, _osname}, arch, 64} when arch in ~w(x86_64 amd64) -> "linux-x64"
{_os, _arch, _wordsize} -> raise "tailwind is not available for architecture: #{arch_str}"
target_triple = arch_str |> List.to_string() |> String.split("-")

{arch, abi} =
case target_triple do
[arch, _vendor, _system, abi] -> {arch, abi}
[arch, _vendor, abi] -> {arch, abi}
[arch | _] -> {arch, nil}
end

case {:os.type(), arch, abi, :erlang.system_info(:wordsize) * 8} do
{{:win32, _}, _arch, _abi, 64} ->
"windows-x64.exe"

{{:unix, :darwin}, arch, _abi, 64} when arch in ~w(arm aarch64) ->
"macos-arm64"

{{:unix, :darwin}, "x86_64", _abi, 64} ->
"macos-x64"

{{:unix, :freebsd}, "aarch64", _abi, 64} ->
"freebsd-arm64"

{{:unix, :freebsd}, arch, _abi, 64} when arch in ~w(x86_64 amd64) ->
"freebsd-x64"

{{:unix, :linux}, "aarch64", "musl", 64} ->
"linux-arm64-musl"

{{:unix, :linux}, "aarch64", _abi, 64} ->
"linux-arm64"

{{:unix, _osname}, arch, "musl", 64} when arch in ~w(x86_64 amd64) ->
"linux-x64-musl"

{{:unix, _osname}, arch, _abi, 64} when arch in ~w(x86_64 amd64) ->
"linux-x64"

{_os, _arch, _abi, _wordsize} ->
raise "tailwind is not available for architecture: #{arch_str}"
end
end

Expand Down Expand Up @@ -297,6 +334,18 @@ defmodule Tailwind do
{_, {:ok, {{_, 200, _}, _headers, body}}} ->
body

{_, {:ok, {{_, 404, _}, _headers, _body}}} ->
raise """
The tailwind binary couldn't be found at: #{url}
This could mean that you're trying to install a version that does not support the detected
target architecture.
You can see the available files for the configured version at:
https://github.com/tailwindlabs/tailwindcss/releases/tag/v#{configured_version()}
"""

{true, {:error, {:failed_connect, [{:to_address, _}, {inet, _, reason}]}}}
when inet in [:inet, :inet6] and
reason in [:ehostunreach, :enetunreach, :eprotonosupport, :nxdomain] ->
Expand All @@ -314,7 +363,7 @@ defmodule Tailwind do
your certificates are set via OTP ca certfile overide via SSL configuration.
2. Manually download the executable from the URL above and
place it inside "_build/tailwind-#{target()}"
place it inside "_build/tailwind-#{configured_target()}"
3. Install and use Tailwind from npmJS. See our module documentation
to learn more: https://hexdocs.pm/tailwind
Expand Down Expand Up @@ -361,6 +410,6 @@ defmodule Tailwind do
defp get_url(base_url) do
base_url
|> String.replace("$version", configured_version())
|> String.replace("$target", target())
|> String.replace("$target", configured_target())
end
end

0 comments on commit dd1725a

Please sign in to comment.