1
2
3
4
5 import os
6 import sys
7 from fnmatch import fnmatchcase
8 from distutils.util import convert_path
9
10
11
12
13 standard_exclude = ('*.py', '*.pyc', '*~', '.*', '*.bak', '*.swp*')
14 standard_exclude_directories = ('.*', 'CVS', '_darcs', './build',
15 './dist', 'EGG-INFO', '*.egg-info')
16
23 """
24 Return a dictionary suitable for use in ``package_data``
25 in a distutils ``setup.py`` file.
26
27 The dictionary looks like::
28
29 {'package': [files]}
30
31 Where ``files`` is a list of all the files in that package that
32 don't match anything in ``exclude``.
33
34 If ``only_in_packages`` is true, then top-level directories that
35 are not packages won't be included (but directories under packages
36 will).
37
38 Directories matching any pattern in ``exclude_directories`` will
39 be ignored; by default directories with leading ``.``, ``CVS``,
40 and ``_darcs`` will be ignored.
41
42 If ``show_ignored`` is true, then all the files that aren't
43 included in package data are shown on stderr (for debugging
44 purposes).
45
46 Note patterns use wildcards, or can be exact paths (including
47 leading ``./``), and all searching is case-insensitive.
48 """
49
50 out = {}
51 stack = [(convert_path(where), '', package, only_in_packages)]
52 while stack:
53 where, prefix, package, only_in_packages = stack.pop(0)
54 for name in os.listdir(where):
55 fn = os.path.join(where, name)
56 if os.path.isdir(fn):
57 bad_name = False
58 for pattern in exclude_directories:
59 if (fnmatchcase(name, pattern)
60 or fn.lower() == pattern.lower()):
61 bad_name = True
62 if show_ignored:
63 print >> sys.stderr, (
64 "Directory %s ignored by pattern %s"
65 % (fn, pattern))
66 break
67 if bad_name:
68 continue
69 if os.path.isfile(os.path.join(fn, '__init__.py')):
70 if not package:
71 new_package = name
72 else:
73 new_package = package + '.' + name
74 stack.append((fn, '', new_package, False))
75 else:
76 stack.append((fn, prefix + name + '/', package, only_in_packages))
77 elif package or not only_in_packages:
78
79 bad_name = False
80 for pattern in exclude:
81 if (fnmatchcase(name, pattern)
82 or fn.lower() == pattern.lower()):
83 bad_name = True
84 if show_ignored:
85 print >> sys.stderr, (
86 "File %s ignored by pattern %s"
87 % (fn, pattern))
88 break
89 if bad_name:
90 continue
91 out.setdefault(package, []).append(prefix+name)
92 return out
93
94 if __name__ == '__main__':
95 import pprint
96 pprint.pprint(
97 find_package_data(show_ignored=True))
98