Repository: python-babel/babel
Pull request #335 (2016-01-27 14:46:26)

Frontend: Add multi-domain support to compile_catalog command
Some projects have their translations split up into several text
domains within one package.  This change adds the possibility to
specify a space seperated list of domains in the configuration, like
'setup.py compile_catalog --domain="foo bar"', for instance.

codecov-io: ## [Current coverage][1] is `89.40%`
> Merging **#335** into **master** will not affect coverage as of [`df7ac8a`][3]


```diff
@@            master   #335   diff @@
=====================================
  Files           23     23       
  Stmts         3736   3738     +2
  Branches         0      0       
  Methods          0      0       
=====================================
+ Hit           3340   3342     +2
  Partial          0      0       
  Missed         396    396       
```

> Review entire [Coverage Diff][4] as of [`df7ac8a`][3]


[1]: https://codecov.io/github/python-babel/babel?ref=df7ac8ab245b00769b30cb07416a36bcd9e7b8c8
[2]: https://codecov.io/github/python-babel/babel/features/suggestions?ref=df7ac8ab245b00769b30cb07416a36bcd9e7b8c8
[3]: https://codecov.io/github/python-babel/babel/commit/df7ac8ab245b00769b30cb07416a36bcd9e7b8c8
[4]: https://codecov.io/github/python-babel/babel/compare/0d78912fa4944a279541ed8286ee4f1f557c3b16...df7ac8ab245b00769b30cb07416a36bcd9e7b8c8

> Powered by [Codecov](https://codecov.io). Updated on successful CI builds.
ansiwen: 56% patch coverage? That's not fair, just because I had to indent the whole block? 😒
akx: @ansiwen Heh, don't worry about codecov's patch measurements. It's a cranky ol' thing sometimes.

Patch:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index dfad49f..2fa0a65 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -39,9 +39,6 @@ For a PR to be merged, the following statements must hold true:
   not the author of the PR. Commits shall comply to the "Good Commits" standards
   outlined below.
 
-To begin contributing have a look at the open [easy issues](https://github.com/python-babel/babel/issues?q=is%3Aopen+is%3Aissue+label%3Adifficulty%2Flow) 
-which could be fixed.
-
 ## Correcting PRs
 
 Rebasing PRs is preferred over merging master into the source branches again
diff --git a/README.md b/README.md
index 98ea014..4fa81e6 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ Contributing to Babel
 =====================
 
 If you want to contribute code to Babel, please take a look at our
-[CONTRIBUTING.md](https://github.com/python-babel/babel/blob/master/CONTRIBUTING.md).
+CONTRIBUTING.md.
 
 If you know your way around Babels codebase a bit and like to help further, we
 would appreciate any help in reviewing pull requests. Please contact us at
diff --git a/babel/messages/frontend.py b/babel/messages/frontend.py
index 8c6fd82..73abf4f 100644
--- a/babel/messages/frontend.py
+++ b/babel/messages/frontend.py
@@ -83,7 +83,7 @@ class compile_catalog(Command):
     description = 'compile message catalogs to binary MO files'
     user_options = [
         ('domain=', 'D',
-         "domain of PO file (default 'messages')"),
+         "domains of PO files (space separated list, default 'messages')"),
         ('directory=', 'd',
          'path to base directory containing the catalogs'),
         ('input-file=', 'i',
@@ -118,6 +118,12 @@ class compile_catalog(Command):
                                        'or the base directory')
 
     def run(self):
+        domains = self.domain.split()
+
+        for domain in domains:
+            self._run_domain(domain)
+
+    def _run_domain(self, domain):
         po_files = []
         mo_files = []
 
@@ -126,19 +132,19 @@ class compile_catalog(Command):
                 po_files.append((self.locale,
                                  os.path.join(self.directory, self.locale,
                                               'LC_MESSAGES',
-                                              self.domain + '.po')))
+                                              domain + '.po')))
                 mo_files.append(os.path.join(self.directory, self.locale,
                                              'LC_MESSAGES',
-                                             self.domain + '.mo'))
+                                             domain + '.mo'))
             else:
                 for locale in os.listdir(self.directory):
                     po_file = os.path.join(self.directory, locale,
-                                           'LC_MESSAGES', self.domain + '.po')
+                                           'LC_MESSAGES', domain + '.po')
                     if os.path.exists(po_file):
                         po_files.append((locale, po_file))
                         mo_files.append(os.path.join(self.directory, locale,
                                                      'LC_MESSAGES',
-                                                     self.domain + '.mo'))
+                                                     domain + '.mo'))
         else:
             po_files.append((self.locale, self.input_file))
             if self.output_file:
