guix graph: Add '--path'.
* guix/scripts/graph.scm (display-path): New procedure. (%options, show-help): Add '--path'. (guix-graph): Handle it. * tests/guix-graph.sh: Add tests. * doc/guix.texi (Invoking guix graph): Document it. (Invoking guix size): Mention it.
This commit is contained in:
parent
36c2192414
commit
88a96c568c
@ -10021,6 +10021,12 @@ In this example we see that the combination of the four packages takes
|
|||||||
102.3@tie{}MiB in total, which is much less than the sum of each closure
|
102.3@tie{}MiB in total, which is much less than the sum of each closure
|
||||||
since they have a lot of dependencies in common.
|
since they have a lot of dependencies in common.
|
||||||
|
|
||||||
|
When looking at the profile returned by @command{guix size}, you may
|
||||||
|
find yourself wondering why a given package shows up in the profile at
|
||||||
|
all. To understand it, you can use @command{guix graph --path -t
|
||||||
|
references} to display the shortest path between the two packages
|
||||||
|
(@pxref{Invoking guix graph}).
|
||||||
|
|
||||||
The available options are:
|
The available options are:
|
||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
@ -10081,8 +10087,9 @@ directly to the @command{dot} command of Graphviz. It can also emit an
|
|||||||
HTML page with embedded JavaScript code to display a ``chord diagram''
|
HTML page with embedded JavaScript code to display a ``chord diagram''
|
||||||
in a Web browser, using the @uref{https://d3js.org/, d3.js} library, or
|
in a Web browser, using the @uref{https://d3js.org/, d3.js} library, or
|
||||||
emit Cypher queries to construct a graph in a graph database supporting
|
emit Cypher queries to construct a graph in a graph database supporting
|
||||||
the @uref{https://www.opencypher.org/, openCypher} query language.
|
the @uref{https://www.opencypher.org/, openCypher} query language. With
|
||||||
The general syntax is:
|
@option{--path}, it simply displays the shortest path between two
|
||||||
|
packages. The general syntax is:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
guix graph @var{options} @var{package}@dots{}
|
guix graph @var{options} @var{package}@dots{}
|
||||||
@ -10235,6 +10242,29 @@ collected.
|
|||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@cindex shortest path, between packages
|
||||||
|
Often, the graph of the package you are interested in does not fit on
|
||||||
|
your screen, and anyway all you want to know is @emph{why} that package
|
||||||
|
actually depends on some seemingly unrelated package. The
|
||||||
|
@option{--path} option instructs @command{guix graph} to display the
|
||||||
|
shortest path between two packages (or derivations, or store items,
|
||||||
|
etc.):
|
||||||
|
|
||||||
|
@example
|
||||||
|
$ guix graph --path emacs libunistring
|
||||||
|
emacs@@26.3
|
||||||
|
mailutils@@3.9
|
||||||
|
libunistring@@0.9.10
|
||||||
|
$ guix graph --path -t derivation emacs libunistring
|
||||||
|
/gnu/store/@dots{}-emacs-26.3.drv
|
||||||
|
/gnu/store/@dots{}-mailutils-3.9.drv
|
||||||
|
/gnu/store/@dots{}-libunistring-0.9.10.drv
|
||||||
|
$ guix graph --path -t references emacs libunistring
|
||||||
|
/gnu/store/@dots{}-emacs-26.3
|
||||||
|
/gnu/store/@dots{}-libidn2-2.2.0
|
||||||
|
/gnu/store/@dots{}-libunistring-0.9.10
|
||||||
|
@end example
|
||||||
|
|
||||||
The available options are the following:
|
The available options are the following:
|
||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
@ -10255,6 +10285,20 @@ List the supported graph backends.
|
|||||||
|
|
||||||
Currently, the available backends are Graphviz and d3.js.
|
Currently, the available backends are Graphviz and d3.js.
|
||||||
|
|
||||||
|
@item --path
|
||||||
|
Display the shortest path between two nodes of the type specified by
|
||||||
|
@option{--type}. The example below shows the shortest path between
|
||||||
|
@code{libreoffice} and @code{llvm} according to the references of
|
||||||
|
@code{libreoffice}:
|
||||||
|
|
||||||
|
@example
|
||||||
|
$ guix graph --path -t references libreoffice llvm
|
||||||
|
/gnu/store/@dots{}-libreoffice-6.4.2.2
|
||||||
|
/gnu/store/@dots{}-libepoxy-1.5.4
|
||||||
|
/gnu/store/@dots{}-mesa-19.3.4
|
||||||
|
/gnu/store/@dots{}-llvm-9.0.1
|
||||||
|
@end example
|
||||||
|
|
||||||
@item --expression=@var{expr}
|
@item --expression=@var{expr}
|
||||||
@itemx -e @var{expr}
|
@itemx -e @var{expr}
|
||||||
Consider the package @var{expr} evaluates to.
|
Consider the package @var{expr} evaluates to.
|
||||||
|
@ -455,6 +455,29 @@ package modules, while attempting to retain user package modules."
|
|||||||
(graph-backend-description backend)))
|
(graph-backend-description backend)))
|
||||||
%graph-backends))
|
%graph-backends))
|
||||||
|
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; Displaying a path.
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(define (display-path node1 node2 type)
|
||||||
|
"Display the shortest path from NODE1 to NODE2, of TYPE."
|
||||||
|
(mlet %store-monad ((path (shortest-path node1 node2 type)))
|
||||||
|
(define node-label
|
||||||
|
(let ((label (node-type-label type)))
|
||||||
|
;; Special-case derivations and store items to print them in full,
|
||||||
|
;; contrary to what their 'node-type-label' normally does.
|
||||||
|
(match-lambda
|
||||||
|
((? derivation? drv) (derivation-file-name drv))
|
||||||
|
((? string? str) str)
|
||||||
|
(node (label node)))))
|
||||||
|
|
||||||
|
(if path
|
||||||
|
(format #t "~{~a~%~}" (map node-label path))
|
||||||
|
(leave (G_ "no path from '~a' to '~a'~%")
|
||||||
|
(node-label node1) (node-label node2)))
|
||||||
|
(return #t)))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Command-line options.
|
;;; Command-line options.
|
||||||
@ -465,6 +488,9 @@ package modules, while attempting to retain user package modules."
|
|||||||
(lambda (opt name arg result)
|
(lambda (opt name arg result)
|
||||||
(alist-cons 'node-type (lookup-node-type arg)
|
(alist-cons 'node-type (lookup-node-type arg)
|
||||||
result)))
|
result)))
|
||||||
|
(option '("path") #f #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'path? #t result)))
|
||||||
(option '("list-types") #f #f
|
(option '("list-types") #f #f
|
||||||
(lambda (opt name arg result)
|
(lambda (opt name arg result)
|
||||||
(list-node-types)
|
(list-node-types)
|
||||||
@ -510,6 +536,8 @@ Emit a representation of the dependency graph of PACKAGE...\n"))
|
|||||||
-t, --type=TYPE represent nodes of the given TYPE"))
|
-t, --type=TYPE represent nodes of the given TYPE"))
|
||||||
(display (G_ "
|
(display (G_ "
|
||||||
--list-types list the available graph types"))
|
--list-types list the available graph types"))
|
||||||
|
(display (G_ "
|
||||||
|
--path display the shortest path between the given nodes"))
|
||||||
(display (G_ "
|
(display (G_ "
|
||||||
-e, --expression=EXPR consider the package EXPR evaluates to"))
|
-e, --expression=EXPR consider the package EXPR evaluates to"))
|
||||||
(display (G_ "
|
(display (G_ "
|
||||||
@ -566,11 +594,19 @@ Emit a representation of the dependency graph of PACKAGE...\n"))
|
|||||||
(mlet %store-monad ((_ (set-grafting #f))
|
(mlet %store-monad ((_ (set-grafting #f))
|
||||||
(nodes (mapm %store-monad
|
(nodes (mapm %store-monad
|
||||||
(node-type-convert type)
|
(node-type-convert type)
|
||||||
items)))
|
(reverse items))))
|
||||||
(export-graph (concatenate nodes)
|
(if (assoc-ref opts 'path?)
|
||||||
(current-output-port)
|
(match nodes
|
||||||
#:node-type type
|
(((node1 _ ...) (node2 _ ...))
|
||||||
#:backend backend))
|
(display-path node1 node2 type))
|
||||||
|
(_
|
||||||
|
(leave (G_ "'--path' option requires exactly two \
|
||||||
|
nodes (given ~a)~%")
|
||||||
|
(length nodes))))
|
||||||
|
(export-graph (concatenate nodes)
|
||||||
|
(current-output-port)
|
||||||
|
#:node-type type
|
||||||
|
#:backend backend)))
|
||||||
#:system (assq-ref opts 'system)))))
|
#:system (assq-ref opts 'system)))))
|
||||||
#t)
|
#t)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# GNU Guix --- Functional package management for GNU
|
# GNU Guix --- Functional package management for GNU
|
||||||
# Copyright © 2015, 2016, 2019 Ludovic Courtès <ludo@gnu.org>
|
# Copyright © 2015, 2016, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
||||||
# Copyright © 2019 Simon Tournier <zimon.toutoune@gmail.com>
|
# Copyright © 2019 Simon Tournier <zimon.toutoune@gmail.com>
|
||||||
#
|
#
|
||||||
# This file is part of GNU Guix.
|
# This file is part of GNU Guix.
|
||||||
@ -82,3 +82,17 @@ then false; else true; fi
|
|||||||
|
|
||||||
# Try --load-path
|
# Try --load-path
|
||||||
guix graph -L $module_dir dummy | grep 'label = "dummy'
|
guix graph -L $module_dir dummy | grep 'label = "dummy'
|
||||||
|
|
||||||
|
# Displaying shortest paths (or lack thereof).
|
||||||
|
if guix graph --path emacs vim; then false; else true; fi
|
||||||
|
|
||||||
|
path="\
|
||||||
|
emacs
|
||||||
|
gnutls
|
||||||
|
guile
|
||||||
|
libffi"
|
||||||
|
test "`guix graph --path emacs libffi | cut -d '@' -f1`" = "$path"
|
||||||
|
|
||||||
|
# At the derivation level, there's a direct path because libffi is propagated
|
||||||
|
# via gtk+.
|
||||||
|
test "`guix graph --path -t derivation emacs libffi | wc -l`" -ge 2
|
||||||
|
Loading…
Reference in New Issue
Block a user