Skip to content

Instantly share code, notes, and snippets.

@dims
Last active September 26, 2022 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dims/3a416e0d83741cf8f31943f99cf1c7ee to your computer and use it in GitHub Desktop.
Save dims/3a416e0d83741cf8f31943f99cf1c7ee to your computer and use it in GitHub Desktop.

Say in kubernetes/kubernetes, you need to see how we drag in rsc.io/pdf

python ~/bin/gomod_graph.py -p rsc.io/pdf > filename.dot
dot -Tsvg filename.dot -o filename.svg

if you are not interested in the version numbers

python ~/bin/gomod_graph.py -p rsc.io/pdf --skip > filename.dot
dot -Tsvg filename.dot -o filename.svg
#!/usr/bin/python
import argparse
import atexit
import logging
import subprocess
from copy import deepcopy
def get_dependencies():
dependson = {}
usedby = {}
f = subprocess.Popen('go mod graph', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
(stdout, stderr) = f.communicate()
if stderr:
logging.fatal(stderr)
for line in stdout.splitlines():
key, value = line.decode().split(' ')
key = key.split('@')[0]
value = value.split('@')[0]
dependson.setdefault(key, set()).add(value)
usedby.setdefault(value, set()).add(key)
return usedby, dependson
def get_all_parents(dep, visited, usedby):
visited.add(dep)
if dep not in usedby:
return set()
array = usedby[dep].copy()
for item in array.copy():
if item not in visited:
array |= get_all_parents(item, visited, usedby)
return array
def draw_diagraph(items, skip):
f = subprocess.Popen('go mod graph', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
(stdout, stderr) = f.communicate()
if stderr:
logging.fatal(stderr)
print("digraph G {")
print("rankdir=LR;")
for line in stdout.splitlines():
key, value = line.decode().split(' ')
if skip:
key = key.split('@')[0]
value = value.split('@')[0]
found_key = False
found_value = False
for item in items:
if key.startswith(item):
found_key = True
if value.startswith(item):
found_value = True
if found_key and found_value:
print("\"%s\" -> \"%s\"" % (key, value))
print("}")
chains = {}
def print_chains():
longest = max(chains.keys())
print("Longest chain is:", longest)
print("%r" % chains[longest])
def visit_node(dep, parents, dependson):
parents.append(dep)
if dep in dependson:
for item in dependson[dep]:
if item not in parents:
visit_node(item, deepcopy(parents), dependson)
else:
chains.setdefault(len(parents), list()).append(parents)
else:
chains.setdefault(len(parents), list()).append(parents)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-p', '--package', required=True)
parser.add_argument('-s', '--skip', action='store_true')
parser.add_argument('-d', '--depth', action='store_true')
args = parser.parse_args()
usedby, dependson = get_dependencies()
if args.depth:
atexit.register(print_chains)
visit_node(args.package, [], dependson)
print_chains()
else:
parents = get_all_parents(args.package, set(), usedby)
draw_diagraph(parents | {args.package}, args.skip)
if __name__ == "__main__":
main()
#/bin/bash
set -xeu
python ~/bin/gomod_graph.py -p $1 > graph.dot && cat graph.dot && (cat graph.dot | dot -Tsvg -o graph.svg) && open graph.svg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment