Created
January 28, 2015 19:02
-
-
Save mythmon/3e983c11fb6417cca554 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
""" | |
Looks through installed and current requirements, and report any discrepencies. | |
Run this script like `./manage.py runscript checkreqs | |
""" | |
import os | |
import re | |
from collections import defaultdict | |
from subprocess import check_output | |
from traceback import print_exc | |
def run(): | |
try: | |
run_() | |
except Exception: | |
print_exc() | |
raise | |
def run_(): | |
req_files = [] | |
for dirpath, _, filenames in os.walk('requirements'): | |
for name in filenames: | |
req_files.append(os.path.join(dirpath, name)) | |
wanted = {} | |
for req_file in req_files: | |
with open(req_file) as f: | |
for name, version in parse_reqs(f.read()): | |
wanted[name] = version | |
installed = {} | |
for name, version in parse_reqs(check_output(['pip', 'freeze'])): | |
installed[name] = version | |
all_keys = set(wanted.keys()) | |
all_keys.update(installed.keys()) | |
not_wanted = set() | |
not_installed = set() | |
unknown_version = set() | |
wrong_version = set() | |
for key in all_keys: | |
if key in installed and key in wanted: | |
if wanted[key] is None: | |
unknown_version.add(key) | |
elif installed[key] != wanted[key]: | |
wrong_version.add(key) | |
elif key in installed and key not in wanted: | |
not_wanted.add(key) | |
elif key in wanted and key not in installed: | |
not_installed.add(key) | |
if not_wanted: | |
print '### Not wanted, but installed' | |
for key in sorted(not_wanted): | |
print '{} {}'.format(key, installed[key]) | |
if not_installed: | |
print '### Not installed, but wanted' | |
for key in sorted(not_installed): | |
print '{} {}'.format(key, wanted[key]) | |
if wrong_version: | |
print '### Wrong version' | |
for key in sorted(wrong_version): | |
print '{}: wanted {}, but got {}'.format(key, wanted[key], installed[key]) | |
if unknown_version: | |
print '### Unspecified version' | |
for key in sorted(unknown_version): | |
print '{}: {} installed, no version in reqs'.format(key, installed[key]) | |
def parse_reqs(req_str): | |
for line in req_str.split('\n'): | |
if not line or line.startswith('-r') or line.startswith('#'): | |
continue | |
if re.match(r'^https?://', line): | |
match = re.search('#egg=(.*)$', line) | |
if match is not None: | |
line = match.groups()[0] | |
else: | |
print 'XXX', line | |
continue | |
if '==' in line: | |
name, version = re.match(r'^(.+)==(.+)?$', line).groups() | |
else: | |
name = line | |
version = None | |
yield (name, version) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment