##// END OF EJS Templates
add missing plugin .txt to package_data
MinRK -
Show More
@@ -1,396 +1,397 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 try:
26 try:
27 from configparser import ConfigParser
27 from configparser import ConfigParser
28 except:
28 except:
29 from ConfigParser import ConfigParser
29 from ConfigParser import ConfigParser
30 from distutils.command.build_py import build_py
30 from distutils.command.build_py import build_py
31 from glob import glob
31 from glob import glob
32
32
33 from setupext import install_data_ext
33 from setupext import install_data_ext
34
34
35 #-------------------------------------------------------------------------------
35 #-------------------------------------------------------------------------------
36 # Useful globals and utility functions
36 # Useful globals and utility functions
37 #-------------------------------------------------------------------------------
37 #-------------------------------------------------------------------------------
38
38
39 # A few handy globals
39 # A few handy globals
40 isfile = os.path.isfile
40 isfile = os.path.isfile
41 pjoin = os.path.join
41 pjoin = os.path.join
42
42
43 def oscmd(s):
43 def oscmd(s):
44 print(">", s)
44 print(">", s)
45 os.system(s)
45 os.system(s)
46
46
47 # Py3 compatibility hacks, without assuming IPython itself is installed with
47 # Py3 compatibility hacks, without assuming IPython itself is installed with
48 # the full py3compat machinery.
48 # the full py3compat machinery.
49
49
50 try:
50 try:
51 execfile
51 execfile
52 except NameError:
52 except NameError:
53 def execfile(fname, globs, locs=None):
53 def execfile(fname, globs, locs=None):
54 locs = locs or globs
54 locs = locs or globs
55 exec(compile(open(fname).read(), fname, "exec"), globs, locs)
55 exec(compile(open(fname).read(), fname, "exec"), globs, locs)
56
56
57 # A little utility we'll need below, since glob() does NOT allow you to do
57 # A little utility we'll need below, since glob() does NOT allow you to do
58 # exclusion on multiple endings!
58 # exclusion on multiple endings!
59 def file_doesnt_endwith(test,endings):
59 def file_doesnt_endwith(test,endings):
60 """Return true if test is a file and its name does NOT end with any
60 """Return true if test is a file and its name does NOT end with any
61 of the strings listed in endings."""
61 of the strings listed in endings."""
62 if not isfile(test):
62 if not isfile(test):
63 return False
63 return False
64 for e in endings:
64 for e in endings:
65 if test.endswith(e):
65 if test.endswith(e):
66 return False
66 return False
67 return True
67 return True
68
68
69 #---------------------------------------------------------------------------
69 #---------------------------------------------------------------------------
70 # Basic project information
70 # Basic project information
71 #---------------------------------------------------------------------------
71 #---------------------------------------------------------------------------
72
72
73 # release.py contains version, authors, license, url, keywords, etc.
73 # release.py contains version, authors, license, url, keywords, etc.
74 execfile(pjoin('IPython','core','release.py'), globals())
74 execfile(pjoin('IPython','core','release.py'), globals())
75
75
76 # Create a dict with the basic information
76 # Create a dict with the basic information
77 # This dict is eventually passed to setup after additional keys are added.
77 # This dict is eventually passed to setup after additional keys are added.
78 setup_args = dict(
78 setup_args = dict(
79 name = name,
79 name = name,
80 version = version,
80 version = version,
81 description = description,
81 description = description,
82 long_description = long_description,
82 long_description = long_description,
83 author = author,
83 author = author,
84 author_email = author_email,
84 author_email = author_email,
85 url = url,
85 url = url,
86 download_url = download_url,
86 download_url = download_url,
87 license = license,
87 license = license,
88 platforms = platforms,
88 platforms = platforms,
89 keywords = keywords,
89 keywords = keywords,
90 classifiers = classifiers,
90 classifiers = classifiers,
91 cmdclass = {'install_data': install_data_ext},
91 cmdclass = {'install_data': install_data_ext},
92 )
92 )
93
93
94
94
95 #---------------------------------------------------------------------------
95 #---------------------------------------------------------------------------
96 # Find packages
96 # Find packages
97 #---------------------------------------------------------------------------
97 #---------------------------------------------------------------------------
98
98
99 def find_packages():
99 def find_packages():
100 """
100 """
101 Find all of IPython's packages.
101 Find all of IPython's packages.
102 """
102 """
103 excludes = ['deathrow', 'quarantine']
103 excludes = ['deathrow', 'quarantine']
104 packages = []
104 packages = []
105 for dir,subdirs,files in os.walk('IPython'):
105 for dir,subdirs,files in os.walk('IPython'):
106 package = dir.replace(os.path.sep, '.')
106 package = dir.replace(os.path.sep, '.')
107 if any(package.startswith('IPython.'+exc) for exc in excludes):
107 if any(package.startswith('IPython.'+exc) for exc in excludes):
108 # package is to be excluded (e.g. deathrow)
108 # package is to be excluded (e.g. deathrow)
109 continue
109 continue
110 if '__init__.py' not in files:
110 if '__init__.py' not in files:
111 # not a package
111 # not a package
112 continue
112 continue
113 packages.append(package)
113 packages.append(package)
114 return packages
114 return packages
115
115
116 #---------------------------------------------------------------------------
116 #---------------------------------------------------------------------------
117 # Find package data
117 # Find package data
118 #---------------------------------------------------------------------------
118 #---------------------------------------------------------------------------
119
119
120 def find_package_data():
120 def find_package_data():
121 """
121 """
122 Find IPython's package_data.
122 Find IPython's package_data.
123 """
123 """
124 # This is not enough for these things to appear in an sdist.
124 # This is not enough for these things to appear in an sdist.
125 # We need to muck with the MANIFEST to get this to work
125 # We need to muck with the MANIFEST to get this to work
126
126
127 # exclude static things that we don't ship (e.g. mathjax)
127 # exclude static things that we don't ship (e.g. mathjax)
128 excludes = ['mathjax']
128 excludes = ['mathjax']
129
129
130 # add 'static/' prefix to exclusions, and tuplify for use in startswith
130 # add 'static/' prefix to exclusions, and tuplify for use in startswith
131 excludes = tuple([os.path.join('static', ex) for ex in excludes])
131 excludes = tuple([os.path.join('static', ex) for ex in excludes])
132
132
133 # walk notebook resources:
133 # walk notebook resources:
134 cwd = os.getcwd()
134 cwd = os.getcwd()
135 os.chdir(os.path.join('IPython', 'frontend', 'html', 'notebook'))
135 os.chdir(os.path.join('IPython', 'frontend', 'html', 'notebook'))
136 static_walk = list(os.walk('static'))
136 static_walk = list(os.walk('static'))
137 os.chdir(cwd)
137 os.chdir(cwd)
138 static_data = []
138 static_data = []
139 for parent, dirs, files in static_walk:
139 for parent, dirs, files in static_walk:
140 if parent.startswith(excludes):
140 if parent.startswith(excludes):
141 continue
141 continue
142 for f in files:
142 for f in files:
143 static_data.append(os.path.join(parent, f))
143 static_data.append(os.path.join(parent, f))
144
144
145 package_data = {
145 package_data = {
146 'IPython.config.profile' : ['README*', '*/*.py'],
146 'IPython.config.profile' : ['README*', '*/*.py'],
147 'IPython.testing' : ['*.txt'],
147 'IPython.testing' : ['*.txt'],
148 'IPython.testing.plugin' : ['*.txt'],
148 'IPython.frontend.html.notebook' : ['templates/*'] + static_data,
149 'IPython.frontend.html.notebook' : ['templates/*'] + static_data,
149 'IPython.frontend.qt.console' : ['resources/icon/*.svg'],
150 'IPython.frontend.qt.console' : ['resources/icon/*.svg'],
150 }
151 }
151 return package_data
152 return package_data
152
153
153
154
154 #---------------------------------------------------------------------------
155 #---------------------------------------------------------------------------
155 # Find data files
156 # Find data files
156 #---------------------------------------------------------------------------
157 #---------------------------------------------------------------------------
157
158
158 def make_dir_struct(tag,base,out_base):
159 def make_dir_struct(tag,base,out_base):
159 """Make the directory structure of all files below a starting dir.
160 """Make the directory structure of all files below a starting dir.
160
161
161 This is just a convenience routine to help build a nested directory
162 This is just a convenience routine to help build a nested directory
162 hierarchy because distutils is too stupid to do this by itself.
163 hierarchy because distutils is too stupid to do this by itself.
163
164
164 XXX - this needs a proper docstring!
165 XXX - this needs a proper docstring!
165 """
166 """
166
167
167 # we'll use these a lot below
168 # we'll use these a lot below
168 lbase = len(base)
169 lbase = len(base)
169 pathsep = os.path.sep
170 pathsep = os.path.sep
170 lpathsep = len(pathsep)
171 lpathsep = len(pathsep)
171
172
172 out = []
173 out = []
173 for (dirpath,dirnames,filenames) in os.walk(base):
174 for (dirpath,dirnames,filenames) in os.walk(base):
174 # we need to strip out the dirpath from the base to map it to the
175 # we need to strip out the dirpath from the base to map it to the
175 # output (installation) path. This requires possibly stripping the
176 # output (installation) path. This requires possibly stripping the
176 # path separator, because otherwise pjoin will not work correctly
177 # path separator, because otherwise pjoin will not work correctly
177 # (pjoin('foo/','/bar') returns '/bar').
178 # (pjoin('foo/','/bar') returns '/bar').
178
179
179 dp_eff = dirpath[lbase:]
180 dp_eff = dirpath[lbase:]
180 if dp_eff.startswith(pathsep):
181 if dp_eff.startswith(pathsep):
181 dp_eff = dp_eff[lpathsep:]
182 dp_eff = dp_eff[lpathsep:]
182 # The output path must be anchored at the out_base marker
183 # The output path must be anchored at the out_base marker
183 out_path = pjoin(out_base,dp_eff)
184 out_path = pjoin(out_base,dp_eff)
184 # Now we can generate the final filenames. Since os.walk only produces
185 # Now we can generate the final filenames. Since os.walk only produces
185 # filenames, we must join back with the dirpath to get full valid file
186 # filenames, we must join back with the dirpath to get full valid file
186 # paths:
187 # paths:
187 pfiles = [pjoin(dirpath,f) for f in filenames]
188 pfiles = [pjoin(dirpath,f) for f in filenames]
188 # Finally, generate the entry we need, which is a pari of (output
189 # Finally, generate the entry we need, which is a pari of (output
189 # path, files) for use as a data_files parameter in install_data.
190 # path, files) for use as a data_files parameter in install_data.
190 out.append((out_path, pfiles))
191 out.append((out_path, pfiles))
191
192
192 return out
193 return out
193
194
194
195
195 def find_data_files():
196 def find_data_files():
196 """
197 """
197 Find IPython's data_files.
198 Find IPython's data_files.
198
199
199 Most of these are docs.
200 Most of these are docs.
200 """
201 """
201
202
202 docdirbase = pjoin('share', 'doc', 'ipython')
203 docdirbase = pjoin('share', 'doc', 'ipython')
203 manpagebase = pjoin('share', 'man', 'man1')
204 manpagebase = pjoin('share', 'man', 'man1')
204
205
205 # Simple file lists can be made by hand
206 # Simple file lists can be made by hand
206 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
207 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
207 if not manpages:
208 if not manpages:
208 # When running from a source tree, the manpages aren't gzipped
209 # When running from a source tree, the manpages aren't gzipped
209 manpages = filter(isfile, glob(pjoin('docs','man','*.1')))
210 manpages = filter(isfile, glob(pjoin('docs','man','*.1')))
210 igridhelpfiles = filter(isfile,
211 igridhelpfiles = filter(isfile,
211 glob(pjoin('IPython','extensions','igrid_help.*')))
212 glob(pjoin('IPython','extensions','igrid_help.*')))
212
213
213 # For nested structures, use the utility above
214 # For nested structures, use the utility above
214 example_files = make_dir_struct(
215 example_files = make_dir_struct(
215 'data',
216 'data',
216 pjoin('docs','examples'),
217 pjoin('docs','examples'),
217 pjoin(docdirbase,'examples')
218 pjoin(docdirbase,'examples')
218 )
219 )
219 manual_files = make_dir_struct(
220 manual_files = make_dir_struct(
220 'data',
221 'data',
221 pjoin('docs','html'),
222 pjoin('docs','html'),
222 pjoin(docdirbase,'manual')
223 pjoin(docdirbase,'manual')
223 )
224 )
224
225
225 # And assemble the entire output list
226 # And assemble the entire output list
226 data_files = [ (manpagebase, manpages),
227 data_files = [ (manpagebase, manpages),
227 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
228 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
228 ] + manual_files + example_files
229 ] + manual_files + example_files
229
230
230 return data_files
231 return data_files
231
232
232
233
233 def make_man_update_target(manpage):
234 def make_man_update_target(manpage):
234 """Return a target_update-compliant tuple for the given manpage.
235 """Return a target_update-compliant tuple for the given manpage.
235
236
236 Parameters
237 Parameters
237 ----------
238 ----------
238 manpage : string
239 manpage : string
239 Name of the manpage, must include the section number (trailing number).
240 Name of the manpage, must include the section number (trailing number).
240
241
241 Example
242 Example
242 -------
243 -------
243
244
244 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
245 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
245 ('docs/man/ipython.1.gz',
246 ('docs/man/ipython.1.gz',
246 ['docs/man/ipython.1'],
247 ['docs/man/ipython.1'],
247 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
248 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
248 """
249 """
249 man_dir = pjoin('docs', 'man')
250 man_dir = pjoin('docs', 'man')
250 manpage_gz = manpage + '.gz'
251 manpage_gz = manpage + '.gz'
251 manpath = pjoin(man_dir, manpage)
252 manpath = pjoin(man_dir, manpage)
252 manpath_gz = pjoin(man_dir, manpage_gz)
253 manpath_gz = pjoin(man_dir, manpage_gz)
253 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
254 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
254 locals() )
255 locals() )
255 return (manpath_gz, [manpath], gz_cmd)
256 return (manpath_gz, [manpath], gz_cmd)
256
257
257 # The two functions below are copied from IPython.utils.path, so we don't need
258 # The two functions below are copied from IPython.utils.path, so we don't need
258 # to import IPython during setup, which fails on Python 3.
259 # to import IPython during setup, which fails on Python 3.
259
260
260 def target_outdated(target,deps):
261 def target_outdated(target,deps):
261 """Determine whether a target is out of date.
262 """Determine whether a target is out of date.
262
263
263 target_outdated(target,deps) -> 1/0
264 target_outdated(target,deps) -> 1/0
264
265
265 deps: list of filenames which MUST exist.
266 deps: list of filenames which MUST exist.
266 target: single filename which may or may not exist.
267 target: single filename which may or may not exist.
267
268
268 If target doesn't exist or is older than any file listed in deps, return
269 If target doesn't exist or is older than any file listed in deps, return
269 true, otherwise return false.
270 true, otherwise return false.
270 """
271 """
271 try:
272 try:
272 target_time = os.path.getmtime(target)
273 target_time = os.path.getmtime(target)
273 except os.error:
274 except os.error:
274 return 1
275 return 1
275 for dep in deps:
276 for dep in deps:
276 dep_time = os.path.getmtime(dep)
277 dep_time = os.path.getmtime(dep)
277 if dep_time > target_time:
278 if dep_time > target_time:
278 #print "For target",target,"Dep failed:",dep # dbg
279 #print "For target",target,"Dep failed:",dep # dbg
279 #print "times (dep,tar):",dep_time,target_time # dbg
280 #print "times (dep,tar):",dep_time,target_time # dbg
280 return 1
281 return 1
281 return 0
282 return 0
282
283
283
284
284 def target_update(target,deps,cmd):
285 def target_update(target,deps,cmd):
285 """Update a target with a given command given a list of dependencies.
286 """Update a target with a given command given a list of dependencies.
286
287
287 target_update(target,deps,cmd) -> runs cmd if target is outdated.
288 target_update(target,deps,cmd) -> runs cmd if target is outdated.
288
289
289 This is just a wrapper around target_outdated() which calls the given
290 This is just a wrapper around target_outdated() which calls the given
290 command if target is outdated."""
291 command if target is outdated."""
291
292
292 if target_outdated(target,deps):
293 if target_outdated(target,deps):
293 os.system(cmd)
294 os.system(cmd)
294
295
295 #---------------------------------------------------------------------------
296 #---------------------------------------------------------------------------
296 # Find scripts
297 # Find scripts
297 #---------------------------------------------------------------------------
298 #---------------------------------------------------------------------------
298
299
299 def find_scripts(entry_points=False, suffix=''):
300 def find_scripts(entry_points=False, suffix=''):
300 """Find IPython's scripts.
301 """Find IPython's scripts.
301
302
302 if entry_points is True:
303 if entry_points is True:
303 return setuptools entry_point-style definitions
304 return setuptools entry_point-style definitions
304 else:
305 else:
305 return file paths of plain scripts [default]
306 return file paths of plain scripts [default]
306
307
307 suffix is appended to script names if entry_points is True, so that the
308 suffix is appended to script names if entry_points is True, so that the
308 Python 3 scripts get named "ipython3" etc.
309 Python 3 scripts get named "ipython3" etc.
309 """
310 """
310 if entry_points:
311 if entry_points:
311 console_scripts = [s % suffix for s in [
312 console_scripts = [s % suffix for s in [
312 'ipython%s = IPython.frontend.terminal.ipapp:launch_new_instance',
313 'ipython%s = IPython.frontend.terminal.ipapp:launch_new_instance',
313 'pycolor%s = IPython.utils.PyColorize:main',
314 'pycolor%s = IPython.utils.PyColorize:main',
314 'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
315 'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
315 'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance',
316 'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance',
316 'iplogger%s = IPython.parallel.apps.iploggerapp:launch_new_instance',
317 'iplogger%s = IPython.parallel.apps.iploggerapp:launch_new_instance',
317 'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance',
318 'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance',
318 'iptest%s = IPython.testing.iptest:main',
319 'iptest%s = IPython.testing.iptest:main',
319 'irunner%s = IPython.lib.irunner:main'
320 'irunner%s = IPython.lib.irunner:main'
320 ]]
321 ]]
321 gui_scripts = []
322 gui_scripts = []
322 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
323 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
323 else:
324 else:
324 parallel_scripts = pjoin('IPython','parallel','scripts')
325 parallel_scripts = pjoin('IPython','parallel','scripts')
325 main_scripts = pjoin('IPython','scripts')
326 main_scripts = pjoin('IPython','scripts')
326 scripts = [
327 scripts = [
327 pjoin(parallel_scripts, 'ipengine'),
328 pjoin(parallel_scripts, 'ipengine'),
328 pjoin(parallel_scripts, 'ipcontroller'),
329 pjoin(parallel_scripts, 'ipcontroller'),
329 pjoin(parallel_scripts, 'ipcluster'),
330 pjoin(parallel_scripts, 'ipcluster'),
330 pjoin(parallel_scripts, 'iplogger'),
331 pjoin(parallel_scripts, 'iplogger'),
331 pjoin(main_scripts, 'ipython'),
332 pjoin(main_scripts, 'ipython'),
332 pjoin(main_scripts, 'pycolor'),
333 pjoin(main_scripts, 'pycolor'),
333 pjoin(main_scripts, 'irunner'),
334 pjoin(main_scripts, 'irunner'),
334 pjoin(main_scripts, 'iptest')
335 pjoin(main_scripts, 'iptest')
335 ]
336 ]
336 return scripts
337 return scripts
337
338
338 #---------------------------------------------------------------------------
339 #---------------------------------------------------------------------------
339 # Verify all dependencies
340 # Verify all dependencies
340 #---------------------------------------------------------------------------
341 #---------------------------------------------------------------------------
341
342
342 def check_for_dependencies():
343 def check_for_dependencies():
343 """Check for IPython's dependencies.
344 """Check for IPython's dependencies.
344
345
345 This function should NOT be called if running under setuptools!
346 This function should NOT be called if running under setuptools!
346 """
347 """
347 from setupext.setupext import (
348 from setupext.setupext import (
348 print_line, print_raw, print_status,
349 print_line, print_raw, print_status,
349 check_for_sphinx, check_for_pygments,
350 check_for_sphinx, check_for_pygments,
350 check_for_nose, check_for_pexpect,
351 check_for_nose, check_for_pexpect,
351 check_for_pyzmq, check_for_readline
352 check_for_pyzmq, check_for_readline
352 )
353 )
353 print_line()
354 print_line()
354 print_raw("BUILDING IPYTHON")
355 print_raw("BUILDING IPYTHON")
355 print_status('python', sys.version)
356 print_status('python', sys.version)
356 print_status('platform', sys.platform)
357 print_status('platform', sys.platform)
357 if sys.platform == 'win32':
358 if sys.platform == 'win32':
358 print_status('Windows version', sys.getwindowsversion())
359 print_status('Windows version', sys.getwindowsversion())
359
360
360 print_raw("")
361 print_raw("")
361 print_raw("OPTIONAL DEPENDENCIES")
362 print_raw("OPTIONAL DEPENDENCIES")
362
363
363 check_for_sphinx()
364 check_for_sphinx()
364 check_for_pygments()
365 check_for_pygments()
365 check_for_nose()
366 check_for_nose()
366 check_for_pexpect()
367 check_for_pexpect()
367 check_for_pyzmq()
368 check_for_pyzmq()
368 check_for_readline()
369 check_for_readline()
369
370
370 def record_commit_info(pkg_dir, build_cmd=build_py):
371 def record_commit_info(pkg_dir, build_cmd=build_py):
371 """ Return extended build command class for recording commit
372 """ Return extended build command class for recording commit
372
373
373 records git commit in IPython.utils._sysinfo.commit
374 records git commit in IPython.utils._sysinfo.commit
374
375
375 for use in IPython.utils.sysinfo.sys_info() calls after installation.
376 for use in IPython.utils.sysinfo.sys_info() calls after installation.
376 """
377 """
377
378
378 class MyBuildPy(build_cmd):
379 class MyBuildPy(build_cmd):
379 ''' Subclass to write commit data into installation tree '''
380 ''' Subclass to write commit data into installation tree '''
380 def run(self):
381 def run(self):
381 build_cmd.run(self)
382 build_cmd.run(self)
382 import subprocess
383 import subprocess
383 proc = subprocess.Popen('git rev-parse --short HEAD',
384 proc = subprocess.Popen('git rev-parse --short HEAD',
384 stdout=subprocess.PIPE,
385 stdout=subprocess.PIPE,
385 stderr=subprocess.PIPE,
386 stderr=subprocess.PIPE,
386 shell=True)
387 shell=True)
387 repo_commit, _ = proc.communicate()
388 repo_commit, _ = proc.communicate()
388 repo_commit = repo_commit.strip()
389 repo_commit = repo_commit.strip()
389 # We write the installation commit even if it's empty
390 # We write the installation commit even if it's empty
390 out_pth = pjoin(self.build_lib, pkg_dir, 'utils', '_sysinfo.py')
391 out_pth = pjoin(self.build_lib, pkg_dir, 'utils', '_sysinfo.py')
391 with open(out_pth, 'w') as out_file:
392 with open(out_pth, 'w') as out_file:
392 out_file.writelines([
393 out_file.writelines([
393 '# GENERATED BY setup.py\n',
394 '# GENERATED BY setup.py\n',
394 'commit = "%s"\n' % repo_commit.decode('ascii'),
395 'commit = "%s"\n' % repo_commit.decode('ascii'),
395 ])
396 ])
396 return MyBuildPy
397 return MyBuildPy
General Comments 0
You need to be logged in to leave comments. Login now