Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #17008 -- Added makemessages option to not remove .pot files.

Thanks airstrike for the report and initial patch, Julien for an
enhanced patch and Jannis for reviewing.
  • Loading branch information...
commit eee865257aaa9005947a7b4994c475c2ad59d698 1 parent d406afe
Ramiro Morales authored January 16, 2013
33  django/core/management/commands/makemessages.py
@@ -126,7 +126,7 @@ def write_pot_file(potfile, msgs, file, work_file, is_templatized):
126 126
         fp.write(msgs)
127 127
 
128 128
 def process_file(file, dirpath, potfile, domain, verbosity,
129  
-                 extensions, wrap, location, stdout=sys.stdout):
  129
+                 extensions, wrap, location, keep_pot, stdout=sys.stdout):
130 130
     """
131 131
     Extract translatable literals from :param file: for :param domain:
132 132
     creating or updating the :param potfile: POT file.
@@ -183,7 +183,7 @@ def process_file(file, dirpath, potfile, domain, verbosity,
183 183
         if status != STATUS_OK:
184 184
             if is_templatized:
185 185
                 os.unlink(work_file)
186  
-            if os.path.exists(potfile):
  186
+            if not keep_pot and os.path.exists(potfile):
187 187
                 os.unlink(potfile)
188 188
             raise CommandError(
189 189
                 "errors happened while running xgettext on %s\n%s" %
@@ -197,7 +197,7 @@ def process_file(file, dirpath, potfile, domain, verbosity,
197 197
         os.unlink(work_file)
198 198
 
199 199
 def write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
200  
-                  copy_pforms, wrap, location, no_obsolete):
  200
+                  copy_pforms, wrap, location, no_obsolete, keep_pot):
201 201
     """
202 202
     Creates of updates the :param pofile: PO file for :param domain: and :param
203 203
     locale:.  Uses contents of the existing :param potfile:.
@@ -208,7 +208,8 @@ def write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
208 208
                                     (wrap, location, potfile))
209 209
     if errors:
210 210
         if status != STATUS_OK:
211  
-            os.unlink(potfile)
  211
+            if not keep_pot:
  212
+                os.unlink(potfile)
212 213
             raise CommandError(
213 214
                 "errors happened while running msguniq\n%s" % errors)
214 215
         elif verbosity > 0:
@@ -221,7 +222,8 @@ def write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
221 222
                                         (wrap, location, pofile, potfile))
222 223
         if errors:
223 224
             if status != STATUS_OK:
224  
-                os.unlink(potfile)
  225
+                if not keep_pot:
  226
+                    os.unlink(potfile)
225 227
                 raise CommandError(
226 228
                     "errors happened while running msgmerge\n%s" % errors)
227 229
             elif verbosity > 0:
@@ -232,7 +234,8 @@ def write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
232 234
         "#. #-#-#-#-#  %s.pot (PACKAGE VERSION)  #-#-#-#-#\n" % domain, "")
233 235
     with open(pofile, 'w') as fp:
234 236
         fp.write(msgs)
235  
-    os.unlink(potfile)
  237
+    if not keep_pot:
  238
+        os.unlink(potfile)
236 239
     if no_obsolete:
