##// END OF EJS Templates
install zmq.qui fixes problems with using ipython --pylab gtk
Jens Hedegaard Nielsen -
Show More
@@ -1,387 +1,388 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 This module defines the things that are used in setup.py for building IPython
3 This module defines the things that are used in setup.py for building IPython
4
4
5 This includes:
5 This includes:
6
6
7 * The basic arguments to setup
7 * The basic arguments to setup
8 * Functions for finding things like packages, package data, etc.
8 * Functions for finding things like packages, package data, etc.
9 * A function for checking dependencies.
9 * A function for checking dependencies.
10 """
10 """
11 from __future__ import print_function
11 from __future__ import print_function
12
12
13 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
14 # Copyright (C) 2008 The IPython Development Team
14 # Copyright (C) 2008 The IPython Development Team
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #-------------------------------------------------------------------------------
18 #-------------------------------------------------------------------------------
19
19
20 #-------------------------------------------------------------------------------
20 #-------------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-------------------------------------------------------------------------------
22 #-------------------------------------------------------------------------------
23 import os
23 import os
24 import sys
24 import sys
25
25
26 from ConfigParser import ConfigParser
26 from ConfigParser import ConfigParser
27 from distutils.command.build_py import build_py
27 from distutils.command.build_py import build_py
28 from glob import glob
28 from glob import glob
29
29
30 from setupext import install_data_ext
30 from setupext import install_data_ext
31
31
32 #-------------------------------------------------------------------------------
32 #-------------------------------------------------------------------------------
33 # Useful globals and utility functions
33 # Useful globals and utility functions
34 #-------------------------------------------------------------------------------
34 #-------------------------------------------------------------------------------
35
35
36 # A few handy globals
36 # A few handy globals
37 isfile = os.path.isfile
37 isfile = os.path.isfile
38 pjoin = os.path.join
38 pjoin = os.path.join
39
39
40 def oscmd(s):
40 def oscmd(s):
41 print(">", s)
41 print(">", s)
42 os.system(s)
42 os.system(s)
43
43
44 # A little utility we'll need below, since glob() does NOT allow you to do
44 # A little utility we'll need below, since glob() does NOT allow you to do
45 # exclusion on multiple endings!
45 # exclusion on multiple endings!
46 def file_doesnt_endwith(test,endings):
46 def file_doesnt_endwith(test,endings):
47 """Return true if test is a file and its name does NOT end with any
47 """Return true if test is a file and its name does NOT end with any
48 of the strings listed in endings."""
48 of the strings listed in endings."""
49 if not isfile(test):
49 if not isfile(test):
50 return False
50 return False
51 for e in endings:
51 for e in endings:
52 if test.endswith(e):
52 if test.endswith(e):
53 return False
53 return False
54 return True
54 return True
55
55
56 #---------------------------------------------------------------------------
56 #---------------------------------------------------------------------------
57 # Basic project information
57 # Basic project information
58 #---------------------------------------------------------------------------
58 #---------------------------------------------------------------------------
59
59
60 # release.py contains version, authors, license, url, keywords, etc.
60 # release.py contains version, authors, license, url, keywords, etc.
61 execfile(pjoin('IPython','core','release.py'))
61 execfile(pjoin('IPython','core','release.py'))
62
62
63 # Create a dict with the basic information
63 # Create a dict with the basic information
64 # This dict is eventually passed to setup after additional keys are added.
64 # This dict is eventually passed to setup after additional keys are added.
65 setup_args = dict(
65 setup_args = dict(
66 name = name,
66 name = name,
67 version = version,
67 version = version,
68 description = description,
68 description = description,
69 long_description = long_description,
69 long_description = long_description,
70 author = author,
70 author = author,
71 author_email = author_email,
71 author_email = author_email,
72 url = url,
72 url = url,
73 download_url = download_url,
73 download_url = download_url,
74 license = license,
74 license = license,
75 platforms = platforms,
75 platforms = platforms,
76 keywords = keywords,
76 keywords = keywords,
77 cmdclass = {'install_data': install_data_ext},
77 cmdclass = {'install_data': install_data_ext},
78 )
78 )
79
79
80
80
81 #---------------------------------------------------------------------------
81 #---------------------------------------------------------------------------
82 # Find packages
82 # Find packages
83 #---------------------------------------------------------------------------
83 #---------------------------------------------------------------------------
84
84
85 def add_package(packages,pname,config=False,tests=False,scripts=False,
85 def add_package(packages,pname,config=False,tests=False,scripts=False,
86 others=None):
86 others=None):
87 """
87 """
88 Add a package to the list of packages, including certain subpackages.
88 Add a package to the list of packages, including certain subpackages.
89 """
89 """
90 packages.append('.'.join(['IPython',pname]))
90 packages.append('.'.join(['IPython',pname]))
91 if config:
91 if config:
92 packages.append('.'.join(['IPython',pname,'config']))
92 packages.append('.'.join(['IPython',pname,'config']))
93 if tests:
93 if tests:
94 packages.append('.'.join(['IPython',pname,'tests']))
94 packages.append('.'.join(['IPython',pname,'tests']))
95 if scripts:
95 if scripts:
96 packages.append('.'.join(['IPython',pname,'scripts']))
96 packages.append('.'.join(['IPython',pname,'scripts']))
97 if others is not None:
97 if others is not None:
98 for o in others:
98 for o in others:
99 packages.append('.'.join(['IPython',pname,o]))
99 packages.append('.'.join(['IPython',pname,o]))
100
100
101 def find_packages():
101 def find_packages():
102 """
102 """
103 Find all of IPython's packages.
103 Find all of IPython's packages.
104 """
104 """
105 packages = ['IPython']
105 packages = ['IPython']
106 add_package(packages, 'config', tests=True, others=['default','profile'])
106 add_package(packages, 'config', tests=True, others=['default','profile'])
107 add_package(packages, 'core', tests=True)
107 add_package(packages, 'core', tests=True)
108 add_package(packages, 'deathrow', tests=True)
108 add_package(packages, 'deathrow', tests=True)
109 add_package(packages, 'extensions')
109 add_package(packages, 'extensions')
110 add_package(packages, 'external')
110 add_package(packages, 'external')
111 add_package(packages, 'external.argparse')
111 add_package(packages, 'external.argparse')
112 add_package(packages, 'external.configobj')
112 add_package(packages, 'external.configobj')
113 add_package(packages, 'external.decorator')
113 add_package(packages, 'external.decorator')
114 add_package(packages, 'external.decorators')
114 add_package(packages, 'external.decorators')
115 add_package(packages, 'external.guid')
115 add_package(packages, 'external.guid')
116 add_package(packages, 'external.Itpl')
116 add_package(packages, 'external.Itpl')
117 add_package(packages, 'external.mglob')
117 add_package(packages, 'external.mglob')
118 add_package(packages, 'external.path')
118 add_package(packages, 'external.path')
119 add_package(packages, 'external.pexpect')
119 add_package(packages, 'external.pexpect')
120 add_package(packages, 'external.pyparsing')
120 add_package(packages, 'external.pyparsing')
121 add_package(packages, 'external.simplegeneric')
121 add_package(packages, 'external.simplegeneric')
122 add_package(packages, 'external.ssh')
122 add_package(packages, 'external.ssh')
123 add_package(packages, 'external.validate')
123 add_package(packages, 'external.validate')
124 add_package(packages, 'kernel')
124 add_package(packages, 'kernel')
125 add_package(packages, 'frontend')
125 add_package(packages, 'frontend')
126 add_package(packages, 'frontend.qt')
126 add_package(packages, 'frontend.qt')
127 add_package(packages, 'frontend.qt.console', tests=True)
127 add_package(packages, 'frontend.qt.console', tests=True)
128 add_package(packages, 'frontend.terminal', tests=True)
128 add_package(packages, 'frontend.terminal', tests=True)
129 add_package(packages, 'lib', tests=True)
129 add_package(packages, 'lib', tests=True)
130 add_package(packages, 'parallel', tests=True, scripts=True,
130 add_package(packages, 'parallel', tests=True, scripts=True,
131 others=['apps','engine','client','controller'])
131 others=['apps','engine','client','controller'])
132 add_package(packages, 'quarantine', tests=True)
132 add_package(packages, 'quarantine', tests=True)
133 add_package(packages, 'scripts')
133 add_package(packages, 'scripts')
134 add_package(packages, 'testing', tests=True)
134 add_package(packages, 'testing', tests=True)
135 add_package(packages, 'testing.plugin', tests=False)
135 add_package(packages, 'testing.plugin', tests=False)
136 add_package(packages, 'utils', tests=True)
136 add_package(packages, 'utils', tests=True)
137 add_package(packages, 'zmq')
137 add_package(packages, 'zmq')
138 add_package(packages, 'zmq.pylab')
138 add_package(packages, 'zmq.pylab')
139 add_package(packages, 'zmq.gui')
139 return packages
140 return packages
140
141
141 #---------------------------------------------------------------------------
142 #---------------------------------------------------------------------------
142 # Find package data
143 # Find package data
143 #---------------------------------------------------------------------------
144 #---------------------------------------------------------------------------
144
145
145 def find_package_data():
146 def find_package_data():
146 """
147 """
147 Find IPython's package_data.
148 Find IPython's package_data.
148 """
149 """
149 # This is not enough for these things to appear in an sdist.
150 # This is not enough for these things to appear in an sdist.
150 # We need to muck with the MANIFEST to get this to work
151 # We need to muck with the MANIFEST to get this to work
151 package_data = {
152 package_data = {
152 'IPython.config.userconfig' : ['*'],
153 'IPython.config.userconfig' : ['*'],
153 'IPython.testing' : ['*.txt']
154 'IPython.testing' : ['*.txt']
154 }
155 }
155 return package_data
156 return package_data
156
157
157
158
158 #---------------------------------------------------------------------------
159 #---------------------------------------------------------------------------
159 # Find data files
160 # Find data files
160 #---------------------------------------------------------------------------
161 #---------------------------------------------------------------------------
161
162
162 def make_dir_struct(tag,base,out_base):
163 def make_dir_struct(tag,base,out_base):
163 """Make the directory structure of all files below a starting dir.
164 """Make the directory structure of all files below a starting dir.
164
165
165 This is just a convenience routine to help build a nested directory
166 This is just a convenience routine to help build a nested directory
166 hierarchy because distutils is too stupid to do this by itself.
167 hierarchy because distutils is too stupid to do this by itself.
167
168
168 XXX - this needs a proper docstring!
169 XXX - this needs a proper docstring!
169 """
170 """
170
171
171 # we'll use these a lot below
172 # we'll use these a lot below
172 lbase = len(base)
173 lbase = len(base)
173 pathsep = os.path.sep
174 pathsep = os.path.sep
174 lpathsep = len(pathsep)
175 lpathsep = len(pathsep)
175
176
176 out = []
177 out = []
177 for (dirpath,dirnames,filenames) in os.walk(base):
178 for (dirpath,dirnames,filenames) in os.walk(base):
178 # we need to strip out the dirpath from the base to map it to the
179 # we need to strip out the dirpath from the base to map it to the
179 # output (installation) path. This requires possibly stripping the
180 # output (installation) path. This requires possibly stripping the
180 # path separator, because otherwise pjoin will not work correctly
181 # path separator, because otherwise pjoin will not work correctly
181 # (pjoin('foo/','/bar') returns '/bar').
182 # (pjoin('foo/','/bar') returns '/bar').
182
183
183 dp_eff = dirpath[lbase:]
184 dp_eff = dirpath[lbase:]
184 if dp_eff.startswith(pathsep):
185 if dp_eff.startswith(pathsep):
185 dp_eff = dp_eff[lpathsep:]
186 dp_eff = dp_eff[lpathsep:]
186 # The output path must be anchored at the out_base marker
187 # The output path must be anchored at the out_base marker
187 out_path = pjoin(out_base,dp_eff)
188 out_path = pjoin(out_base,dp_eff)
188 # Now we can generate the final filenames. Since os.walk only produces
189 # Now we can generate the final filenames. Since os.walk only produces
189 # filenames, we must join back with the dirpath to get full valid file
190 # filenames, we must join back with the dirpath to get full valid file
190 # paths:
191 # paths:
191 pfiles = [pjoin(dirpath,f) for f in filenames]
192 pfiles = [pjoin(dirpath,f) for f in filenames]
192 # Finally, generate the entry we need, which is a pari of (output
193 # Finally, generate the entry we need, which is a pari of (output
193 # path, files) for use as a data_files parameter in install_data.
194 # path, files) for use as a data_files parameter in install_data.
194 out.append((out_path, pfiles))
195 out.append((out_path, pfiles))
195
196
196 return out
197 return out
197
198
198
199
199 def find_data_files():
200 def find_data_files():
200 """
201 """
201 Find IPython's data_files.
202 Find IPython's data_files.
202
203
203 Most of these are docs.
204 Most of these are docs.
204 """
205 """
205
206
206 docdirbase = pjoin('share', 'doc', 'ipython')
207 docdirbase = pjoin('share', 'doc', 'ipython')
207 manpagebase = pjoin('share', 'man', 'man1')
208 manpagebase = pjoin('share', 'man', 'man1')
208
209
209 # Simple file lists can be made by hand
210 # Simple file lists can be made by hand
210 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
211 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
211 igridhelpfiles = filter(isfile,
212 igridhelpfiles = filter(isfile,
212 glob(pjoin('IPython','extensions','igrid_help.*')))
213 glob(pjoin('IPython','extensions','igrid_help.*')))
213
214
214 # For nested structures, use the utility above
215 # For nested structures, use the utility above
215 example_files = make_dir_struct(
216 example_files = make_dir_struct(
216 'data',
217 'data',
217 pjoin('docs','examples'),
218 pjoin('docs','examples'),
218 pjoin(docdirbase,'examples')
219 pjoin(docdirbase,'examples')
219 )
220 )
220 manual_files = make_dir_struct(
221 manual_files = make_dir_struct(
221 'data',
222 'data',
222 pjoin('docs','dist'),
223 pjoin('docs','dist'),
223 pjoin(docdirbase,'manual')
224 pjoin(docdirbase,'manual')
224 )
225 )
225
226
226 # And assemble the entire output list
227 # And assemble the entire output list
227 data_files = [ (manpagebase, manpages),
228 data_files = [ (manpagebase, manpages),
228 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
229 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
229 ] + manual_files + example_files
230 ] + manual_files + example_files
230
231
231 return data_files
232 return data_files
232
233
233
234
234 def make_man_update_target(manpage):
235 def make_man_update_target(manpage):
235 """Return a target_update-compliant tuple for the given manpage.
236 """Return a target_update-compliant tuple for the given manpage.
236
237
237 Parameters
238 Parameters
238 ----------
239 ----------
239 manpage : string
240 manpage : string
240 Name of the manpage, must include the section number (trailing number).
241 Name of the manpage, must include the section number (trailing number).
241
242
242 Example
243 Example
243 -------
244 -------
244
245
245 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
246 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
246 ('docs/man/ipython.1.gz',
247 ('docs/man/ipython.1.gz',
247 ['docs/man/ipython.1'],
248 ['docs/man/ipython.1'],
248 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
249 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
249 """
250 """
250 man_dir = pjoin('docs', 'man')
251 man_dir = pjoin('docs', 'man')
251 manpage_gz = manpage + '.gz'
252 manpage_gz = manpage + '.gz'
252 manpath = pjoin(man_dir, manpage)
253 manpath = pjoin(man_dir, manpage)
253 manpath_gz = pjoin(man_dir, manpage_gz)
254 manpath_gz = pjoin(man_dir, manpage_gz)
254 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
255 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
255 locals() )
256 locals() )
256 return (manpath_gz, [manpath], gz_cmd)
257 return (manpath_gz, [manpath], gz_cmd)
257
258
258 #---------------------------------------------------------------------------
259 #---------------------------------------------------------------------------
259 # Find scripts
260 # Find scripts
260 #---------------------------------------------------------------------------
261 #---------------------------------------------------------------------------
261
262
262 def find_scripts(entry_points=False):
263 def find_scripts(entry_points=False):
263 """Find IPython's scripts.
264 """Find IPython's scripts.
264
265
265 if entry_points is True:
266 if entry_points is True:
266 return setuptools entry_point-style definitions
267 return setuptools entry_point-style definitions
267 else:
268 else:
268 return file paths of plain scripts [default]
269 return file paths of plain scripts [default]
269
270
270 """
271 """
271 if entry_points:
272 if entry_points:
272 scripts = [
273 scripts = [
273 'ipython = IPython.frontend.terminal.ipapp:launch_new_instance',
274 'ipython = IPython.frontend.terminal.ipapp:launch_new_instance',
274 'ipython-qtconsole = IPython.frontend.qt.console.ipythonqt:main',
275 'ipython-qtconsole = IPython.frontend.qt.console.ipythonqt:main',
275 'pycolor = IPython.utils.PyColorize:main',
276 'pycolor = IPython.utils.PyColorize:main',
276 'ipcontroller = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
277 'ipcontroller = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
277 'ipengine = IPython.parallel.apps.ipengineapp:launch_new_instance',
278 'ipengine = IPython.parallel.apps.ipengineapp:launch_new_instance',
278 'iplogger = IPython.parallel.apps.iploggerapp:launch_new_instance',
279 'iplogger = IPython.parallel.apps.iploggerapp:launch_new_instance',
279 'ipcluster = IPython.parallel.apps.ipclusterapp:launch_new_instance',
280 'ipcluster = IPython.parallel.apps.ipclusterapp:launch_new_instance',
280 'iptest = IPython.testing.iptest:main',
281 'iptest = IPython.testing.iptest:main',
281 'irunner = IPython.lib.irunner:main'
282 'irunner = IPython.lib.irunner:main'
282 ]
283 ]
283 else:
284 else:
284 parallel_scripts = pjoin('IPython','parallel','scripts')
285 parallel_scripts = pjoin('IPython','parallel','scripts')
285 main_scripts = pjoin('IPython','scripts')
286 main_scripts = pjoin('IPython','scripts')
286 scripts = [
287 scripts = [
287 pjoin(parallel_scripts, 'ipengine'),
288 pjoin(parallel_scripts, 'ipengine'),
288 pjoin(parallel_scripts, 'ipcontroller'),
289 pjoin(parallel_scripts, 'ipcontroller'),
289 pjoin(parallel_scripts, 'ipcluster'),
290 pjoin(parallel_scripts, 'ipcluster'),
290 pjoin(parallel_scripts, 'iplogger'),
291 pjoin(parallel_scripts, 'iplogger'),
291 pjoin(main_scripts, 'ipython'),
292 pjoin(main_scripts, 'ipython'),
292 pjoin(main_scripts, 'ipython-qtconsole'),
293 pjoin(main_scripts, 'ipython-qtconsole'),
293 pjoin(main_scripts, 'pycolor'),
294 pjoin(main_scripts, 'pycolor'),
294 pjoin(main_scripts, 'irunner'),
295 pjoin(main_scripts, 'irunner'),
295 pjoin(main_scripts, 'iptest')
296 pjoin(main_scripts, 'iptest')
296 ]
297 ]
297
298
298 return scripts
299 return scripts
299
300
300 #---------------------------------------------------------------------------
301 #---------------------------------------------------------------------------
301 # Verify all dependencies
302 # Verify all dependencies
302 #---------------------------------------------------------------------------
303 #---------------------------------------------------------------------------
303
304
304 def check_for_dependencies():
305 def check_for_dependencies():
305 """Check for IPython's dependencies.
306 """Check for IPython's dependencies.
306
307
307 This function should NOT be called if running under setuptools!
308 This function should NOT be called if running under setuptools!
308 """
309 """
309 from setupext.setupext import (
310 from setupext.setupext import (
310 print_line, print_raw, print_status,
311 print_line, print_raw, print_status,
311 check_for_sphinx, check_for_pygments,
312 check_for_sphinx, check_for_pygments,
312 check_for_nose, check_for_pexpect,
313 check_for_nose, check_for_pexpect,
313 check_for_pyzmq, check_for_readline
314 check_for_pyzmq, check_for_readline
314 )
315 )
315 print_line()
316 print_line()
316 print_raw("BUILDING IPYTHON")
317 print_raw("BUILDING IPYTHON")
317 print_status('python', sys.version)
318 print_status('python', sys.version)
318 print_status('platform', sys.platform)
319 print_status('platform', sys.platform)
319 if sys.platform == 'win32':
320 if sys.platform == 'win32':
320 print_status('Windows version', sys.getwindowsversion())
321 print_status('Windows version', sys.getwindowsversion())
321
322
322 print_raw("")
323 print_raw("")
323 print_raw("OPTIONAL DEPENDENCIES")
324 print_raw("OPTIONAL DEPENDENCIES")
324
325
325 check_for_sphinx()
326 check_for_sphinx()
326 check_for_pygments()
327 check_for_pygments()
327 check_for_nose()
328 check_for_nose()
328 check_for_pexpect()
329 check_for_pexpect()
329 check_for_pyzmq()
330 check_for_pyzmq()
330 check_for_readline()
331 check_for_readline()
331
332
332 def record_commit_info(pkg_dir, build_cmd=build_py):
333 def record_commit_info(pkg_dir, build_cmd=build_py):
333 """ Return extended build command class for recording commit
334 """ Return extended build command class for recording commit
334
335
335 The extended command tries to run git to find the current commit, getting
336 The extended command tries to run git to find the current commit, getting
336 the empty string if it fails. It then writes the commit hash into a file
337 the empty string if it fails. It then writes the commit hash into a file
337 in the `pkg_dir` path, named ``.git_commit_info.ini``.
338 in the `pkg_dir` path, named ``.git_commit_info.ini``.
338
339
339 In due course this information can be used by the package after it is
340 In due course this information can be used by the package after it is
340 installed, to tell you what commit it was installed from if known.
341 installed, to tell you what commit it was installed from if known.
341
342
342 To make use of this system, you need a package with a .git_commit_info.ini
343 To make use of this system, you need a package with a .git_commit_info.ini
343 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
344 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
344 this::
345 this::
345
346
346 # This is an ini file that may contain information about the code state
347 # This is an ini file that may contain information about the code state
347 [commit hash]
348 [commit hash]
348 # The line below may contain a valid hash if it has been substituted
349 # The line below may contain a valid hash if it has been substituted
349 # during 'git archive'
350 # during 'git archive'
350 archive_subst_hash=$Format:%h$
351 archive_subst_hash=$Format:%h$
351 # This line may be modified by the install process
352 # This line may be modified by the install process
352 install_hash=
353 install_hash=
353
354
354 The .git_commit_info file above is also designed to be used with git
355 The .git_commit_info file above is also designed to be used with git
355 substitution - so you probably also want a ``.gitattributes`` file in the
356 substitution - so you probably also want a ``.gitattributes`` file in the
356 root directory of your working tree that contains something like this::
357 root directory of your working tree that contains something like this::
357
358
358 myproject/.git_commit_info.ini export-subst
359 myproject/.git_commit_info.ini export-subst
359
360
360 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
361 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
361 archive`` - useful in case someone makes such an archive - for example with
362 archive`` - useful in case someone makes such an archive - for example with
362 via the github 'download source' button.
363 via the github 'download source' button.
363
364
364 Although all the above will work as is, you might consider having something
365 Although all the above will work as is, you might consider having something
365 like a ``get_info()`` function in your package to display the commit
366 like a ``get_info()`` function in your package to display the commit
366 information at the terminal. See the ``pkg_info.py`` module in the nipy
367 information at the terminal. See the ``pkg_info.py`` module in the nipy
367 package for an example.
368 package for an example.
368 """
369 """
369 class MyBuildPy(build_cmd):
370 class MyBuildPy(build_cmd):
370 ''' Subclass to write commit data into installation tree '''
371 ''' Subclass to write commit data into installation tree '''
371 def run(self):
372 def run(self):
372 build_py.run(self)
373 build_py.run(self)
373 import subprocess
374 import subprocess
374 proc = subprocess.Popen('git rev-parse --short HEAD',
375 proc = subprocess.Popen('git rev-parse --short HEAD',
375 stdout=subprocess.PIPE,
376 stdout=subprocess.PIPE,
376 stderr=subprocess.PIPE,
377 stderr=subprocess.PIPE,
377 shell=True)
378 shell=True)
378 repo_commit, _ = proc.communicate()
379 repo_commit, _ = proc.communicate()
379 # We write the installation commit even if it's empty
380 # We write the installation commit even if it's empty
380 cfg_parser = ConfigParser()
381 cfg_parser = ConfigParser()
381 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
382 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
382 cfg_parser.set('commit hash', 'install_hash', repo_commit)
383 cfg_parser.set('commit hash', 'install_hash', repo_commit)
383 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
384 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
384 out_file = open(out_pth, 'wt')
385 out_file = open(out_pth, 'wt')
385 cfg_parser.write(out_file)
386 cfg_parser.write(out_file)
386 out_file.close()
387 out_file.close()
387 return MyBuildPy
388 return MyBuildPy
General Comments 0
You need to be logged in to leave comments. Login now