Georg Brandl committed 7f85b43

Apply static path exclusion patterns again.

Refactor exclusion stuff a bit, so that matchers only have to be compiled once.

Comments (0)

Files changed (4)


 from sphinx import package_dir, __version__
 from sphinx.util import SEP, os_path, relative_uri, ensuredir, \
-    movefile, ustrftime, copy_static_entry, copyfile
+    movefile, ustrftime, copy_static_entry, copyfile, compile_matchers
 from sphinx.errors import SphinxError
 from import js_index
 from sphinx.theming import Theme
                             for themepath in self.theme.get_dirchain()[::-1]]
             for entry in themeentries:
                 copy_static_entry(entry, path.join(self.outdir, '_static'),
-                                  self, self.globalcontext, exclude=False)
+                                  self, self.globalcontext)
         # then, copy over all user-supplied static files
         staticentries = [path.join(self.confdir, spath)
                          for spath in self.config.html_static_path]
+        matchers = compile_matchers(
+            self.config.exclude_patterns +
+            ['**/' + d for d in self.config.exclude_dirnames]
+        )
         for entry in staticentries:
             if not path.exists(entry):
                 self.warn('html_static_path entry %r does not exist' % entry)
-            copy_static_entry(entry, path.join(self.outdir, '_static'),
-                              self, self.globalcontext)
+            copy_static_entry(entry, path.join(self.outdir, '_static'), self,
+                              self.globalcontext, exclude_matchers=matchers)
         # last, copy logo file (handled differently XXX why?)
         if self.config.html_logo:
             logobase = path.basename(self.config.html_logo)


 from sphinx import addnodes
 from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \
-     docname_join, FilenameUniqDict, url_re, clean_astext
+     docname_join, FilenameUniqDict, url_re, clean_astext, compile_matchers
 from sphinx.errors import SphinxError
 from sphinx.directives import additional_xref_types
         Find all source files in the source dir and put them in self.found_docs.
-        patterns = config.exclude_patterns[:]
-        patterns += config.exclude_trees
-        patterns += [d + config.source_suffix for d in config.unused_docs]
-        patterns += ['**/' + d for d in config.exclude_dirnames]
-        patterns += ['**/_sources']
+        matchers = compile_matchers(
+            config.exclude_patterns[:] +
+            config.exclude_trees +
+            [d + config.source_suffix for d in config.unused_docs] +
+            ['**/' + d for d in config.exclude_dirnames] +
+            ['**/_sources']
+        )
         self.found_docs = set(get_matching_docs(
-            self.srcdir, config.source_suffix, exclude_patterns=patterns))
+            self.srcdir, config.source_suffix, exclude_matchers=matchers))
     def get_outdated_files(self, config_changed):


 from os import path
 import docutils
+from docutils.utils import relative_path
 import sphinx
 # Errnos that we need.
         yield top, dirs, nondirs
-def get_matching_files(dirname, exclude_patterns=()):
+def get_matching_files(dirname, exclude_matchers=()):
     Get all file names in a directory, recursively.
-    Exclude files and dirs matching a pattern in *exclude_patterns*.
+    Exclude files and dirs matching some matcher in *exclude_matchers*.
     # dirname is a normalized absolute path.
     dirname = path.normpath(path.abspath(dirname))
     dirlen = len(dirname) + 1    # exclude final os.path.sep
-    matchers = [re.compile(_translate_pattern(pat)).match
-                for pat in exclude_patterns]
     for root, dirs, files in walk(dirname, followlinks=True):
         relativeroot = root[dirlen:]
                           for dn in dirs)
         qfiles = enumerate(path.join(relativeroot, fn).replace(os.path.sep, SEP)
                            for fn in files)
-        for matcher in matchers:
+        for matcher in exclude_matchers:
             qdirs = [entry for entry in qdirs if not matcher(entry[1])]
             qfiles = [entry for entry in qfiles if not matcher(entry[1])]
             yield filename
-def get_matching_docs(dirname, suffix, exclude_patterns=()):
+def get_matching_docs(dirname, suffix, exclude_matchers=()):
     Get all file names (without suffix) matching a suffix in a
     directory, recursively.
     Exclude files and dirs matching a pattern in *exclude_patterns*.
     suffixpattern = '*' + suffix
-    for filename in get_matching_files(dirname, exclude_patterns):
+    for filename in get_matching_files(dirname, exclude_matchers):
         if not fnmatch.fnmatch(filename, suffixpattern):
         yield filename[:-len(suffix)]
             res += re.escape(c)
     return res + '$'
+def compile_matchers(patterns):
+    return [re.compile(_translate_pattern(pat)).match for pat in patterns]
 _pat_cache = {}
 def copy_static_entry(source, targetdir, builder, context={},
-                      exclude=True, level=0):
-    # XXX: exclusion
+                      exclude_matchers=(), level=0):
+    if exclude_matchers:
+        relpath = relative_path(builder.srcdir, source)
+        for matcher in exclude_matchers:
+            if matcher(relpath):
+                return
     if path.isfile(source):
         target = path.join(targetdir, path.basename(source))
         if source.lower().endswith('_t') and builder.templates:
                 if entry.startswith('.'):
                 copy_static_entry(path.join(source, entry), targetdir,
-                                  builder, context, level=1)
+                                  builder, context, level=1,
+                                  exclude_matchers=exclude_matchers)
             target = path.join(targetdir, path.basename(source))
             if path.exists(target):


     assert (staticdir / 'templated.css').isfile()
     assert (staticdir / 'templated.css').text().splitlines()[1] == __version__
     # a file from _static, but matches exclude_patterns
-    ##assert not (staticdir / 'excluded.css').exists()
+    assert not (staticdir / 'excluded.css').exists()
 @gen_with_app(buildername='html', warning=html_warnfile, cleanenv=True,
               confoverrides={'html_context.hckey_co': 'hcval_co'},
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.