]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
Implement `--init-missing` option for `pybabel update` (#785)
authorruro <ruro.ruro@ya.ru>
Tue, 15 Jun 2021 10:56:16 +0000 (13:56 +0300)
committerGitHub <noreply@github.com>
Tue, 15 Jun 2021 10:56:16 +0000 (13:56 +0300)
* implement update --init-missing option

* trivial test that the --init-missing option exists

* add non-trivial update --init-missing test

babel/messages/frontend.py
tests/messages/test_frontend.py

index c5eb1dea9ac7ef2bc0fd3a718d624540826586a1..a61c4f5628d859aadb1e9fa1bd6e806f20975549 100644 (file)
@@ -668,6 +668,8 @@ class update_catalog(Command):
          'into several lines'),
         ('ignore-obsolete=', None,
          'whether to omit obsolete messages from the output'),
+        ('init-missing=', None,
+         'if any output files are missing, initialize them first'),
         ('no-fuzzy-matching', 'N',
          'do not use fuzzy matching'),
         ('update-header-comment', None,
@@ -676,8 +678,8 @@ class update_catalog(Command):
          'keep previous msgids of translated messages'),
     ]
     boolean_options = [
-        'omit-header', 'no-wrap', 'ignore-obsolete', 'no-fuzzy-matching',
-        'previous', 'update-header-comment',
+        'omit-header', 'no-wrap', 'ignore-obsolete', 'init-missing',
+        'no-fuzzy-matching', 'previous', 'update-header-comment',
     ]
 
     def initialize_options(self):
@@ -690,6 +692,7 @@ class update_catalog(Command):
         self.width = None
         self.no_wrap = False
         self.ignore_obsolete = False
+        self.init_missing = False
         self.no_fuzzy_matching = False
         self.update_header_comment = False
         self.previous = False
@@ -702,6 +705,19 @@ class update_catalog(Command):
                                        'directory')
         if self.output_file and not self.locale:
             raise DistutilsOptionError('you must specify the locale')
+
+        if self.init_missing:
+            if not self.locale:
+                raise DistutilsOptionError('you must specify the locale for '
+                                           'the init-missing option to work')
+
+            try:
+                self._locale = Locale.parse(self.locale)
+            except UnknownLocaleError as e:
+                raise DistutilsOptionError(e)
+        else:
+            self._locale = None
+
         if self.no_wrap and self.width:
             raise DistutilsOptionError("'--no-wrap' and '--width' are mutually "
                                        "exclusive")
@@ -741,6 +757,23 @@ class update_catalog(Command):
             template = read_po(infile)
 
         for locale, filename in po_files:
+            if self.init_missing and not os.path.exists(filename):
+                self.log.info(
+                    'creating catalog %s based on %s', filename, self.input_file
+                )
+
+                with open(self.input_file, 'rb') as infile:
+                    # Although reading from the catalog template, read_po must
+                    # be fed the locale in order to correctly calculate plurals
+                    catalog = read_po(infile, locale=self.locale)
+
+                catalog.locale = self._locale
+                catalog.revision_date = datetime.now(LOCALTZ)
+                catalog.fuzzy = False
+
+                with open(filename, 'wb') as outfile:
+                    write_po(outfile, catalog)
+
             self.log.info('updating catalog %s based on %s', filename, self.input_file)
             with open(filename, 'rb') as infile:
                 catalog = read_po(infile, locale=locale, domain=domain)
index 70580215ed0aed9558d565f3c45eefe5e9a7c096..b56554c81e0f6971eed28558a37d840a3e195ff0 100644 (file)
@@ -1208,6 +1208,43 @@ compiling catalog %s to %s
             catalog = read_po(infp)
             assert len(catalog) == 4  # Catalog was updated
 
+    def test_update_init_missing(self):
+        template = Catalog()
+        template.add("1")
+        template.add("2")
+        template.add("3")
+        tmpl_file = os.path.join(i18n_dir, 'temp2-template.pot')
+        with open(tmpl_file, "wb") as outfp:
+            write_po(outfp, template)
+        po_file = os.path.join(i18n_dir, 'temp2.po')
+
+        self.cli.run(sys.argv + ['update',
+                                 '--init-missing',
+                                 '-l', 'fi',
+                                 '-o', po_file,
+                                 '-i', tmpl_file])
+
+        with open(po_file, "r") as infp:
+            catalog = read_po(infp)
+            assert len(catalog) == 3
+
+        # Add another entry to the template
+
+        template.add("4")
+
+        with open(tmpl_file, "wb") as outfp:
+            write_po(outfp, template)
+
+        self.cli.run(sys.argv + ['update',
+                                 '--init-missing',
+                                 '-l', 'fi_FI',
+                                 '-o', po_file,
+                                 '-i', tmpl_file])
+
+        with open(po_file, "r") as infp:
+            catalog = read_po(infp)
+            assert len(catalog) == 4  # Catalog was updated
+
 
 def test_parse_mapping():
     buf = StringIO(
@@ -1351,8 +1388,9 @@ def test_extract_distutils_keyword_arg_388(kwarg, expected):
 
 
 def test_update_catalog_boolean_args():
-    cmdinst = configure_cli_command("update --no-wrap -N --ignore-obsolete --previous -i foo -o foo -l en")
+    cmdinst = configure_cli_command("update --init-missing --no-wrap -N --ignore-obsolete --previous -i foo -o foo -l en")
     assert isinstance(cmdinst, update_catalog)
+    assert cmdinst.init_missing is True
     assert cmdinst.no_wrap is True
     assert cmdinst.no_fuzzy_matching is True
     assert cmdinst.ignore_obsolete is True