生成整个系统的依赖图

生成整个系统的依赖图

我知道debtree可以为给定的包生成依赖关系图,如下所示:

sudo apt-get install debtree
sudo apt-get install graphviz
debtree alsa-base > alsa-base.dot
dot -T png -o alsa-base.png alsa-base.dot

但是如果我想要整个系统的依赖图,并且每个包只显示一次,该怎么办?

答案1

这是使用 Python 实现此操作的一种巧妙方法。

首先将所有已安装的包写入一个文件。

apt list --installed > installed_packages.txt

遍历该列表并使用debtree获取每个包的一阶依赖关系。如果您有很多包(主要是lib*),这可能需要相当长的时间。

此脚本最好在 Jupyter Lab 等交互式环境中运行。它会缓存所有工作edges_dict,如果已经有条目,则会跳过检索过程。

import json
import subprocess
from io import StringIO
import pydot
import networkx as nx



names = [package.split("/")[0] for package in open("installed_packages.txt").read().split("\n")[1:-1]]

edges_dict = dict()

command = "debtree --with-suggests --max-depth 1 {}"
for name in names:
    if name not in edges_dict.keys():
        try:
            process = subprocess.Popen(command.format(name).split(), stdout=subprocess.PIPE)
            output, error = process.communicate()
            if error is None:
                g = nx.drawing.nx_pydot.read_dot(StringIO(output.decode()))
                edges_dict[name] = list(g.edges())
            else:
                print(name, error)
        except:
            print(name, "Failed")

json.dump(edges_dict, open("edges.json", "w"))
edges_dict = json.load(open("edges.json"))

利用这些数据,您可以使用 networkx 创建图表......

import networkx as nx
g = nx.DiGraph()
for name, edges in edges_dict.items():
    g.add_edges_from(edges)

或者带有 pandas 的 DataFrame。

data = list()
for name, edges in edges_dict.items():
    for node1, node2 in edges:
        data.append([name, node1, node2])

df = pd.DataFrame(data, columns=["name", "package", "dependency"])

# many packages have themself as a dependency
df = df[df["package"] != df["dependency"]]

希望对您有帮助:)

相关内容