##// END OF EJS Templates
Generate package list automatically in find_packages...
MinRK -
Show More
@@ -1,388 +1,351 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,
86 others=None):
87 """
88 Add a package to the list of packages, including certain subpackages.
89 """
90 packages.append('.'.join(['IPython',pname]))
91 if config:
92 packages.append('.'.join(['IPython',pname,'config']))
93 if tests:
94 packages.append('.'.join(['IPython',pname,'tests']))
95 if scripts:
96 packages.append('.'.join(['IPython',pname,'scripts']))
97 if others is not None:
98 for o in others:
99 packages.append('.'.join(['IPython',pname,o]))
100
101 def find_packages():
85 def find_packages():
102 """
86 """
103 Find all of IPython's packages.
87 Find all of IPython's packages.
104 """
88 """
105 packages = ['IPython']
89 excludes = ['deathrow']
106 add_package(packages, 'config', tests=True, others=['profile'])
90 packages = []
107 add_package(packages, 'core', tests=True)
91 for dir,subdirs,files in os.walk('IPython'):
108 add_package(packages, 'extensions')
92 package = dir.replace(os.path.sep, '.')
109 add_package(packages, 'external')
93 if any([ package.startswith('IPython.'+exc) for exc in excludes ]):
110 add_package(packages, 'external.argparse')
94 # package is to be excluded (e.g. deathrow)
111 add_package(packages, 'external.decorator')
95 continue
112 add_package(packages, 'external.decorators')
96 if '__init__.py' not in files:
113 add_package(packages, 'external.guid')
97 # not a package
114 add_package(packages, 'external.Itpl')
98 continue
115 add_package(packages, 'external.mglob')
99 packages.append(package)
116 add_package(packages, 'external.path')
117 add_package(packages, 'external.pexpect')
118 add_package(packages, 'external.pyparsing')
119 add_package(packages, 'external.simplegeneric')
120 add_package(packages, 'external.ssh')
121 add_package(packages, 'kernel')
122 add_package(packages, 'frontend')
123 add_package(packages, 'frontend.qt')
124 add_package(packages, 'frontend.qt.console', tests=True)
125 add_package(packages, 'frontend.terminal', tests=True)
126 add_package(packages, 'lib', tests=True)
127 add_package(packages, 'parallel', tests=True, scripts=True,
128 others=['apps','engine','client','controller'])
129 add_package(packages, 'quarantine', tests=True)
130 add_package(packages, 'scripts')
131 add_package(packages, 'testing', tests=True)
132 add_package(packages, 'testing.plugin', tests=False)
133 add_package(packages, 'utils', tests=True)
134 add_package(packages, 'zmq')
135 add_package(packages, 'zmq.pylab')
136 add_package(packages, 'zmq.gui')
137 return packages
100 return packages
138
101
139 #---------------------------------------------------------------------------
102 #---------------------------------------------------------------------------
140 # Find package data
103 # Find package data
141 #---------------------------------------------------------------------------
104 #---------------------------------------------------------------------------
142
105
143 def find_package_data():
106 def find_package_data():
144 """
107 """
145 Find IPython's package_data.
108 Find IPython's package_data.
146 """
109 """
147 # This is not enough for these things to appear in an sdist.
110 # This is not enough for these things to appear in an sdist.
148 # We need to muck with the MANIFEST to get this to work
111 # We need to muck with the MANIFEST to get this to work
149 package_data = {
112 package_data = {
150 'IPython.config.profile' : ['README', '*/*.py'],
113 'IPython.config.profile' : ['README', '*/*.py'],
151 'IPython.testing' : ['*.txt'],
114 'IPython.testing' : ['*.txt'],
152 }
115 }
153 return package_data
116 return package_data
154
117
155
118
156 #---------------------------------------------------------------------------
119 #---------------------------------------------------------------------------
157 # Find data files
120 # Find data files
158 #---------------------------------------------------------------------------
121 #---------------------------------------------------------------------------
159
122
160 def make_dir_struct(tag,base,out_base):
123 def make_dir_struct(tag,base,out_base):
161 """Make the directory structure of all files below a starting dir.
124 """Make the directory structure of all files below a starting dir.
162
125
163 This is just a convenience routine to help build a nested directory
126 This is just a convenience routine to help build a nested directory
164 hierarchy because distutils is too stupid to do this by itself.
127 hierarchy because distutils is too stupid to do this by itself.
165
128
166 XXX - this needs a proper docstring!
129 XXX - this needs a proper docstring!
167 """
130 """
168
131
169 # we'll use these a lot below
132 # we'll use these a lot below
170 lbase = len(base)
133 lbase = len(base)
171 pathsep = os.path.sep
134 pathsep = os.path.sep
172 lpathsep = len(pathsep)
135 lpathsep = len(pathsep)
173
136
174 out = []
137 out = []
175 for (dirpath,dirnames,filenames) in os.walk(base):
138 for (dirpath,dirnames,filenames) in os.walk(base):
176 # we need to strip out the dirpath from the base to map it to the
139 # we need to strip out the dirpath from the base to map it to the
177 # output (installation) path. This requires possibly stripping the
140 # output (installation) path. This requires possibly stripping the
178 # path separator, because otherwise pjoin will not work correctly
141 # path separator, because otherwise pjoin will not work correctly
179 # (pjoin('foo/','/bar') returns '/bar').
142 # (pjoin('foo/','/bar') returns '/bar').
180
143
181 dp_eff = dirpath[lbase:]
144 dp_eff = dirpath[lbase:]
182 if dp_eff.startswith(pathsep):
145 if dp_eff.startswith(pathsep):
183 dp_eff = dp_eff[lpathsep:]
146 dp_eff = dp_eff[lpathsep:]
184 # The output path must be anchored at the out_base marker
147 # The output path must be anchored at the out_base marker
185 out_path = pjoin(out_base,dp_eff)
148 out_path = pjoin(out_base,dp_eff)
186 # Now we can generate the final filenames. Since os.walk only produces
149 # Now we can generate the final filenames. Since os.walk only produces
187 # filenames, we must join back with the dirpath to get full valid file
150 # filenames, we must join back with the dirpath to get full valid file
188 # paths:
151 # paths:
189 pfiles = [pjoin(dirpath,f) for f in filenames]
152 pfiles = [pjoin(dirpath,f) for f in filenames]
190 # Finally, generate the entry we need, which is a pari of (output
153 # Finally, generate the entry we need, which is a pari of (output
191 # path, files) for use as a data_files parameter in install_data.
154 # path, files) for use as a data_files parameter in install_data.
192 out.append((out_path, pfiles))
155 out.append((out_path, pfiles))
193
156
194 return out
157 return out
195
158
196
159
197 def find_data_files():
160 def find_data_files():
198 """
161 """
199 Find IPython's data_files.
162 Find IPython's data_files.
200
163
201 Most of these are docs.
164 Most of these are docs.
202 """
165 """
203
166
204 docdirbase = pjoin('share', 'doc', 'ipython')
167 docdirbase = pjoin('share', 'doc', 'ipython')
205 manpagebase = pjoin('share', 'man', 'man1')
168 manpagebase = pjoin('share', 'man', 'man1')
206
169
207 # Simple file lists can be made by hand
170 # Simple file lists can be made by hand
208 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
171 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
209 if not manpages:
172 if not manpages:
210 # When running from a source tree, the manpages aren't gzipped
173 # When running from a source tree, the manpages aren't gzipped
211 manpages = filter(isfile, glob(pjoin('docs','man','*.1')))
174 manpages = filter(isfile, glob(pjoin('docs','man','*.1')))
212 igridhelpfiles = filter(isfile,
175 igridhelpfiles = filter(isfile,
213 glob(pjoin('IPython','extensions','igrid_help.*')))
176 glob(pjoin('IPython','extensions','igrid_help.*')))
214
177
215 # For nested structures, use the utility above
178 # For nested structures, use the utility above
216 example_files = make_dir_struct(
179 example_files = make_dir_struct(
217 'data',
180 'data',
218 pjoin('docs','examples'),
181 pjoin('docs','examples'),
219 pjoin(docdirbase,'examples')
182 pjoin(docdirbase,'examples')
220 )
183 )
221 manual_files = make_dir_struct(
184 manual_files = make_dir_struct(
222 'data',
185 'data',
223 pjoin('docs','html'),
186 pjoin('docs','html'),
224 pjoin(docdirbase,'manual')
187 pjoin(docdirbase,'manual')
225 )
188 )
226
189
227 # And assemble the entire output list
190 # And assemble the entire output list
228 data_files = [ (manpagebase, manpages),
191 data_files = [ (manpagebase, manpages),
229 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
192 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
230 ] + manual_files + example_files
193 ] + manual_files + example_files
231
194
232 return data_files
195 return data_files
233
196
234
197
235 def make_man_update_target(manpage):
198 def make_man_update_target(manpage):
236 """Return a target_update-compliant tuple for the given manpage.
199 """Return a target_update-compliant tuple for the given manpage.
237
200
238 Parameters
201 Parameters
239 ----------
202 ----------
240 manpage : string
203 manpage : string
241 Name of the manpage, must include the section number (trailing number).
204 Name of the manpage, must include the section number (trailing number).
242
205
243 Example
206 Example
244 -------
207 -------
245
208
246 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
209 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
247 ('docs/man/ipython.1.gz',
210 ('docs/man/ipython.1.gz',
248 ['docs/man/ipython.1'],
211 ['docs/man/ipython.1'],
249 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
212 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
250 """
213 """
251 man_dir = pjoin('docs', 'man')
214 man_dir = pjoin('docs', 'man')
252 manpage_gz = manpage + '.gz'
215 manpage_gz = manpage + '.gz'
253 manpath = pjoin(man_dir, manpage)
216 manpath = pjoin(man_dir, manpage)
254 manpath_gz = pjoin(man_dir, manpage_gz)
217 manpath_gz = pjoin(man_dir, manpage_gz)
255 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
218 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
256 locals() )
219 locals() )
257 return (manpath_gz, [manpath], gz_cmd)
220 return (manpath_gz, [manpath], gz_cmd)
258
221
259 #---------------------------------------------------------------------------
222 #---------------------------------------------------------------------------
260 # Find scripts
223 # Find scripts
261 #---------------------------------------------------------------------------
224 #---------------------------------------------------------------------------
262
225
263 def find_scripts(entry_points=False):
226 def find_scripts(entry_points=False):
264 """Find IPython's scripts.
227 """Find IPython's scripts.
265
228
266 if entry_points is True:
229 if entry_points is True:
267 return setuptools entry_point-style definitions
230 return setuptools entry_point-style definitions
268 else:
231 else:
269 return file paths of plain scripts [default]
232 return file paths of plain scripts [default]
270 """
233 """
271 if entry_points:
234 if entry_points:
272 console_scripts = [
235 console_scripts = [
273 'ipython = IPython.frontend.terminal.ipapp:launch_new_instance',
236 'ipython = IPython.frontend.terminal.ipapp:launch_new_instance',
274 'pycolor = IPython.utils.PyColorize:main',
237 'pycolor = IPython.utils.PyColorize:main',
275 'ipcontroller = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
238 'ipcontroller = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
276 'ipengine = IPython.parallel.apps.ipengineapp:launch_new_instance',
239 'ipengine = IPython.parallel.apps.ipengineapp:launch_new_instance',
277 'iplogger = IPython.parallel.apps.iploggerapp:launch_new_instance',
240 'iplogger = IPython.parallel.apps.iploggerapp:launch_new_instance',
278 'ipcluster = IPython.parallel.apps.ipclusterapp:launch_new_instance',
241 'ipcluster = IPython.parallel.apps.ipclusterapp:launch_new_instance',
279 'iptest = IPython.testing.iptest:main',
242 'iptest = IPython.testing.iptest:main',
280 'irunner = IPython.lib.irunner:main'
243 'irunner = IPython.lib.irunner:main'
281 ]
244 ]
282 gui_scripts = [
245 gui_scripts = [
283 'ipython-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main',
246 'ipython-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main',
284 ]
247 ]
285 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
248 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
286 else:
249 else:
287 parallel_scripts = pjoin('IPython','parallel','scripts')
250 parallel_scripts = pjoin('IPython','parallel','scripts')
288 main_scripts = pjoin('IPython','scripts')
251 main_scripts = pjoin('IPython','scripts')
289 scripts = [
252 scripts = [
290 pjoin(parallel_scripts, 'ipengine'),
253 pjoin(parallel_scripts, 'ipengine'),
291 pjoin(parallel_scripts, 'ipcontroller'),
254 pjoin(parallel_scripts, 'ipcontroller'),
292 pjoin(parallel_scripts, 'ipcluster'),
255 pjoin(parallel_scripts, 'ipcluster'),
293 pjoin(parallel_scripts, 'iplogger'),
256 pjoin(parallel_scripts, 'iplogger'),
294 pjoin(main_scripts, 'ipython'),
257 pjoin(main_scripts, 'ipython'),
295 pjoin(main_scripts, 'pycolor'),
258 pjoin(main_scripts, 'pycolor'),
296 pjoin(main_scripts, 'irunner'),
259 pjoin(main_scripts, 'irunner'),
297 pjoin(main_scripts, 'iptest')
260 pjoin(main_scripts, 'iptest')
298 ]
261 ]
299 return scripts
262 return scripts
300
263
301 #---------------------------------------------------------------------------
264 #---------------------------------------------------------------------------
302 # Verify all dependencies
265 # Verify all dependencies
303 #---------------------------------------------------------------------------
266 #---------------------------------------------------------------------------
304
267
305 def check_for_dependencies():
268 def check_for_dependencies():
306 """Check for IPython's dependencies.
269 """Check for IPython's dependencies.
307
270
308 This function should NOT be called if running under setuptools!
271 This function should NOT be called if running under setuptools!
309 """
272 """
310 from setupext.setupext import (
273 from setupext.setupext import (
311 print_line, print_raw, print_status,
274 print_line, print_raw, print_status,
312 check_for_sphinx, check_for_pygments,
275 check_for_sphinx, check_for_pygments,
313 check_for_nose, check_for_pexpect,
276 check_for_nose, check_for_pexpect,
314 check_for_pyzmq, check_for_readline
277 check_for_pyzmq, check_for_readline
315 )
278 )
316 print_line()
279 print_line()
317 print_raw("BUILDING IPYTHON")
280 print_raw("BUILDING IPYTHON")
318 print_status('python', sys.version)
281 print_status('python', sys.version)
319 print_status('platform', sys.platform)
282 print_status('platform', sys.platform)
320 if sys.platform == 'win32':
283 if sys.platform == 'win32':
321 print_status('Windows version', sys.getwindowsversion())
284 print_status('Windows version', sys.getwindowsversion())
322
285
323 print_raw("")
286 print_raw("")
324 print_raw("OPTIONAL DEPENDENCIES")
287 print_raw("OPTIONAL DEPENDENCIES")
325
288
326 check_for_sphinx()
289 check_for_sphinx()
327 check_for_pygments()
290 check_for_pygments()
328 check_for_nose()
291 check_for_nose()
329 check_for_pexpect()
292 check_for_pexpect()
330 check_for_pyzmq()
293 check_for_pyzmq()
331 check_for_readline()
294 check_for_readline()
332
295
333 def record_commit_info(pkg_dir, build_cmd=build_py):
296 def record_commit_info(pkg_dir, build_cmd=build_py):
334 """ Return extended build command class for recording commit
297 """ Return extended build command class for recording commit
335
298
336 The extended command tries to run git to find the current commit, getting
299 The extended command tries to run git to find the current commit, getting
337 the empty string if it fails. It then writes the commit hash into a file
300 the empty string if it fails. It then writes the commit hash into a file
338 in the `pkg_dir` path, named ``.git_commit_info.ini``.
301 in the `pkg_dir` path, named ``.git_commit_info.ini``.
339
302
340 In due course this information can be used by the package after it is
303 In due course this information can be used by the package after it is
341 installed, to tell you what commit it was installed from if known.
304 installed, to tell you what commit it was installed from if known.
342
305
343 To make use of this system, you need a package with a .git_commit_info.ini
306 To make use of this system, you need a package with a .git_commit_info.ini
344 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
307 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
345 this::
308 this::
346
309
347 # This is an ini file that may contain information about the code state
310 # This is an ini file that may contain information about the code state
348 [commit hash]
311 [commit hash]
349 # The line below may contain a valid hash if it has been substituted
312 # The line below may contain a valid hash if it has been substituted
350 # during 'git archive'
313 # during 'git archive'
351 archive_subst_hash=$Format:%h$
314 archive_subst_hash=$Format:%h$
352 # This line may be modified by the install process
315 # This line may be modified by the install process
353 install_hash=
316 install_hash=
354
317
355 The .git_commit_info file above is also designed to be used with git
318 The .git_commit_info file above is also designed to be used with git
356 substitution - so you probably also want a ``.gitattributes`` file in the
319 substitution - so you probably also want a ``.gitattributes`` file in the
357 root directory of your working tree that contains something like this::
320 root directory of your working tree that contains something like this::
358
321
359 myproject/.git_commit_info.ini export-subst
322 myproject/.git_commit_info.ini export-subst
360
323
361 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
324 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
362 archive`` - useful in case someone makes such an archive - for example with
325 archive`` - useful in case someone makes such an archive - for example with
363 via the github 'download source' button.
326 via the github 'download source' button.
364
327
365 Although all the above will work as is, you might consider having something
328 Although all the above will work as is, you might consider having something
366 like a ``get_info()`` function in your package to display the commit
329 like a ``get_info()`` function in your package to display the commit
367 information at the terminal. See the ``pkg_info.py`` module in the nipy
330 information at the terminal. See the ``pkg_info.py`` module in the nipy
368 package for an example.
331 package for an example.
369 """
332 """
370 class MyBuildPy(build_cmd):
333 class MyBuildPy(build_cmd):
371 ''' Subclass to write commit data into installation tree '''
334 ''' Subclass to write commit data into installation tree '''
372 def run(self):
335 def run(self):
373 build_py.run(self)
336 build_py.run(self)
374 import subprocess
337 import subprocess
375 proc = subprocess.Popen('git rev-parse --short HEAD',
338 proc = subprocess.Popen('git rev-parse --short HEAD',
376 stdout=subprocess.PIPE,
339 stdout=subprocess.PIPE,
377 stderr=subprocess.PIPE,
340 stderr=subprocess.PIPE,
378 shell=True)
341 shell=True)
379 repo_commit, _ = proc.communicate()
342 repo_commit, _ = proc.communicate()
380 # We write the installation commit even if it's empty
343 # We write the installation commit even if it's empty
381 cfg_parser = ConfigParser()
344 cfg_parser = ConfigParser()
382 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
345 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
383 cfg_parser.set('commit hash', 'install_hash', repo_commit)
346 cfg_parser.set('commit hash', 'install_hash', repo_commit)
384 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
347 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
385 out_file = open(out_pth, 'wt')
348 out_file = open(out_pth, 'wt')
386 cfg_parser.write(out_file)
349 cfg_parser.write(out_file)
387 out_file.close()
350 out_file.close()
388 return MyBuildPy
351 return MyBuildPy
General Comments 0
You need to be logged in to leave comments. Login now