Newer
Older
import argparse
import json
import os
import re
import subprocess
import sys
def find_dependencies(json_input, package):
if isinstance(json_input, dict):
keys = json_input.keys()
if 'package_name' in keys and 'required_version' in keys:
if re.search(r'^%s$' % package, json_input['package_name'], re.IGNORECASE):
yield json_input['required_version']
for child_val in find_dependencies(json_input['dependencies'], package):
yield child_val
elif isinstance(json_input, list):
for item in json_input:
for item_val in find_dependencies(item, package):
yield item_val
def arg_parse():
parser = argparse.ArgumentParser(description="Pipupgradedependencies upgrades all outdated packages with respect to existing dependencies.")
os.environ["PYTHONWARNINGS"] = "ignore:DEPRECATION"
try:
subprocess.check_call(["pip", "install", "--upgrade", "pip"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
sys.exit(1)
finished_upgrades = []
while True:
try:
outdated_packages = subprocess.check_output(["pip", "list", "--outdated"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
sys.exit(1)
outdated_packages = [line.split()[0] for line in outdated_packages.strip().split("\n")[2:]]
try:
pipdeptree = subprocess.check_output(["pipdeptree", "--json-tree"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
sys.exit(1)
pipdeptree = pipdeptree.strip()
jsonpipdeptree = json.loads(pipdeptree)
possible_upgrades = []
for package in outdated_packages:
if package in finished_upgrades:
continue
package_dependencies = [ _ for _ in find_dependencies(jsonpipdeptree, package)]
package_dependencies = list(set(package_dependencies))
if len([dependency for dependency in package_dependencies if re.search(r'(^==.*|^\d.*)', dependency) is not None]) == 0:
possible_upgrades.append({'package': package, 'dependencies': [ dependency for dependency in package_dependencies if 'Any' not in dependency]})
try:
package = possible_upgrades[-1]
except IndexError:
break
finished_upgrades.append(package['package'])
try:
subprocess.check_call(["pip", "install", "--upgrade", "%s%s" % (package['package'], "".join(package['dependencies']))], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
sys.exit(1)
if len(possible_upgrades) == len(finished_upgrades):
break
print "Done."
if __name__ == "__main__":
main()