From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp11.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id gNjsBSLmqWMirwAAbAwnHQ (envelope-from ) for ; Mon, 26 Dec 2022 19:21:22 +0100 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp11.migadu.com with LMTPS id uPjzBSLmqWNrLQAA9RJhRA (envelope-from ) for ; Mon, 26 Dec 2022 19:21:22 +0100 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 6EEB42F2C9 for ; Mon, 26 Dec 2022 19:21:21 +0100 (CET) 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 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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+larch=yhetil.org@gnu.org Sender: guix-patches-bounces+larch=yhetil.org@gnu.org X-Migadu-Country: US X-Migadu-Flow: FLOW_IN ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1672078881; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:resent-cc: resent-from:resent-sender:resent-message-id:list-id:list-help: list-unsubscribe:list-subscribe:list-post:dkim-signature; bh=w16Xa9XGXEA31PBhkbHgKl9B6mn/HRUFLEYGIdf8cuo=; b=KZsPAfbQGb/cu5TKnmSxkE1z4vzOvf+vPn+hbP0wGLkMR4LhWfSkWYGMOqYYCiJhjiOIAL 0VSTEgdn6+rW9EyFV0nrYq1u3KjCdgLs+kd/FT3UixUJVzjcfogLhVsl0MRTrbeqB5OgLO R+93llOwl8lEIKlUJyVR3334juTsTEaYlhVrxGpwaP32X80SjS53/tsXi9cW1zdTnyPGBo iH+A7WCRCF6cbynhvSydMibAVITqpAMeJy9gQVS37stfYHPIpHR+TVJ8/2NMtUvM3bouXS ASTr2ifqQG4mwZY95YU6NX7H2AmoFcTfDz7ier5wZa1xcWGiKlsUQ8goBuSTvQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gnu.org header.s=fencepost-gnu-org header.b=e4Tb0rSj; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org"; dmarc=pass (policy=none) header.from=gnu.org ARC-Seal: i=1; s=key1; d=yhetil.org; t=1672078881; a=rsa-sha256; cv=none; b=MbUXAvRWdr336wZyu898E0Gt5QMwpiLLqwR9rSgz/4eMbVXQS/oxvZaEDexcqGCPEZ2ZRL yZqRgMCclPz0jJK+snUG/nMJjKTS9COxL4Cz8ylKjJKtFRaoV3MlT9Ru6vEL++Rer4p4Mr 7zw2PbEdAumRbgm/wski1ecjzVcud1OcB/LBXIFpIfqUp3ESkJ2aeKAEmhCJzulCHN9E+v Ai78GXT1lL6sOahOyPkWde7D+kt0IzC6XyEwlJEhm7FFQ76s5zCGFdJlXYahmiyzWdbxuN xHfVlDa6tukepgEFwKGA2C1VvZPg5iykF3ILBR6wc08ciUZmOnIrnNq77ghH6Q== X-Spam-Score: -2.93 X-Migadu-Queue-Id: 6EEB42F2C9 Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gnu.org header.s=fencepost-gnu-org header.b=e4Tb0rSj; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org"; dmarc=pass (policy=none) header.from=gnu.org X-Migadu-Scanner: scn1.migadu.com X-Migadu-Spam-Score: -2.93 X-TUID: RWBaVzg6glM3 * 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’. 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" base-commit: 9369c1ccf47d9bf6f2e28a9454c1c329a2044f19 -- 2.38.1