changed CHANGELOG.md
 
@@ -1,5 +1,11 @@
1
1
# Changelog
2
2
3
+ ## v0.5.1
4
+
5
+ * Fix instruction commands for `Expo.PO.DuplicateMessagesError`.
6
+ * Fix `FunctionClauseError` in `msguniq` Mix task.
7
+ * Fix duplicated flags and comments for `Expo.Message.merge/2`.
8
+
3
9
## v0.5.0
4
10
5
11
* Add `mix expo.msquniq` Mix task.
changed hex_metadata.config
 
@@ -4,7 +4,7 @@
4
4
{<<"GitHub">>,<<"https://github.com/elixir-gettext/expo">>},
5
5
{<<"Issues">>,<<"https://github.com/elixir-gettext/expo/issues">>}]}.
6
6
{<<"name">>,<<"expo">>}.
7
- {<<"version">>,<<"0.5.0">>}.
7
+ {<<"version">>,<<"0.5.1">>}.
8
8
{<<"description">>,
9
9
<<"Low-level Gettext file handling (.po/.pot/.mo file writer and parser).">>}.
10
10
{<<"elixir">>,<<"~> 1.11">>}.
 
@@ -14,21 +14,20 @@
14
14
{<<"files">>,
15
15
[<<"lib">>,<<"lib/mix">>,<<"lib/mix/tasks">>,
16
16
<<"lib/mix/tasks/expo.msguniq.ex">>,<<"lib/mix/tasks/expo.msgmft.ex">>,
17
- <<"lib/expo">>,<<"lib/expo/util.ex">>,<<"lib/expo/message.ex">>,
18
- <<"lib/expo/mo">>,<<"lib/expo/mo/composer.ex">>,
19
- <<"lib/expo/mo/unsupported_version_error.ex">>,
20
- <<"lib/expo/mo/invalid_file_error.ex">>,<<"lib/expo/mo/parser.ex">>,
21
- <<"lib/expo/mo.ex">>,<<"lib/expo/message">>,
22
- <<"lib/expo/message/singular.ex">>,<<"lib/expo/message/plural.ex">>,
23
- <<"lib/expo/po">>,<<"lib/expo/po/duplicate_translations_error.ex">>,
24
- <<"lib/expo/po/composer.ex">>,<<"lib/expo/po/syntax_error.ex">>,
25
- <<"lib/expo/po/tokenizer.ex">>,<<"lib/expo/po/parser.ex">>,
26
- <<"lib/expo/plural_forms">>,<<"lib/expo/plural_forms/syntax_error.ex">>,
17
+ <<"lib/expo">>,<<"lib/expo/po.ex">>,<<"lib/expo/message">>,
18
+ <<"lib/expo/message/plural.ex">>,<<"lib/expo/message/singular.ex">>,
19
+ <<"lib/expo/mo">>,<<"lib/expo/mo/unsupported_version_error.ex">>,
20
+ <<"lib/expo/mo/parser.ex">>,<<"lib/expo/mo/invalid_file_error.ex">>,
21
+ <<"lib/expo/mo/composer.ex">>,<<"lib/expo/mo.ex">>,
22
+ <<"lib/expo/messages.ex">>,<<"lib/expo/plural_forms">>,
27
23
<<"lib/expo/plural_forms/known.ex">>,
28
- <<"lib/expo/plural_forms/tokenizer.ex">>,<<"lib/expo/plural_forms.ex">>,
29
- <<"lib/expo/messages.ex">>,<<"lib/expo/po.ex">>,<<".formatter.exs">>,
24
+ <<"lib/expo/plural_forms/tokenizer.ex">>,
25
+ <<"lib/expo/plural_forms/syntax_error.ex">>,<<"lib/expo/message.ex">>,
26
+ <<"lib/expo/plural_forms.ex">>,<<"lib/expo/util.ex">>,<<"lib/expo/po">>,
27
+ <<"lib/expo/po/composer.ex">>,<<"lib/expo/po/parser.ex">>,
28
+ <<"lib/expo/po/tokenizer.ex">>,<<"lib/expo/po/syntax_error.ex">>,
29
+ <<"lib/expo/po/duplicate_translations_error.ex">>,<<".formatter.exs">>,
30
30
<<"mix.exs">>,<<"README.md">>,<<"LICENSE">>,<<"CHANGELOG.md">>,<<"src">>,
31
- <<"src/expo_po_parser.erl">>,<<"src/expo_po_parser.yrl">>,
32
- <<"src/expo_plural_forms_parser.erl">>,
33
- <<"src/expo_plural_forms_parser.yrl">>]}.
31
+ <<"src/expo_plural_forms_parser.erl">>,<<"src/expo_po_parser.yrl">>,
32
+ <<"src/expo_plural_forms_parser.yrl">>,<<"src/expo_po_parser.erl">>]}.
34
33
{<<"build_tools">>,[<<"mix">>]}.
changed lib/expo/message.ex
 
