summaryrefslogtreecommitdiff
path: root/sphinx/util
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2010-01-07 21:41:03 +0100
committerGeorg Brandl <georg@python.org>2010-01-07 21:41:03 +0100
commit4f2ab257185be851cd2c57f636ce990232bc1bb9 (patch)
tree6bdd77acf8c3695f3cba5e0e80f13dfc1d8612cc /sphinx/util
parent51261adf4a87e8e70838fd59fe51b031147a0d5a (diff)
parent0483cc8635b8968643afa985fb656a450ffe41bf (diff)
downloadsphinx-4f2ab257185be851cd2c57f636ce990232bc1bb9.tar.gz
merge with trunk (not working perfectly yet)
Diffstat (limited to 'sphinx/util')
-rw-r--r--sphinx/util/__init__.py108
1 files changed, 75 insertions, 33 deletions
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index b7f756fc..248b0ce2 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -12,7 +12,6 @@
import os
import re
import sys
-import stat
import time
import errno
import types
@@ -25,6 +24,7 @@ from os import path
import docutils
from docutils import nodes
+from docutils.utils import relative_path
import sphinx
@@ -103,38 +103,45 @@ def walk(top, topdown=True, followlinks=False):
yield top, dirs, nondirs
-def get_matching_docs(dirname, suffix, exclude_docs=(), exclude_dirs=(),
- exclude_trees=(), exclude_dirnames=()):
+def get_matching_files(dirname, exclude_matchers=()):
"""
- Get all file names (without suffix) matching a suffix in a
- directory, recursively.
+ Get all file names in a directory, recursively.
- Exclude docs in *exclude_docs*, exclude dirs in *exclude_dirs*,
- prune dirs in *exclude_trees*, prune dirnames in *exclude_dirnames*.
+ Exclude files and dirs matching some matcher in *exclude_matchers*.
"""
- pattern = '*' + suffix
# dirname is a normalized absolute path.
dirname = path.normpath(path.abspath(dirname))
- dirlen = len(dirname) + 1 # exclude slash
+ dirlen = len(dirname) + 1 # exclude final os.path.sep
+
for root, dirs, files in walk(dirname, followlinks=True):
- if root[dirlen:] in exclude_dirs:
- continue
- if root[dirlen:] in exclude_trees:
- del dirs[:]
+ relativeroot = root[dirlen:]
+
+ qdirs = enumerate(path.join(relativeroot, dn).replace(os.path.sep, SEP)
+ for dn in dirs)
+ qfiles = enumerate(path.join(relativeroot, fn).replace(os.path.sep, SEP)
+ for fn in files)
+ 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])]
+
+ dirs[:] = sorted(dirs[i] for (i, _) in qdirs)
+
+ for i, filename in sorted(qfiles):
+ yield filename
+
+
+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_matchers):
+ if not fnmatch.fnmatch(filename, suffixpattern):
continue
- dirs.sort()
- files.sort()
- for prunedir in exclude_dirnames:
- if prunedir in dirs:
- dirs.remove(prunedir)
- for sfile in files:
- if not fnmatch.fnmatch(sfile, pattern):
- continue
- qualified_name = path.join(root[dirlen:], sfile[:-len(suffix)])
- qualified_name = qualified_name.replace(os.path.sep, SEP)
- if qualified_name in exclude_docs:
- continue
- yield qualified_name
+ yield filename[:-len(suffix)]
def mtimes_of_files(dirnames, suffix):
@@ -272,9 +279,20 @@ def _translate_pattern(pat):
res += re.escape(c)
return res + '$'
+def compile_matchers(patterns):
+ return [re.compile(_translate_pattern(pat)).match for pat in patterns]
+
_pat_cache = {}
+def patmatch(name, pat):
+ """
+ Return if name matches pat. Adapted from fnmatch module.
+ """
+ if pat not in _pat_cache:
+ _pat_cache[pat] = re.compile(_translate_pattern(pat))
+ return _pat_cache[pat].match(name)
+
def patfilter(names, pat):
"""
Return the subset of the list NAMES that match PAT.
@@ -424,9 +442,16 @@ def copyfile(source, dest):
pass
-def copy_static_entry(source, target, builder, context={}):
+def copy_static_entry(source, targetdir, builder, context={},
+ 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):
- if source.lower().endswith('_t'):
+ target = path.join(targetdir, path.basename(source))
+ if source.lower().endswith('_t') and builder.templates:
# templated!
fsrc = open(source, 'rb')
fdst = open(target[:-2], 'wb')
@@ -436,11 +461,18 @@ def copy_static_entry(source, target, builder, context={}):
else:
copyfile(source, target)
elif path.isdir(source):
- if source in builder.config.exclude_dirnames:
- return
- if path.exists(target):
- shutil.rmtree(target)
- shutil.copytree(source, target)
+ if level == 0:
+ for entry in os.listdir(source):
+ if entry.startswith('.'):
+ continue
+ copy_static_entry(path.join(source, entry), targetdir,
+ builder, context, level=1,
+ exclude_matchers=exclude_matchers)
+ else:
+ target = path.join(targetdir, path.basename(source))
+ if path.exists(target):
+ shutil.rmtree(target)
+ shutil.copytree(source, target)
def clean_astext(node):
@@ -473,6 +505,16 @@ def make_refnode(builder, fromdocname, todocname, targetid, child, title=None):
return node
+try:
+ any = any
+except NameError:
+ def any(gen):
+ for i in gen:
+ if i:
+ return True
+ return False
+
+
# monkey-patch Node.traverse to get more speed
# traverse() is called so many times during a build that it saves
# on average 20-25% overall build time!