cat-bookmarker/deps/expo/lib/mix/tasks/expo.msguniq.ex

102 lines
2.4 KiB
Elixir

defmodule Mix.Tasks.Expo.Msguniq do
@shortdoc "Unifies duplicate translations in message catalog"
@moduledoc """
Unifies duplicate translations in the given PO file.
By default, this task outputs the file on standard output. If you want to
*overwrite* the given PO file, pass in the `--output` flag.
*This task is available since v0.5.0.*
## Usage
mix expo.msguniq PO_FILE [--output-file=OUTPUT_FILE]
## Options
* `--output-file` (`-o`) - File to store the output in. `-` for
standard output. Defaults to `-`.
"""
@moduledoc since: "0.5.0"
use Mix.Task
alias Expo.Message
alias Expo.Messages
alias Expo.PO
alias Expo.PO.DuplicateMessagesError
@switches [output_file: :string]
@aliases [o: :output_file]
@default_options [output_file: "-"]
@impl Mix.Task
def run(args) do
{:ok, _} = Application.ensure_all_started(:expo)
{opts, argv} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)
opts = Keyword.merge(@default_options, opts)
output =
case opts[:output_file] do
"-" -> IO.stream(:stdio, :line)
file -> File.stream!(file)
end
file =
case argv do
[] ->
Mix.raise("""
mix expo.msguniq failed due to missing po file path argument
""")
[_file_one, _file_two | _other_files] ->
Mix.raise("""
mix expo.msguniq failed due to multiple po file path arguments
Only one is currently supported
""")
[file] ->
file
end
case PO.parse_file(file) do
{:ok, _messages} ->
:ok
{:error, %DuplicateMessagesError{duplicates: duplicates, catalogue: catalogue}} ->
po =
duplicates
|> Enum.reduce(catalogue, &merge_duplicate/2)
|> PO.compose()
|> Enum.map(&List.wrap/1)
_output = Enum.into(po, output)
IO.puts(:stderr, IO.ANSI.format("Merged #{length(duplicates)} translations"))
{:error, error} ->
raise error
end
end
defp merge_duplicate(
{duplicate, _error_message, _line, _original_line},
%Messages{messages: messages} = po
) do
%Messages{
po
| messages:
Enum.map(messages, fn message ->
if Message.key(message) == Message.key(duplicate) do
Message.merge(message, duplicate)
else
message
end
end)
}
end
end