Permalink
Browse files

NF - added commit info machinery

  • Loading branch information...
1 parent b30330b commit ce71d8922d95674a0bf671e1a8dcb083a0febcd5 @matthew-brett matthew-brett committed Oct 3, 2010
Showing with 114 additions and 76 deletions.
  1. +1 −0 .gitattributes
  2. +12 −0 Makefile
  3. +0 −74 build_helpers.py
  4. +6 −0 nipy/COMMIT_INFO.txt
  5. +6 −0 nipy/__init__.py
  6. +83 −0 nipy/pkg_info.py
  7. +6 −2 setup.py
View
@@ -0,0 +1 @@
+nipy/COMMIT_INFO.txt export-subst
View
@@ -1,5 +1,7 @@
# Automating common tasks for NIPY development
+PYTHON = python
+
clean:
find . -regex ".*\.pyc" -exec rm -rf "{}" \;
find . -regex ".*\.so" -exec rm -rf "{}" \;
@@ -19,3 +21,13 @@ build:
install:
python setup.py install
+
+# Update nisext subtree from remote
+update-nisext:
+ git fetch nisext
+ git merge --squash -s subtree --no-commit nisext/master
+
+# Print out info for possible install methods
+check-version-info:
+ $(PYTHON) -c 'from nisext.testers import info_from_here; info_from_here("nipy")'
+
View
@@ -204,80 +204,6 @@ def finalize_options(self):
'build_sphinx': MyBuildDoc}
-# Dependency checks
-def package_check(pkg_name, version=None,
- optional=False,
- checker=LooseVersion,
- version_getter=None,
- messages=None
- ):
- ''' Check if package `pkg_name` is present, and correct version
-
- Parameters
- ----------
- pkg_name : str
- name of package as imported into python
- version : {None, str}, optional
- minimum version of the package that we require. If None, we don't
- check the version. Default is None
- optional : {False, True}, optional
- If False, raise error for absent package or wrong version;
- otherwise warn
- checker : callable, optional
- callable with which to return comparable thing from version
- string. Default is ``distutils.version.LooseVersion``
- version_getter : {None, callable}:
- Callable that takes `pkg_name` as argument, and returns the
- package version string - as in::
-
- ``version = version_getter(pkg_name)``
-
- If None, equivalent to::
-
- mod = __import__(pkg_name); version = mod.__version__``
- messages : None or dict, optional
- dictionary giving output messages
- '''
- if version_getter is None:
- def version_getter(pkg_name):
- mod = __import__(pkg_name)
- return mod.__version__
- if messages is None:
- messages = {}
- msgs = {
- 'missing': 'Cannot import package "%s" - is it installed?',
- 'missing opt': 'Missing optional package "%s"',
- 'opt suffix' : '; you may get run-time errors',
- 'version too old': 'You have version %s of package "%s"'
- ' but we need version >= %s', }
- msgs.update(messages)
- try:
- __import__(pkg_name)
- except ImportError:
- if not optional:
- raise RuntimeError(msgs['missing'] % pkg_name)
- log.warn(msgs['missing opt'] % pkg_name +
- msgs['opt suffix'])
- return
- if not version:
- return
- try:
- have_version = version_getter(pkg_name)
- except AttributeError:
- raise RuntimeError('Cannot find version for %s' % pkg_name)
- if checker(have_version) < checker(version):
- if optional:
- log.warn(msgs['version too old'] + msgs['opt suffix'],
- have_version,
- pkg_name,
- version)
- else:
- raise RuntimeError(msgs['version too old'],
- have_version,
- pkg_name,
- version)
-
-
def have_good_cython():
try:
from Cython.Compiler.Version import version
View
@@ -0,0 +1,6 @@
+# This is an ini file that may contain information about the code state
+[commit hash]
+# The line below may contain a valid hash if it has been substituted during 'git archive'
+archive_subst_hash=$Format:%h$
+# This line may be modified by the install process
+install_hash=
View
@@ -1,5 +1,7 @@
# emacs: -*- coding: utf-8; mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set fileencoding=utf-8 ft=python sts=4 ts=4 sw=4 et:
+import os
+
from .info import (LONG_DESCRIPTION as __doc__,
URL as __url__,
STATUS as __status__)
@@ -47,6 +49,10 @@ def _test_local_install():
from nipy.io.api import load_image, save_image, as_image
from nipy.core.api import is_image
+# Set up package information function
+from .pkg_info import get_pkg_info as _get_pkg_info
+get_info = lambda : _get_pkg_info(os.path.dirname(__file__))
+
# Cleanup namespace
del _test_local_install
# If this file is exec after being imported, the following lines will
View
@@ -0,0 +1,83 @@
+import os
+import sys
+import subprocess
+from ConfigParser import ConfigParser
+
+COMMIT_INFO_FNAME = 'COMMIT_INFO.txt'
+
+def pkg_commit_hash(pkg_path):
+ ''' Get short form of commit hash given directory `pkg_path`
+
+ There should be a file called 'COMMIT_INFO.txt' in `pkg_path`. This is a
+ file in INI file format, with at least one section: ``commit hash``, and two
+ variables ``archive_subst_hash`` and ``install_hash``. The first has a
+ substitution pattern in it which may have been filled by the execution of
+ ``git archive`` if this is an archive generated that way. The second is
+ filled in by the installation, if the installation is from a git archive.
+
+ We get the commit hash from (in order of preference):
+
+ * A substituted value in ``archive_subst_hash``
+ * A written commit hash value in ``install_hash`
+ * git's output, if we are in a git repository
+
+ If all these fail, we return a not-found placeholder tuple
+
+ Parameters
+ ----------
+ pkg_path : str
+ directory containing package
+
+ Returns
+ -------
+ hash_from : str
+ Where we got the hash from - description
+ hash_str : str
+ short form of hash
+ '''
+ # Try and get commit from written commit text file
+ pth = os.path.join(pkg_path, COMMIT_INFO_FNAME)
+ if not os.path.isfile(pth):
+ raise IOError('Missing commit info file %s' % pth)
+ cfg_parser = ConfigParser()
+ cfg_parser.read(pth)
+ archive_subst = cfg_parser.get('commit hash', 'archive_subst_hash')
+ if not archive_subst.startswith('$Format'): # it has been substituted
+ return 'archive substitution', archive_subst
+ install_subst = cfg_parser.get('commit hash', 'install_hash')
+ if install_subst != '':
+ return 'installation', install_subst
+ # maybe we are in a repository
+ proc = subprocess.Popen('git rev-parse --short HEAD',
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ cwd=pkg_path, shell=True)
+ repo_commit, _ = proc.communicate()
+ if repo_commit:
+ return 'repository', repo_commit.strip()
+ return '(none found)', '<not found>'
+
+
+def get_pkg_info(pkg_path):
+ ''' Return dict describing the context of this package
+
+ Parameters
+ ----------
+ pkg_path : str
+ path containing __init__.py for package
+
+ Returns
+ -------
+ context : dict
+ with named parameters of interest
+ '''
+ src, hsh = pkg_commit_hash(pkg_path)
+ import numpy
+ return dict(
+ pkg_path=pkg_path,
+ commit_source=src,
+ commit_hash=hsh,
+ sys_version=sys.version,
+ sys_executable=sys.executable,
+ sys_platform=sys.platform,
+ np_version=numpy.__version__)
View
@@ -5,12 +5,16 @@
from glob import glob
from distutils import log
-# monkey-patch numpy distutils to use Cython instead of Pyrex
-from build_helpers import (generate_a_pyrex_source, package_check,
+# Import build helpers
+from nisext.sexts import package_check, get_comrec_build
+from build_helpers import (generate_a_pyrex_source,
cmdclass, INFO_VARS)
+# monkey-patch numpy distutils to use Cython instead of Pyrex
from numpy.distutils.command.build_src import build_src
build_src.generate_a_pyrex_source = generate_a_pyrex_source
+# Add custom commit-recording build command
+cmdclass['build_py'] = get_comrec_build('nipy')
def configuration(parent_package='',top_path=None):
from numpy.distutils.misc_util import Configuration

0 comments on commit ce71d89

Please sign in to comment.