mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-25 05:48:07 -05:00
monad-repl: Add REPL commands to inspect package arguments.
* guix/monad-repl.scm (keyword-argument-value, package-argument-command): New procedures. (phases, configure-flags, make-flags): New REPL commands. * doc/guix.texi (package Reference): Link to “Using Guix Interactively”. (Defining Package Variants): Add “Tips” quotation. (Build Phases): Add “Tip” quotation. (Using Guix Interactively): Document the new REPL commands. Change-Id: I7049c1d8aa9241e07d7c921aa396e578a1b4ef16
This commit is contained in:
parent
01361d46b8
commit
3178b1a442
2 changed files with 131 additions and 4 deletions
|
@ -7975,6 +7975,10 @@ The exact set of supported keywords depends on the build system
|
||||||
@code{#:phases}. The @code{#:phases} keyword in particular lets you
|
@code{#:phases}. The @code{#:phases} keyword in particular lets you
|
||||||
modify the set of build phases for your package (@pxref{Build Phases}).
|
modify the set of build phases for your package (@pxref{Build Phases}).
|
||||||
|
|
||||||
|
The REPL has dedicated commands to interactively inspect values of some
|
||||||
|
of these arguments, as a convenient debugging aid (@pxref{Using Guix
|
||||||
|
Interactively}).
|
||||||
|
|
||||||
@quotation Compatibility Note
|
@quotation Compatibility Note
|
||||||
Until version 1.3.0, the @code{arguments} field would typically use
|
Until version 1.3.0, the @code{arguments} field would typically use
|
||||||
@code{quote} (@code{'}) or @code{quasiquote} (@code{`}) and no
|
@code{quote} (@code{'}) or @code{quasiquote} (@code{`}) and no
|
||||||
|
@ -8774,6 +8778,23 @@ when @var{cut?} returns true for a given package. When @var{deep?} is true, @va
|
||||||
applied to implicit inputs as well.
|
applied to implicit inputs as well.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@quotation Tips
|
||||||
|
Understanding what a variant really looks like can be difficult as one
|
||||||
|
starts combining the tools shown above. There are several ways to
|
||||||
|
inspect a package before attempting to build it that can prove handy:
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
You can inspect the package interactively at the REPL, for instance to
|
||||||
|
view its inputs, the code of its build phases, or its configure flags
|
||||||
|
(@pxref{Using Guix Interactively}).
|
||||||
|
|
||||||
|
@item
|
||||||
|
When rewriting dependencies, @command{guix graph} can often help
|
||||||
|
visualize the changes that are made (@pxref{Invoking guix graph}).
|
||||||
|
@end itemize
|
||||||
|
@end quotation
|
||||||
|
|
||||||
@node Writing Manifests
|
@node Writing Manifests
|
||||||
@section Writing Manifests
|
@section Writing Manifests
|
||||||
|
|
||||||
|
@ -10585,6 +10606,11 @@ we have seen before. @xref{Build Utilities}, for more about
|
||||||
the helpers used by this phase, and for more examples of
|
the helpers used by this phase, and for more examples of
|
||||||
@code{modify-phases}.
|
@code{modify-phases}.
|
||||||
|
|
||||||
|
@quotation Tip
|
||||||
|
You can inspect the code associated with a package's @code{#:phases}
|
||||||
|
argument interactively, at the REPL (@pxref{Using Guix Interactively}).
|
||||||
|
@end quotation
|
||||||
|
|
||||||
@cindex code staging
|
@cindex code staging
|
||||||
@cindex staging, of code
|
@cindex staging, of code
|
||||||
Keep in mind that build phases are code evaluated at the time the
|
Keep in mind that build phases are code evaluated at the time the
|
||||||
|
@ -12763,6 +12789,30 @@ scheme@@(guix-user)> (scandir (string-append $3 "/bin"))
|
||||||
$5 = ("." ".." "egrep" "fgrep" "grep")
|
$5 = ("." ".." "egrep" "fgrep" "grep")
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
As a packager, you may be willing to inspect the build phases or flags
|
||||||
|
of a given package; this is particularly useful when relying a lot on
|
||||||
|
inheritance to define package variants (@pxref{Defining Package
|
||||||
|
Variants}) or when package arguments are a result of some computation,
|
||||||
|
both of which can make it harder to foresee what ends up in the package
|
||||||
|
arguments. Additional commands let you inspect those package arguments:
|
||||||
|
|
||||||
|
@example
|
||||||
|
scheme@@(guix-user)> ,phases grep
|
||||||
|
$1 = (modify-phases %standard-phases
|
||||||
|
(add-after 'install 'fix-egrep-and-fgrep
|
||||||
|
(lambda* (#:key outputs #:allow-other-keys)
|
||||||
|
(let* ((out (assoc-ref outputs "out"))
|
||||||
|
(bin (string-append out "/bin")))
|
||||||
|
(substitute* (list (string-append bin "/egrep")
|
||||||
|
(string-append bin "/fgrep"))
|
||||||
|
(("^exec grep")
|
||||||
|
(string-append "exec " bin "/grep")))))))
|
||||||
|
scheme@@(guix-user)> ,configure-flags findutils
|
||||||
|
$2 = (list "--localstatedir=/var")
|
||||||
|
scheme@@(guix-user)> ,make-flags binutils
|
||||||
|
$3 = '("MAKEINFO=true")
|
||||||
|
@end example
|
||||||
|
|
||||||
At a lower-level, a useful command is @code{lower}: it takes a file-like
|
At a lower-level, a useful command is @code{lower}: it takes a file-like
|
||||||
object and ``lowers'' it into a derivation (@pxref{Derivations}) or a
|
object and ``lowers'' it into a derivation (@pxref{Derivations}) or a
|
||||||
store file:
|
store file:
|
||||||
|
@ -12794,6 +12844,17 @@ This is similar to the @option{--verbosity} command-line option
|
||||||
shows build events only, and higher levels print build logs.
|
shows build events only, and higher levels print build logs.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {REPL command} phases @var{package}
|
||||||
|
@deffnx {REPL command} configure-flags @var{package}
|
||||||
|
@deffnx {REPL command} make-flags @var{package}
|
||||||
|
These REPL commands return the value of one element of the
|
||||||
|
@code{arguments} field of @var{package} (@pxref{package Reference}): the
|
||||||
|
first one show the staged code associated with @code{#:phases}
|
||||||
|
(@pxref{Build Phases}), the second shows the code for
|
||||||
|
@code{#:configure-flags}, and @code{,make-flags} returns the code for
|
||||||
|
@code{#:make-flags}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@deffn {REPL command} run-in-store @var{exp}
|
@deffn {REPL command} run-in-store @var{exp}
|
||||||
Run @var{exp}, a monadic expression, through the store monad.
|
Run @var{exp}, a monadic expression, through the store monad.
|
||||||
@xref{The Store Monad}, for more information.
|
@xref{The Store Monad}, for more information.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2014, 2015, 2016, 2022 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2014-2016, 2022-2023 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -21,13 +21,15 @@ (define-module (guix monad-repl)
|
||||||
#:use-module (guix monads)
|
#:use-module (guix monads)
|
||||||
#:use-module (guix utils)
|
#:use-module (guix utils)
|
||||||
#:use-module (guix packages)
|
#:use-module (guix packages)
|
||||||
|
#:autoload (guix build-system) (bag)
|
||||||
#:use-module (guix status)
|
#:use-module (guix status)
|
||||||
#:autoload (guix gexp) (lower-object)
|
#:autoload (guix gexp) (gexp gexp? lower-gexp lowered-gexp-sexp lower-object)
|
||||||
#:use-module ((guix derivations)
|
#:use-module ((guix derivations)
|
||||||
#:select (derivation?
|
#:select (derivation?
|
||||||
derivation->output-paths built-derivations))
|
derivation->output-paths built-derivations))
|
||||||
|
#:autoload (guix read-print) (pretty-print-with-comments)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:use-module (ice-9 pretty-print)
|
#:autoload (ice-9 pretty-print) (pretty-print)
|
||||||
#:use-module (system repl repl)
|
#:use-module (system repl repl)
|
||||||
#:use-module (system repl common)
|
#:use-module (system repl common)
|
||||||
#:use-module (system repl command)
|
#:use-module (system repl command)
|
||||||
|
@ -138,4 +140,68 @@ (define-meta-command ((enter-store-monad guix) repl)
|
||||||
(repl-option-set! new 'interp #t)
|
(repl-option-set! new 'interp #t)
|
||||||
(run-repl new))))
|
(run-repl new))))
|
||||||
|
|
||||||
;;; monad-repl.scm ends here
|
|
||||||
|
;;;
|
||||||
|
;;; Viewing package arguments.
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(define (keyword-argument-value args keyword default)
|
||||||
|
"Return the value associated with KEYWORD in ARGS, a keyword/value sequence,
|
||||||
|
or DEFAULT if KEYWORD is missing from ARGS."
|
||||||
|
(let loop ((args args))
|
||||||
|
(match args
|
||||||
|
(()
|
||||||
|
default)
|
||||||
|
((kw value rest ...)
|
||||||
|
(if (eq? kw keyword)
|
||||||
|
value
|
||||||
|
(loop rest))))))
|
||||||
|
|
||||||
|
(define (package-argument-command repl form keyword default)
|
||||||
|
"Implement a command that display KEYWORD, a keyword such as #:phases, in
|
||||||
|
the arguments of the package FORM evaluates to. Return DEFAULT is KEYWORD is
|
||||||
|
missing from those arguments."
|
||||||
|
(match (repl-eval repl form)
|
||||||
|
((? package? package)
|
||||||
|
(let* ((bag* (bag
|
||||||
|
(inherit (package->bag package))
|
||||||
|
(build (lambda* (name inputs #:rest args)
|
||||||
|
(with-monad %store-monad
|
||||||
|
(return (keyword-argument-value args keyword
|
||||||
|
default))))))))
|
||||||
|
(define phases
|
||||||
|
(parameterize ((%graft? #f))
|
||||||
|
(with-store store
|
||||||
|
(set-build-options store
|
||||||
|
#:print-build-trace #t
|
||||||
|
#:print-extended-build-trace? #t
|
||||||
|
#:multiplexed-build-output? #t)
|
||||||
|
(run-with-store store
|
||||||
|
(mlet %store-monad ((exp (bag->derivation bag*)))
|
||||||
|
(if (gexp? exp)
|
||||||
|
(mlet %store-monad ((gexp (lower-gexp exp)))
|
||||||
|
(return (lowered-gexp-sexp gexp)))
|
||||||
|
(return exp)))))))
|
||||||
|
|
||||||
|
(run-hook before-print-hook phases)
|
||||||
|
(let ((column (port-column (current-output-port))))
|
||||||
|
(pretty-print-with-comments (current-output-port) phases
|
||||||
|
#:indent column)
|
||||||
|
(newline (current-output-port)))))
|
||||||
|
(_
|
||||||
|
(format #t ";; ERROR: This command only accepts package records.~%"))))
|
||||||
|
|
||||||
|
(define-meta-command ((phases guix) repl (form))
|
||||||
|
"phases
|
||||||
|
Return the build phases of the package defined by FORM."
|
||||||
|
(package-argument-command repl form #:phases #~%standard-phases))
|
||||||
|
|
||||||
|
(define-meta-command ((configure-flags guix) repl (form))
|
||||||
|
"configure-flags
|
||||||
|
Return the configure flags of the package defined by FORM."
|
||||||
|
(package-argument-command repl form #:configure-flags #~'()))
|
||||||
|
|
||||||
|
(define-meta-command ((make-flags guix) repl (form))
|
||||||
|
"make-flags
|
||||||
|
Return the make flags of the package defined by FORM."
|
||||||
|
(package-argument-command repl form #:make-flags #~'()))
|
||||||
|
|
Loading…
Reference in a new issue