237 240
         msgs, errors, status = _popen(
238 241
             'msgattrib %s %s -o "%s" --no-obsolete "%s"' %
@@ -246,7 +249,7 @@ def write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
246 249
 
247 250
 def make_messages(locale=None, domain='django', verbosity=1, all=False,
248 251
         extensions=None, symlinks=False, ignore_patterns=None, no_wrap=False,
249  
-        no_location=False, no_obsolete=False, stdout=sys.stdout):
  252
+        no_location=False, no_obsolete=False, stdout=sys.stdout, keep_pot=False):
250 253
     """
251 254
     Uses the ``locale/`` directory from the Django Git tree or an
252 255
     application/project to process all files with translatable literals for
@@ -280,10 +283,12 @@ def make_messages(locale=None, domain='django', verbosity=1, all=False,
280 283
                 "if you want to enable i18n for your project or application.")
281 284
 
282 285
     if domain not in ('django', 'djangojs'):
283  
-        raise CommandError("currently makemessages only supports domains 'django' and 'djangojs'")
  286
+        raise CommandError("currently makemessages only supports domains "
  287
+                           "'django' and 'djangojs'")
284 288
 
285 289
     if (locale is None and not all) or domain is None:
286  
-        message = "Type '%s help %s' for usage information." % (os.path.basename(sys.argv[0]), sys.argv[1])
  290
+        message = "Type '%s help %s' for usage information." % (
  291
+                  os.path.basename(sys.argv[0]), sys.argv[1])
287 292
         raise CommandError(message)
288 293
 
289 294
     # We require gettext version 0.15 or newer.
@@ -325,11 +330,11 @@ def make_messages(locale=None, domain='django', verbosity=1, all=False,
325 330
         for dirpath, file in find_files(".", ignore_patterns, verbosity,
326 331
                 stdout, symlinks=symlinks):
327 332
             process_file(file, dirpath, potfile, domain, verbosity, extensions,
328  
-                    wrap, location, stdout)
  333
+                    wrap, location, keep_pot, stdout)
329 334
 
330 335
         if os.path.exists(potfile):
331 336
             write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
332  
-                    not invoked_for_django, wrap, location, no_obsolete)
  337
+                    not invoked_for_django, wrap, location, no_obsolete, keep_pot)
333 338
 
334 339
 
335 340
 class Command(NoArgsCommand):
@@ -355,6 +360,8 @@ class Command(NoArgsCommand):
355 360
             default=False, help="Don't write '#: filename:line' lines"),
356 361
         make_option('--no-obsolete', action='store_true', dest='no_obsolete',
357 362
             default=False, help="Remove obsolete message strings"),
  363
+        make_option('--keep-pot', action='store_true', dest='keep_pot',
  364
+            default=False, help="Keep .pot file after making messages. Useful when debugging."),
358 365
     )
359 366
     help = ("Runs over the entire source tree of the current directory and "
360 367
 "pulls out all strings marked for translation. It creates (or updates) a message "
@@ -379,6 +386,7 @@ def handle_noargs(self, *args, **options):
379 386
         no_wrap = options.get('no_wrap')
380 387
         no_location = options.get('no_location')
381 388
         no_obsolete = options.get('no_obsolete')
  389
+        keep_pot = options.get('keep_pot')
382 390
         if domain == 'djangojs':
383 391
             exts = extensions if extensions else ['js']
384 392
         else:
@@ -390,4 +398,5 @@ def handle_noargs(self, *args, **options):
390 398
                              % get_text_list(list(extensions), 'and'))
391 399
 
392 400
         make_messages(locale, domain, verbosity, process_all, extensions,
393  
-            symlinks, ignore_patterns, no_wrap, no_location, no_obsolete, self.stdout)
  401
+                      symlinks, ignore_patterns, no_wrap, no_location,
  402
+                      no_obsolete, self.stdout, keep_pot)
8  docs/ref/django-admin.txt
@@ -472,6 +472,14 @@ Use the ``--no-location`` option to not write '``#: filename:line``'
472 472
 comment lines in language files. Note that using this option makes it harder
473 473
 for technically skilled translators to understand each message's context.
474 474
 
  475
+.. django-admin-option:: --keep-pot
  476
+
  477
+.. versionadded:: 1.6
  478
+
  479
+Use the ``--keep-pot`` option to prevent django from deleting the temporary
  480
+.pot file it generates before creating the .po file. This is useful for
  481
+debugging errors which may prevent the final language files from being created.
  482
+
475 483
 runfcgi [options]
476 484
 -----------------
477 485
 
33  tests/regressiontests/i18n/commands/extraction.py
@@ -293,3 +293,36 @@ def test_no_location_disabled(self):
293 293
         with open(self.PO_FILE, 'r') as fp:
294 294
             po_contents = force_text(fp.read())
295 295
             self.assertTrue('#: templates/test.html:55' in po_contents)
  296
+
  297
+
  298
+class KeepPotFileExtractorTests(ExtractorTests):
  299
+
  300
+    def setUp(self):
  301
+        self.POT_FILE = self.PO_FILE + 't'
  302
+        super(KeepPotFileExtractorTests, self).setUp()
  303
+
  304
+    def tearDown(self):
  305
+        super(KeepPotFileExtractorTests, self).tearDown()
  306
+        os.chdir(self.test_dir)
  307
+        try:
  308
+            os.unlink(self.POT_FILE)
  309
+        except OSError:
  310
+            pass
  311
+        os.chdir(self._cwd)
  312
+
  313
+    def test_keep_pot_disabled_by_default(self):
  314
+        os.chdir(self.test_dir)
  315
+        management.call_command('makemessages', locale=LOCALE, verbosity=0)
  316
+        self.assertFalse(os.path.exists(self.POT_FILE))
  317
+
  318
+    def test_keep_pot_explicitly_disabled(self):
  319
+        os.chdir(self.test_dir)
  320
+        management.call_command('makemessages', locale=LOCALE, verbosity=0,
  321
+                                keep_pot=False)
  322
+        self.assertFalse(os.path.exists(self.POT_FILE))
  323
+
  324
+    def test_keep_pot_enabled(self):
  325
+        os.chdir(self.test_dir)
  326
+        management.call_command('makemessages', locale=LOCALE, verbosity=0,
  327
+                                keep_pot=True)
  328
+        self.assertTrue(os.path.exists(self.POT_FILE))
2  tests/regressiontests/i18n/tests.py
@@ -32,7 +32,7 @@
32 32
     from .commands.extraction import (ExtractorTests, BasicExtractorTests,
33 33
         JavascriptExtractorTests, IgnoredExtractorTests, SymlinkExtractorTests,
34 34
         CopyPluralFormsExtractorTests, NoWrapExtractorTests,
35  
-        NoLocationExtractorTests)
  35
+        NoLocationExtractorTests, KeepPotFileExtractorTests)
36 36
 if can_run_compilation_tests:
37 37
     from .commands.compilation import (PoFileTests, PoFileContentsTests,
38 38
         PercentRenderingTests)

0 notes on commit eee8652

Please sign in to comment.
Something went wrong with that request. Please try again.