Refs #26940 -- Re-allowed makemessages without settings

Thanks Tim Graham for the review.
This commit is contained in:
Claude Paroz 2016-09-29 16:13:10 +02:00
parent 63bf615d5e
commit fa2f55cfd5
6 changed files with 37 additions and 12 deletions

View File

@ -11,6 +11,7 @@ from itertools import dropwhile
import django import django
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.files.temp import NamedTemporaryFile from django.core.files.temp import NamedTemporaryFile
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from django.core.management.utils import ( from django.core.management.utils import (
@ -103,13 +104,14 @@ class BuildFile(object):
if not self.is_templatized: if not self.is_templatized:
return return
with io.open(self.path, 'r', encoding=settings.FILE_CHARSET) as fp: encoding = settings.FILE_CHARSET if self.command.settings_available else 'utf-8'
with io.open(self.path, 'r', encoding=encoding) as fp:
src_data = fp.read() src_data = fp.read()
if self.domain == 'djangojs': if self.domain == 'djangojs':
content = prepare_js_for_gettext(src_data) content = prepare_js_for_gettext(src_data)
elif self.domain == 'django': elif self.domain == 'django':
content = templatize(src_data, self.path[2:]) content = templatize(src_data, origin=self.path[2:], charset=encoding)
with io.open(self.work_path, 'w', encoding='utf-8') as fp: with io.open(self.work_path, 'w', encoding='utf-8') as fp:
fp.write(content) fp.write(content)
@ -325,7 +327,8 @@ class Command(BaseCommand):
self.default_locale_path = self.locale_paths[0] self.default_locale_path = self.locale_paths[0]
self.invoked_for_django = True self.invoked_for_django = True
else: else:
self.locale_paths.extend(settings.LOCALE_PATHS) if self.settings_available:
self.locale_paths.extend(settings.LOCALE_PATHS)
# Allow to run makemessages inside an app dir # Allow to run makemessages inside an app dir
if os.path.isdir('locale'): if os.path.isdir('locale'):
self.locale_paths.append(os.path.abspath('locale')) self.locale_paths.append(os.path.abspath('locale'))
@ -377,6 +380,16 @@ class Command(BaseCommand):
else: else:
raise CommandError("Unable to get gettext version. Is it installed?") raise CommandError("Unable to get gettext version. Is it installed?")
@cached_property
def settings_available(self):
try:
settings.LOCALE_PATHS
except ImproperlyConfigured:
if self.verbosity > 1:
self.stderr.write("Running without configured settings.")
return False
return True
def build_potfiles(self): def build_potfiles(self):
""" """
Build pot files and apply msguniq to them. Build pot files and apply msguniq to them.
@ -438,7 +451,9 @@ class Command(BaseCommand):
norm_patterns.append(p) norm_patterns.append(p)
all_files = [] all_files = []
ignored_roots = [os.path.normpath(p) for p in (settings.MEDIA_ROOT, settings.STATIC_ROOT) if p] ignored_roots = []
if self.settings_available:
ignored_roots = [os.path.normpath(p) for p in (settings.MEDIA_ROOT, settings.STATIC_ROOT) if p]
for dirpath, dirnames, filenames in os.walk(root, topdown=True, followlinks=self.symlinks): for dirpath, dirnames, filenames in os.walk(root, topdown=True, followlinks=self.symlinks):
for dirname in dirnames[:]: for dirname in dirnames[:]:
if (is_ignored(os.path.normpath(os.path.join(dirpath, dirname)), norm_patterns) or if (is_ignored(os.path.normpath(os.path.join(dirpath, dirname)), norm_patterns) or

View File

@ -212,9 +212,9 @@ def get_language_from_path(path):
return _trans.get_language_from_path(path) return _trans.get_language_from_path(path)
def templatize(src, origin=None): def templatize(src, **kwargs):
from .template import templatize from .template import templatize
return templatize(src, origin) return templatize(src, **kwargs)
def deactivate_all(): def deactivate_all():

View File

@ -3,7 +3,6 @@ from __future__ import unicode_literals
import re import re
import warnings import warnings
from django.conf import settings
from django.template.base import ( from django.template.base import (
TOKEN_BLOCK, TOKEN_COMMENT, TOKEN_TEXT, TOKEN_VAR, TRANSLATOR_COMMENT_MARK, TOKEN_BLOCK, TOKEN_COMMENT, TOKEN_TEXT, TOKEN_VAR, TRANSLATOR_COMMENT_MARK,
Lexer, Lexer,
@ -40,13 +39,13 @@ plural_re = re.compile(r"""^\s*plural$""")
constant_re = re.compile(r"""_\(((?:".*?")|(?:'.*?'))\)""") constant_re = re.compile(r"""_\(((?:".*?")|(?:'.*?'))\)""")
def templatize(src, origin=None): def templatize(src, origin=None, charset='utf-8'):
""" """
Turn a Django template into something that is understood by xgettext. It Turn a Django template into something that is understood by xgettext. It
does so by translating the Django translation tags into standard gettext does so by translating the Django translation tags into standard gettext
function invocations. function invocations.
""" """
src = force_text(src, settings.FILE_CHARSET) src = force_text(src, charset)
out = StringIO('') out = StringIO('')
message_context = None message_context = None
intrans = False intrans = False

View File

@ -564,6 +564,11 @@ directory. After making changes to the messages files you need to compile them
with :djadmin:`compilemessages` for use with the builtin gettext support. See with :djadmin:`compilemessages` for use with the builtin gettext support. See
the :ref:`i18n documentation <how-to-create-language-files>` for details. the :ref:`i18n documentation <how-to-create-language-files>` for details.
This command doesn't require configured settings. However, when settings aren't
configured, the command can't ignore the :setting:`MEDIA_ROOT` and
:setting:`STATIC_ROOT` directories or include :setting:`LOCALE_PATHS`. It will
also write files in UTF-8 rather than in :setting:`FILE_CHARSET`.
.. django-admin-option:: --all, -a .. django-admin-option:: --all, -a
Updates the message files for all available languages. Updates the message files for all available languages.

View File

@ -515,9 +515,6 @@ Miscellaneous
called a second time before calling called a second time before calling
:func:`~django.test.utils.teardown_test_environment`. :func:`~django.test.utils.teardown_test_environment`.
* The :djadmin:`makemessages` command now requires configured settings, like
most other commands.
* The undocumented ``DateTimeAwareJSONEncoder`` alias for * The undocumented ``DateTimeAwareJSONEncoder`` alias for
:class:`~django.core.serializers.json.DjangoJSONEncoder` (renamed in Django :class:`~django.core.serializers.json.DjangoJSONEncoder` (renamed in Django
1.0) is removed. 1.0) is removed.

View File

@ -9,6 +9,8 @@ import time
import warnings import warnings
from unittest import skipUnless from unittest import skipUnless
from admin_scripts.tests import AdminScriptTestCase
from django.core import management from django.core import management
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line
from django.core.management.base import CommandError from django.core.management.base import CommandError
@ -713,3 +715,10 @@ class CustomLayoutExtractionTests(ExtractorTests):
with open(app_de_locale, 'r') as fp: with open(app_de_locale, 'r') as fp:
po_contents = force_text(fp.read()) po_contents = force_text(fp.read())
self.assertMsgId('This app has a locale directory', po_contents) self.assertMsgId('This app has a locale directory', po_contents)
class NoSettingsExtractionTests(AdminScriptTestCase):
def test_makemessages_no_settings(self):
out, err = self.run_django_admin(['makemessages', '-l', 'en', '-v', '0'])
self.assertNoOutput(err)
self.assertNoOutput(out)