Skip to content
Snippets Groups Projects
pipupgradedependencies.py 2.61 KiB
Newer Older
  • Learn to ignore specific revisions
  • Marek Chrastina's avatar
    Marek Chrastina committed
    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.")
    
    Marek Chrastina's avatar
    Marek Chrastina committed
      parser_args = parser.parse_args()
    
    def main():
    
      arg_parse()
    
    Marek Chrastina's avatar
    Marek Chrastina committed
      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))
    
    Marek Chrastina's avatar
    Marek Chrastina committed
          if len([dependency for dependency in package_dependencies if re.search(r'(^==.*|^\d.*)', dependency) is not None]) == 0:
    
    Marek Chrastina's avatar
    Marek Chrastina committed
            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()