diff options
Diffstat (limited to 'baserockimport/exts/importer_pip_common.py')
-rw-r--r-- | baserockimport/exts/importer_pip_common.py | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/baserockimport/exts/importer_pip_common.py b/baserockimport/exts/importer_pip_common.py new file mode 100644 index 0000000..be8346d --- /dev/null +++ b/baserockimport/exts/importer_pip_common.py @@ -0,0 +1,100 @@ +from __future__ import print_function + +import sys +import logging + +from importer_base import ImportExtension + +PYPI_URL = 'http://pypi.python.org/pypi' + +# TODO: I'm guessing these things are probably standard somewhere +def warn(*args, **kwargs): + print('%s:' % sys.argv[0], *args, file=sys.stderr, **kwargs) + +def error(*args, **kwargs): + warn(*args, **kwargs) + sys.exit(1) + +def specs_satisfied(version, specs): + def mapping_error(op): + # We parse ops with requirements-parser, so any invalid user input + # should be detected there. This really guards against + # the pip developers adding some new operation to a requirement. + error("Invalid op in spec: %s" % op) + + opmap = {'==' : lambda x, y: x == y, '!=' : lambda x, y: x != y, + '<=' : lambda x, y: x <= y, '>=' : lambda x, y: x >= y, + '<': lambda x, y: x < y, '>' : lambda x, y: x > y} + + def get_op_func(op): + return opmap[op] if op in opmap else lambda x, y: mapping_error(op) + + return all([get_op_func(op)(version, sv) for (op, sv) in specs]) + +def name_or_closest(client, package_name): + '''Obtain a list of releases for a given package, + packages on pypi are case insensitive, so we need this hack + to obtain a release when our input package name doesn't + case-sensitively match the package name used on pypi''' + + # TODO: update above comment + + results = client.package_releases(package_name) + + if len(results) > 0: + logging.debug('Found package %s' % package_name) + return package_name + + logging.debug("Couldn't find exact match for %s," + "searching for a similar match" % package_name) + results = client.search({'name': package_name}) + + logging.debug("Got the following similarly named packages '%s': %s" + % (package_name, str([(result['name'], result['version']) + for result in results]))) + + logging.debug('Filtering for exact case-insensitive matches') + + results = [result for result in results + if result['name'].lower() == package_name.lower()] + + logging.debug('Filtered results: %s' % results) + + return results[0]['name'] if len(results) > 0 else None + +def find_releases(client, package_name): + + logging.debug('Finding releases for %s' % package_name) + results = client.package_releases(package_name) + + if len(results) > 0: + logging.debug('Found package %s' % package_name) + return results + + logging.debug("Couldn't find exact match for %s," + "searching for a similar match" % package_name) + results = client.search({'name': package_name}) + + logging.debug("Got the following similarly named packages '%s': %s" + % (package_name, str([(result['name'], result['version']) + for result in results]))) + + logging.debug('Filtering for exact case-insensitive matches') + + results = [result for result in results + if result['name'].lower() == package_name.lower()] + + logging.debug('Filtered results: %s' % results) + + return (client.package_releases(results[0]['name']) + if len(results) > 0 else []) + +# We subclass the ImportExtension to setup the logger, +# so that we can send logs to the import tool's log (morph's log in fact) +class PythonExtension(ImportExtension): + def __init__(self): + super(PythonExtension, self).__init__() + + def process_args(self, _): + import __main__ + __main__.main() |