diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/third_party/botan/src/scripts/show_dependencies.py | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/third_party/botan/src/scripts/show_dependencies.py')
-rwxr-xr-x | comm/third_party/botan/src/scripts/show_dependencies.py | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/scripts/show_dependencies.py b/comm/third_party/botan/src/scripts/show_dependencies.py new file mode 100755 index 0000000000..edf2d91e01 --- /dev/null +++ b/comm/third_party/botan/src/scripts/show_dependencies.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python + +""" +Show Botan module dependencies as a list or graph. + +Requires graphviz from pip when graphical output is selected: +https://pypi.python.org/pypi/graphviz + +(C) 2015,2018 Simon Warta (Kullo GmbH) + +Botan is released under the Simplified BSD License (see license.txt) +""" + +# global +import argparse +import copy +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="dot", + help='The graph engine (drawing mode only)') +parser.add_argument('--all', dest='all', action='store_const', + const=True, default=False, + help='Show all dependencies. Default: direct dependencies only. (list 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(None)))) + +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 ...") + +def cartinality(depdict): + return sum([len(depdict[k]) for k in depdict]) + +registered_dependencies = dict() +all_dependencies = dict() +direct_dependencies = dict() + +for module in modules: + lst = module.dependencies(None) + registered_dependencies[module.basename] = set(lst) - set([module.basename]) + +# Get all_dependencies from registered_dependencies +def add_dependency(): + for key in all_dependencies: + potentially_new_modules_for_key = None + new_modules_for_key = None + for currently_in in all_dependencies[key]: + if currently_in in all_dependencies: + potentially_new_modules_for_key = all_dependencies[currently_in] - set([key]) + if not potentially_new_modules_for_key <= all_dependencies[key]: + new_modules_for_key = potentially_new_modules_for_key.copy() + break + if new_modules_for_key: + all_dependencies[key] |= new_modules_for_key + return + + +all_dependencies = copy.deepcopy(registered_dependencies) +direct_dependencies = copy.deepcopy(registered_dependencies) + +# Sort +all_dependencies = OrderedDict(sorted(all_dependencies.items())) +direct_dependencies = OrderedDict(sorted(direct_dependencies.items())) + +#print(direct_dependencies) + +last_card = -1 +while True: + card = cartinality(all_dependencies) + # print(card) + if card == last_card: + break + last_card = card + add_dependency() + +# Return true iff a depends on b, +# i.e. b is in the dependencies of a +def depends_on(a, b): + if not a in direct_dependencies: + return False + else: + return b in direct_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(other, one): + 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): + # pylint: disable=no-member + # os.startfile is available on Windows only + 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": + if args.all: + for key in all_dependencies: + print(key.ljust(17) + " : " + ", ".join(sorted(all_dependencies[key]))) + else: + 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) + g2.attr('graph', rankdir='RL') # draw horizontally + 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) |