environment: For --ad-hoc, allow users to specify an output.

* guix/scripts/environment.scm (package+propagated-inputs): Add 'output'
  parameter.  Use it in return value.
  (options/resolve-packages): Use 'append-map' instead of 'map'.  For 'load'
  and 'expression', return all the outputs of the resulting package.  For
  'package', use 'specification->package+output' instead of
  'specification->package'.
  (guix-environment): Adjust uses of PACKAGES accordingly.
* doc/guix.texi (Invoking guix environment): Document it.
* tests/guix-environment.sh: Add test for --ad-hoc guile-bootstrap:out.
This commit is contained in:
Ludovic Courtès 2015-06-30 23:16:42 +02:00
parent ce367ef3a9
commit 417c39f132
3 changed files with 39 additions and 16 deletions

View File

@ -4211,6 +4211,11 @@ guix environment --ad-hoc guile guile-sdl -E guile
runs @command{guile} in an environment where Guile and Guile-SDL are runs @command{guile} in an environment where Guile and Guile-SDL are
available. available.
Note that this example implicitly asks for the default output of
@code{guile} and @code{guile-sdl} but it is possible to ask for a
specific output---e.g., @code{glib:bin} asks for the @code{bin} output
of @code{glib} (@pxref{Packages with Multiple Outputs}).
@item --pure @item --pure
Unset existing environment variables when building the new environment. Unset existing environment variables when building the new environment.
This has the effect of creating an environment in which search paths This has the effect of creating an environment in which search paths

View File

@ -32,6 +32,7 @@
#:use-module (ice-9 format) #:use-module (ice-9 format)
#:use-module (ice-9 match) #:use-module (ice-9 match)
#:use-module (srfi srfi-1) #:use-module (srfi srfi-1)
#:use-module (srfi srfi-11)
#:use-module (srfi srfi-26) #:use-module (srfi srfi-26)
#:use-module (srfi srfi-37) #:use-module (srfi srfi-37)
#:use-module (srfi srfi-98) #:use-module (srfi srfi-98)
@ -91,9 +92,9 @@ existing environment variables with additional search paths."
(newline))) (newline)))
(evaluate-input-search-paths inputs search-paths))) (evaluate-input-search-paths inputs search-paths)))
(define (package+propagated-inputs package) (define (package+propagated-inputs package output)
"Return the union of PACKAGE and its transitive propagated inputs." "Return the union of PACKAGE's OUTPUT and its transitive propagated inputs."
`((,(package-name package) ,package) `((,(package-name package) ,package ,output)
,@(package-transitive-propagated-inputs package))) ,@(package-transitive-propagated-inputs package)))
(define (show-help) (define (show-help)
@ -185,17 +186,26 @@ shell command in that environment.\n"))
(define (options/resolve-packages opts) (define (options/resolve-packages opts)
"Return OPTS with package specification strings replaced by actual "Return OPTS with package specification strings replaced by actual
packages." packages."
(map (match-lambda (append-map (match-lambda
(('package . (? string? spec)) (('package . (? string? spec))
`(package . ,(specification->package spec))) (let-values (((package output)
(('expression . str) (specification->package+output spec)))
(match (read/eval str) `((package ,package ,output))))
((? package? p) (('expression . str)
`(package . ,p)))) ;; Add all the outputs of the package STR evaluates to.
(('load . file) (match (read/eval str)
`(package . ,(load (string-append (getcwd) "/" file)))) ((? package? package)
(opt opt)) (map (lambda (output)
opts)) `(package ,package ,output))
(package-outputs package)))))
(('load . file)
;; Add all the outputs of the package defined in FILE.
(let ((package (load (string-append (getcwd) "/" file))))
(map (lambda (output)
`(package ,package ,output))
(package-outputs package))))
(opt (list opt)))
opts))
(define (build-inputs inputs opts) (define (build-inputs inputs opts)
"Build the derivations in INPUTS, a list of (DERIVATION) or (DERIVATION "Build the derivations in INPUTS, a list of (DERIVATION) or (DERIVATION
@ -228,9 +238,14 @@ OUTPUT) tuples, using the build options in OPTS."
(command (assoc-ref opts 'exec)) (command (assoc-ref opts 'exec))
(packages (pick-all (options/resolve-packages opts) 'package)) (packages (pick-all (options/resolve-packages opts) 'package))
(inputs (if ad-hoc? (inputs (if ad-hoc?
(append-map package+propagated-inputs packages) (append-map (match-lambda
((package output)
(package+propagated-inputs package
output)))
packages)
(append-map (compose bag-transitive-inputs (append-map (compose bag-transitive-inputs
package->bag) package->bag
first)
packages))) packages)))
(paths (delete-duplicates (paths (delete-duplicates
(cons $PATH (cons $PATH

View File

@ -31,11 +31,14 @@ mkdir "$tmpdir"
# Check the environment variables for the bootstrap Guile. # Check the environment variables for the bootstrap Guile.
guix environment --ad-hoc guile-bootstrap --pure --search-paths > "$tmpdir/a" guix environment --ad-hoc guile-bootstrap --pure --search-paths > "$tmpdir/a"
guix environment --ad-hoc guile-bootstrap:out --pure --search-paths > "$tmpdir/b"
# $PATH must appear in the search paths, and nothing else. # $PATH must appear in the search paths, and nothing else.
grep -E '^export PATH=.*guile-bootstrap-[0-9.]+/bin' "$tmpdir/a" grep -E '^export PATH=.*guile-bootstrap-[0-9.]+/bin' "$tmpdir/a"
test "`wc -l < "$tmpdir/a"`" = 1 test "`wc -l < "$tmpdir/a"`" = 1
cmp "$tmpdir/a" "$tmpdir/b"
if guile -c '(getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)' 2> /dev/null if guile -c '(getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)' 2> /dev/null
then then
# Compute the build environment for the initial GNU Make. # Compute the build environment for the initial GNU Make.