Skip to content

Instantly share code, notes, and snippets.

@mythmon
Created January 28, 2015 19:02
Show Gist options
  • Save mythmon/3e983c11fb6417cca554 to your computer and use it in GitHub Desktop.
Save mythmon/3e983c11fb6417cca554 to your computer and use it in GitHub Desktop.
#!/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
print '### Not installed, but wanted'
for key in sorted(not_installed):
print '{} {}'.format(key, wanted[key])
if wrong_version:
print
print '### Wrong version'
for key in sorted(wrong_version):
print '{}: wanted {}, but got {}'.format(key, wanted[key], installed[key])
if unknown_version:
print
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