Repository: elixir-gettext/gettext
Pull request #310 (2022-05-19 15:55:32)

Dump flags after references in PO files
## Summary

This PR changes the order in which flags and references are dumped into PO files, so that flags are placed after references. This behavior seems to be common among a small sample of non-Elixir PO files I saw.

## Background

In of the projects, I'm going to use transifex.com to enable easier management of translations. However, I've noticed that they output comments in PO files in a different order than Elixir's gettext. They first output file references and then flags, while Elixir's gettext does it the other way. This results in some unnecessary churn in git history, because these 2 lines are swapped back and forth. Folks at transifex.com insist that Elixir's gettext is outputing comments in the wrong order:

> After investigation, our team concluded that the resulting order of the comments is not caused by a bug in our parser. Instead, our parser while following the PO file entry schematic structure, arranges the comments in the order specified in the GNU guidelines. You can find more information about this [here](https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html).
>
> Since these are the best practices for PO file handling our advice would be to follow them to avoid any future issues.

However, I wasn't able to find any explicit mention of the "standard" comment order in PO files, except for the example PO file in the linked gettext doc. My short GitHub research indicated that indeed PO files with flags (that I've found) had them placed after the references, so that gives some additional credibility to transifex claim.



whatyouhide: This will potentially generate large diffs for folks with lots of PO files. It's alright, just something that we might want to call out in the CHANGELOG. 🙃 

Thanks @wpiekutowski! ❤️ 

Patch:
diff --git a/lib/gettext/po.ex b/lib/gettext/po.ex
index c4c300a..9432fa1 100644
--- a/lib/gettext/po.ex
+++ b/lib/gettext/po.ex
@@ -231,8 +231,8 @@ defmodule Gettext.PO do
     [
       dump_comments(t.comments),
       dump_comments(t.extracted_comments),
-      dump_flags(t.flags),
       dump_references(t.references, gettext_config),
+      dump_flags(t.flags),
       dump_msgctxt(t.msgctxt),
       dump_kw_and_strings("msgid", t.msgid),
       dump_kw_and_strings("msgstr", t.msgstr)
@@ -243,8 +243,8 @@ defmodule Gettext.PO do
     [
       dump_comments(t.comments),
       dump_comments(t.extracted_comments),
-      dump_flags(t.flags),
       dump_references(t.references, gettext_config),
+      dump_flags(t.flags),
       dump_msgctxt(t.msgctxt),
       dump_kw_and_strings("msgid", t.msgid),
       dump_kw_and_strings("msgid_plural", t.msgid_plural),


Test patch:
diff --git a/test/gettext/extractor_test.exs b/test/gettext/extractor_test.exs
index b2765ac..bc0c673 100644
--- a/test/gettext/extractor_test.exs
+++ b/test/gettext/extractor_test.exs
@@ -297,14 +297,14 @@ defmodule Gettext.ExtractorTest do
        #. some other comment
        #. repeated comment
        #. one more comment
-       #, elixir-autogen, elixir-format
        #: foo.ex:17
        #: foo.ex:22
+       #, elixir-autogen, elixir-format
        msgid "foo"
        msgstr ""
 
-       #, elixir-autogen, elixir-format
        #: foo.ex:24
+       #, elixir-autogen, elixir-format
        msgctxt "test"
        msgid "context based translation"
        msgstr ""
@@ -314,8 +314,8 @@ defmodule Gettext.ExtractorTest do
        msgid ""
        msgstr ""
 
-       #, elixir-autogen, elixir-format
        #: foo.ex:18
+       #, elixir-autogen, elixir-format
        msgid "one error"
        msgid_plural "%{count} errors"
        msgstr[0] ""
@@ -326,8 +326,8 @@ defmodule Gettext.ExtractorTest do
        msgid ""
        msgstr ""
 
-       #, elixir-autogen, elixir-format
        #: foo.ex:23
+       #, elixir-autogen, elixir-format
        msgid "hi"
        msgstr ""
        """}
diff --git a/test/mix/tasks/gettext.extract_test.exs b/test/mix/tasks/gettext.extract_test.exs
index 2aa1f21..6a5fe2b 100644
--- a/test/mix/tasks/gettext.extract_test.exs
+++ b/test/mix/tasks/gettext.extract_test.exs
@@ -38,8 +38,8 @@ defmodule Mix.Tasks.Gettext.ExtractTest do
     assert output =~ "Extracted priv/gettext/default.pot"
 
     assert read_file("priv/gettext/default.pot") =~ """
-           #, elixir-autogen, elixir-format
            #: lib/my_app.ex:7
+           #, elixir-autogen, elixir-format
            msgid "hello"
            msgstr ""
            """
@@ -60,8 +60,8 @@ defmodule Mix.Tasks.Gettext.ExtractTest do
     end)
 
     assert read_file("priv/gettext/it/LC_MESSAGES/my_domain.po") == """
-           #, elixir-autogen, elixir-format
            #: lib/other.ex:3
+           #, elixir-autogen, elixir-format
            msgid "other"
            msgstr ""
            """