defmodule Burrito.Builder.Target do
use TypedStruct
alias __MODULE__
alias Burrito.Util
@type erts_source ::
{:unresolved | :runtime | :precompiled | :local | :local_unpacked | :url,
keyword() | atom()}
typedstruct enforce: true do
field(:alias, atom())
field(:cpu, atom())
field(:os, atom())
field(:cross_build, boolean)
field(:qualifiers, keyword())
field(:erts_source, erts_source())
field(:debug?, boolean())
end
def init_target(target_alias, definition) do
# pop off required options, then erts definitions
{fields, qualifiers} = Keyword.split(definition, [:os, :cpu, :debug?])
{custom_erts, qualifiers} = Keyword.pop(qualifiers, :custom_erts)
if !fields[:os] || !fields[:cpu] do
raise "You must define your target with AT LEAST `:os`, `:cpu` defined!"
end
erts_source = translate_erts_source(custom_erts)
fields =
fields
|> Keyword.put(:alias, target_alias)
|> Keyword.put(:erts_source, erts_source)
|> Keyword.put(:debug?, fields[:debug?] || false)
|> Keyword.put(:qualifiers, qualifiers)
|> Keyword.put(:cross_build, is_cross_build?(fields))
struct!(__MODULE__, fields)
end
defp translate_erts_source(custom_location) do
if custom_location do
cond do
is_uri?(custom_location) ->
{:url, url: URI.parse(custom_location)}
String.ends_with?(custom_location, ".tar.gz") or
String.ends_with?(custom_location, ".exe") ->
{:local, path: custom_location}
File.dir?(custom_location) ->
{:local_unpacked, path: custom_location}
true ->
raise "`:custom_erts` was not a URL, local path to tarball/compressed-exe, or local path to a directory"
end
else
{:precompiled, version: Util.get_otp_version()}
end
end
defp is_uri?(string) do
case URI.parse(string) do
%URI{scheme: nil} -> false
%URI{host: nil, path: nil} -> false
_ -> true
end
end
defp is_cross_build?(fields) do
fields[:os] != Util.get_current_os() || fields[:cpu] != Util.get_current_cpu() or
fields[:os] == :linux
end
@spec make_triplet(Burrito.Builder.Target.t()) :: String.t()
def make_triplet(%Target{} = target) do
os =
case target.os do
:darwin -> "macos"
:windows -> "windows"
:linux -> "linux"
end
triplet = "#{target.cpu}-#{os}"
if target.qualifiers[:os] == :linux do
"#{triplet}-musl"
else
triplet
end
end
end