Repository: freedomofpress/securedrop

Issue:
Generating desktop icon templates with i18n_tool.py generates review noise
## Description

When compiling the desktop icon templates for 1.5.0, `i18n_tool.py` produced [output](https://github.com/freedomofpress/securedrop/commit/706424c3a) that only differed in the sorting of the `Name` lines. There's no `--sort-output` argument to `msgfmt` as there is for `xgettext`, but we could open up the generated template and sort those lines ourselves. This could save the localization managers the time it takes to examine the diff, only to find nothing should have changed.


Discussion:
My point would be to open up the `.j2` file after the `msgfmt` call, and then sort properly. I will wait for @zenmonkeykstop's comment on this. 

Resolving patch:
diff --git a/securedrop/i18n_tool.py b/securedrop/i18n_tool.py
--- a/securedrop/i18n_tool.py
+++ b/securedrop/i18n_tool.py
@@ -91,15 +91,25 @@ def translate_messages(self, args: argparse.Namespace) -> None:
                 '--version', args.version,
                 "--msgid-bugs-address=securedrop@freedom.press",
                 "--copyright-holder=Freedom of the Press Foundation",
+                "--add-comments=Translators:",
+                "--strip-comments",
+                "--add-location=never",
+                "--no-wrap",
                 *sources)
+
             sed('-i', '-e', '/^"POT-Creation-Date/d', messages_file)
 
             if (self.file_is_modified(messages_file) and
                     len(os.listdir(args.translations_dir)) > 1):
                 tglob = '{}/*/LC_MESSAGES/*.po'.format(args.translations_dir)
                 for translation in glob.iglob(tglob):
-                    msgmerge('--previous', '--update', translation,
-                             messages_file)
+                    msgmerge(
+                        '--previous',
+                        '--update',
+                        '--no-wrap',
+                        translation,
+                        messages_file
+                    )
                 log.warning("messages translations updated in {}".format(
                             messages_file))
             else:
@@ -141,15 +151,34 @@ def translate_desktop(self, args: argparse.Namespace) -> None:
             pos = [f for f in os.listdir(args.translations_dir) if f.endswith('.po')]
             linguas = [l[:-3] for l in pos]
             content = "\n".join(linguas) + "\n"
-            open(join(args.translations_dir, 'LINGUAS'), 'w').write(content)
-
-            for source in args.sources.split(','):
-                target = source.rstrip('.in')
-                msgfmt('--desktop',
-                       '--template', source,
-                       '-o', target,
-                       '-d', '.',
-                       _cwd=args.translations_dir)
+            linguas_file = join(args.translations_dir, 'LINGUAS')
+            try:
+                open(linguas_file, 'w').write(content)
+
+                for source in args.sources.split(','):
+                    target = source.rstrip('.in')
+                    msgfmt('--desktop',
+                           '--template', source,
+                           '-o', target,
+                           '-d', '.',
+                           _cwd=args.translations_dir)
+                    self.sort_desktop_template(join(args.translations_dir, target))
+            finally:
+                if os.path.exists(linguas_file):
+                    os.unlink(linguas_file)
+
+    def sort_desktop_template(self, template: str) -> None:
+        """
+        Sorts the lines containing the icon names.
+        """
+        lines = open(template).readlines()
+        names = sorted(l for l in lines if l.startswith("Name"))
+        others = (l for l in lines if not l.startswith("Name"))
+        with open(template, "w") as new_template:
+            for line in others:
+                new_template.write(line)
+            for line in names:
+                new_template.write(line)
 
     def set_translate_parser(self,
                              parser: argparse.ArgumentParser,


Test patch: