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.
This commit is contained in:
Ramiro Morales 2013-01-16 15:36:22 -03:00
parent d406afe12e
commit eee865257a
4 changed files with 63 additions and 13 deletions

View File

@ -126,7 +126,7 @@ def write_pot_file(potfile, msgs, file, work_file, is_templatized):
fp.write(msgs) fp.write(msgs)
def process_file(file, dirpath, potfile, domain, verbosity, def process_file(file, dirpath, potfile, domain, verbosity,
extensions, wrap, location, stdout=sys.stdout): extensions, wrap, location, keep_pot, stdout=sys.stdout):
""" """
Extract translatable literals from :param file: for :param domain: Extract translatable literals from :param file: for :param domain:
creating or updating the :param potfile: POT file. creating or updating the :param potfile: POT file.
@ -183,7 +183,7 @@ def process_file(file, dirpath, potfile, domain, verbosity,
if status != STATUS_OK: if status != STATUS_OK:
if is_templatized: if is_templatized:
os.unlink(work_file) os.unlink(work_file)
if os.path.exists(potfile): if not keep_pot and os.path.exists(potfile):
os.unlink(potfile) os.unlink(potfile)
raise CommandError( raise CommandError(
"errors happened while running xgettext on %s\n%s" % "errors happened while running xgettext on %s\n%s" %
@ -197,7 +197,7 @@ def process_file(file, dirpath, potfile, domain, verbosity,
os.unlink(work_file) os.unlink(work_file)
def write_po_file(pofile, potfile, domain, locale, verbosity, stdout, def write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
copy_pforms, wrap, location, no_obsolete): copy_pforms, wrap, location, no_obsolete, keep_pot):
""" """
Creates of updates the :param pofile: PO file for :param domain: and :param Creates of updates the :param pofile: PO file for :param domain: and :param
locale:. Uses contents of the existing :param potfile:. locale:. Uses contents of the existing :param potfile:.
@ -208,7 +208,8 @@ def write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
(wrap, location, potfile)) (wrap, location, potfile))
if errors: if errors:
if status != STATUS_OK: if status != STATUS_OK:
os.unlink(potfile) if not keep_pot:
os.unlink(potfile)
raise CommandError( raise CommandError(
"errors happened while running msguniq\n%s" % errors) "errors happened while running msguniq\n%s" % errors)
elif verbosity > 0: elif verbosity > 0:
@ -221,7 +222,8 @@ def write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
(wrap, location, pofile, potfile)) (wrap, location, pofile, potfile))
if errors: if errors:
if status != STATUS_OK: if status != STATUS_OK:
os.unlink(potfile) if not keep_pot:
os.unlink(potfile)
raise CommandError( raise CommandError(
"errors happened while running msgmerge\n%s" % errors) "errors happened while running msgmerge\n%s" % errors)
elif verbosity > 0: elif verbosity > 0:
@ -232,7 +234,8 @@ def write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
"#. #-#-#-#-# %s.pot (PACKAGE VERSION) #-#-#-#-#\n" % domain, "") "#. #-#-#-#-# %s.pot (PACKAGE VERSION) #-#-#-#-#\n" % domain, "")
with open(pofile, 'w') as fp: with open(pofile, 'w') as fp:
fp.write(msgs) fp.write(msgs)
os.unlink(potfile) if not keep_pot:
os.unlink(potfile)
if no_obsolete: if no_obsolete:
msgs, errors, status = _popen( msgs, errors, status = _popen(
'msgattrib %s %s -o "%s" --no-obsolete "%s"' % 'msgattrib %s %s -o "%s" --no-obsolete "%s"' %
@ -246,7 +249,7 @@ def write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
def make_messages(locale=None, domain='django', verbosity=1, all=False, def make_messages(locale=None, domain='django', verbosity=1, all=False,
extensions=None, symlinks=False, ignore_patterns=None, no_wrap=False, extensions=None, symlinks=False, ignore_patterns=None, no_wrap=False,
no_location=False, no_obsolete=False, stdout=sys.stdout): no_location=False, no_obsolete=False, stdout=sys.stdout, keep_pot=False):
""" """
Uses the ``locale/`` directory from the Django Git tree or an Uses the ``locale/`` directory from the Django Git tree or an
application/project to process all files with translatable literals for 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,
"if you want to enable i18n for your project or application.") "if you want to enable i18n for your project or application.")
if domain not in ('django', 'djangojs'): if domain not in ('django', 'djangojs'):
raise CommandError("currently makemessages only supports domains 'django' and 'djangojs'") raise CommandError("currently makemessages only supports domains "
"'django' and 'djangojs'")
if (locale is None and not all) or domain is None: if (locale is None and not all) or domain is None:
message = "Type '%s help %s' for usage information." % (os.path.basename(sys.argv[0]), sys.argv[1]) message = "Type '%s help %s' for usage information." % (
os.path.basename(sys.argv[0]), sys.argv[1])
raise CommandError(message) raise CommandError(message)
# We require gettext version 0.15 or newer. # We require gettext version 0.15 or newer.
@ -325,11 +330,11 @@ def make_messages(locale=None, domain='django', verbosity=1, all=False,
for dirpath, file in find_files(".", ignore_patterns, verbosity, for dirpath, file in find_files(".", ignore_patterns, verbosity,
stdout, symlinks=symlinks): stdout, symlinks=symlinks):
process_file(file, dirpath, potfile, domain, verbosity, extensions, process_file(file, dirpath, potfile, domain, verbosity, extensions,
wrap, location, stdout) wrap, location, keep_pot, stdout)
if os.path.exists(potfile): if os.path.exists(potfile):
write_po_file(pofile, potfile, domain, locale, verbosity, stdout, write_po_file(pofile, potfile, domain, locale, verbosity, stdout,
not invoked_for_django, wrap, location, no_obsolete) not invoked_for_django, wrap, location, no_obsolete, keep_pot)
class Command(NoArgsCommand): class Command(NoArgsCommand):
@ -355,6 +360,8 @@ class Command(NoArgsCommand):
default=False, help="Don't write '#: filename:line' lines"), default=False, help="Don't write '#: filename:line' lines"),
make_option('--no-obsolete', action='store_true', dest='no_obsolete', make_option('--no-obsolete', action='store_true', dest='no_obsolete',
default=False, help="Remove obsolete message strings"), default=False, help="Remove obsolete message strings"),
make_option('--keep-pot', action='store_true', dest='keep_pot',
default=False, help="Keep .pot file after making messages. Useful when debugging."),
) )
help = ("Runs over the entire source tree of the current directory and " help = ("Runs over the entire source tree of the current directory and "
"pulls out all strings marked for translation. It creates (or updates) a message " "pulls out all strings marked for translation. It creates (or updates) a message "
@ -379,6 +386,7 @@ class Command(NoArgsCommand):
no_wrap = options.get('no_wrap') no_wrap = options.get('no_wrap')
no_location = options.get('no_location') no_location = options.get('no_location')
no_obsolete = options.get('no_obsolete') no_obsolete = options.get('no_obsolete')
keep_pot = options.get('keep_pot')
if domain == 'djangojs': if domain == 'djangojs':
exts = extensions if extensions else ['js'] exts = extensions if extensions else ['js']
else: else:
@ -390,4 +398,5 @@ class Command(NoArgsCommand):
% get_text_list(list(extensions), 'and')) % get_text_list(list(extensions), 'and'))
make_messages(locale, domain, verbosity, process_all, extensions, make_messages(locale, domain, verbosity, process_all, extensions,
symlinks, ignore_patterns, no_wrap, no_location, no_obsolete, self.stdout) symlinks, ignore_patterns, no_wrap, no_location,
no_obsolete, self.stdout, keep_pot)