@@ -146,7 +152,7 @@ class compile_catalog(Command):
             else:
                 mo_files.append(os.path.join(self.directory, self.locale,
                                              'LC_MESSAGES',
-                                             self.domain + '.mo'))
+                                             domain + '.mo'))
 
         if not po_files:
             raise DistutilsOptionError('no message catalogs found')


Test patch:
diff --git a/tests/messages/data/project/i18n/de_DE/LC_MESSAGES/bar.po b/tests/messages/data/project/i18n/de_DE/LC_MESSAGES/bar.po
new file mode 100644
index 0000000..c5c9748
--- /dev/null
+++ b/tests/messages/data/project/i18n/de_DE/LC_MESSAGES/bar.po
@@ -0,0 +1,32 @@
+# German (Germany) translations for TestProject.
+# Copyright (C) 2007 FooBar, Inc.
+# This file is distributed under the same license as the TestProject
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: TestProject 0.1\n"
+"Report-Msgid-Bugs-To: bugs.address@email.tld\n"
+"POT-Creation-Date: 2007-04-01 15:30+0200\n"
+"PO-Revision-Date: 2007-07-30 22:18+0200\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: de_DE <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9dev-r245\n"
+
+#. This will be a translator coment,
+#. that will include several lines
+#: project/file1.py:8
+msgid "bar"
+msgstr "Stange"
+
+#: project/file2.py:9
+msgid "foobar"
+msgid_plural "foobars"
+msgstr[0] "Fuhstange"
+msgstr[1] "Fuhstangen"
+
diff --git a/tests/messages/data/project/i18n/de_DE/LC_MESSAGES/foo.po b/tests/messages/data/project/i18n/de_DE/LC_MESSAGES/foo.po
new file mode 100644
index 0000000..c5c9748
--- /dev/null
+++ b/tests/messages/data/project/i18n/de_DE/LC_MESSAGES/foo.po
@@ -0,0 +1,32 @@
+# German (Germany) translations for TestProject.
+# Copyright (C) 2007 FooBar, Inc.
+# This file is distributed under the same license as the TestProject
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: TestProject 0.1\n"
+"Report-Msgid-Bugs-To: bugs.address@email.tld\n"
+"POT-Creation-Date: 2007-04-01 15:30+0200\n"
+"PO-Revision-Date: 2007-07-30 22:18+0200\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: de_DE <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 0.9dev-r245\n"
+
+#. This will be a translator coment,
+#. that will include several lines
+#: project/file1.py:8
+msgid "bar"
+msgstr "Stange"
+
+#: project/file2.py:9
+msgid "foobar"
+msgid_plural "foobars"
+msgstr[0] "Fuhstange"
+msgstr[1] "Fuhstangen"
+
diff --git a/tests/messages/test_frontend.py b/tests/messages/test_frontend.py
index 975876a..fc1efad 100644
--- a/tests/messages/test_frontend.py
+++ b/tests/messages/test_frontend.py
@@ -1112,6 +1112,29 @@ compiling catalog %r to %r
             if os.path.isfile(mo_file):
                 os.unlink(mo_file)
 
+    def test_compile_catalog_multidomain(self):
+        po_foo = os.path.join(self._i18n_dir(), 'de_DE', 'LC_MESSAGES',
+                              'foo.po')
+        po_bar = os.path.join(self._i18n_dir(), 'de_DE', 'LC_MESSAGES',
+                              'bar.po')
+        mo_foo = po_foo.replace('.po', '.mo')
+        mo_bar = po_bar.replace('.po', '.mo')
+        try:
+            self.cli.run(sys.argv + ['compile',
+                '--locale', 'de_DE', '--domain', 'foo bar', '--use-fuzzy',
+                '-d', self._i18n_dir()])
+            for mo_file in [mo_foo, mo_bar]:
+                assert os.path.isfile(mo_file)
+            self.assertEqual("""\
+compiling catalog %r to %r
+compiling catalog %r to %r
+""" % (po_foo, mo_foo, po_bar, mo_bar), sys.stderr.getvalue())
+
+        finally:
+            for mo_file in [mo_foo, mo_bar]:
+                if os.path.isfile(mo_file):
+                    os.unlink(mo_file)
+
     def test_update(self):
         template = Catalog()
         template.add("1")