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 ``_darcs``, ``./build``, ``.dist``, ``EGG-INFO`` and ``*.egg-info``
41 will be ignored.
42
43 If ``show_ignored`` is true, then all the files that aren't
44 included in package data are shown on stderr (for debugging
45 purposes).
46
47 Note patterns use wildcards, or can be exact paths (including
48 leading ``./``), and all searching is case-insensitive.
49 """
50
51 out = {}
52 stack = [(convert_path(where), '', package, only_in_packages)]
53 while stack:
54 where, prefix, package, only_in_packages = stack.pop(0)
55 for name in os.listdir(where):
56 fn = os.path.join(where, name)
57 if os.path.isdir(fn):
58 bad_name = False
59 for pattern in exclude_directories:
60 if (fnmatchcase(name, pattern)
61 or fn.lower() == pattern.lower()):
62 bad_name = True
63 if show_ignored:
64 print >> sys.stderr, (
65 "Directory %s ignored by pattern %s"
66 % (fn, pattern))
67 break
68 if bad_name:
69 continue
70 if os.path.isfile(os.path.join(fn, '__init__.py')):
71 if not package:
72 new_package = name
73 else:
74 new_package = package + '.' + name
75 stack.append((fn, '', new_package, False))
76 else:
77 stack.append((fn, prefix + name + '/', package, only_in_packages))
78 elif package or not only_in_packages:
79
80 bad_name = False
81 for pattern in exclude:
82 if (fnmatchcase(name, pattern)
83 or fn.lower() == pattern.lower()):
84 bad_name = True
85 if show_ignored:
86 print >> sys.stderr, (
87 "File %s ignored by pattern %s"
88 % (fn, pattern))
89 break
90 if bad_name:
91 continue
92 out.setdefault(package, []).append(prefix+name)
93 return out
94
95 if __name__ == '__main__':
96 import pprint
97 pprint.pprint(
98 find_package_data(show_ignored=True))
99