summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi18
-rw-r--r--guix/scripts/graph.scm21
-rw-r--r--tests/graph.scm14
3 files changed, 52 insertions, 1 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 3a9ebe8a63..adc7fefcae 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -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.
diff --git a/guix/scripts/graph.scm b/guix/scripts/graph.scm
index d96df5fbaf..79ce503a2e 100644
--- a/guix/scripts/graph.scm
+++ b/guix/scripts/graph.scm
@@ -37,6 +37,7 @@
#: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
@@ -103,6 +104,25 @@ name."
;;;
+;;; 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 @@ substitutes."
(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
diff --git a/tests/graph.scm b/tests/graph.scm
index bc4d62fe50..6431c482f7 100644
--- a/tests/graph.scm
+++ b/tests/graph.scm
@@ -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 @@
#: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 @@ edges."
(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 _