@@ -115,9 +115,11 @@ defmodule Expo.Message do
115
115
"""
116
116
@spec has_flag?(t(), String.t()) :: boolean()
117
117
def has_flag?(%mod{flags: flags} = _message, flag)
118
- when mod in [Singular, Plural] and is_binary(flag) do
119
- flag in List.flatten(flags)
120
- end
118
+ when mod in [Singular, Plural] and is_binary(flag),
119
+ do: raw_has_flag?(flags, flag)
120
+
121
+ defp raw_has_flag?(flags, flag) when is_list(flags) when is_binary(flag),
122
+ do: flag in List.flatten(flags)
121
123
122
124
@doc """
123
125
Appends the given `flag` to the given `message`.
 
@@ -132,19 +134,21 @@ defmodule Expo.Message do
132
134
133
135
"""
134
136
@spec append_flag(t(), String.t()) :: t()
135
- def append_flag(%mod{flags: flags} = message, flag) when mod in [Singular, Plural] do
136
- flags =
137
- if has_flag?(message, flag) do
138
- flags
139
- else
140
- case flags do
141
- [] -> [[flag]]
142
- [flag_line] -> [flag_line ++ [flag]]
143
- _multiple_lines -> flags ++ [[flag]]
144
- end
145
- end
137
+ def append_flag(%mod{flags: flags} = message, flag) when mod in [Singular, Plural],
138
+ do: struct!(message, flags: raw_append_flag(flags, flag))
146
139
147
- struct!(message, flags: flags)
140
+ @doc false
141
+ @spec raw_append_flag([[String.t()]], String.t()) :: [[String.t()]]
142
+ def raw_append_flag(flags, flag) when is_list(flags) when is_binary(flag) do
143
+ if raw_has_flag?(flags, flag) do
144
+ flags
145
+ else
146
+ case flags do
147
+ [] -> [[flag]]
148
+ [flag_line] -> [flag_line ++ [flag]]
149
+ _multiple_lines -> flags ++ [[flag]]
150
+ end
151
+ end
148
152
end
149
153
150
154
@doc """
 
@@ -178,10 +182,10 @@ defmodule Expo.Message do
178
182
179
183
## Examples
180
184
181
- iex> msg1 = %Expo.Message.Singular{msgid: ["test"], flags: ["one"]}
182
- ...> msg2 = %Expo.Message.Singular{msgid: ["test"], flags: ["two"]}
185
+ iex> msg1 = %Expo.Message.Singular{msgid: ["test"], flags: [["one"]]}
186
+ ...> msg2 = %Expo.Message.Singular{msgid: ["test"], flags: [["one", "two"]]}
183
187
...> Expo.Message.merge(msg1, msg2)
184
- %Expo.Message.Singular{msgid: ["test"], flags: ["one", "two"]}
188
+ %Expo.Message.Singular{msgid: ["test"], flags: [["one", "two"]]}
185
189
186
190
iex> msg1 = %Expo.Message.Singular{msgid: ["test"]}
187
191
...> msg2 = %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["tests"]}
changed lib/expo/message/plural.ex
 
