summaryrefslogtreecommitdiff
path: root/baserockimport/exts/importer_pip_common.py
diff options
context:
space:
mode:
Diffstat (limited to 'baserockimport/exts/importer_pip_common.py')
-rw-r--r--baserockimport/exts/importer_pip_common.py100
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()