Packages
mob_dev
0.6.0
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.37
0.3.35
0.3.34
0.3.33
0.3.28
0.3.26
0.3.23
0.3.21
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.18
0.2.17
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Development tooling for the Mob mobile framework
Current section
Files
Jump to
Current section
Files
lib/mob_dev/app_file.ex
defmodule MobDev.AppFile do
@moduledoc false
# Helpers for parsing OTP .app files (the Erlang term file every
# compiled app ships in `<app>-<vsn>/ebin/<app>.app`).
@doc """
Extract the `vsn` value from an .app file's contents.
iex> MobDev.AppFile.vsn_from_content(~s|{application,foo,[{vsn,"1.2.3"}]}|)
"1.2.3"
iex> MobDev.AppFile.vsn_from_content("not an app file")
nil
"""
@spec vsn_from_content(String.t()) :: String.t() | nil
def vsn_from_content(content) when is_binary(content) do
case Regex.run(Regex.compile!("\\{vsn,\"([^\"]+)\"\\}"), content) do
[_, vsn] -> vsn
_ -> nil
end
end
@doc """
Read an .app file from disk and return its vsn, or nil if the file
doesn't exist or doesn't parse.
"""
@spec vsn_from_path(Path.t()) :: String.t() | nil
def vsn_from_path(path) do
case File.read(path) do
{:ok, content} -> vsn_from_content(content)
_ -> nil
end
end
@doc """
Resolve the installed version of a hex dep. Prefers `mix.lock` (most
reliable, survives across envs); falls back to the compiled .app file
under `_build/dev/lib/<dep>/ebin/<dep>.app`. Returns nil if neither
source resolves.
"""
@spec dep_version(String.t() | atom()) :: String.t() | nil
def dep_version(dep) when is_atom(dep), do: dep_version(Atom.to_string(dep))
def dep_version(dep) when is_binary(dep) do
case lock_version(dep) do
nil -> wildcard_app_version(dep)
vsn -> vsn
end
end
defp lock_version(dep) do
with {:ok, lock} <- File.read("mix.lock"),
pattern <- Regex.compile!("\"#{Regex.escape(dep)}\"[^\"]*\"(\\d+\\.\\d+\\.\\d+)\""),
[_, vsn] <- Regex.run(pattern, lock) do
vsn
else
_ -> nil
end
end
defp wildcard_app_version(dep) do
case Path.wildcard("_build/dev/lib/#{dep}/ebin/#{dep}.app") do
[app_file | _] -> vsn_from_path(app_file)
_ -> nil
end
end
end