7Class representing the list of files in a distribution.
9Equivalent to distutils.filelist, but fixes some problems.
17from .
import DistlibException
18from .compat
import fsdecode
19from .util
import convert_path
38 """A list of files built by on exploring the filesystem and filtered by
39 applying various patterns to what we find there.
44 Initialise an instance.
46 :param base: The base directory to explore under.
58 """Find all files under the base and set ``allfiles`` to the absolute
59 pathnames of files found.
61 from stat
import S_ISREG, S_ISDIR, S_ISLNK
86 Add a file to the manifest.
88 :param item: The pathname to add. This can be relative to the base.
96 Add a list of files to the manifest.
98 :param items: The pathnames to add. These can be relative to the base.
105 Return sorted files in directory order
113 assert parent
not in (
'',
'/')
116 result = set(self.
files)
126 """Clear all collected files."""
132 Process a directive which either adds some files from ``allfiles`` to
133 ``files``, or removes some files from ``files``.
135 :param directive: The directive to process. This should be in a format
136 compatible with distutils ``MANIFEST.in`` files:
138 http://docs.python.org/distutils/sourcedist.html#commands
150 if action ==
'include':
151 for pattern
in patterns:
155 elif action ==
'exclude':
156 for pattern
in patterns:
162 elif action ==
'global-include':
163 for pattern
in patterns:
166 'anywhere in distribution', pattern)
168 elif action ==
'global-exclude':
169 for pattern
in patterns:
176 elif action ==
'recursive-include':
177 for pattern
in patterns:
180 'under directory %r', pattern, thedir)
182 elif action ==
'recursive-exclude':
183 for pattern
in patterns:
190 elif action ==
'graft':
195 elif action ==
'prune':
198 'matching %r', dirpattern)
202 raise DistlibException(
203 'invalid action %r' % action)
211 Validate a directive.
212 :param directive: The directive to validate.
213 :return: A tuple of action, patterns, thedir, dir_patterns
216 if len(words) == 1
and words[0]
not in (
'include',
'exclude',
226 patterns = thedir = dir_pattern =
None
228 if action
in (
'include',
'exclude',
229 'global-include',
'global-exclude'):
231 raise DistlibException(
232 '%r expects <pattern1> <pattern2> ...' % action)
234 patterns = [convert_path(word)
for word
in words[1:]]
236 elif action
in (
'recursive-include',
'recursive-exclude'):
238 raise DistlibException(
239 '%r expects <dir> <pattern1> <pattern2> ...' % action)
241 thedir = convert_path(words[1])
242 patterns = [convert_path(word)
for word
in words[2:]]
244 elif action
in (
'graft',
'prune'):
246 raise DistlibException(
247 '%r expects a single <dir_pattern>' % action)
249 dir_pattern = convert_path(words[1])
252 raise DistlibException(
'unknown action %r' % action)
254 return action, patterns, thedir, dir_pattern
258 """Select strings (presumably filenames) from 'self.files' that
259 match 'pattern', a Unix-style wildcard (glob) pattern.
261 Patterns are not quite the same as implemented by the 'fnmatch'
262 module: '*' and '?' match non-special characters, where "special"
263 is platform-dependent: slash on Unix; colon, slash, and backslash on
264 DOS/Windows; and colon on Mac OS.
266 If 'anchor' is true (the default), then the pattern match is more
267 stringent: "*.py" will match "foo.py" but not "foo/bar.py". If
268 'anchor' is false, both of these will match.
270 If 'prefix' is supplied, then only filenames starting with 'prefix'
271 (itself a pattern) and ending with 'pattern', with anything in between
272 them, will match. 'anchor' is ignored in this case.
274 If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and
275 'pattern' is assumed to be either a string containing a regex or a
276 regex object -- no translation is done, the regex is just compiled
279 Selected strings will be added to self.files.
281 Return True if files are found.
299 """Remove strings (presumably filenames) from 'files' that match
302 Other parameters are the same as for 'include_pattern()', above.
303 The list 'self.files' is modified in place. Return True if files are
306 This API is public to allow e.g. exclusion of SCM subdirs, e.g. when
307 packaging source distributions
311 for f
in list(self.
files):
319 """Translate a shell-like wildcard pattern to a compiled regular
322 Return the compiled regex. If 'is_regex' true,
323 then 'pattern' is directly compiled to a regex (if it's a string)
324 or just returned as-is (assumes it's a regex object).
332 if _PYTHON_VERSION > (3, 2):
334 start, _, end = self.
_glob_to_re(
'_').partition(
'_')
338 if _PYTHON_VERSION > (3, 2):
344 if prefix
is not None:
346 if _PYTHON_VERSION <= (3, 2):
352 prefix_re = prefix_re[
len(start):
len(prefix_re) -
len(end)]
356 if _PYTHON_VERSION <= (3, 2):
357 pattern_re =
'^' + base +
sep.join((prefix_re,
360 pattern_re = pattern_re[
len(start):
len(pattern_re) -
len(end)]
361 pattern_re =
r'%s%s%s%s.*%s%s' % (start, base, prefix_re, sep,
365 if _PYTHON_VERSION <= (3, 2):
366 pattern_re =
'^' + base + pattern_re
368 pattern_re =
r'%s%s%s' % (start, base, pattern_re[
len(start):])
373 """Translate a shell-like glob pattern to a regular expression.
375 Return a string containing the regex. Differs from
376 'fnmatch.translate()' in that '*' does not match "special characters"
377 (which are platform-specific).
391 escaped =
r'\1[^%s]' % sep
392 pattern_re =
re.sub(
r'((?<!\\)(\\\\)*)\.', escaped, pattern_re)
process_directive(self, directive)
_include_pattern(self, pattern, anchor=True, prefix=None, is_regex=False)
_translate_pattern(self, pattern, anchor=True, prefix=None, is_regex=False)
_glob_to_re(self, pattern)
_exclude_pattern(self, pattern, anchor=True, prefix=None, is_regex=False)
sorted(self, wantdirs=False)
_parse_directive(self, directive)
__init__(self, base=None)