Пример #1
0
def _make_dependency_graph(root, reversed=True, rreqs=None, edge_attrs=_E_ATTRS):
    """
    Make RPM dependency graph with using Networkx.DiGraph for given root.

    :param root: RPM Database root dir
    :param reversed: Resolve reversed dependency from required to requires
    :param rreqs: A dict represents RPM dependencies;
        {x: [package_requires_x]} or {x: [package_required_by_x]}.
    :param edge_attrs: Default edge attributes :: dict

    :return: networkx.DiGraph instance
    """
    g = NX.DiGraph()

    if rreqs is None:
        rreqs = RU.make_requires_dict(root, reversed)

    for k, vs in rreqs.iteritems():
        g.add_node(k, names=[k])
        g.add_edges_from([(k, v, edge_attrs) for v in vs])

    # Remove edges of self cyclic nodes:
    g.remove_edges_from(g.selfloop_edges())

    return g
Пример #2
0
def _make_dependency_graph(root,
                           reversed=True,
                           rreqs=None,
                           edge_attrs=_E_ATTRS):
    """
    Make RPM dependency graph with using Networkx.DiGraph for given root.

    :param root: RPM Database root dir
    :param reversed: Resolve reversed dependency from required to requires
    :param rreqs: A dict represents RPM dependencies;
        {x: [package_requires_x]} or {x: [package_required_by_x]}.
    :param edge_attrs: Default edge attributes :: dict

    :return: networkx.DiGraph instance
    """
    g = NX.DiGraph()

    if rreqs is None:
        rreqs = RU.make_requires_dict(root, reversed)

    for k, vs in rreqs.iteritems():
        g.add_node(k, names=[k])
        g.add_edges_from([(k, v, edge_attrs) for v in vs])

    # Remove edges of self cyclic nodes:
    g.remove_edges_from(g.selfloop_edges())

    return g
Пример #3
0
def dump_gv_depgraph(root, workdir, tpaths=_TEMPLATE_PATHS, engine=_GV_ENGINE, html=True):
    """
    Generate dependency graph with graphviz.

    TODO: Utilize graph, DAG and trees generated w/ ``dump_graphs``.

    :param root: Root dir where 'var/lib/rpm' exists
    :param workdir: Working dir to dump the result
    :param tpaths: Template path list
    :param engine: Graphviz rendering engine to choose, e.g. neato
    :param html: Generate HTML graph files if True
    """
    reqs = RU.make_requires_dict(root)

    # Set virtual root for root rpms:
    for p, rs in reqs.iteritems():
        if not rs:  # This is a root RPM:
            reqs[p] = ["<rpmlibs>"]  # Set virtual root for this root rpm.

    # Remove self dependency refs:
    ctx = dict(dependencies=[(r, [p for p in ps if p != r]) for r, ps in reqs.iteritems()])

    depgraph_s = RT.render("rpmdep_graph_gv.j2", ctx, tpaths, ask=True)
    src = os.path.join(workdir, "rpmdep_graph.dot")
    U.copen(src, "w").write(depgraph_s)

    output = src + ".svg"
    SH.run("%s -Tsvg -o %s %s" % (engine, output, src), workdir=workdir)

    if html:
        logging.info("Generate HTML files for graphviz outputs")
        for t in ("js/graphviz-svg.js.j2", "js/jquery.js.j2", "rpmdep_graph_gv.html.j2"):
            _renderfile(workdir, t, ctx={}, tpaths=tpaths)
