graph: Add the 'reverse-bag' graph.

Suggested by Julien Lepiller.

* guix/scripts/graph.scm (%reverse-bag-node-type): New variable.
(%node-types): Add it.
* tests/graph.scm ("reverse bag DAG"): New test.
* doc/guix.texi (Invoking guix graph): Document it.
This commit is contained in:
Ludovic Courtès 2019-03-23 15:04:44 +01:00
parent e190d12eae
commit 2b81eac01e
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
3 changed files with 62 additions and 3 deletions

View File

@ -9290,7 +9290,9 @@ This shows the @emph{reverse} DAG of packages. For example:
guix graph --type=reverse-package ocaml guix graph --type=reverse-package ocaml
@end example @end example
...@: yields the graph of packages that depend on OCaml. ...@: yields the graph of packages that @emph{explicitly} depend on OCaml (if
you are also interested in cases where OCaml is an implicit dependency, see
@code{reverse-bag} below.)
Note that for core packages this can yield huge graphs. If all you want 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 is to know the number of packages that depend on a given package, use
@ -9324,6 +9326,20 @@ dependencies.
@item bag-with-origins @item bag-with-origins
Similar to @code{bag}, but also showing origins and their dependencies. Similar to @code{bag}, but also showing origins and their dependencies.
@item reverse-bag
This shows the @emph{reverse} DAG of packages. Unlike @code{reverse-package},
it also takes implicit dependencies into account. For example:
@example
guix graph -t reverse-bag dune
@end example
@noindent
...@: yields the graph of all packages that depend on Dune, directly or
indirectly. Since Dune is an @emph{implicit} dependency of many packages
@i{via} @code{dune-build-system}, this shows a large number of packages,
whereas @code{reverse-package} would show very few if any.
@item derivation @item derivation
This is the most detailed representation: It shows the DAG of This is the most detailed representation: It shows the DAG of
derivations (@pxref{Derivations}) and plain store items. Compared to derivations (@pxref{Derivations}) and plain store items. Compared to

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -43,6 +43,7 @@
%bag-node-type %bag-node-type
%bag-with-origins-node-type %bag-with-origins-node-type
%bag-emerged-node-type %bag-emerged-node-type
%reverse-bag-node-type
%derivation-node-type %derivation-node-type
%reference-node-type %reference-node-type
%referrer-node-type %referrer-node-type
@ -219,6 +220,21 @@ GNU-BUILD-SYSTEM have zero dependencies."
bag-node-edges-sans-bootstrap) bag-node-edges-sans-bootstrap)
%store-monad)))) %store-monad))))
(define %reverse-bag-node-type
;; Type for the reverse traversal of package nodes via the "bag"
;; representation, which includes implicit inputs.
(let* ((packages (delay (package-closure (fold-packages cons '()))))
(back-edges (delay (run-with-store #f ;store not actually needed
(node-back-edges %bag-node-type
(force packages))))))
(node-type
(name "reverse-bag")
(description "the reverse DAG of packages, including implicit inputs")
(convert nodes-from-package)
(identifier bag-node-identifier)
(label node-full-name)
(edges (lift1 (force back-edges) %store-monad)))))
;;; ;;;
;;; Derivation DAG. ;;; Derivation DAG.
@ -375,6 +391,7 @@ package modules, while attempting to retain user package modules."
%bag-node-type %bag-node-type
%bag-with-origins-node-type %bag-with-origins-node-type
%bag-emerged-node-type %bag-emerged-node-type
%reverse-bag-node-type
%derivation-node-type %derivation-node-type
%reference-node-type %reference-node-type
%referrer-node-type %referrer-node-type

View File

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -191,6 +191,32 @@ edges."
(string=? target (derivation-file-name g))))) (string=? target (derivation-file-name g)))))
edges))))))))) edges)))))))))
(test-assert "reverse bag DAG"
(let-values (((dune bap ocaml-base)
(values (specification->package "dune")
(specification->package "bap")
(specification->package "ocaml-base")))
((backend nodes+edges) (make-recording-backend)))
(run-with-store %store
(export-graph (list dune) 'port
#:node-type %reverse-bag-node-type
#:backend backend))
(run-with-store %store
(mlet %store-monad ((dune-drv (package->derivation dune))
(bap-drv (package->derivation bap))
(ocaml-base-drv (package->derivation ocaml-base)))
;; OCAML-BASE uses 'dune-build-system' so DUNE is a direct dependency.
;; BAP is much higher in the stack but it should be there.
(let-values (((nodes edges) (nodes+edges)))
(return
(and (member `(,(derivation-file-name bap-drv)
,(package-full-name bap))
nodes)
(->bool (member (map derivation-file-name
(list dune-drv ocaml-base-drv))
edges)))))))))
(test-assert "derivation DAG" (test-assert "derivation DAG"
(let-values (((backend nodes+edges) (make-recording-backend))) (let-values (((backend nodes+edges) (make-recording-backend)))
(run-with-store %store (run-with-store %store