root/develop/pkg_setup.py

Revision 63, 7.5 kB (checked in by robin, 3 years ago)

sorted out packaging

Line 
1 """pkg_setup: utilities for the build phase of python setup.py scripts
2
3 svn propset svn:externals 'develop http:://svn.wiretooth.com/svn/open/pkg_setup' .
4
5 """
6
7 import sys, os
8 from distutils.util import convert_path
9 from fnmatch import fnmatchcase
10
11 __all__ = '''\
12 find_data get_descriptors_rst oswalk_sources
13 packages_standard_exclude
14 data_standard_exclude data_standard_exclude_directories
15 install_new_module'''.split()
16
17 def get_descriptors_rst(
18     filename,
19     short=':Abstract:',
20     long='',
21     version='',
22     other=[],
23     includeprefix=[],
24     excludeprefix=[]):
25     f = file(filename)
26     seeksections=other[:] # last entry is terminator.
27     if long: seeksections.insert(0,long)
28     if short: seeksections.insert(0,short)
29     if version: seeksections.insert(0,version)
30     lines,section,sectionlines,sections = [],None,[],{}
31     try:
32         for line in f:
33             #line = line.strip()
34             for candidate in seeksections:
35                 if line.startswith(candidate):
36                     if section:
37                         sections[section]=sectionlines
38                         sectionlines=[]
39                     if candidate == seeksections[-1]:
40                         for section, lines in sections.items():
41                             sections[section]=''.join(lines)
42                         short=sections.pop(short,'')
43                         long=sections.pop(long,'')
44                         #version=float(sections.pop(version,'0.0').split()[-1])
45                         version=sections.pop(version,'0.0'
46                             ).strip().split()[-1].strip()
47                         return dict(short=short, long=long, version=version,
48                             other='\n'.join(sections.values()))
49                     section=candidate
50                     break
51             for include,exclude in zip(includeprefix,excludeprefix):
52                 if line.startswith(include):
53                     sectionlines.append(line)
54                     break
55                 elif line.startswith(exclude):
56                     line=None
57                     break
58             line and sectionlines.append(line)
59     finally:
60         f.close()
61     return sections
62 def install_new_module(packagename, basemodulename):
63     """Dynamicaly installs a new package.
64    
65     Note: take care with this one, for example don't pass in __name__ as
66     package name, unless you want to replace your own module right under
67     your feet!"""
68     try:
69         packagemod = sys.modules[packagename]
70     except KeyError:
71         packagemod = new.module(packagename)
72         sys.modules[packagename] = packagemod
73     modulename = '.'.join([packagename, basemodulename])
74     mod = new.module(modulename)
75     # if packagename == __name__ then your probably buggered.
76     setattr(packagemod, basemodulename, mod)
77     sys.modules[modulename] = getattr(packagemod, basemodulename)
78     return mod
79
80
81 def oswalk_sources(basepath, destpath, excludedirs, mkdestdirs=True):
82     absbasepath = os.path.abspath(basepath)   
83     for root, dirs, files in os.walk(basepath):
84         dirs[:]=[d for d in dirs if d not in excludedirs]
85         destroot = os.path.join(destpath, root[len(basepath):])
86         for fn in files:
87             dst = os.path.join(destroot, '', fn)
88             src = os.path.join(root, fn)
89             yield (dst, src, destroot)
90
91
92 # Provided as an attribute, so you can append to these instead
93 # of replicating them:
94 packages_standard_exclude = ('ez_setup',)
95
96 data_standard_exclude = ('setup.cfg', '#*', '*.py', '*.pyc', '*~', '.*',
97     '*.bak', '*.in')
98 data_standard_exclude_directories = ('.*', 'CVS', '_darcs', './build',
99                                 './dist', './ez_setup', 'EGG-INFO', '*.egg-info')
100 def find_data(
101     where='.', package='', package_data=True,
102     exclude=data_standard_exclude,
103     exclude_directories=data_standard_exclude_directories,
104     only_in_packages=False,
105     show_ignored=False):
106     """
107     find your distributions data.
108
109     If package_data is true: Return a dictionary suitable for use in
110     ``package_data`` in a distutils ``setup.py`` file.
111     Otherwise: Return a data_files compatible list of tuples.
112
113     The package data dictionary looks like::
114
115         {'package': [files]}
116
117     Where ``files`` is a list of all the files in that package that
118     don't match anything in ``exclude``.
119
120     The data_files tuple list looks like::
121
122         [('', datadir1),...]
123        
124     Note that egg distributions bundle all data in your egg file. So using
125     pkg_resources, you access you data using paths relative to your egg_base
126     directory. If you are supporting instalation using distutils you should
127     post process this list and convert empty target dirs to the desired data
128     install location for that set of files. see distutils documentation
129     for more information.
130
131     If ``only_in_packages`` is true, the default is false, then top-level
132     directories that are not packages won't be included (but directories under
133     packages will).
134
135     Directories matching any pattern in ``exclude_directories`` will
136     be ignored; by default directories with leading ``.``, ``CVS``,
137     and ``_darcs`` will be ignored.
138
139     If ``show_ignored`` is true, then all the files that aren't
140     included in package data are shown on stderr (for debugging
141     purposes).
142
143     Note patterns use wildcards, or can be exact paths (including
144     leading ``./``), and all searching is case-insensitive.
145     """
146    
147     out = {}
148     stack = [(convert_path(where), '', package, only_in_packages)]
149     while stack:
150         where, prefix, package, only_in_packages = stack.pop(0)
151         for name in os.listdir(where):
152             fn = os.path.join(where, name)
153             if os.path.isdir(fn):
154                 bad_name = False
155                 for pattern in exclude_directories:
156                     if (fnmatchcase(name, pattern)
157                         or fn.lower() == pattern.lower()):
158                         bad_name = True
159                         if show_ignored:
160                             print >> sys.stderr, (
161                                 "Directory %s ignored by pattern %s"
162                                 % (fn, pattern))
163                         break
164                 if bad_name:
165                     continue
166                 if not package:
167                     new_package = name
168                 else:
169                     new_package = package + '.' + name
170                 if os.path.isfile(os.path.join(fn, '__init__.py')):
171                     stack.append((fn, '', new_package, False))
172                 elif not package_data:
173                     stack.append((fn, prefix + name + '/',
174                         new_package, only_in_packages))
175                 else:
176                     stack.append((fn, prefix + name + '/',
177                         package, only_in_packages))
178             elif package or not only_in_packages:
179                 # is a file
180                 bad_name = False
181                 for pattern in exclude:
182                     if (fnmatchcase(name, pattern)
183                         or fn.lower() == pattern.lower()):
184                         bad_name = True
185                         if show_ignored:
186                             print >> sys.stderr, (
187                                 "File %s ignored by pattern %s"
188                                 % (fn, pattern))
189                         break
190                 if bad_name:
191                     continue
192                 out.setdefault(package, []).append(prefix+name)
193     if not package_data:
194         out = [('/'.join(fakepackage.split('.')), datadir)
195                 for fakepackage, datadir in out.items()]
196     return out
Note: See TracBrowser for help on using the browser.