graph: Add '%reverse-package-node-type'.

* guix/scripts/graph.scm (%reverse-package-node-type): New variable.
(%node-types): Add it.
* tests/graph.scm ("reverse package DAG"): New test.
* doc/guix.texi (Invoking guix refresh): Add cross-reference to
"Invoking guix graph".
(Invoking guix graph): Document 'reverse-package'.
This commit is contained in:
Ludovic Courtès 2017-01-04 16:16:17 +01:00
parent a614ce389f
commit b96a0640a3
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
3 changed files with 52 additions and 1 deletions

View file

@ -5445,6 +5445,10 @@ end, display the fraction of packages covered by all these updaters.
List top-level dependent packages that would need to be rebuilt as a
result of upgrading one or more packages.
@xref{Invoking guix graph, the @code{reverse-package} type of
@command{guix graph}}, for information on how to visualize the list of
dependents of a package.
@end table
Be aware that the @code{--list-dependent} option only
@ -5746,6 +5750,20 @@ This is the default type used in the example above. It shows the DAG of
package objects, excluding implicit dependencies. It is concise, but
filters out many details.
@item reverse-package
This shows the @emph{reverse} DAG of packages. For example:
@example
guix graph --type=reverse-package ocaml
@end example
... yields the graph of packages that depend on OCaml.
Note that for core packages this can yield huge graphs. If all you want
is to know the number of packages that depend on a given package, use
@command{guix refresh --list-dependent} (@pxref{Invoking guix refresh,
@option{--list-dependent}}).
@item bag-emerged
This is the package DAG, @emph{including} implicit inputs.

View file

@ -37,6 +37,7 @@ (define-module (guix scripts graph)
#:use-module (srfi srfi-37)
#:use-module (ice-9 match)
#:export (%package-node-type
%reverse-package-node-type
%bag-node-type
%bag-with-origins-node-type
%bag-emerged-node-type
@ -101,6 +102,25 @@ (define %package-node-type
(label node-full-name)
(edges (lift1 package-node-edges %store-monad))))
;;;
;;; Reverse package DAG.
;;;
(define %reverse-package-node-type
;; For this node type we first need to compute the list of packages and the
;; list of back-edges. Since we want to do it only once, we use the
;; promises below.
(let* ((packages (delay (fold-packages cons '())))
(back-edges (delay (run-with-store #f ;store not actually needed
(node-back-edges %package-node-type
(force packages))))))
(node-type
(inherit %package-node-type)
(name "reverse-package")
(description "the reverse DAG of packages")
(edges (lift1 (force back-edges) %store-monad)))))
;;;
;;; Package DAG using bags.
@ -323,6 +343,7 @@ (define %referrer-node-type
(define %node-types
;; List of all the node types.
(list %package-node-type
%reverse-package-node-type
%bag-node-type
%bag-with-origins-node-type
%bag-emerged-node-type

View file

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@ -32,6 +32,7 @@ (define-module (test-graph)
#:use-module (gnu packages)
#:use-module (gnu packages base)
#:use-module (gnu packages guile)
#:use-module (gnu packages libunistring)
#:use-module (gnu packages bootstrap)
#:use-module (ice-9 match)
#:use-module (srfi srfi-1)
@ -92,6 +93,17 @@ (define (edge->tuple source target)
(list p3 p3 p2)
(list p2 p1 p1))))))))
(test-assert "reverse package DAG"
(let-values (((backend nodes+edges) (make-recording-backend)))
(run-with-store %store
(export-graph (list libunistring) 'port
#:node-type %reverse-package-node-type
#:backend backend))
;; We should see nothing more than these 3 packages.
(let-values (((nodes edges) (nodes+edges)))
(and (member (package->tuple guile-2.0) nodes)
(->bool (member (edge->tuple libunistring guile-2.0) edges))))))
(test-assert "bag-emerged DAG"
(let-values (((backend nodes+edges) (make-recording-backend)))
(let* ((o (dummy-origin (method (lambda _