@@ -188,31 +188,36 @@ defmodule Expo.Message.Plural do
188
188
189
189
## Examples
190
190
191
- iex> msg1 = %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["one"], flags: ["one"], msgstr: %{0 => "une"}}
192
- ...> msg2 = %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["two"], flags: ["two"], msgstr: %{2 => "deux"}}
191
+ iex> msg1 = %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["one"], flags: [["one"]], msgstr: %{0 => "une"}}
192
+ ...> msg2 = %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["two"], flags: [["two"]], msgstr: %{2 => "deux"}}
193
193
...> Expo.Message.Plural.merge(msg1, msg2)
194
- %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["two"], flags: ["one", "two"], msgstr: %{0 => "une", 2 => "deux"}}
194
+ %Expo.Message.Plural{msgid: ["test"], msgid_plural: ["two"], flags: [["two", "one"]], msgstr: %{0 => "une", 2 => "deux"}}
195
195
196
196
"""
197
197
@doc since: "0.5.0"
198
198
@spec merge(t(), t()) :: t()
199
- def merge(message1, message2) do
199
+ def merge(%__MODULE__{} = message1, %__MODULE__{} = message2) do
200
200
Map.merge(message1, message2, fn
201
- key, value_1, value_2 when key in [:msgid, :msgid_plural] ->
202
- if IO.iodata_length(value_2) > 0, do: value_2, else: value_1
201
+ key, value1, value2 when key in [:msgid, :msgid_plural] ->
202
+ if IO.iodata_length(value2) > 0, do: value2, else: value1
203
203
204
- :msgctxt, _msgctxt_a, msgctxt_b ->
205
- msgctxt_b
204
+ :msgctxt, _msgctxt1, msgctxt2 ->
205
+ msgctxt2
206
206
207
- key, value_1, value_2
208
- when key in [:comments, :extracted_comments, :flags, :previous_messages, :references] ->
209
- Enum.concat(value_1, value_2)
207
+ :flags, flags1, flags2 ->
208
+ flags1
209
+ |> List.flatten()
210
+ |> Enum.reduce(flags2, &Message.raw_append_flag(&2, &1))
210
211
211
- :msgstr, msgstr_a, msgstr_b ->
212
- merge_msgstr(msgstr_a, msgstr_b)
212
+ key, value1, value2
213
+ when key in [:comments, :extracted_comments, :previous_messages, :references] ->
214
+ Enum.uniq(Enum.concat(value2, value1))
213
215
214
- _key, _value_1, value_2 ->
215
- value_2
216
+ :msgstr, msgstr1, msgstr2 ->
217
+ merge_msgstr(msgstr1, msgstr2)
218
+
219
+ _key, _value1, value2 ->
220
+ value2
216
221
end)
217
222
end
changed lib/expo/message/singular.ex
 
@@ -179,25 +179,30 @@ defmodule Expo.Message.Singular do
179
179
180
180
## Examples
181
181
182
- iex> msg1 = %Expo.Message.Singular{msgid: ["test"], flags: ["one"]}
183
- ...> msg2 = %Expo.Message.Singular{msgid: ["test"], flags: ["two"]}
182
+ iex> msg1 = %Expo.Message.Singular{msgid: ["test"], flags: [["one"]]}
183
+ ...> msg2 = %Expo.Message.Singular{msgid: ["test"], flags: [["two"]]}
184
184
...> Expo.Message.Singular.merge(msg1, msg2)
185
- %Expo.Message.Singular{msgid: ["test"], flags: ["one", "two"]}
185
+ %Expo.Message.Singular{msgid: ["test"], flags: [["two", "one"]]}
186
186
187
187
"""
188
188
@doc since: "0.5.0"
189
189
@spec merge(t(), t()) :: t()
190
- def merge(message1, message2) do
190
+ def merge(%__MODULE__{} = message1, %__MODULE__{} = message2) do
191
191
Map.merge(message1, message2, fn
192
192
key, value1, value2 when key in [:msgid, :msgstr] ->
193
193
if IO.iodata_length(value2) > 0, do: value2, else: value1
194
194
195
- :msgctxt, _msgctxt_a, msgctxt_b ->
196
- msgctxt_b
195
+ :msgctxt, _msgctxt1, msgctxt2 ->
196
+ msgctxt2
197
+
198
+ :flags, flags1, flags2 ->
199
+ flags1
200
+ |> List.flatten()
201
+ |> Enum.reduce(flags2, &Message.raw_append_flag(&2, &1))
197
202
198
203
key, value1, value2
199
- when key in [:comments, :extracted_comments, :flags, :previous_messages, :references] ->
200
- Enum.concat(value1, value2)
204
+ when key in [:comments, :extracted_comments, :previous_messages, :references] ->
205
+ Enum.uniq(Enum.concat(value1, value2))
201
206
202
207
_key, _value1, value2 ->
203
208
value2
changed lib/expo/po/duplicate_translations_error.ex
 
@@ -31,7 +31,7 @@ defmodule Expo.PO.DuplicateMessagesError do
31
31
"""
32
32
To merge the duplicates, run:
33
33
34
- mix expo.msguniq #{file}
34
+ mix expo.msguniq #{file} --output-file #{file}
35
35
"""
36
36
else
37
37
~s(To merge the duplicates, run "mix expo.msguniq" with the input file)
 
@@ -39,9 +39,9 @@ defmodule Expo.PO.DuplicateMessagesError do
39
39
40
40
errors =
41
41
Enum.map(duplicates, fn {_message, error_message, new_line, _old_line} ->
42
- [prefix, Integer.to_string(new_line), ": ", error_message]
42
+ [prefix, Integer.to_string(new_line), ": ", error_message, ?\n]
43
43
end)
44
44
45
- IO.iodata_to_binary([errors, "\n\n", fix_description])
45
+ IO.iodata_to_binary([errors, ?\n, fix_description])
46
46
end
47
47
end
changed lib/mix/tasks/expo.msguniq.ex
 
@@ -11,7 +11,7 @@ defmodule Mix.Tasks.Expo.Msguniq do
11
11
12
12
## Usage
13
13
14
- mix expo.msguniq PO_FILE [--output=OUTPUT_FILE]
14
+ mix expo.msguniq PO_FILE [--output-file=OUTPUT_FILE]
15
15
16
16
## Options
17
17
 
@@ -71,6 +71,7 @@ defmodule Mix.Tasks.Expo.Msguniq do
71
71
duplicates
72
72
|> Enum.reduce(catalogue, &merge_duplicate/2)
73
73
|> PO.compose()
74
+ |> Enum.map(&List.wrap/1)
74
75
75
76
_output = Enum.into(po, output)
changed mix.exs
 
@@ -2,7 +2,7 @@
2
2
defmodule Expo.MixProject do
3
3
use Mix.Project
4
4
5
- @version "0.5.0"
5
+ @version "0.5.1"
6
6
@source_url "https://github.com/elixir-gettext/expo"
7
7
@description "Low-level Gettext file handling (.po/.pot/.mo file writer and parser)."
changed src/expo_plural_forms_parser.erl
 
@@ -6,7 +6,7 @@ value({int, _Line, Int}) -> Int.
6
6
7
7
operator({Op, _Line}) -> Op.
8
8
9
- -file("/Users/andrea/.asdf/installs/erlang/25.0/lib/parsetools-2.4/include/yeccpre.hrl", 0).
9
+ -file("/home/maennchen/.asdf/installs/erlang/25.2/lib/parsetools-2.4.1/include/yeccpre.hrl", 0).
10
10
%%
11
11
%% %CopyrightBegin%
12
12
%%
changed src/expo_po_parser.erl
 
@@ -40,7 +40,7 @@ group_meta(MetaFields) ->
40
40
)
41
41
).
42
42
43
- -file("/Users/andrea/.asdf/installs/erlang/25.0/lib/parsetools-2.4/include/yeccpre.hrl", 0).
43
+ -file("/home/maennchen/.asdf/installs/erlang/25.2/lib/parsetools-2.4.1/include/yeccpre.hrl", 0).
44
44
%%
45
45
%% %CopyrightBegin%
46
46
%%