Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #7050 - Allow the makemessages command to optionally ignore pat…

…hs when examining source code and templates for translation strings.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12444 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit eb26c9686bc1f9b9b5bcd10e861fc7d055845209 1 parent fef575a
Jannis Leidel authored February 16, 2010
42  django/core/management/commands/makemessages.py
... ...
@@ -1,7 +1,8 @@
1  
-import re
  1
+import fnmatch
  2
+import glob
2 3
 import os
  4
+import re
3 5
 import sys
4  
-import glob
5 6
 from itertools import dropwhile
6 7
 from optparse import make_option
7 8
 from subprocess import PIPE, Popen
@@ -56,18 +57,33 @@ def walk(root, topdown=True, onerror=None, followlinks=False):
56 57
                     for link_dirpath, link_dirnames, link_filenames in walk(p):
57 58
                         yield (link_dirpath, link_dirnames, link_filenames)
58 59
 
59  
-def find_files(root, symlinks=False):
  60
+def is_ignored(path, ignore_patterns):
  61
+    """
  62
+    Helper function to check if the given path should be ignored or not.
  63
+    """
  64
+    for pattern in ignore_patterns:
  65
+        if fnmatch.fnmatchcase(path, pattern):
  66
+            return True
  67
+    return False
  68
+
  69
+def find_files(root, ignore_patterns, verbosity, symlinks=False):
60 70
     """
61 71
     Helper function to get all files in the given root.
62 72
     """
63 73
     all_files = []
64 74
     for (dirpath, dirnames, filenames) in walk(".", followlinks=symlinks):
65  
-        all_files.extend([(dirpath, f) for f in filenames])
  75
+        for f in filenames:
  76
+            norm_filepath = os.path.normpath(os.path.join(dirpath, f))
  77
+            if is_ignored(norm_filepath, ignore_patterns):
  78
+                if verbosity > 1:
  79
+                    sys.stdout.write('ignoring file %s in %s\n' % (f, dirpath))
  80
+            else:
  81
+                all_files.extend([(dirpath, f)])
66 82
     all_files.sort()
67 83
     return all_files
68 84
 
69 85
 def make_messages(locale=None, domain='django', verbosity='1', all=False,
70  
-        extensions=None, symlinks=False):
  86
