From patchwork Mon Dec 26 18:19:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ludovic_Court=C3=A8s?= X-Patchwork-Id: 45590 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 4631E27BBEB; Mon, 26 Dec 2022 18:21:25 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-3.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 5754A27BBE9 for ; Mon, 26 Dec 2022 18:21:21 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p9s61-0006Mk-G7; Mon, 26 Dec 2022 13:21:09 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p9s5z-0006J3-4V for guix-patches@gnu.org; Mon, 26 Dec 2022 13:21:07 -0500 Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p9s5u-000641-J2 for guix-patches@gnu.org; Mon, 26 Dec 2022 13:21:06 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1p9s5t-00043N-TL for guix-patches@gnu.org; Mon, 26 Dec 2022 13:21:01 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#60341] [PATCH Home] home: services: environment-variables: Add support for literal strings. Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Mon, 26 Dec 2022 18:21:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 60341 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 60341@debbugs.gnu.org Cc: Ludovic =?utf-8?q?Court=C3=A8s?= X-Debbugs-Original-To: guix-patches@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.167207880315499 (code B ref -1); Mon, 26 Dec 2022 18:21:01 +0000 Received: (at submit) by debbugs.gnu.org; 26 Dec 2022 18:20:03 +0000 Received: from localhost ([127.0.0.1]:54098 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p9s4w-00041s-LZ for submit@debbugs.gnu.org; Mon, 26 Dec 2022 13:20:03 -0500 Received: from lists.gnu.org ([209.51.188.17]:39598) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1p9s4u-00041P-50 for submit@debbugs.gnu.org; Mon, 26 Dec 2022 13:20:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p9s4m-0005fx-CG for guix-patches@gnu.org; Mon, 26 Dec 2022 13:19:52 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p9s4j-0005fs-Ih; Mon, 26 Dec 2022 13:19:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:Date:Subject:To:From:in-reply-to: references; bh=w16Xa9XGXEA31PBhkbHgKl9B6mn/HRUFLEYGIdf8cuo=; b=e4Tb0rSj7k6KJG PCazL8Z3Ks0LcuzLxDFz2sIURMxRXLPX4k4xd/uGCjE4SlteZGcrqS4RSPR6j7JY7VB5yVT5VdXf3 t4MkF92kP6n+y6BLzqD+nZRpk//1rgRJbV3qg2rR8qPbWyottSONw7W2JoLtz4E+TTyyQr4VntexT a1b9/jg7TIEtXaMIh8YYFtOMxCnUP2j6Pp7Aqsd9QrOAf3elRSeMpGQL8024P1c990c8pI1a9ZpXk 2jDalD14z2S4Q+cXRlWMK6YsFQNOxq58XWBtfJ/oxevzKl/3wCbrUTqVYwq130rG4nGYbcV+Mgiv/ x+G2GI5ho0o7RjrrM/mA==; Received: from 91-160-117-201.subs.proxad.net ([91.160.117.201] helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1p9s4h-0007Fq-RZ; Mon, 26 Dec 2022 13:19:48 -0500 From: Ludovic =?utf-8?q?Court=C3=A8s?= Date: Mon, 26 Dec 2022 19:19:38 +0100 Message-Id: <20221226181938.30003-1-ludo@gnu.org> X-Mailer: git-send-email 2.38.1 MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * gnu/home/services.scm (): New record type. (environment-variable-shell-definitions): Split 'shell-quote' into 'quote-string' and 'shell-double-quote'. Add 'shell-single-quote'. Add clause for 'literal-string' records. * tests/guix-home.sh: Test it. * doc/guix.texi (Essential Home Services): Document it. --- doc/guix.texi | 14 ++++++++++--- gnu/home/services.scm | 48 ++++++++++++++++++++++++++++++++----------- tests/guix-home.sh | 4 +++- 3 files changed, 50 insertions(+), 16 deletions(-) Hi! I found that it’s occasionally useful to be able to define shell variables with a value that is to be taken literally, without shell expansion. This is what this patch implements. Thoughts? Ludo’. base-commit: 9369c1ccf47d9bf6f2e28a9454c1c329a2044f19 diff --git a/doc/guix.texi b/doc/guix.texi index efd281d9b0..44361b481a 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -40972,13 +40972,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 @@ -40986,11 +40988,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 99035686f1..2c1f58fddf 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 ;;; Copyright © 2021 Xinglu Chen +;;; Copyright © 2022 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -33,6 +34,7 @@ (define-module (gnu home services) #: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 @@ (define-module (gnu home services) 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 @@ (define home-profile-service-type configuration files that the user has declared in their @code{home-environment} record."))) +;; Representation of a literal string. +(define-record-type + (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-quote #$value) "\n"))) + (shell-double-quote #$value) + "\n")) + ((key . (? literal-string? value)) + #~(string-append "export " #$key "=" + (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"