aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi14
-rw-r--r--gnu/home/services.scm48
-rw-r--r--tests/guix-home.sh4
3 files changed, 50 insertions, 16 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 96b4675a01..32e34b7d52 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -41007,13 +41007,15 @@ The easiest way to extend a service type, without defining a new service
type is to use the @code{simple-service} helper from @code{(gnu
services)}.
+@findex literal-string
@lisp
(simple-service 'some-useful-env-vars-service
home-environment-variables-service-type
`(("LESSHISTFILE" . "$XDG_CACHE_HOME/.lesshst")
("SHELL" . ,(file-append zsh "/bin/zsh"))
("USELESS_VAR" . #f)
- ("_JAVA_AWT_WM_NONREPARENTING" . #t)))
+ ("_JAVA_AWT_WM_NONREPARENTING" . #t)
+ ("LITERAL_VALUE" . ,(literal-string "$@{abc@}"))))
@end lisp
If you include such a service in you home environment definition, it
@@ -41021,11 +41023,17 @@ will add the following content to the @file{setup-environment} script
(which is expected to be sourced by the login shell):
@example
-export LESSHISTFILE=$XDG_CACHE_HOME/.lesshst
-export SHELL=/gnu/store/2hsg15n644f0glrcbkb1kqknmmqdar03-zsh-5.8/bin/zsh
+export LESSHISTFILE="$XDG_CACHE_HOME/.lesshst"
+export SHELL="/gnu/store/2hsg15n644f0glrcbkb1kqknmmqdar03-zsh-5.8/bin/zsh"
export _JAVA_AWT_WM_NONREPARENTING
+export LITERAL_VALUE='$@{abc@}'
@end example
+Notice that @code{literal-string} above lets us declare that a value is
+to be interpreted as a @dfn{literal string}, meaning that ``special
+characters'' such as the dollar sign will not be interpreted by the
+shell.
+
@quotation Note
Make sure that module @code{(gnu packages shells)} is imported with
@code{use-modules} or any other way, this namespace contains the
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index e154f5c443..692354c644 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
+;;; Copyright © 2022 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -33,6 +34,7 @@
#:use-module (guix i18n)
#:use-module (guix modules)
#:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-9)
#:use-module (ice-9 match)
#:use-module (ice-9 vlist)
@@ -47,6 +49,10 @@
home-run-on-change-service-type
home-provenance-service-type
+ literal-string
+ literal-string?
+ literal-string-value
+
environment-variable-shell-definitions
home-files-directory
xdg-configuration-files-directory
@@ -171,32 +177,50 @@ packages, configuration files, activation script, and so on.")))
configuration files that the user has declared in their
@code{home-environment} record.")))
+;; Representation of a literal string.
+(define-record-type <literal-string>
+ (literal-string str)
+ literal-string?
+ (str literal-string-value))
+
(define (environment-variable-shell-definitions variables)
"Return a gexp that evaluates to a list of POSIX shell statements defining
VARIABLES, a list of environment variable name/value pairs. The returned code
ensures variable values are properly quoted."
- #~(let ((shell-quote
- (lambda (value)
- ;; Double-quote VALUE, leaving dollar sign as is.
- (let ((quoted (list->string
- (string-fold-right
+ #~(let* ((quote-string
+ (lambda (value quoted-chars)
+ (list->string (string-fold-right
(lambda (chr lst)
- (case chr
- ((#\" #\\)
- (append (list chr #\\) lst))
- (else (cons chr lst))))
+ (if (memq chr quoted-chars)
+ (append (list chr #\\) lst)
+ (cons chr lst)))
'()
value))))
- (string-append "\"" quoted "\"")))))
+ (shell-double-quote
+ (lambda (value)
+ ;; Double-quote VALUE, leaving dollar sign as is.
+ (string-append "\"" (quote-string value '(#\" #\\))
+ "\"")))
+ (shell-single-quote
+ (lambda (value)
+ ;; Single-quote VALUE to enter a literal string.
+ (string-append "'" (quote-string value '(#\' #\\))
+ "'"))))
(string-append
#$@(map (match-lambda
((key . #f)
"")
((key . #t)
#~(string-append "export " #$key "\n"))
- ((key . value)
+ ((key . (? string? value))
+ #~(string-append "export " #$key "="
+ (shell-double-quote #$value)
+ "\n"))
+ ((key . (? literal-string? value))
#~(string-append "export " #$key "="
- (shell-quote #$value) "\n")))
+ (shell-single-quote
+ #$(literal-string-value value))
+ "\n")))
variables))))
(define (environment-variables->setup-environment-script vars)
diff --git a/tests/guix-home.sh b/tests/guix-home.sh
index d5e2dadbb5..423ebf6f33 100644
--- a/tests/guix-home.sh
+++ b/tests/guix-home.sh
@@ -81,7 +81,8 @@ trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_directory"' EXIT
(simple-service 'add-environment-variable
home-environment-variables-service-type
- '(("TODAY" . "26 messidor")))
+ `(("TODAY" . "26 messidor")
+ ("LITERAL" . ,(literal-string "${abc}"))))
(simple-service 'home-bash-service-extension-test
home-bash-service-type
@@ -149,6 +150,7 @@ EOF
grep -q "the content of ~/.config/test.conf" "${HOME}/.config/test.conf"
grep '^export PS1="\$GUIX_ENVIRONMENT λ "$' "${HOME}/.bash_profile"
( . "${HOME}/.guix-home/setup-environment"; test "$TODAY" = "26 messidor" )
+ ( . "${HOME}/.guix-home/setup-environment"; test "$LITERAL" = '${abc}' )
# This one should still be here.
grep "stay around" "$HOME/.config/random-file"