guix package: Add `--install-from-expression'.
* guix/scripts/package.scm (read/eval-package-expression): New procedure. (show-help): Add `-e'. (%options): Likewise. (guix-package)[process-actions]: Handle ('install . p) pairs, where P is a package. * tests/guix-package.sh: Add `boot_make_drv'. Use `-i $boot_make_drv' once, and then use `-e $boot_make'. * doc/guix.texi (Invoking guix package): Document `-e'.
This commit is contained in:
parent
431a35518f
commit
5d4b411f8a
|
@ -514,6 +514,19 @@ Thus, when installing MPC, the MPFR and GMP libraries also get installed
|
||||||
in the profile; removing MPC also removes MPFR and GMP---unless they had
|
in the profile; removing MPC also removes MPFR and GMP---unless they had
|
||||||
also been explicitly installed independently.
|
also been explicitly installed independently.
|
||||||
|
|
||||||
|
@item --install-from-expression=@var{exp}
|
||||||
|
@itemx -e @var{exp}
|
||||||
|
Install the package @var{exp} evaluates to.
|
||||||
|
|
||||||
|
@var{exp} must be a Scheme expression that evaluates to a
|
||||||
|
@code{<package>} object. This option is notably useful to disambiguate
|
||||||
|
between same-named variants of a package, with expressions such as
|
||||||
|
@code{(@@ (gnu packages base) guile-final)}.
|
||||||
|
|
||||||
|
Note that this option installs the first output of the specified
|
||||||
|
package, which may be insufficient when needing a specific output of a
|
||||||
|
multiple-output package.
|
||||||
|
|
||||||
@item --remove=@var{package}
|
@item --remove=@var{package}
|
||||||
@itemx -r @var{package}
|
@itemx -r @var{package}
|
||||||
Remove @var{package}.
|
Remove @var{package}.
|
||||||
|
|
|
@ -266,6 +266,26 @@ matching packages."
|
||||||
(assoc-ref (derivation-outputs drv) sub-drv))))
|
(assoc-ref (derivation-outputs drv) sub-drv))))
|
||||||
`(,name ,out))))))
|
`(,name ,out))))))
|
||||||
|
|
||||||
|
(define (read/eval-package-expression str)
|
||||||
|
"Read and evaluate STR and return the package it refers to, or exit an
|
||||||
|
error."
|
||||||
|
(let ((exp (catch #t
|
||||||
|
(lambda ()
|
||||||
|
(call-with-input-string str read))
|
||||||
|
(lambda args
|
||||||
|
(leave (_ "failed to read expression ~s: ~s~%")
|
||||||
|
str args)))))
|
||||||
|
(let ((p (catch #t
|
||||||
|
(lambda ()
|
||||||
|
(eval exp the-scm-module))
|
||||||
|
(lambda args
|
||||||
|
(leave (_ "failed to evaluate expression `~a': ~s~%")
|
||||||
|
exp args)))))
|
||||||
|
(if (package? p)
|
||||||
|
p
|
||||||
|
(leave (_ "expression `~s' does not evaluate to a package~%")
|
||||||
|
exp)))))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Command-line options.
|
;;; Command-line options.
|
||||||
|
@ -281,6 +301,9 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
|
||||||
(display (_ "
|
(display (_ "
|
||||||
-i, --install=PACKAGE install PACKAGE"))
|
-i, --install=PACKAGE install PACKAGE"))
|
||||||
(display (_ "
|
(display (_ "
|
||||||
|
-e, --install-from-expression=EXP
|
||||||
|
install the package EXP evaluates to"))
|
||||||
|
(display (_ "
|
||||||
-r, --remove=PACKAGE remove PACKAGE"))
|
-r, --remove=PACKAGE remove PACKAGE"))
|
||||||
(display (_ "
|
(display (_ "
|
||||||
-u, --upgrade=REGEXP upgrade all the installed packages matching REGEXP"))
|
-u, --upgrade=REGEXP upgrade all the installed packages matching REGEXP"))
|
||||||
|
@ -325,6 +348,10 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
|
||||||
(option '(#\i "install") #t #f
|
(option '(#\i "install") #t #f
|
||||||
(lambda (opt name arg result)
|
(lambda (opt name arg result)
|
||||||
(alist-cons 'install arg result)))
|
(alist-cons 'install arg result)))
|
||||||
|
(option '(#\e "install-from-expression") #t #f
|
||||||
|
(lambda (opt name arg result)
|
||||||
|
(alist-cons 'install (read/eval-package-expression arg)
|
||||||
|
result)))
|
||||||
(option '(#\r "remove") #t #f
|
(option '(#\r "remove") #t #f
|
||||||
(lambda (opt name arg result)
|
(lambda (opt name arg result)
|
||||||
(alist-cons 'remove arg result)))
|
(alist-cons 'remove arg result)))
|
||||||
|
@ -490,6 +517,19 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
|
||||||
|
|
||||||
(delete-duplicates (map input->name+path deps) same?))
|
(delete-duplicates (map input->name+path deps) same?))
|
||||||
|
|
||||||
|
(define (package->tuple p)
|
||||||
|
(let ((path (package-derivation (%store) p))
|
||||||
|
(deps (package-transitive-propagated-inputs p)))
|
||||||
|
`(,(package-name p)
|
||||||
|
,(package-version p)
|
||||||
|
|
||||||
|
;; When given a package via `-e', install the first of its
|
||||||
|
;; outputs (XXX).
|
||||||
|
,(car (package-outputs p))
|
||||||
|
|
||||||
|
,path
|
||||||
|
,(canonicalize-deps deps))))
|
||||||
|
|
||||||
;; First roll back if asked to.
|
;; First roll back if asked to.
|
||||||
(if (and (assoc-ref opts 'roll-back?) (not dry-run?))
|
(if (and (assoc-ref opts 'roll-back?) (not dry-run?))
|
||||||
(begin
|
(begin
|
||||||
|
@ -515,6 +555,8 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
|
||||||
(install (append
|
(install (append
|
||||||
upgrade
|
upgrade
|
||||||
(filter-map (match-lambda
|
(filter-map (match-lambda
|
||||||
|
(('install . (? package? p))
|
||||||
|
#f)
|
||||||
(('install . (? store-path?))
|
(('install . (? store-path?))
|
||||||
#f)
|
#f)
|
||||||
(('install . package)
|
(('install . package)
|
||||||
|
@ -530,6 +572,8 @@ Install, remove, or upgrade PACKAGES in a single transaction.\n"))
|
||||||
install))
|
install))
|
||||||
(install* (append
|
(install* (append
|
||||||
(filter-map (match-lambda
|
(filter-map (match-lambda
|
||||||
|
(('install . (? package? p))
|
||||||
|
(package->tuple p))
|
||||||
(('install . (? store-path? path))
|
(('install . (? store-path? path))
|
||||||
(let-values (((name version)
|
(let-values (((name version)
|
||||||
(package-name->name+version
|
(package-name->name+version
|
||||||
|
|
|
@ -33,6 +33,10 @@ rm -f "$profile"
|
||||||
|
|
||||||
trap 'rm "$profile" "$profile-"[0-9]* ; rm -rf t-home-'"$$" EXIT
|
trap 'rm "$profile" "$profile-"[0-9]* ; rm -rf t-home-'"$$" EXIT
|
||||||
|
|
||||||
|
# Use `-e' with a non-package expression.
|
||||||
|
if guix package --bootstrap -e +;
|
||||||
|
then false; else true; fi
|
||||||
|
|
||||||
guix package --bootstrap -p "$profile" -i guile-bootstrap
|
guix package --bootstrap -p "$profile" -i guile-bootstrap
|
||||||
test -L "$profile" && test -L "$profile-1-link"
|
test -L "$profile" && test -L "$profile-1-link"
|
||||||
test -f "$profile/bin/guile"
|
test -f "$profile/bin/guile"
|
||||||
|
@ -46,8 +50,9 @@ test -f "$profile/bin/guile"
|
||||||
# Check whether we have network access.
|
# Check whether we have network access.
|
||||||
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
|
||||||
boot_make="`guix build -e '(@@ (gnu packages base) gnu-make-boot0)'`"
|
boot_make="(@@ (gnu packages base) gnu-make-boot0)"
|
||||||
guix package --bootstrap -p "$profile" -i "$boot_make"
|
boot_make_drv="`guix build -e "$boot_make"`"
|
||||||
|
guix package --bootstrap -p "$profile" -i "$boot_make_drv"
|
||||||
test -L "$profile-2-link"
|
test -L "$profile-2-link"
|
||||||
test -f "$profile/bin/make" && test -f "$profile/bin/guile"
|
test -f "$profile/bin/make" && test -f "$profile/bin/guile"
|
||||||
|
|
||||||
|
@ -94,7 +99,7 @@ then
|
||||||
done
|
done
|
||||||
|
|
||||||
# Reinstall after roll-back to the empty profile.
|
# Reinstall after roll-back to the empty profile.
|
||||||
guix package --bootstrap -p "$profile" -i "$boot_make"
|
guix package --bootstrap -p "$profile" -e "$boot_make"
|
||||||
test "`readlink_base "$profile"`" = "$profile-1-link"
|
test "`readlink_base "$profile"`" = "$profile-1-link"
|
||||||
test -x "$profile/bin/guile" && ! test -x "$profile/bin/make"
|
test -x "$profile/bin/guile" && ! test -x "$profile/bin/make"
|
||||||
|
|
||||||
|
@ -104,7 +109,7 @@ then
|
||||||
test -x "$profile/bin/guile" && ! test -x "$profile/bin/make"
|
test -x "$profile/bin/guile" && ! test -x "$profile/bin/make"
|
||||||
|
|
||||||
# Install Make.
|
# Install Make.
|
||||||
guix package --bootstrap -p "$profile" -i "$boot_make"
|
guix package --bootstrap -p "$profile" -e "$boot_make"
|
||||||
test "`readlink_base "$profile"`" = "$profile-2-link"
|
test "`readlink_base "$profile"`" = "$profile-2-link"
|
||||||
test -x "$profile/bin/guile" && test -x "$profile/bin/make"
|
test -x "$profile/bin/guile" && test -x "$profile/bin/make"
|
||||||
|
|
||||||
|
@ -145,7 +150,7 @@ test -f "$HOME/.guix-profile/bin/guile"
|
||||||
|
|
||||||
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
|
||||||
guix package --bootstrap -i "$boot_make"
|
guix package --bootstrap -e "$boot_make"
|
||||||
test -f "$HOME/.guix-profile/bin/make"
|
test -f "$HOME/.guix-profile/bin/make"
|
||||||
first_environment="`cd $HOME/.guix-profile ; pwd`"
|
first_environment="`cd $HOME/.guix-profile ; pwd`"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue