root/asynwsgi/trunk/pkg_info.py

Revision 384, 5.2 kB (checked in by robin, 2 years ago)

--

  • Property svn:eol-style set to native
Line 
1 PKG_INFO_BASENAME='pkg-info.rst'
2 PKG_INFO_FN=None
3 PKG_INFO=None
4 """python setup.py / python .egg distribution boiler plate utilities
5
6 For reasons that should be obvious this can not be in its own package. Some
7 exmples of use, assuming you place a copy of this file allong side your
8 setup.py and use pkg-info.rst for your build meta information.
9
10 A setup.py that gets its release meta data from a .rst format plain text file.
11
12 execfile('pkg_info.py', globals())
13 setup(
14     name=PKG_INFO['Name'][0],
15     version=PKG_INFO['Version'][0],
16     provides=PKG_INFO.get('Provides',PKG_INFO['Name'])[0],
17     install_requires=PKG_INFO.get('Requires',[]),
18     description=PKG_INFO['Summary'][0],
19     license=PKG_INFO['License'][0],
20     author=PKG_INFO['Author'][0],
21     author_email=PKG_INFO['Author-email'][0],
22     package_dir = {'':'lib'},
23     packages = find_packages('lib', exclude=(
24         'ez_setup','develop', '*.tests','*.tests.*','tests.*', 'tests'))
25 )
26
27 Activation of a distribution in a particular source tree in preference to
28 an existing install (or python setup.py develop install) with the same name
29 and "better" version::
30
31 pkg_info_py_fn = join(
32         dirname(dirname(abspath(normpath(expanduser(__file__))))),
33         'pkg_info.py'
34         )
35 if isfile(pkg_info_py_fn):
36     ns = globals().copy()
37     ns.update(dict(
38         __file__=pkg_info_py_fn,
39         __use_this_source_version__=True)
40         )
41     execfile(pkg_info_py_fn, ns)
42
43 # go ahead with normal application & dependent imports
44
45 """
46
47 def get_info(data=None, fn=None, fileobj=None):
48     import re
49     info={}
50     data = data or fn and file(fn).read() or fileobj and fileobj.read()
51     for k,v,_ in re.findall(
52         r'(?ims)^:?(?P<key>[a-z][\w\-_ ]*):\s*'
53          '(?P<value>.*?'
54          '(?=(\Z|\n^:?[a-z][\w\-_ ]*:)))',
55          data):
56         info.setdefault(k,[]).append(v)
57     return info
58
59 def read_info(relativeto=__file__, fn=PKG_INFO_BASENAME):
60     from os.path import expanduser, join, abspath, normpath, dirname
61     from os.path import isfile, isdir
62     relativeto=abspath(normpath(expanduser(relativeto)))
63     if isfile(relativeto):
64         relativeto=dirname(relativeto)
65     assert isdir(relativeto)
66     pkg_info_fn=join(relativeto, fn)
67     pkg_info=get_info(fn=pkg_info_fn)
68     return pkg_info_fn, pkg_info
69 try:
70     PKG_INFO_FN, PKG_INFO = read_info()
71 except (IOError, OSError):
72     from traceback import print_exc
73     print_exc()
74
75
76 def use_source_dist(project_name, distdir, ws=None, search_path=None):
77     from os.path import isdir
78     from operator import itemgetter
79     assert isdir(distdir), '"%s" is not a directory' % distdir
80     import pkg_resources
81     if ws is None:
82         ws = pkg_resources.working_set
83     if search_path is None:
84         search_path = sys.path
85     pruned = remove_projects(ws, search_path,
86             pkg_resources.safe_name(project_name)
87             )
88     if pruned:
89         print 'Pruned: %s' % ', '.join(map(itemgetter(0), pruned))
90     else:
91         print 'No potentialy conflicting versions exist for "%s"' % project_name
92
93     ws.add_entry(distdir)
94     dist = pkg_resources.get_distribution(project_name)
95     assert dist
96     print 'added:', dist.project_name, dist.location
97
98
99 def yield_dist_entries(ws):
100     seen = {}
101     for item in ws.entries:
102         for key in ws.entry_keys[item]:
103             if key not in seen:
104                 seen[key]=1
105                 yield item, key, ws.by_key[key]
106
107
108 def remove_projects(ws=None, search_path=None, *project_names):
109     """Explicitly remove all named projects from the working set.
110
111     With a normal setuptools environment it is dificult to have *both*
112     a python setup.py develop/install of a project and an arbitrary non
113     installed development source tree side by side.
114
115     In the development source tree, to force use of the python modules in
116     that tree, first call this function to remove all 'normal' installs
117     from both sys.path and pkg_resources.working_set
118
119     """
120     import pkg_resources
121
122     if ws is None:
123         ws = pkg_resources.working_set
124     if search_path is None:
125         search_path = sys.path
126     project_names = set(map(pkg_resources.safe_name, project_names))
127     seen=set([])
128     entry_prune = []
129     pth_prune = set([])
130     pruned = []
131     for e, k, d in list(yield_dist_entries(ws)):
132         if e in seen:
133             continue
134         seen.add(e)
135         if d.project_name not in project_names:
136             continue
137         if e in ws.entry_keys:
138             ws.entry_keys[e][:] = [
139                     kk for kk in ws.entry_keys[e]
140                     if k != kk
141                     ]
142             if not ws.entry_keys[e]:
143                 del ws.entry_keys[e]
144         if k in ws.by_key:
145             del ws.by_key[k]
146         pruned.append((e, k, d))
147         pth_prune.add(e)
148         #pth_prune.add(d.location)
149
150     search_path[:] = [pth for pth in sys.path if pth not in pth_prune]
151     ws.entries[:] = [ent for ent in ws.entries if ent not in pth_prune]
152     return pruned
153
154 try:
155     if __use_this_source_version__:
156         from os.path import dirname
157         # Assumes __file__ is set appropriately; which causes the
158         # automatic call of read_info (above) to do the "right thing"
159         use_source_dist(PKG_INFO['Name'][0], dirname(__file__))
160 except NameError:
161     pass
162 #
Note: See TracBrowser for help on using the browser.