Packages
ex_cldr
1.4.0-rc.3
2.47.5
2.47.4
2.47.3
2.47.2
2.47.1
2.47.0
2.46.0
2.45.2
2.45.1
2.45.0
2.44.1
2.44.0
2.43.2
2.43.1
2.43.0
2.42.0
2.41.1
2.41.0
2.40.4
2.40.3
2.40.2
2.40.1
2.40.0
2.39.2
2.39.1
2.39.0
2.38.1
2.38.0
2.37.5
2.37.4
2.37.3
retired
2.37.2
2.37.1
2.37.0
2.36.0
2.35.1
2.35.0
retired
2.34.2
2.34.1
2.34.0
2.33.2
2.33.1
2.33.1-rc.0
2.33.0
2.32.1
2.32.0
2.31.0
2.30.0
2.29.0
2.28.0
2.27.1
2.27.0
retired
2.26.3
2.26.2
2.26.1
2.26.0
2.25.0
2.24.2
2.24.1
2.24.0
2.24.0-rc.6
2.24.0-rc.5
2.24.0-rc.4
2.24.0-rc.3
2.24.0-rc.2
2.24.0-rc.1
2.24.0-rc.0
2.23.2
2.23.1
2.23.0
2.22.1
2.22.0
2.21.0
2.20.0
2.20.0-rc.3
2.20.0-rc.2
2.20.0-rc.1
2.20.0-rc.0
2.19.1
2.19.0
2.18.2
2.18.1
2.18.0
2.18.0-rc.0
2.17.2
2.17.1
2.17.0
2.16.2
2.16.1
2.16.1-rc.0
2.16.0
2.15.0
2.14.1
2.14.0
2.14.0-rc.0
2.13.0
2.12.1
2.12.0
2.11.1
2.11.0
2.10.2
2.10.1
2.10.0
retired
2.9.0
2.8.1
2.8.0
2.7.2
2.7.1
2.7.0
2.6.2
2.6.1
2.6.0
2.5.0
2.4.3
2.4.2
2.4.1
2.4.0
2.3.2
2.3.1
2.3.0
2.2.7
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.1.0
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-rc.3
retired
2.0.0-rc.2
retired
2.0.0-rc.1
retired
2.0.0-rc.0
retired
1.8.2
1.8.1
1.8.0
1.7.1
1.7.0
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.2
1.5.1
1.5.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
retired
1.4.0-rc.3
retired
1.4.0-rc.2
retired
1.4.0-rc.1
retired
1.4.0-rc.0
retired
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.0
1.0.0-rc.3
retired
1.0.0-rc.2
retired
1.0.0-rc.1
retired
1.0.0-rc.0
retired
0.13.1
0.13.0
0.12.2
retired
0.12.1
retired
0.12.0
retired
0.11.0
retired
0.10.0
retired
0.9.0
retired
0.8.3
retired
0.8.2
retired
0.8.1
retired
0.8.0
retired
0.7.0
retired
0.6.2
retired
0.6.1
retired
0.6.0
retired
0.5.2
retired
0.5.1
retired
0.5.0
retired
0.4.2
retired
0.4.1
retired
0.4.0
retired
0.3.0
retired
0.2.1
retired
0.2.0
retired
0.1.3
retired
0.1.2
retired
0.1.1
retired
0.1.0
retired
0.0.20
retired
0.0.19
retired
0.0.18
retired
0.0.17
retired
0.0.16
retired
0.0.15
retired
0.0.14
retired
0.0.13
retired
0.0.12
retired
0.0.11
retired
0.0.10
retired
0.0.8
retired
0.0.7
retired
0.0.6
retired
0.0.5
retired
0.0.4
retired
0.0.3
retired
Common Locale Data Repository (CLDR) functions for Elixir to localize and format numbers, dates, lists, messages, languages, territories and units with support for over 700 locales for internationalized (i18n) and localized (L10N) applications.
Retired package: Deprecated
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/compile.cldr.ex
if Version.match?(System.version, ">= 1.6.0") do
defmodule Mix.Tasks.Compile.Cldr do
@moduledoc """
Recompiles Cldr modules when the Cldr locale
configuration changes.
Cldr defines a lot of compile-time functions based
upon the configuration in mix.exs. However since
Cldr is a dependency it is not automatically recompile
when the host application configuration changes.
An additional issue is that dependencies are compiled
before the host application (as they should be) but
that means that a host application `Gettext` module
won't be available and therefore its locales won't be
configured in Cldr.
This module implements a `Mix compiler` that is designed
to execute after the host application is compiled. It then
detects if the Cldr configuration has changed and if so it:
* Searches all dependencies to find those modules that
depend on `Cldr.Config` since that is the module that
serves Cldr configuration content.
* Recompiles each of the dependent modules for each of
app dependencies in the right dependency order
* Reloads the modules that were recompiled
Since this compilation happens after the host application
is compiled, any `Gettext` module will have been compiled
and its configuraiton is now available to Cldr.
## Configuration
To enable the automatic detection locale configuration
change and subsequent recompilation and reload, add the
`[:cldr]` compiler to the `:compilers` section of the
`mix.exs` project definition:
For example:
```
def project do
[
app: :app_name,
...
compilers: Mix.compilers ++ [:cldr]
]
end
```
"""
use Mix.Task
require Logger
@manifest "compile.cldr"
@callee_references [Cldr.Config]
@dont_recompile @callee_references ++ [Cldr.Locale.Cache, __MODULE__]
def run(_args) do
if configured_locales() != previous_locales() do
case compile_cldr_files() do
:ok ->
create_manifest(configured_locales())
_ ->
:noop
end
else
:noop
end
end
def manifests, do: [manifest()]
def manifest do
Path.join(Mix.Project.manifest_path(), @manifest)
end
def compile_cldr_files do
deps = Mix.Dep.loaded(env: Mix.env())
apps_to_compile =
deps
|> modules_to_compile()
|> Enum.group_by(fn {app, _module} -> app end,fn {_app, module} -> module end)
|> print_console_note
compile_results =
deps_in_order deps, apps_to_compile, %{}, fn {app, modules} ->
build_dir = build_dir(app)
sources = sources(modules)
purge_modules(modules, build_dir)
Kernel.ParallelCompiler.compile_to_path(sources, build_dir)
end
return(compile_results)
end
defp return(list) do
return_codes = Enum.map(list, fn {_, {:ok, _, _}} -> :ok; _ -> :error end)
if Enum.all?(return_codes, &(&1 == :ok)), do: :ok, else: :error
end
defp print_console_note(apps_to_compile) do
module_count = Enum.reduce(apps_to_compile, 0,
fn {_app, modules}, acc -> acc + Enum.count(modules)
end)
if module_count > 0 do
IO.puts "Recompiling #{module_count} modules from " <>
"#{inspect Map.keys(apps_to_compile)} " <>
"due to a locale configuration change"
end
apps_to_compile
end
defp deps_in_order([], _apps, acc, _fun) do
acc
end
defp deps_in_order(deps, apps, already_done, fun) do
Enum.reduce deps, already_done, fn dep, acc ->
acc = deps_in_order(dep.deps, apps, acc, fun)
app = dep.app
if app in Map.keys(apps) && app not in Map.keys(acc) do
Map.put(acc, app, fun.({app, Map.get(apps, app)}))
else
acc
end
end
end
defp modules_to_compile(nil) do
[]
end
defp modules_to_compile(deps) do
for dep <- deps do
callers(dep) ++ modules_to_compile(dep.deps)
end
|> List.flatten
|> Enum.map(fn {app,
%{caller_module: caller_module}} -> {app, caller_module}
{app, caller} -> {app, caller}
end)
|> Enum.reject(fn
{_app, module} when module in @dont_recompile -> true
_ -> false
end)
|> Enum.uniq
end
defp callers(dep) do
try do
Mix.Dep.in_dependency(dep, fn _module ->
Mix.Tasks.Xref.calls
|> Enum.filter(&compile_module?/1)
|> Enum.map(fn callee -> {dep.app, callee} end)
end)
rescue File.Error ->
[]
end
end
def compile_module?(%{callee: {reference, _, _}}) do
reference in @callee_references
end
def purge_modules([], _build_dir) do
:ok
end
def purge_modules([module | modules], build_dir) do
:code.purge(module)
:code.delete(module)
File.rm!(build_dir <> "/Elixir." <> inspect(module) <> ".beam")
purge_modules(modules, build_dir)
end
def build_dir(dep) do
Mix.Dep.loaded_by_name([dep], [])
|> hd
|> Map.get(:opts)
|> Keyword.get(:build)
|> String.replace_suffix("","/ebin")
end
def sources([]) do
[]
end
def sources([module | modules]) do
if source = source(module) do
[source | sources(modules)]
else
sources(modules)
end
end
def source(module) do
case Code.ensure_loaded(module) do
{:module, _} -> List.to_string(module.module_info(:compile)[:source])
_ -> nil
end
end
def create_manifest(locales \\ []) do
File.write!(manifest(), :erlang.term_to_binary(locales))
end
def configured_locales do
Cldr.Config.known_locale_names
end
def previous_locales do
case File.read(manifest()) do
{:error, :enoent} ->
create_manifest([])
previous_locales()
{:ok, ""} ->
[]
{:ok, binary} ->
:erlang.binary_to_term(binary)
end
end
end
else
defmodule Mix.Tasks.Compile.Cldr do
def run(_args) do
:noop
end
end
end