##// END OF EJS Templates
Add utility to record commit information in archives/tarballs....
Fernando Perez -
Show More
@@ -1,5 +1,4 b''
1 # encoding: utf-8
1 # encoding: utf-8
2
3 """
2 """
4 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
5
4
@@ -9,8 +8,7 b' This includes:'
9 * Functions for finding things like packages, package data, etc.
8 * Functions for finding things like packages, package data, etc.
10 * A function for checking dependencies.
9 * A function for checking dependencies.
11 """
10 """
12
11 from __future__ import print_function
13 __docformat__ = "restructuredtext en"
14
12
15 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
16 # Copyright (C) 2008 The IPython Development Team
14 # Copyright (C) 2008 The IPython Development Team
@@ -22,9 +20,11 b' __docformat__ = "restructuredtext en"'
22 #-------------------------------------------------------------------------------
20 #-------------------------------------------------------------------------------
23 # Imports
21 # Imports
24 #-------------------------------------------------------------------------------
22 #-------------------------------------------------------------------------------
23 import os
24 import sys
25
25
26 import os, sys
26 from ConfigParser import ConfigParser
27
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
@@ -38,7 +38,7 b' 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
@@ -214,10 +214,10 b' def find_data_files():'
214 ] + manual_files + example_files
214 ] + manual_files + example_files
215
215
216 ## import pprint # dbg
216 ## import pprint # dbg
217 ## print '*'*80
217 ## print('*'*80)
218 ## print 'data files'
218 ## print('data files')
219 ## pprint.pprint(data_files)
219 ## pprint.pprint(data_files)
220 ## print '*'*80
220 ## print('*'*80)
221
221
222 return data_files
222 return data_files
223
223
@@ -271,8 +271,10 b' def find_scripts():'
271 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
271 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
272 # doesn't find them.
272 # doesn't find them.
273 if 'bdist_wininst' in sys.argv:
273 if 'bdist_wininst' in sys.argv:
274 if len(sys.argv) > 2 and ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
274 if len(sys.argv) > 2 and \
275 print >> sys.stderr,"ERROR: bdist_wininst must be run alone. Exiting."
275 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
276 print("ERROR: bdist_wininst must be run alone. Exiting.",
277 file=sys.stderr)
276 sys.exit(1)
278 sys.exit(1)
277 scripts.append(pjoin('scripts','ipython_win_post_install.py'))
279 scripts.append(pjoin('scripts','ipython_win_post_install.py'))
278
280
@@ -288,7 +290,7 b' def check_for_dependencies():'
288 This function should NOT be called if running under setuptools!
290 This function should NOT be called if running under setuptools!
289 """
291 """
290 from setupext.setupext import (
292 from setupext.setupext import (
291 print_line, print_raw, print_status, print_message,
293 print_line, print_raw, print_status,
292 check_for_zopeinterface, check_for_twisted,
294 check_for_zopeinterface, check_for_twisted,
293 check_for_foolscap, check_for_pyopenssl,
295 check_for_foolscap, check_for_pyopenssl,
294 check_for_sphinx, check_for_pygments,
296 check_for_sphinx, check_for_pygments,
@@ -312,3 +314,61 b' def check_for_dependencies():'
312 check_for_pygments()
314 check_for_pygments()
313 check_for_nose()
315 check_for_nose()
314 check_for_pexpect()
316 check_for_pexpect()
317
318
319 def record_commit_info(pkg_dir, build_cmd=build_py):
320 """ Return extended build command class for recording commit
321
322 The extended command tries to run git to find the current commit, getting
323 the empty string if it fails. It then writes the commit hash into a file
324 in the `pkg_dir` path, named ``.git_commit_info.ini``.
325
326 In due course this information can be used by the package after it is
327 installed, to tell you what commit it was installed from if known.
328
329 To make use of this system, you need a package with a .git_commit_info.ini
330 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
331 this::
332
333 # This is an ini file that may contain information about the code state
334 [commit hash]
335 # The line below may contain a valid hash if it has been substituted
336 # during 'git archive'
337 archive_subst_hash=$Format:%h$
338 # This line may be modified by the install process
339 install_hash=
340
341 The .git_commit_info file above is also designed to be used with git
342 substitution - so you probably also want a ``.gitattributes`` file in the
343 root directory of your working tree that contains something like this::
344
345 myproject/.git_commit_info.ini export-subst
346
347 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
348 archive`` - useful in case someone makes such an archive - for example with
349 via the github 'download source' button.
350
351 Although all the above will work as is, you might consider having something
352 like a ``get_info()`` function in your package to display the commit
353 information at the terminal. See the ``pkg_info.py`` module in the nipy
354 package for an example.
355 """
356 class MyBuildPy(build_cmd):
357 ''' Subclass to write commit data into installation tree '''
358 def run(self):
359 build_py.run(self)
360 import subprocess
361 proc = subprocess.Popen('git rev-parse --short HEAD',
362 stdout=subprocess.PIPE,
363 stderr=subprocess.PIPE,
364 shell=True)
365 repo_commit, _ = proc.communicate()
366 # We write the installation commit even if it's empty
367 cfg_parser = ConfigParser()
368 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
369 cfg_parser.set('commit hash', 'install_hash', repo_commit)
370 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
371 out_file = open(out_pth, 'wt')
372 cfg_parser.write(out_file)
373 out_file.close()
374 return MyBuildPy
General Comments 0
You need to be logged in to leave comments. Login now