aboutsummaryrefslogtreecommitdiff
path: root/verhawk
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2016-08-08 16:03:02 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2016-08-08 17:07:13 -0400
commit597b1d6e39039066ce51e4c02d74ed6545ffccdf (patch)
tree535605fa822704c447ed94d9e89c4f28d23b6a5b /verhawk
parent9f6283fd7e9085154345fceeb01f66e5c50a4a2d (diff)
downloadverhawk-597b1d6e39039066ce51e4c02d74ed6545ffccdf.tar.gz
Refactor into a package; Add RELIC 1.0.50.0.1
Diffstat (limited to 'verhawk')
-rw-r--r--verhawk/__init__.py3
-rw-r--r--verhawk/cli/__init__.py0
-rw-r--r--verhawk/cli/verhawk.py61
-rw-r--r--verhawk/constants.py4
-rw-r--r--verhawk/scanner.py81
5 files changed, 149 insertions, 0 deletions
diff --git a/verhawk/__init__.py b/verhawk/__init__.py
new file mode 100644
index 0000000..30eb98f
--- /dev/null
+++ b/verhawk/__init__.py
@@ -0,0 +1,3 @@
+from . import scanner
+from .version import *
+
diff --git a/verhawk/cli/__init__.py b/verhawk/cli/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/verhawk/cli/__init__.py
diff --git a/verhawk/cli/verhawk.py b/verhawk/cli/verhawk.py
new file mode 100644
index 0000000..bf69dab
--- /dev/null
+++ b/verhawk/cli/verhawk.py
@@ -0,0 +1,61 @@
+import argparse
+import importlib
+import os
+import sys
+import verhawk.scanner
+import verhawk.constants as constants
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('parent_package')
+ parser.add_argument('-V', '--version',
+ action='store_true',
+ help='Display version information'),
+ parser.add_argument('-e', '--exclude',
+ action='append',
+ default=[],
+ help='Ignore sub-[package|module] by name.')
+ parser.add_argument('-v', '--verbose',
+ action='store_true',
+ help='Show packages without version data.')
+ parser.add_argument('-j', '--json',
+ action='store_true',
+ help='Emit JSON to stdout')
+ parser.add_argument('-p', '--packages-only',
+ action='store_true',
+ help='Ignore non-packages (i.e modules)')
+ parser.add_argument('-r', '--recursive',
+ action='store_true',
+ help='Descend into package looking for additional version data.')
+
+ args = parser.parse_args()
+
+ if args.version:
+ print(verhawk.version.__version_long__)
+ exit(0)
+
+ try:
+ with open(os.devnull, 'w') as devnull:
+ sys.stdout = devnull
+ parent_package = importlib.import_module(args.parent_package)
+
+ sys.stdout = constants.STDOUT
+ except ImportError as e:
+ print(e, file=sys.stderr)
+ exit(1)
+
+ scanner = verhawk.scanner.Scanner(parent_package, args.exclude,
+ args.recursive, args.packages_only)
+
+ if args.json:
+ print(scanner.as_json())
+ else:
+ for pkg, version in sorted(scanner):
+ if not args.verbose and version is None:
+ continue
+
+ print('{0}={1}'.format(pkg, version))
+
+if __name__ == '__main__':
+ main()
diff --git a/verhawk/constants.py b/verhawk/constants.py
new file mode 100644
index 0000000..f9dff6c
--- /dev/null
+++ b/verhawk/constants.py
@@ -0,0 +1,4 @@
+import sys
+
+
+STDERR, STDOUT = sys.stderr, sys.stdout
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())
+
+