+        extensions=None, symlinks=False, ignore_patterns=[]):
71 87
     """
72 88
     Uses the locale directory from the Django SVN tree or an application/
73 89
     project to process all
@@ -127,7 +143,7 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,
127 143
         if os.path.exists(potfile):
128 144
             os.unlink(potfile)
129 145
 
130  
-        for dirpath, file in find_files(".", symlinks=symlinks):
  146
+        for dirpath, file in find_files(".", ignore_patterns, verbosity, symlinks=symlinks):
131 147
             file_base, file_ext = os.path.splitext(file)
132 148
             if domain == 'djangojs' and file_ext in extensions:
133 149
                 if verbosity > 1:
@@ -204,11 +220,15 @@ class Command(BaseCommand):
204 220
             help='The domain of the message files (default: "django").'),
205 221
         make_option('--all', '-a', action='store_true', dest='all',
206 222
             default=False, help='Reexamines all source code and templates for new translation strings and updates all message files for all available languages.'),
207  
-        make_option('--symlinks', '-s', action='store_true', dest='symlinks',
208  
-            default=False, help='Follows symlinks to directories when examining source code and templates for translation strings.'),
209 223
         make_option('--extension', '-e', dest='extensions',
210 224
             help='The file extension(s) to examine (default: ".html", separate multiple extensions with commas, or use -e multiple times)',
211 225
             action='append'),
  226
+        make_option('--symlinks', '-s', action='store_true', dest='symlinks',
  227
+            default=False, help='Follows symlinks to directories when examining source code and templates for translation strings.'),
  228
+        make_option('--ignore', '-i', action='append', dest='ignore_patterns',
  229
+            default=[], metavar='PATTERN', help='Ignore files or directories matching this glob-style pattern. Use multiple times to ignore more.'),
  230
+        make_option('--no-default-ignore', action='store_false', dest='use_default_ignore_patterns',
  231
+            default=True, help="Don't ignore the common glob-style patterns 'CVS', '.*' and '*~'."),
212 232
     )
213 233
     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 file in the conf/locale (in the django tree) or locale (for project and application) directory."
214 234
 
@@ -225,6 +245,10 @@ def handle(self, *args, **options):
225 245
         process_all = options.get('all')
226 246
         extensions = options.get('extensions')
227 247
         symlinks = options.get('symlinks')
  248
+        ignore_patterns = options.get('ignore_patterns')
  249
+        if options.get('use_default_ignore_patterns'):
  250
+            ignore_patterns += ['CVS', '.*', '*~']
  251
+        ignore_patterns = list(set(ignore_patterns))
228 252
 
229 253
         if domain == 'djangojs':
230 254
             extensions = handle_extensions(extensions or ['js'])
@@ -234,4 +258,4 @@ def handle(self, *args, **options):
234 258
         if verbosity > 1:
235 259
             sys.stdout.write('examining files with the extensions: %s\n' % get_text_list(list(extensions), 'and'))
236 260
 
237  
-        make_messages(locale, domain, verbosity, process_all, extensions, symlinks)
  261
+        make_messages(locale, domain, verbosity, process_all, extensions, symlinks, ignore_patterns)
9  docs/man/django-admin.1
@@ -46,7 +46,7 @@ Executes
46 46
 .B sqlall
47 47
 for the given app(s) in the current database.
48 48
 .TP
49  
-.BI "makemessages [" "\-\-locale=LOCALE" "] [" "\-\-domain=DOMAIN" "] [" "\-\-extension=EXTENSION" "] [" "\-\-all" "] [" "\-\-symlinks" "]"
  49
+.BI "makemessages [" "\-\-locale=LOCALE" "] [" "\-\-domain=DOMAIN" "] [" "\-\-extension=EXTENSION" "] [" "\-\-all" "] [" "\-\-symlinks" "] [" "\-\-ignore=PATTERN" "] [" "\-\-no\-default\-ignore" "]"
50 50
 Runs over the entire source tree of the current directory and pulls out all
51 51
 strings marked for translation. It creates (or updates) a message file in the
52 52
 conf/locale (in the django tree) or locale (for project and application) directory.
@@ -159,6 +159,13 @@ extensions with commas, or use -e multiple times).
159 159
 Follows symlinks to directories when examining source code and templates for
160 160
 translation strings.
161 161
 .TP
  162
+.I \-e, \-\-ignore=PATTERN
  163
+Ignore files or directories matching this glob-style pattern. Use multiple
  164
+times to ignore more.
  165
+.TP
  166
+.I \-e, \-\-no\-default\-ignore
  167
+Don't ignore the common private glob-style patterns 'CVS', '.*' and '*~'.
  168
+.TP
162 169
 .I \-a, \-\-all
163 170
 Process all available locales when using makemessages..SH "ENVIRONMENT"
164 171
 .TP
18  docs/ref/django-admin.txt
@@ -483,6 +483,24 @@ Example usage::
483 483
 
484 484
     django-admin.py makemessages --locale=de --symlinks
485 485
 
  486
+.. django-admin-option:: --ignore
  487
+
  488
+Use the ``--ignore`` or ``-i`` option to ignore files or directories matching
  489
+the given `glob-style pattern`_. Use multiple times to ignore more.
  490
+
  491
+These patterns are used by default: ``'CVS'``, ``'.*'``, ``'*~'``
  492
+
  493
+Example usage::
  494
+
  495
+    django-admin.py makemessages --locale=en_US --ignore=apps/* --ignore=secret/*.html
  496
+
  497
+.. _`glob-style pattern`: http://docs.python.org/library/glob.html
  498
+
  499
+.. django-admin-option:: --no-default-ignore
  500
+
  501
+Use the ``--no-default-ignore`` option to disable the default values of
  502
+:djadminopt:`--ignore`.
  503
+
486 504
 reset <appname appname ...>
487 505
 ---------------------------
488 506
 
2  tests/regressiontests/makemessages/ignore_dir/ignored.html
... ...
@@ -0,0 +1,2 @@
  1
+{% load i18n %}
  2
+{% trans "This should be ignored." %}
17  tests/regressiontests/makemessages/tests.py
@@ -28,6 +28,9 @@ def tearDown(self):
28 28
     def assertMsgId(self, msgid, s):
29 29
         return self.assert_(re.search('^msgid "%s"' % msgid, s, re.MULTILINE))
30 30
 
  31
+    def assertNotMsgId(self, msgid, s):
  32
+        return self.assert_(not re.search('^msgid "%s"' % msgid, s, re.MULTILINE))
  33
+
31 34
 
32 35
 class JavascriptExtractorTests(ExtractorTests):
33 36
 
@@ -41,6 +44,20 @@ def test_javascript_literals(self):
41 44
         self.assertMsgId('This literal should be included.', po_contents)
42 45
         self.assertMsgId('This one as well.', po_contents)
43 46
 
  47
+
  48
+class IgnoredExtractorTests(ExtractorTests):
  49
+
  50
+    PO_FILE='locale/%s/LC_MESSAGES/django.po' % LOCALE
  51
+
  52
+    def test_ignore_option(self):
  53
+        os.chdir(self.test_dir)
  54
+        management.call_command('makemessages', locale=LOCALE, verbosity=0, ignore_patterns=['ignore_dir/*'])
  55
+        self.assert_(os.path.exists(self.PO_FILE))
  56
+        po_contents = open(self.PO_FILE, 'r').read()
  57
+        self.assertMsgId('This literal should be included.', po_contents)
  58
+        self.assertNotMsgId('This should be ignored.', po_contents)
  59
+
  60
+
44 61
 class SymlinkExtractorTests(ExtractorTests):
45 62
 
46 63
     PO_FILE='locale/%s/LC_MESSAGES/django.po' % LOCALE

0 notes on commit eb26c96

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