##// END OF EJS Templates
Fix installation of manpages.
Fernando Perez -
Show More
@@ -1,268 +1,268 b''
1 1 #!/usr/bin/env python
2 2 # -*- coding: utf-8 -*-
3 3 """Setup script for IPython.
4 4
5 5 Under Posix environments it works like a typical setup.py script.
6 6 Under Windows, the command sdist is not supported, since IPython
7 7 requires utilities which are not available under Windows."""
8 8
9 9 #-----------------------------------------------------------------------------
10 # Copyright (c) 2008-2010, IPython Development Team.
10 # Copyright (c) 2008-2011, IPython Development Team.
11 11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 14 #
15 15 # Distributed under the terms of the Modified BSD License.
16 16 #
17 17 # The full license is in the file COPYING.txt, distributed with this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Minimal Python version sanity check
22 22 #-----------------------------------------------------------------------------
23 23
24 24 import sys
25 25
26 26 # This check is also made in IPython/__init__, don't forget to update both when
27 27 # changing Python version requirements.
28 28 if sys.version[0:3] < '2.6':
29 29 error = """\
30 30 ERROR: 'IPython requires Python Version 2.6 or above.'
31 31 Exiting."""
32 32 print >> sys.stderr, error
33 33 sys.exit(1)
34 34
35 35 # At least we're on the python version we need, move on.
36 36
37 37 #-------------------------------------------------------------------------------
38 38 # Imports
39 39 #-------------------------------------------------------------------------------
40 40
41 41 # Stdlib imports
42 42 import os
43 43 import shutil
44 44
45 45 from glob import glob
46 46
47 47 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
48 48 # update it when the contents of directories change.
49 49 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
50 50
51 51 from distutils.core import setup
52 52
53 53 # Our own imports
54 54 from IPython.utils.path import target_update
55 55
56 56 from setupbase import (
57 57 setup_args,
58 58 find_packages,
59 59 find_package_data,
60 60 find_scripts,
61 61 find_data_files,
62 62 check_for_dependencies,
63 63 record_commit_info,
64 64 )
65 65 from setupext import setupext
66 66
67 67 isfile = os.path.isfile
68 68 pjoin = os.path.join
69 69
70 70 #-----------------------------------------------------------------------------
71 71 # Function definitions
72 72 #-----------------------------------------------------------------------------
73 73
74 74 def cleanup():
75 75 """Clean up the junk left around by the build process"""
76 76 if "develop" not in sys.argv:
77 77 try:
78 78 shutil.rmtree('ipython.egg-info')
79 79 except:
80 80 try:
81 81 os.unlink('ipython.egg-info')
82 82 except:
83 83 pass
84 84
85 85 #-------------------------------------------------------------------------------
86 86 # Handle OS specific things
87 87 #-------------------------------------------------------------------------------
88 88
89 89 if os.name == 'posix':
90 90 os_name = 'posix'
91 91 elif os.name in ['nt','dos']:
92 92 os_name = 'windows'
93 93 else:
94 94 print 'Unsupported operating system:',os.name
95 95 sys.exit(1)
96 96
97 97 # Under Windows, 'sdist' has not been supported. Now that the docs build with
98 98 # Sphinx it might work, but let's not turn it on until someone confirms that it
99 99 # actually works.
100 100 if os_name == 'windows' and 'sdist' in sys.argv:
101 101 print 'The sdist command is not available under Windows. Exiting.'
102 102 sys.exit(1)
103 103
104 104 #-------------------------------------------------------------------------------
105 105 # Things related to the IPython documentation
106 106 #-------------------------------------------------------------------------------
107 107
108 108 # update the manuals when building a source dist
109 109 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
110 110 import textwrap
111 111
112 112 # List of things to be updated. Each entry is a triplet of args for
113 113 # target_update()
114 114 to_update = [
115 115 # FIXME - Disabled for now: we need to redo an automatic way
116 116 # of generating the magic info inside the rst.
117 117 #('docs/magic.tex',
118 118 #['IPython/Magic.py'],
119 119 #"cd doc && ./update_magic.sh" ),
120 120
121 121 ('docs/man/ipcluster.1.gz',
122 122 ['docs/man/ipcluster.1'],
123 123 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
124 124
125 125 ('docs/man/ipcontroller.1.gz',
126 126 ['docs/man/ipcontroller.1'],
127 127 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
128 128
129 129 ('docs/man/ipengine.1.gz',
130 130 ['docs/man/ipengine.1'],
131 131 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
132 132
133 133 ('docs/man/iplogger.1.gz',
134 134 ['docs/man/iplogger.1'],
135 135 'cd docs/man && gzip -9c iplogger.1 > iplogger.1.gz'),
136 136
137 137 ('docs/man/ipython.1.gz',
138 138 ['docs/man/ipython.1'],
139 139 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
140 140
141 141 ('docs/man/irunner.1.gz',
142 142 ['docs/man/irunner.1'],
143 143 'cd docs/man && gzip -9c irunner.1 > irunner.1.gz'),
144 144
145 145 ('docs/man/pycolor.1.gz',
146 146 ['docs/man/pycolor.1'],
147 147 'cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz'),
148 148 ]
149 149
150 150 # Only build the docs if sphinx is present
151 151 try:
152 152 import sphinx
153 153 except ImportError:
154 154 pass
155 155 else:
156 156 # The Makefile calls the do_sphinx scripts to build html and pdf, so
157 157 # just one target is enough to cover all manual generation
158 158
159 159 # First, compute all the dependencies that can force us to rebuild the
160 160 # docs. Start with the main release file that contains metadata
161 161 docdeps = ['IPython/core/release.py']
162 162 # Inculde all the reST sources
163 163 pjoin = os.path.join
164 164 for dirpath,dirnames,filenames in os.walk('docs/source'):
165 165 if dirpath in ['_static','_templates']:
166 166 continue
167 167 docdeps += [ pjoin(dirpath,f) for f in filenames
168 168 if f.endswith('.txt') ]
169 169 # and the examples
170 170 for dirpath,dirnames,filenames in os.walk('docs/example'):
171 171 docdeps += [ pjoin(dirpath,f) for f in filenames
172 172 if not f.endswith('~') ]
173 173 # then, make them all dependencies for the main PDF (the html will get
174 174 # auto-generated as well).
175 175 to_update.append(
176 176 ('docs/dist/ipython.pdf',
177 177 docdeps,
178 178 "cd docs && make dist")
179 179 )
180 180
181 181 [ target_update(*t) for t in to_update ]
182 182
183 183 #---------------------------------------------------------------------------
184 184 # Find all the packages, package data, and data_files
185 185 #---------------------------------------------------------------------------
186 186
187 187 packages = find_packages()
188 188 package_data = find_package_data()
189 189 data_files = find_data_files()
190 190
191 191 #---------------------------------------------------------------------------
192 192 # Handle scripts, dependencies, and setuptools specific things
193 193 #---------------------------------------------------------------------------
194 194
195 195 # For some commands, use setuptools. Note that we do NOT list install here!
196 196 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
197 197 needs_setuptools = set(('develop', 'sdist', 'release', 'bdist_egg', 'bdist_rpm',
198 198 'bdist', 'bdist_dumb', 'bdist_wininst', 'install_egg_info',
199 199 'build_sphinx', 'egg_info', 'easy_install', 'upload',
200 200 ))
201 201 if sys.platform == 'win32':
202 202 # Depend on setuptools for install on *Windows only*
203 203 # If we get script-installation working without setuptools,
204 204 # then we can back off, but until then use it.
205 205 # See Issue #369 on GitHub for more
206 206 needs_setuptools.add('install')
207 207
208 208 if len(needs_setuptools.intersection(sys.argv)) > 0:
209 209 import setuptools
210 210
211 211 # This dict is used for passing extra arguments that are setuptools
212 212 # specific to setup
213 213 setuptools_extra_args = {}
214 214
215 215 if 'setuptools' in sys.modules:
216 216 setuptools_extra_args['zip_safe'] = False
217 217 setuptools_extra_args['entry_points'] = find_scripts(True)
218 218 setup_args['extras_require'] = dict(
219 219 parallel = 'pyzmq>=2.1.4',
220 220 zmq = 'pyzmq>=2.1.4',
221 221 doc='Sphinx>=0.3',
222 222 test='nose>=0.10.1',
223 223 )
224 224 requires = setup_args.setdefault('install_requires', [])
225 225 setupext.display_status = False
226 226 if not setupext.check_for_readline():
227 227 if sys.platform == 'darwin':
228 228 requires.append('readline')
229 229 elif sys.platform.startswith('win') and sys.maxsize < 2**32:
230 230 # only require pyreadline on 32b Windows, due to 64b bug in pyreadline:
231 231 # https://bugs.launchpad.net/pyreadline/+bug/787574
232 232 requires.append('pyreadline')
233 233 else:
234 234 pass
235 235 # do we want to install readline here?
236 236
237 237 # Script to be run by the windows binary installer after the default setup
238 238 # routine, to add shortcuts and similar windows-only things. Windows
239 239 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
240 240 # doesn't find them.
241 241 if 'bdist_wininst' in sys.argv:
242 242 if len(sys.argv) > 2 and \
243 243 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
244 244 print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
245 245 sys.exit(1)
246 246 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
247 247 setup_args['options'] = {"bdist_wininst": {"install_script": "ipython_win_post_install.py"}}
248 248 else:
249 249 # If we are running without setuptools, call this function which will
250 250 # check for dependencies an inform the user what is needed. This is
251 251 # just to make life easy for users.
252 252 check_for_dependencies()
253 253 setup_args['scripts'] = find_scripts(False)
254 254
255 255 #---------------------------------------------------------------------------
256 256 # Do the actual setup now
257 257 #---------------------------------------------------------------------------
258 258
259 259 setup_args['cmdclass'] = {'build_py': record_commit_info('IPython')}
260 260 setup_args['packages'] = packages
261 261 setup_args['package_data'] = package_data
262 262 setup_args['data_files'] = data_files
263 263 setup_args.update(setuptools_extra_args)
264 264
265 265
266 266 if __name__ == '__main__':
267 267 setup(**setup_args)
268 268 cleanup()
@@ -1,385 +1,388 b''
1 1 # encoding: utf-8
2 2 """
3 3 This module defines the things that are used in setup.py for building IPython
4 4
5 5 This includes:
6 6
7 7 * The basic arguments to setup
8 8 * Functions for finding things like packages, package data, etc.
9 9 * A function for checking dependencies.
10 10 """
11 11 from __future__ import print_function
12 12
13 13 #-------------------------------------------------------------------------------
14 14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-------------------------------------------------------------------------------
19 19
20 20 #-------------------------------------------------------------------------------
21 21 # Imports
22 22 #-------------------------------------------------------------------------------
23 23 import os
24 24 import sys
25 25
26 26 from ConfigParser import ConfigParser
27 27 from distutils.command.build_py import build_py
28 28 from glob import glob
29 29
30 30 from setupext import install_data_ext
31 31
32 32 #-------------------------------------------------------------------------------
33 33 # Useful globals and utility functions
34 34 #-------------------------------------------------------------------------------
35 35
36 36 # A few handy globals
37 37 isfile = os.path.isfile
38 38 pjoin = os.path.join
39 39
40 40 def oscmd(s):
41 41 print(">", s)
42 42 os.system(s)
43 43
44 44 # A little utility we'll need below, since glob() does NOT allow you to do
45 45 # exclusion on multiple endings!
46 46 def file_doesnt_endwith(test,endings):
47 47 """Return true if test is a file and its name does NOT end with any
48 48 of the strings listed in endings."""
49 49 if not isfile(test):
50 50 return False
51 51 for e in endings:
52 52 if test.endswith(e):
53 53 return False
54 54 return True
55 55
56 56 #---------------------------------------------------------------------------
57 57 # Basic project information
58 58 #---------------------------------------------------------------------------
59 59
60 60 # release.py contains version, authors, license, url, keywords, etc.
61 61 execfile(pjoin('IPython','core','release.py'))
62 62
63 63 # Create a dict with the basic information
64 64 # This dict is eventually passed to setup after additional keys are added.
65 65 setup_args = dict(
66 66 name = name,
67 67 version = version,
68 68 description = description,
69 69 long_description = long_description,
70 70 author = author,
71 71 author_email = author_email,
72 72 url = url,
73 73 download_url = download_url,
74 74 license = license,
75 75 platforms = platforms,
76 76 keywords = keywords,
77 77 cmdclass = {'install_data': install_data_ext},
78 78 )
79 79
80 80
81 81 #---------------------------------------------------------------------------
82 82 # Find packages
83 83 #---------------------------------------------------------------------------
84 84
85 85 def add_package(packages,pname,config=False,tests=False,scripts=False,
86 86 others=None):
87 87 """
88 88 Add a package to the list of packages, including certain subpackages.
89 89 """
90 90 packages.append('.'.join(['IPython',pname]))
91 91 if config:
92 92 packages.append('.'.join(['IPython',pname,'config']))
93 93 if tests:
94 94 packages.append('.'.join(['IPython',pname,'tests']))
95 95 if scripts:
96 96 packages.append('.'.join(['IPython',pname,'scripts']))
97 97 if others is not None:
98 98 for o in others:
99 99 packages.append('.'.join(['IPython',pname,o]))
100 100
101 101 def find_packages():
102 102 """
103 103 Find all of IPython's packages.
104 104 """
105 105 packages = ['IPython']
106 106 add_package(packages, 'config', tests=True, others=['profile'])
107 107 add_package(packages, 'core', tests=True)
108 108 add_package(packages, 'extensions')
109 109 add_package(packages, 'external')
110 110 add_package(packages, 'external.argparse')
111 111 add_package(packages, 'external.decorator')
112 112 add_package(packages, 'external.decorators')
113 113 add_package(packages, 'external.guid')
114 114 add_package(packages, 'external.Itpl')
115 115 add_package(packages, 'external.mglob')
116 116 add_package(packages, 'external.path')
117 117 add_package(packages, 'external.pexpect')
118 118 add_package(packages, 'external.pyparsing')
119 119 add_package(packages, 'external.simplegeneric')
120 120 add_package(packages, 'external.ssh')
121 121 add_package(packages, 'kernel')
122 122 add_package(packages, 'frontend')
123 123 add_package(packages, 'frontend.qt')
124 124 add_package(packages, 'frontend.qt.console', tests=True)
125 125 add_package(packages, 'frontend.terminal', tests=True)
126 126 add_package(packages, 'lib', tests=True)
127 127 add_package(packages, 'parallel', tests=True, scripts=True,
128 128 others=['apps','engine','client','controller'])
129 129 add_package(packages, 'quarantine', tests=True)
130 130 add_package(packages, 'scripts')
131 131 add_package(packages, 'testing', tests=True)
132 132 add_package(packages, 'testing.plugin', tests=False)
133 133 add_package(packages, 'utils', tests=True)
134 134 add_package(packages, 'zmq')
135 135 add_package(packages, 'zmq.pylab')
136 136 add_package(packages, 'zmq.gui')
137 137 return packages
138 138
139 139 #---------------------------------------------------------------------------
140 140 # Find package data
141 141 #---------------------------------------------------------------------------
142 142
143 143 def find_package_data():
144 144 """
145 145 Find IPython's package_data.
146 146 """
147 147 # This is not enough for these things to appear in an sdist.
148 148 # We need to muck with the MANIFEST to get this to work
149 149 package_data = {
150 150 'IPython.config.profile' : ['README', '*/*.py'],
151 151 'IPython.testing' : ['*.txt'],
152 152 }
153 153 return package_data
154 154
155 155
156 156 #---------------------------------------------------------------------------
157 157 # Find data files
158 158 #---------------------------------------------------------------------------
159 159
160 160 def make_dir_struct(tag,base,out_base):
161 161 """Make the directory structure of all files below a starting dir.
162 162
163 163 This is just a convenience routine to help build a nested directory
164 164 hierarchy because distutils is too stupid to do this by itself.
165 165
166 166 XXX - this needs a proper docstring!
167 167 """
168 168
169 169 # we'll use these a lot below
170 170 lbase = len(base)
171 171 pathsep = os.path.sep
172 172 lpathsep = len(pathsep)
173 173
174 174 out = []
175 175 for (dirpath,dirnames,filenames) in os.walk(base):
176 176 # we need to strip out the dirpath from the base to map it to the
177 177 # output (installation) path. This requires possibly stripping the
178 178 # path separator, because otherwise pjoin will not work correctly
179 179 # (pjoin('foo/','/bar') returns '/bar').
180 180
181 181 dp_eff = dirpath[lbase:]
182 182 if dp_eff.startswith(pathsep):
183 183 dp_eff = dp_eff[lpathsep:]
184 184 # The output path must be anchored at the out_base marker
185 185 out_path = pjoin(out_base,dp_eff)
186 186 # Now we can generate the final filenames. Since os.walk only produces
187 187 # filenames, we must join back with the dirpath to get full valid file
188 188 # paths:
189 189 pfiles = [pjoin(dirpath,f) for f in filenames]
190 190 # Finally, generate the entry we need, which is a pari of (output
191 191 # path, files) for use as a data_files parameter in install_data.
192 192 out.append((out_path, pfiles))
193 193
194 194 return out
195 195
196 196
197 197 def find_data_files():
198 198 """
199 199 Find IPython's data_files.
200 200
201 201 Most of these are docs.
202 202 """
203 203
204 204 docdirbase = pjoin('share', 'doc', 'ipython')
205 205 manpagebase = pjoin('share', 'man', 'man1')
206 206
207 207 # Simple file lists can be made by hand
208 208 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
209 if not manpages:
210 # When running from a source tree, the manpages aren't gzipped
211 manpages = filter(isfile, glob(pjoin('docs','man','*.1')))
209 212 igridhelpfiles = filter(isfile,
210 213 glob(pjoin('IPython','extensions','igrid_help.*')))
211 214
212 215 # For nested structures, use the utility above
213 216 example_files = make_dir_struct(
214 217 'data',
215 218 pjoin('docs','examples'),
216 219 pjoin(docdirbase,'examples')
217 220 )
218 221 manual_files = make_dir_struct(
219 222 'data',
220 223 pjoin('docs','dist'),
221 224 pjoin(docdirbase,'manual')
222 225 )
223 226
224 227 # And assemble the entire output list
225 228 data_files = [ (manpagebase, manpages),
226 229 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
227 230 ] + manual_files + example_files
228 231
229 232 return data_files
230 233
231 234
232 235 def make_man_update_target(manpage):
233 236 """Return a target_update-compliant tuple for the given manpage.
234 237
235 238 Parameters
236 239 ----------
237 240 manpage : string
238 241 Name of the manpage, must include the section number (trailing number).
239 242
240 243 Example
241 244 -------
242 245
243 246 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
244 247 ('docs/man/ipython.1.gz',
245 248 ['docs/man/ipython.1'],
246 249 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
247 250 """
248 251 man_dir = pjoin('docs', 'man')
249 252 manpage_gz = manpage + '.gz'
250 253 manpath = pjoin(man_dir, manpage)
251 254 manpath_gz = pjoin(man_dir, manpage_gz)
252 255 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
253 256 locals() )
254 257 return (manpath_gz, [manpath], gz_cmd)
255 258
256 259 #---------------------------------------------------------------------------
257 260 # Find scripts
258 261 #---------------------------------------------------------------------------
259 262
260 263 def find_scripts(entry_points=False):
261 264 """Find IPython's scripts.
262 265
263 266 if entry_points is True:
264 267 return setuptools entry_point-style definitions
265 268 else:
266 269 return file paths of plain scripts [default]
267 270 """
268 271 if entry_points:
269 272 console_scripts = [
270 273 'ipython = IPython.frontend.terminal.ipapp:launch_new_instance',
271 274 'pycolor = IPython.utils.PyColorize:main',
272 275 'ipcontroller = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
273 276 'ipengine = IPython.parallel.apps.ipengineapp:launch_new_instance',
274 277 'iplogger = IPython.parallel.apps.iploggerapp:launch_new_instance',
275 278 'ipcluster = IPython.parallel.apps.ipclusterapp:launch_new_instance',
276 279 'iptest = IPython.testing.iptest:main',
277 280 'irunner = IPython.lib.irunner:main'
278 281 ]
279 282 gui_scripts = [
280 283 'ipython-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main',
281 284 ]
282 285 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
283 286 else:
284 287 parallel_scripts = pjoin('IPython','parallel','scripts')
285 288 main_scripts = pjoin('IPython','scripts')
286 289 scripts = [
287 290 pjoin(parallel_scripts, 'ipengine'),
288 291 pjoin(parallel_scripts, 'ipcontroller'),
289 292 pjoin(parallel_scripts, 'ipcluster'),
290 293 pjoin(parallel_scripts, 'iplogger'),
291 294 pjoin(main_scripts, 'ipython'),
292 295 pjoin(main_scripts, 'pycolor'),
293 296 pjoin(main_scripts, 'irunner'),
294 297 pjoin(main_scripts, 'iptest')
295 298 ]
296 299 return scripts
297 300
298 301 #---------------------------------------------------------------------------
299 302 # Verify all dependencies
300 303 #---------------------------------------------------------------------------
301 304
302 305 def check_for_dependencies():
303 306 """Check for IPython's dependencies.
304 307
305 308 This function should NOT be called if running under setuptools!
306 309 """
307 310 from setupext.setupext import (
308 311 print_line, print_raw, print_status,
309 312 check_for_sphinx, check_for_pygments,
310 313 check_for_nose, check_for_pexpect,
311 314 check_for_pyzmq, check_for_readline
312 315 )
313 316 print_line()
314 317 print_raw("BUILDING IPYTHON")
315 318 print_status('python', sys.version)
316 319 print_status('platform', sys.platform)
317 320 if sys.platform == 'win32':
318 321 print_status('Windows version', sys.getwindowsversion())
319 322
320 323 print_raw("")
321 324 print_raw("OPTIONAL DEPENDENCIES")
322 325
323 326 check_for_sphinx()
324 327 check_for_pygments()
325 328 check_for_nose()
326 329 check_for_pexpect()
327 330 check_for_pyzmq()
328 331 check_for_readline()
329 332
330 333 def record_commit_info(pkg_dir, build_cmd=build_py):
331 334 """ Return extended build command class for recording commit
332 335
333 336 The extended command tries to run git to find the current commit, getting
334 337 the empty string if it fails. It then writes the commit hash into a file
335 338 in the `pkg_dir` path, named ``.git_commit_info.ini``.
336 339
337 340 In due course this information can be used by the package after it is
338 341 installed, to tell you what commit it was installed from if known.
339 342
340 343 To make use of this system, you need a package with a .git_commit_info.ini
341 344 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
342 345 this::
343 346
344 347 # This is an ini file that may contain information about the code state
345 348 [commit hash]
346 349 # The line below may contain a valid hash if it has been substituted
347 350 # during 'git archive'
348 351 archive_subst_hash=$Format:%h$
349 352 # This line may be modified by the install process
350 353 install_hash=
351 354
352 355 The .git_commit_info file above is also designed to be used with git
353 356 substitution - so you probably also want a ``.gitattributes`` file in the
354 357 root directory of your working tree that contains something like this::
355 358
356 359 myproject/.git_commit_info.ini export-subst
357 360
358 361 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
359 362 archive`` - useful in case someone makes such an archive - for example with
360 363 via the github 'download source' button.
361 364
362 365 Although all the above will work as is, you might consider having something
363 366 like a ``get_info()`` function in your package to display the commit
364 367 information at the terminal. See the ``pkg_info.py`` module in the nipy
365 368 package for an example.
366 369 """
367 370 class MyBuildPy(build_cmd):
368 371 ''' Subclass to write commit data into installation tree '''
369 372 def run(self):
370 373 build_py.run(self)
371 374 import subprocess
372 375 proc = subprocess.Popen('git rev-parse --short HEAD',
373 376 stdout=subprocess.PIPE,
374 377 stderr=subprocess.PIPE,
375 378 shell=True)
376 379 repo_commit, _ = proc.communicate()
377 380 # We write the installation commit even if it's empty
378 381 cfg_parser = ConfigParser()
379 382 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
380 383 cfg_parser.set('commit hash', 'install_hash', repo_commit)
381 384 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
382 385 out_file = open(out_pth, 'wt')
383 386 cfg_parser.write(out_file)
384 387 out_file.close()
385 388 return MyBuildPy
General Comments 0
You need to be logged in to leave comments. Login now