diff options
Diffstat (limited to 'verhawk/scanner.py')
-rw-r--r-- | verhawk/scanner.py | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/verhawk/scanner.py b/verhawk/scanner.py new file mode 100644 index 0000000..41b6ecd --- /dev/null +++ b/verhawk/scanner.py @@ -0,0 +1,81 @@ +from __future__ import print_function +import json +import os +import pkgutil +import sys +from . import constants + + +class Scanner(object): + def __init__(self, package, exclusions=[], recursive=False, packages_only=False): + self.package = package + self.prefix = self.package.__name__ + '.' + self.exclusions = exclusions + self.versions = dict() + self.recursive = recursive + self.packages_only = packages_only + self.scan() + + def __iter__(self): + for k, v in self.versions.items(): + yield k, v + + def scan(self): + try: + module = self.package + modname = module.__name__ + + try: + self.versions[modname] = module.__version__ or module.version or module._version + except AttributeError: + self.versions[modname] = None + except ImportError as e: + print('ImportError({0}): {1}'.format(modname, e), file=sys.stderr) + + if self.recursive: + try: + for importer, modname, ispkg in pkgutil.iter_modules(self.package.__path__, self.prefix): + excluded = False + for ex in self.exclusions: + ex = self.prefix + ex + if modname == ex: + excluded = True + break + + if excluded: + continue + + if self.packages_only and not ispkg: + continue + + try: + module = None + with open(os.devnull, 'w') as devnull: + sys.stdout = devnull + module = importer.find_module(modname).load_module(modname) + + sys.stdout = constants.STDOUT + + try: + self.versions[modname] = module.__version__ or module.version or module._version + except AttributeError: + self.versions[modname] = None + + except ImportError as e: + print('ImportError({0}): {1}'.format(modname, e), file=sys.stderr) + + except AttributeError: + # has no sub-packages or sub-modules, so ignore + pass + except TypeError: + # has strange requirements at import-time, so ignore + pass + + def as_json(self): + return json.dumps(self.versions, sort_keys=True) + + + def as_zip(self): + return zip(self.versions.keys(), self.versions.values()) + + |