Пример #4
0
def gen_depgraph_gv(root,
                    workdir,
                    template_paths=_TEMPLATE_PATHS,
                    engine=_GV_ENGINE):
    """
    Generate dependency graph with using graphviz.

    :param root: Root dir where 'var/lib/rpm' exists
    :param workdir: Working dir to dump the result
    :param template_paths: Template path list
    :param engine: Graphviz rendering engine to choose, e.g. neato
    """
    reqs = RU.make_requires_dict(root)

    # Set virtual root for root rpms:
    for p, rs in reqs.iteritems():
        if not rs:  # This is a root RPM:
            reqs[p] = ["<rpmlibs>"]

    ctx = dict(dependencies=[(r, ps) for r, ps in reqs.iteritems()])

    renderfile("rpm_dependencies.html.j2", workdir, ctx, tpaths=template_paths)

    depgraph_s = RT.render("rpm_dependencies.graphviz.j2",
                           ctx,
                           template_paths,
                           ask=True)
    src = os.path.join(workdir, "rpm_dependencies.graphviz")

    copen(src, 'w').write(depgraph_s)

    output = src + ".svg"
    (outlog, errlog) = (os.path.join(workdir, "graphviz_out.log"),
                        os.path.join(workdir, "graphviz_err.log"))

    cmd = "%s -Tsvg -o %s %s" % (engine, output, src)
    proc = subprocess.Popen(cmd.split(),
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    (out, err) = proc.communicate()
    if proc.returncode != 0:
        logging.warn(
            "Failed to generate graphviz data: "
            "engine=%s, out=%s, src=%s", engine, out, src)

    copen(outlog, 'w').write(out)
    copen(errlog, 'w').write(err)
Пример #5
0
def make_dependencies_dag(root, reqs=None, rreqs=None):
    """
    Make directed acyclic graph of RPM dependencies.

    see also:

    * http://en.wikipedia.org/wiki/Directed_acyclic_graph
    * http://en.wikipedia.org/wiki/Strongly_connected_component

    :param root: RPM Database root dir
    :param reqs: A dict represents RPM deps, {x: [package_requires_x]}.
    :param rreqs: A dict represents RPM deps, {x: [package_required_by_x]}.

    :return: networkx.DiGraph instance represents the dag of rpm deps.
    """
    if rreqs is None:
        rreqs = RU.make_reversed_requires_dict(root)

    if reqs is None:
        reqs = RU.make_requires_dict(root)

    g = make_dependency_graph(root, rreqs=rreqs)

    # Degenerate strongly connected components:
    for scc in list(NX.strongly_connected_components(g)):
        scc = sorted(U.uniq(scc))  # TODO: Is this needed?

        if len(scc) == 1:  # Ignore sccs of which length is 1.
            continue

        _degenerate_nodes(g, scc, "Strongly Connected Components")

    # Degenerate cyclic nodes:
    for cns in NX.simple_cycles(g):
        cns = sorted(U.uniq(cns))  # TODO: Likewise

        # Should not happen as selc cyclic nodes were removed in advance.
        assert len(cns) != 1, "Self cyclic node: " + cns[0]

        _degenerate_nodes(g, cns, "Cyclic nodes")

    assert NX.is_directed_acyclic_graph(g), \
        "I'm still missing something to make the dep. graph to dag..."

    return g
Пример #6
0
def make_dependencies_dag(root, reqs=None, rreqs=None):
    """
    Make directed acyclic graph of RPM dependencies.

    see also:

    * http://en.wikipedia.org/wiki/Directed_acyclic_graph
    * http://en.wikipedia.org/wiki/Strongly_connected_component

    :param root: RPM Database root dir
    :param reqs: A dict represents RPM deps, {x: [package_requires_x]}.
    :param rreqs: A dict represents RPM deps, {x: [package_required_by_x]}.

    :return: networkx.DiGraph instance represents the dag of rpm deps.
    """
    if rreqs is None:
        rreqs = RU.make_reversed_requires_dict(root)

    if reqs is None:
        reqs = RU.make_requires_dict(root)

    g = make_dependency_graph(root, rreqs=rreqs)

    # Degenerate strongly connected components:
    for scc in list(NX.strongly_connected_components(g)):
        scc = sorted(U.uniq(scc))  # TODO: Is this needed?

        if len(scc) == 1:  # Ignore sccs of which length is 1.
            continue

        _degenerate_nodes(g, scc, "Strongly Connected Components")

    # Degenerate cyclic nodes:
    for cns in NX.simple_cycles(g):
        cns = sorted(U.uniq(cns))  # TODO: Likewise

        # Should not happen as selc cyclic nodes were removed in advance.
        assert len(cns) != 1, "Self cyclic node: " + cns[0]

        _degenerate_nodes(g, cns, "Cyclic nodes")

    assert NX.is_directed_acyclic_graph(g), "I'm still missing something to make the dep. graph to dag..."

    return g
Пример #7
0
def gen_depgraph_gv(root, workdir, template_paths=_TEMPLATE_PATHS,
                    engine=_GV_ENGINE):
    """
    Generate dependency graph with using graphviz.

    :param root: Root dir where 'var/lib/rpm' exists
    :param workdir: Working dir to dump the result
    :param template_paths: Template path list
    :param engine: Graphviz rendering engine to choose, e.g. neato
    """
    reqs = RU.make_requires_dict(root)

    # Set virtual root for root rpms:
    for p, rs in reqs.iteritems():
        if not rs:  # This is a root RPM:
            reqs[p] = ["<rpmlibs>"]

    ctx = dict(dependencies=[(r, ps) for r, ps in reqs.iteritems()])

    renderfile("rpm_dependencies.html.j2", workdir, ctx, tpaths=template_paths)

    depgraph_s = RT.render("rpm_dependencies.graphviz.j2", ctx,
                           template_paths, ask=True)
    src = os.path.join(workdir, "rpm_dependencies.graphviz")

    copen(src, 'w').write(depgraph_s)

    output = src + ".svg"
    (outlog, errlog) = (os.path.join(workdir, "graphviz_out.log"),
                        os.path.join(workdir, "graphviz_err.log"))

    cmd = "%s -Tsvg -o %s %s" % (engine, output, src)
    proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    (out, err) = proc.communicate()
    if proc.returncode != 0:
        logging.warn("Failed to generate graphviz data: "
                     "engine=%s, out=%s, src=%s",
                     engine, out, src)

    copen(outlog, 'w').write(out)
    copen(errlog, 'w').write(err)
Пример #8
0
def dump_gv_depgraph(root,
                     workdir,
                     tpaths=_TEMPLATE_PATHS,
                     engine=_GV_ENGINE,
                     html=True):
    """
    Generate dependency graph with graphviz.

    TODO: Utilize graph, DAG and trees generated w/ ``dump_graphs``.

    :param root: Root dir where 'var/lib/rpm' exists
    :param workdir: Working dir to dump the result
    :param tpaths: Template path list
    :param engine: Graphviz rendering engine to choose, e.g. neato
    :param html: Generate HTML graph files if True
    """
    reqs = RU.make_requires_dict(root)

    # Set virtual root for root rpms:
    for p, rs in reqs.iteritems():
        if not rs:  # This is a root RPM:
            reqs[p] = ["<rpmlibs>"]  # Set virtual root for this root rpm.

    # Remove self dependency refs:
    ctx = dict(dependencies=[(r, [p for p in ps if p != r])
                             for r, ps in reqs.iteritems()])

    depgraph_s = RT.render("rpmdep_graph_gv.j2", ctx, tpaths, ask=True)
    src = os.path.join(workdir, "rpmdep_graph.dot")
    U.copen(src, 'w').write(depgraph_s)

    output = src + ".svg"
    SH.run("%s -Tsvg -o %s %s" % (engine, output, src), workdir=workdir)

    if html:
        logging.info("Generate HTML files for graphviz outputs")
        for t in ("js/graphviz-svg.js.j2", "js/jquery.js.j2",
                  "rpmdep_graph_gv.html.j2"):
            _renderfile(workdir, t, ctx={}, tpaths=tpaths)