Packages
timex
0.18.0
3.7.13
3.7.12
3.7.11
3.7.9
3.7.8
3.7.7
3.7.6
3.7.5
3.7.3
3.7.2
3.7.1
3.7.0
3.6.4
3.6.3
3.6.2
retired
3.6.1
3.6.0
3.5.0
3.4.2
3.4.1
3.3.0
3.2.2
3.2.1
3.2.0
3.1.25
retired
3.1.24
3.1.23
3.1.22
3.1.21
3.1.20
3.1.19
3.1.18
3.1.17
3.1.16
3.1.15
3.1.13
3.1.12
3.1.11
3.1.10
3.1.9
3.1.8
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.8
3.0.7
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.2.1
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.0
1.0.2
1.0.1
1.0.0
1.0.0-rc4
1.0.0-rc3
1.0.0-rc2
1.0.0-rc1
1.0.0-pre
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.2
0.18.1
0.18.0
0.17.0
0.16.2
0.16.1
0.16.0
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.0
0.10.2
0.10.1
0.10.0
0.9.0
0.8.0
0.7.1
0.6.0
0.5.0
0.4.8
0.4.7
0.4.6
Timex is a rich, comprehensive Date/Time library for Elixir projects, with full timezone support via the :tzdata package. If you need to manipulate dates, times, datetimes, timestamps, etc., then Timex is for you!
Current section
Files
Jump to
Current section
Files
lib/utils/utils.ex
defmodule Timex.Utils do
@moduledoc false
@doc """
Determines the current version of OTP running this node. The result is
cached for fast lookups in performance-sensitive functions.
## Example
iex> rel = Timex.Utils.get_otp_release
...> '\#{rel}' == :erlang.system_info(:otp_release)
true
"""
def get_otp_release do
case Process.get(:current_otp_release) do
nil ->
case ("#{:erlang.system_info(:otp_release)}" |> Integer.parse) do
{ver, _} when is_integer(ver) ->
Process.put(:current_otp_release, ver)
ver
_ ->
end
ver -> ver
end
end
@doc """
Loads all modules that extend a given module in the current code path.
The convention is that it will fetch modules with the same root namespace,
and that are suffixed with the name of the module they are extending.
## Example
iex> Timex.Utils.get_plugins(Timex.Parse.DateTime.Tokenizer) |> Enum.sort
[Timex.Parse.DateTime.Tokenizers.Default, Timex.Parse.DateTime.Tokenizers.Strftime]
"""
@spec get_plugins(atom) :: [] | [atom]
def get_plugins(plugin_type) when is_atom(plugin_type) do
case Process.get(:timex_plugins) do
nil ->
plugins = available_modules(plugin_type) |> Enum.reduce([], &load_plugin/2)
Process.put(:timex_plugins, plugins)
plugins
plugins ->
plugins
end
end
defp load_plugin(module, modules) do
if Code.ensure_loaded?(module), do: [module | modules], else: modules
end
defp available_modules(plugin_type) do
apps_path = Mix.Project.build_path |> Path.join("lib")
apps = apps_path |> File.ls!
apps
|> Enum.map(&(Path.join([apps_path, &1, "ebin"])))
|> Enum.map(fn app_path -> app_path |> File.ls! |> Enum.map(&(Path.join(app_path, &1))) end)
|> Enum.flat_map(&(&1))
|> Enum.filter(&(String.ends_with?(&1, ".beam")))
|> Enum.map(fn path ->
{:ok, {module, chunks}} = :beam_lib.chunks('#{path}', [:attributes])
{module, get_in(chunks, [:attributes, :behaviour])}
end)
|> Enum.filter(fn {_module, behaviours} ->
is_list(behaviours) && plugin_type in behaviours
end)
|> Enum.map(fn {module, _} -> module end)
end
end