Packages
gettext
0.12.2
1.0.2
1.0.1
retired
1.0.0
0.26.2
0.26.1
0.26.0
retired
0.25.0
0.24.0
0.23.1
0.23.0
0.22.3
0.22.2
0.22.1
0.22.0
0.21.0
0.20.0
0.19.1
0.19.0
0.18.2
0.18.1
0.18.0
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.1
0.16.0
0.15.0
0.14.1
0.14.0
0.13.1
0.13.0
0.12.2
0.12.1
0.12.0
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.1
0.6.0
0.5.0
Internationalization and localization through gettext
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/compile.gettext.ex
defmodule Mix.Tasks.Compile.Gettext do
use Mix.Task
@recursive true
@moduledoc """
Force Gettext modules to recompile once .po files change.
"""
# This compiler finds .po files in the "priv" directory of the current
# project, then builds a bunch of manifest files based on these .po files (one
# manifest for each "prefix", which corresponds to a Gettext backend) and
# touches these manifests in case they're stale.
# What makes the Gettext backend recompile when .po files change though is
# that each backend specifies the corresponding manifest file as an
# @external_resource.
@default_wildcard "gettext/*/LC_MESSAGES/*.po"
def run(_, priv_dir \\ "priv") do
Application.ensure_all_started(:gettext)
_ = Mix.Project.get!
app_dir = Mix.Project.app_path()
gettext_config = Mix.Project.config()[:gettext] || []
wildcard = gettext_config[:compiler_po_wildcard] || @default_wildcard
changed =
priv_dir
|> Path.join(wildcard)
|> Path.wildcard()
|> Enum.group_by(&priv_prefix(&1, app_dir))
|> Map.delete(:not_in_canonical_dir)
|> change_manifests()
if changed == [], do: :noop, else: :ok
end
defp priv_prefix(path, app_dir) do
parts = Path.split(path)
if index = Enum.find_index(parts, & &1 == "LC_MESSAGES") do
filename =
[".compile" | Enum.take(parts, index - 1)]
|> Path.join()
|> String.replace("/", "_")
Path.join(app_dir, filename)
else
:not_in_canonical_dir
end
end
defp change_manifests(manifest_to_pos) do
for {manifest, pos} <- manifest_to_pos,
manifest_stale?(manifest, pos),
do: write_manifest(manifest, pos)
end
defp read_manifest(manifest) do
case File.read(manifest) do
{:ok, pos} -> String.split(pos, "\n", trim: true)
{:error, _} -> []
end
end
defp write_manifest(manifest, pos) do
File.mkdir_p! Path.dirname(manifest)
File.write! manifest, pos |> Enum.sort |> Enum.map(&[&1, ?\n])
manifest
end
defp manifest_stale?(manifest, pos) do
current = read_manifest(manifest)
added = pos -- current
removed = current -- pos
if added == [] and removed == [] do
Mix.Utils.stale?(pos, [manifest])
else
true
end
end
end