View File

@ -472,6 +472,14 @@ Use the ``--no-location`` option to not write '``#: filename:line``'
comment lines in language files. Note that using this option makes it harder comment lines in language files. Note that using this option makes it harder
for technically skilled translators to understand each message's context. for technically skilled translators to understand each message's context.
.. django-admin-option:: --keep-pot
.. versionadded:: 1.6
Use the ``--keep-pot`` option to prevent django from deleting the temporary
.pot file it generates before creating the .po file. This is useful for
debugging errors which may prevent the final language files from being created.
runfcgi [options] runfcgi [options]
----------------- -----------------

View File

@ -293,3 +293,36 @@ class NoLocationExtractorTests(ExtractorTests):
with open(self.PO_FILE, 'r') as fp: with open(self.PO_FILE, 'r') as fp:
po_contents = force_text(fp.read()) po_contents = force_text(fp.read())
self.assertTrue('#: templates/test.html:55' in po_contents) self.assertTrue('#: templates/test.html:55' in po_contents)
class KeepPotFileExtractorTests(ExtractorTests):
def setUp(self):
self.POT_FILE = self.PO_FILE + 't'
super(KeepPotFileExtractorTests, self).setUp()
def tearDown(self):
super(KeepPotFileExtractorTests, self).tearDown()
os.chdir(self.test_dir)
try:
os.unlink(self.POT_FILE)
except OSError:
pass
os.chdir(self._cwd)
def test_keep_pot_disabled_by_default(self):
os.chdir(self.test_dir)
management.call_command('makemessages', locale=LOCALE, verbosity=0)
self.assertFalse(os.path.exists(self.POT_FILE))
def test_keep_pot_explicitly_disabled(self):
os.chdir(self.test_dir)
management.call_command('makemessages', locale=LOCALE, verbosity=0,
keep_pot=False)
self.assertFalse(os.path.exists(self.POT_FILE))
def test_keep_pot_enabled(self):
os.chdir(self.test_dir)
management.call_command('makemessages', locale=LOCALE, verbosity=0,
keep_pot=True)
self.assertTrue(os.path.exists(self.POT_FILE))

View File

@ -32,7 +32,7 @@ if can_run_extraction_tests:
from .commands.extraction import (ExtractorTests, BasicExtractorTests, from .commands.extraction import (ExtractorTests, BasicExtractorTests,
JavascriptExtractorTests, IgnoredExtractorTests, SymlinkExtractorTests, JavascriptExtractorTests, IgnoredExtractorTests, SymlinkExtractorTests,
CopyPluralFormsExtractorTests, NoWrapExtractorTests, CopyPluralFormsExtractorTests, NoWrapExtractorTests,
NoLocationExtractorTests) NoLocationExtractorTests, KeepPotFileExtractorTests)
if can_run_compilation_tests: if can_run_compilation_tests:
from .commands.compilation import (PoFileTests, PoFileContentsTests, from .commands.compilation import (PoFileTests, PoFileContentsTests,
PercentRenderingTests) PercentRenderingTests)