Mercurial > hg > PaInt
view paint/info.py @ 58:13767ee2ddf4
start adding an egg_info based information thingy
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Wed, 23 Jan 2013 16:59:36 -0800 |
parents | d5e5c7496784 |
children | acee5e882768 |
line wrap: on
line source
""" interfaces to get information from a package """ import imp import os import subprocess import sys from subprocess import check_call as call class PackageInfo(object): """abstract base class of package info""" def __init__(self, path): """ - path : path to setup.py or its directory """ if os.path.isdir(path): path = os.path.join(path, 'setup.py') assert os.path.exists(path), "'%s' not found" % path self.setup_py = os.path.abspath(path) def __call__(self): """returns dictionary of package info""" raise NotImplementedError("abstract base class") class SetupOverridePackageInfo(PackageInfo): """ gather setup.py information by overriding the function """ def __call__(self): setuptools = sys.modules.get('setuptools') sys.modules['setuptools'] = sys.modules[__name__] globals()['setup'] = self._setup try: module = imp.load_source('setup', self.setup_py) finally: sys.modules.pop('setuptools') if setuptools: sys.modules['setuptools'] = setuptools globals().pop('setup') return self.__dict__.pop('_info') def _setup(self, **kwargs): self._info = kwargs class EggInfo(PackageInfo): """ use `python setup.py egg_info` to gather package information """ def __call__(self): info = self.read_pkg_info(self._pkg_info()) # TODO: install_requires return info @classmethod def read_pkg_info(cls, path): """reads PKG-INFO and returns a dict""" # read the package information info_dict = {} for line in file(path).readlines(): if not line or line[0].isspace(): continue # XXX neglects description assert ':' in line key, value = [i.strip() for i in line.split(':', 1)] info_dict[key] = value # return the information return info_dict def _egg_info(self): """build the egg_info directory""" if self._egg_info_path: return self._egg_info_path directory = os.path.dirname(self.setup_py) # setup the egg info try: call([sys.executable, 'setup.py', 'egg_info'], cwd=directory, stdout=subprocess.PIPE) except Exception: print "Failure to generate egg_info: %s" % self.setup_py raise # get the .egg-info directory egg_info = [i for i in os.listdir(directory) if i.endswith('.egg-info')] assert len(egg_info) == 1, 'Expected one .egg-info directory in %s, got: %s' % (directory, egg_info) egg_info = os.path.join(directory, egg_info[0]) assert os.path.isdir(egg_info), "%s is not a directory" % egg_info # cache it self._egg_info_path = egg_info return self._egg_info_path def _pkg_info(self): """returns path to PKG-INFO file""" if self._pkg_info_path: # return cached value return self._pkg_info_path try: egg_info = self._egg_info() except Exception, exception: # try to get the package info from a file path = os.path.dirname(self.setup_py) pkg_info = os.path.join(path, 'PKG-INFO') if os.path.exists(pkg_info): self._pkg_info_path = pkg_info return self._pkg_info_path raise Exception("Cannot find or generate PKG-INFO") pkg_info = os.path.join(egg_info, 'PKG-INFO') assert os.path.exists(pkg_info) self._pkg_info_path = pkg_info return self._pkg_info_path