mirror of
https://git.savannah.gnu.org/git/guix.git
synced 2025-01-18 13:36:36 +01:00
guix build: Add ‘--dependents’.
* guix/scripts/build.scm (show-help, %options): Add ‘--dependents’. (dependents): New procedure. (options->things-to-build): Add ‘store’ parameter; honor ‘dependents’ option. [for-type]: Handle ‘dependents’ type. (options->derivations): Update call to ‘options->things-to-build’. * tests/guix-build.sh: Add test. * doc/guix.texi (Additional Build Options): Document ‘--dependents’. (Invoking guix refresh): Cross-reference it. * doc/contributing.texi (Submitting Patches): Mention it. Change-Id: I00b6d5831e1f1d35dc8b84a82605391d5a8f417c
This commit is contained in:
parent
4b5dae8def
commit
6b14eb3402
4 changed files with 90 additions and 3 deletions
|
@ -1915,7 +1915,9 @@ according to the project's conventions (@pxref{Invoking guix style}).
|
|||
|
||||
@item
|
||||
Make sure the package builds on your platform, using @command{guix build
|
||||
@var{package}}.
|
||||
@var{package}}. Also build at least its direct dependents with
|
||||
@command{guix build --dependents=1 @var{package}}
|
||||
(@pxref{build-dependents, @command{guix build}}).
|
||||
|
||||
@item
|
||||
We recommend you also try building the package on other supported
|
||||
|
|
|
@ -13639,6 +13639,31 @@ cross-compile all the dependencies of the given package when it is built
|
|||
natively.
|
||||
@end quotation
|
||||
|
||||
@cindex dependents of a package, building them
|
||||
@cindex building the dependents of a package
|
||||
@anchor{build-dependents}
|
||||
@item --dependents[=@var{depth}]
|
||||
@itemx -P [@var{depth}]
|
||||
Build the dependents of the following package. By default, build all
|
||||
the direct and indirect dependents; when @var{depth} is provided, limit
|
||||
to dependents at that distance: 1 for direct dependents, 2 for
|
||||
dependents of dependents, and so on.
|
||||
|
||||
For example, the command below builds @emph{all} the dependents of libgit2:
|
||||
|
||||
@example
|
||||
guix build --dependents libgit2
|
||||
@end example
|
||||
|
||||
To build all the packages that directly depend on NumPy, run:
|
||||
|
||||
@example
|
||||
guix build -P1 python-numpy
|
||||
@end example
|
||||
|
||||
The list of dependents is computed in the same way as with @command{guix
|
||||
refresh --list-dependent} (@pxref{Invoking guix refresh}).
|
||||
|
||||
@item --source
|
||||
@itemx -S
|
||||
Build the source derivations of the packages, rather than the packages
|
||||
|
@ -15142,6 +15167,8 @@ result of upgrading one or more packages.
|
|||
@command{guix graph}}, for information on how to visualize the list of
|
||||
dependents of a package.
|
||||
|
||||
@xref{build-dependents, @command{guix build --dependents}}, for a
|
||||
convenient way to build all the dependents of a package.
|
||||
@end table
|
||||
|
||||
Be aware that the @option{--list-dependent} option only
|
||||
|
|
|
@ -33,6 +33,9 @@ (define-module (guix scripts build)
|
|||
#:use-module (guix profiles)
|
||||
#:use-module (guix diagnostics)
|
||||
#:autoload (guix http-client) (http-fetch http-get-error?)
|
||||
#:autoload (guix scripts graph) (%bag-node-type)
|
||||
#:autoload (guix graph) (node-back-edges)
|
||||
#:autoload (guix sets) (setq set-contains? set-insert)
|
||||
#:use-module (ice-9 format)
|
||||
#:use-module (ice-9 match)
|
||||
#:use-module (srfi srfi-1)
|
||||
|
@ -440,6 +443,9 @@ (define (show-help)
|
|||
(display (G_ "
|
||||
-D, --development build the inputs of the following package"))
|
||||
(display (G_ "
|
||||
-P, --dependents[=N] build dependents of the following package, up to
|
||||
depth N"))
|
||||
(display (G_ "
|
||||
-S, --source build the packages' source derivations"))
|
||||
(display (G_ "
|
||||
--sources[=TYPE] build source derivations; TYPE may optionally be one
|
||||
|
@ -527,6 +533,11 @@ (define %options
|
|||
(option '(#\D "development") #f #f
|
||||
(lambda (opt name arg result)
|
||||
(alist-cons 'development? #t result)))
|
||||
(option '(#\P "dependents") #f #t
|
||||
(lambda (opt name arg result)
|
||||
(alist-cons 'dependents
|
||||
(or (and=> arg string->number*) +inf.0)
|
||||
result)))
|
||||
(option '(#\n "dry-run") #f #f
|
||||
(lambda (opt name arg result)
|
||||
(alist-cons 'dry-run? #t result)))
|
||||
|
@ -551,7 +562,39 @@ (define %options
|
|||
%standard-cross-build-options
|
||||
%standard-native-build-options)))
|
||||
|
||||
(define (options->things-to-build opts)
|
||||
(define (dependents store packages max-depth)
|
||||
"List all the things that would need to be rebuilt if PACKAGES are changed."
|
||||
;; Using %BAG-NODE-TYPE is more accurate than using %PACKAGE-NODE-TYPE
|
||||
;; because it includes implicit dependencies.
|
||||
(define (get-dependents packages edges)
|
||||
(let loop ((packages packages)
|
||||
(result '())
|
||||
(depth 0)
|
||||
(visited (setq)))
|
||||
(if (> depth max-depth)
|
||||
(values result visited)
|
||||
(match packages
|
||||
(()
|
||||
(values result visited))
|
||||
((head . tail)
|
||||
(if (set-contains? visited head)
|
||||
(loop tail result depth visited)
|
||||
(let ((next (edges head)))
|
||||
(call-with-values
|
||||
(lambda ()
|
||||
(loop next
|
||||
(cons head result)
|
||||
(+ depth 1)
|
||||
(set-insert head visited)))
|
||||
(lambda (result visited)
|
||||
(loop tail result depth visited))))))))))
|
||||
|
||||
(with-store store
|
||||
(run-with-store store
|
||||
(mlet %store-monad ((edges (node-back-edges %bag-node-type (all-packages))))
|
||||
(return (get-dependents packages edges))))))
|
||||
|
||||
(define (options->things-to-build store opts)
|
||||
"Read the arguments from OPTS and return a list of high-level objects to
|
||||
build---packages, gexps, derivations, and so on."
|
||||
(define (validate-type x)
|
||||
|
@ -600,6 +643,13 @@ (define (for-type obj)
|
|||
(match type
|
||||
('regular
|
||||
(list obj))
|
||||
(('dependents . depth)
|
||||
(if (package? obj)
|
||||
(begin
|
||||
(info (G_ "computing dependents of package ~a...~%")
|
||||
(package-full-name obj))
|
||||
(dependents store (list obj) depth))
|
||||
(list obj)))
|
||||
('development
|
||||
(if (package? obj)
|
||||
(map manifest-entry-item
|
||||
|
@ -661,6 +711,8 @@ (define (for-type obj)
|
|||
result)))
|
||||
(('development? . #t)
|
||||
(loop tail 'development result))
|
||||
(('dependents . depth)
|
||||
(loop tail `(dependents . ,depth) result))
|
||||
(_
|
||||
(loop tail type result)))))))
|
||||
|
||||
|
@ -687,7 +739,7 @@ (define systems
|
|||
(systems systems)))
|
||||
|
||||
(define things-to-build
|
||||
(map transform (options->things-to-build opts)))
|
||||
(map transform (options->things-to-build store opts)))
|
||||
|
||||
(define warn-if-unsupported
|
||||
(let ((target (assoc-ref opts 'target)))
|
||||
|
|
|
@ -196,6 +196,12 @@ test `guix build -D hello -d \
|
|||
| grep -e 'glibc.*\.drv$' -e 'gcc.*\.drv$' -e 'binutils.*\.drv$' \
|
||||
| wc -l` -ge 3
|
||||
|
||||
# Building the dependents.
|
||||
test `guix build -P1 libgit2 -P1 libssh -d \
|
||||
| grep -e 'guile-git.*\.drv$' -e 'guile-ssh.*\.drv$' \
|
||||
-e 'libgit2.*\.drv$' -e 'libssh.*\.drv$' \
|
||||
| wc -l` -eq 4
|
||||
|
||||
# Unbound variable in thunked field.
|
||||
cat > "$module_dir/foo.scm" <<EOF
|
||||
(define-module (foo)
|
||||
|
|
Loading…
Reference in a new issue