new_contents: #!/usr/bin/env python
  
  # global
  import argparse
  import sys
  import subprocess
  from collections import OrderedDict
  import glob
  import os
  
  # Assume this script is in botan/src/scripts
  botan_root = os.path.join(os.path.dirname(sys.argv[0]), "..", "..")
  
  # locale
  sys.path.append(botan_root)
  from configure import ModuleInfo
  
  parser = argparse.ArgumentParser(description=
      'Show Botan module dependencies. '
      'The output is reduced by indirect dependencies, '
      'i.e. you must look at the result recursively to get all dependencies.')
  
  parser.add_argument('mode',
                      choices=["list", "draw"],
                      help='The output mode')
  parser.add_argument('--format',
                      nargs='?',
                      choices=["pdf", "png"],
                      default="pdf",
                      help='The file format (drawing mode only)')
  parser.add_argument('--engine',
                      nargs='?',
                      choices=["fdp", "dot"],
                      default="fdp",
                      help='The graph engine (drawing mode only)')
  parser.add_argument('--verbose', dest='verbose', action='store_const',
                      const=True, default=False,
                      help='Verbose output (default: false)')
  args = parser.parse_args()
  
  files = []
  files += glob.glob(botan_root + '/src/lib/*/*/*/*/*/*/info.txt')
  files += glob.glob(botan_root + '/src/lib/*/*/*/*/*/info.txt')
  files += glob.glob(botan_root + '/src/lib/*/*/*/*/info.txt')
  files += glob.glob(botan_root + '/src/lib/*/*/*/info.txt')
  files += glob.glob(botan_root + '/src/lib/*/*/info.txt')
  files += glob.glob(botan_root + '/src/lib/*/info.txt')
  files += glob.glob(botan_root + '/src/lib/info.txt')
  files.sort()
  
  if len(files) == 0:
      print("No info.txt files found.")
      sys.exit(1)
  
  modules = []
  
  def dicts(t): return {k: dicts(t[k]) for k in t}
  
  def paths(t, path = [], level=0):
      ret =  []
      for key in t:
          ret.append(path + [key])
          ret += paths(t[key], path + [key], level+1)
      return ret
  
  if args.verbose:
      print("Getting dependencies from into.txt files ...")
  
  for filename in files:
      (rest, info_txt) = os.path.split(filename)
      (rest, modname) = os.path.split(rest)
      module = ModuleInfo(filename)
      modules.append(module)
      if args.verbose:
          print(module.basename)
          print("\t" + str(set(module.dependencies())))
  
  if args.verbose:
      print(str(len(modules)) + " modules:")
      names=[m.basename for m in modules]
      names.sort()
      print(names)
      print("")
  
  if args.verbose:
      print("resolving dependencies ...")
  
  all_dependencies = dict()
  direct_dependencies = dict()
  
  for module in modules:
      lst = module.dependencies()
      direct_dependencies[module.basename] = set(lst)
  
  all_dependencies = direct_dependencies.copy()
  
  #print(direct_dependencies)
  
  def cartinality(depdict):
      return sum([len(depdict[k]) for k in depdict])
  
  # Sort
  direct_dependencies = OrderedDict(sorted(direct_dependencies.items()))
  
  def depends_on(a, b):
      if not a in all_dependencies:
          return False
      else:
          return b in all_dependencies[a]
  
  def remove_indirect_dependencies():
      for mod in direct_dependencies:
          for one in direct_dependencies[mod]:
              others = direct_dependencies[mod] - set([one])
              for other in others:
                  if depends_on(one, other):
                      direct_dependencies[mod].remove(one)
                      return
                      # Go to next mod
  
  last_card = -1
  while True:
      card = cartinality(direct_dependencies)
      # print(card)
      if card == last_card:
          break;
      last_card = card
      remove_indirect_dependencies()
  
  def openfile(f):
      if sys.platform.startswith('linux'):
          subprocess.call(["xdg-open", f])
      else:
          os.startfile(f)
  
  if args.verbose:
      print("Done resolving dependencies.")
  
  if args.mode == "list":
      for key in direct_dependencies:
          print(key.ljust(17) + " : " + ", ".join(sorted(direct_dependencies[key])))
  
  if args.mode == "draw":
      import graphviz as gv
      import tempfile
  
      tmpdir = tempfile.mkdtemp(prefix="botan-")
  
      g2 = gv.Digraph(format=args.format, engine=args.engine)
      for key in direct_dependencies:
          g2.node(key)
          for dep in direct_dependencies[key]:
              g2.edge(key, dep)
  
      if args.verbose:
          print("Rendering graph ...")
      filename = g2.render(filename='graph', directory=tmpdir)
  
      if args.verbose:
          print("Opening " + filename + " ...")
      openfile(filename)
  
  
subject: Add script that shows Botan module dependencies