From patchwork Sat Oct 2 10:22:33 2021 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: 33543 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 B742127BBE1; Sat, 2 Oct 2021 11:24:55 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id C1C8F27BBE3 for ; Sat, 2 Oct 2021 11:24:54 +0100 (BST) Received: from localhost ([::1]:52304 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mWcCL-0002HF-Sc for patchwork@mira.cbaines.net; Sat, 02 Oct 2021 06:24:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38416) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mWcBW-0002Fj-8E for guix-patches@gnu.org; Sat, 02 Oct 2021 06:24:02 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:46427) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mWcBW-0000A9-0p for guix-patches@gnu.org; Sat, 02 Oct 2021 06:24:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1mWcBV-0007Ye-U0 for guix-patches@gnu.org; Sat, 02 Oct 2021 06:24:01 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#50960] [PATCH 03/10] DRAFT Add 'guix shell'. Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 02 Oct 2021 10:24:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 50960 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 50960@debbugs.gnu.org Cc: Ludovic =?utf-8?q?Court=C3=A8s?= Received: via spool by 50960-submit@debbugs.gnu.org id=B50960.163317019128934 (code B ref 50960); Sat, 02 Oct 2021 10:24:01 +0000 Received: (at 50960) by debbugs.gnu.org; 2 Oct 2021 10:23:11 +0000 Received: from localhost ([127.0.0.1]:57954 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mWcAW-0007V8-Pu for submit@debbugs.gnu.org; Sat, 02 Oct 2021 06:23:11 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33120) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mWcAT-0007UG-TX for 50960@debbugs.gnu.org; Sat, 02 Oct 2021 06:22:58 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:49192) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mWcAO-0007ci-IF; Sat, 02 Oct 2021 06:22:52 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=36460 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 1mWcAO-0007gb-8c; Sat, 02 Oct 2021 06:22:52 -0400 From: Ludovic =?utf-8?q?Court=C3=A8s?= Date: Sat, 2 Oct 2021 12:22:33 +0200 Message-Id: <20211002102240.27815-3-ludo@gnu.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211002102240.27815-1-ludo@gnu.org> References: <20211002102240.27815-1-ludo@gnu.org> 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" X-getmail-retrieved-from-mailbox: Patches From: Ludovic Courtès DRAFT: Add doc. Print deprecation warning for 'guix environment'? * guix/scripts/shell.scm, tests/guix-shell.sh: New files. * Makefile.am (MODULES): Add 'shell.scm'. (SH_TESTS): Add 'tests/guix-shell.sh'. * guix/scripts/environment.scm (show-environment-options-help): New procedure. (show-help): Use it. (guix-environment*): New procedure. (guix-environment): Use it. * po/guix/POTFILES.in: Add it. --- Makefile.am | 2 + guix/scripts/environment.scm | 52 +++++++++----- guix/scripts/shell.scm | 136 +++++++++++++++++++++++++++++++++++ po/guix/POTFILES.in | 1 + tests/guix-shell.sh | 54 ++++++++++++++ 5 files changed, 228 insertions(+), 17 deletions(-) create mode 100644 guix/scripts/shell.scm create mode 100644 tests/guix-shell.sh diff --git a/Makefile.am b/Makefile.am index b66789fa0b..c28c8799ec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -315,6 +315,7 @@ MODULES = \ guix/scripts/import/stackage.scm \ guix/scripts/import/texlive.scm \ guix/scripts/environment.scm \ + guix/scripts/shell.scm \ guix/scripts/publish.scm \ guix/scripts/edit.scm \ guix/scripts/size.scm \ @@ -550,6 +551,7 @@ SH_TESTS = \ tests/guix-authenticate.sh \ tests/guix-environment.sh \ tests/guix-environment-container.sh \ + tests/guix-shell.sh \ tests/guix-graph.sh \ tests/guix-describe.sh \ tests/guix-repl.sh \ diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm index 54f48a7482..77956fc018 100644 --- a/guix/scripts/environment.scm +++ b/guix/scripts/environment.scm @@ -50,7 +50,11 @@ #:use-module (srfi srfi-37) #:use-module (srfi srfi-98) #:export (assert-container-features - guix-environment)) + guix-environment + guix-environment* + show-environment-options-help + (%options . %environment-options) + (%default-options . %environment-default-options))) (define %default-shell (or (getenv "SHELL") "/bin/sh")) @@ -66,23 +70,16 @@ do not augment existing environment variables with additional search paths." (newline))) (profile-search-paths profile manifest))) -(define (show-help) - (display (G_ "Usage: guix environment [OPTION]... PACKAGE... [-- COMMAND...] -Build an environment that includes the dependencies of PACKAGE and execute -COMMAND or an interactive shell in that environment.\n")) +(define (show-environment-options-help) + "Print help about options shared between 'guix environment' and 'guix +shell'." (display (G_ " -e, --expression=EXPR create environment for the package that EXPR evaluates to")) (display (G_ " - -l, --load=FILE create environment for the package that the code within - FILE evaluates to")) - (display (G_ " -m, --manifest=FILE create environment with the manifest from FILE")) (display (G_ " -p, --profile=PATH create environment from profile at PATH")) - (display (G_ " - --ad-hoc include all specified packages in the environment instead - of only their inputs")) (display (G_ " --pure unset existing environment variables")) (display (G_ " @@ -118,7 +115,24 @@ COMMAND or an interactive shell in that environment.\n")) (display (G_ " -v, --verbosity=LEVEL use the given verbosity LEVEL")) (display (G_ " - --bootstrap use bootstrap binaries to build the environment")) + --bootstrap use bootstrap binaries to build the environment"))) + +(define (show-help) + (display (G_ "Usage: guix environment [OPTION]... PACKAGE... [-- COMMAND...] +Build an environment that includes the dependencies of PACKAGE and execute +COMMAND or an interactive shell in that environment.\n")) + (warning (G_ "This command is deprecated in favor of 'guix shell'.\n")) + (newline) + + ;; These two options are left out in 'guix shell'. + (display (G_ " + -l, --load=FILE create environment for the package that the code within + FILE evaluates to")) + (display (G_ " + --ad-hoc include all specified packages in the environment instead + of only their inputs")) + + (show-environment-options-help) (newline) (show-build-options-help) (newline) @@ -649,11 +663,15 @@ message if any test fails." (define-command (guix-environment . args) (category development) - (synopsis "spawn one-off software environments") + (synopsis "spawn one-off software environments (deprecated)") + (guix-environment* (parse-args args))) + +(define (guix-environment* opts) + "Run the 'guix environment' command on OPTS, an alist resulting for +command-line option processing with 'parse-command-line'." (with-error-handling - (let* ((opts (parse-args args)) - (pure? (assoc-ref opts 'pure)) + (let* ((pure? (assoc-ref opts 'pure)) (container? (assoc-ref opts 'container?)) (link-prof? (assoc-ref opts 'link-profile?)) (network? (assoc-ref opts 'network?)) @@ -724,8 +742,8 @@ message if any test fails." (prof-drv (manifest->derivation manifest system bootstrap?)) (profile -> (if profile - (readlink* profile) - (derivation->output-path prof-drv))) + (readlink* profile) + (derivation->output-path prof-drv))) (gc-root -> (assoc-ref opts 'gc-root))) ;; First build the inputs. This is necessary even for diff --git a/guix/scripts/shell.scm b/guix/scripts/shell.scm new file mode 100644 index 0000000000..6a4b7a5092 --- /dev/null +++ b/guix/scripts/shell.scm @@ -0,0 +1,136 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2021 Ludovic Courtès +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (guix scripts shell) + #:use-module (guix ui) + #:use-module (guix scripts environment) + #:autoload (guix scripts build) (show-build-options-help) + #:autoload (guix transformations) (show-transformation-options-help) + #:use-module (guix scripts) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-37) + #:use-module (srfi srfi-71) + #:use-module (ice-9 match) + #:export (guix-shell)) + +(define (show-help) + (display (G_ "Usage: guix shell [OPTION] PACKAGES... [-- COMMAND...] +Build an environment that includes PACKAGES and execute COMMAND or an +interactive shell in that environment.\n")) + (newline) + + ;; These two options differ from 'guix environment'. + (display (G_ " + -D, --development include the development inputs of the next package")) + (display (G_ " + -f, --install-from-file=FILE + install the package that the code within FILE + evaluates to")) + + (show-environment-options-help) + (newline) + (show-build-options-help) + (newline) + (show-transformation-options-help) + (newline) + (display (G_ " + -h, --help display this help and exit")) + (display (G_ " + -V, --version display version information and exit")) + (newline) + (show-bug-report-information)) + +(define (tag-package-arg opts arg) + "Return a two-element list with the form (TAG ARG) that tags ARG with either +'ad-hoc' in OPTS has the 'ad-hoc?' key set to #t, or 'inputs' otherwise." + (if (assoc-ref opts 'ad-hoc?) + `(ad-hoc-package ,arg) + `(package ,arg))) + +(define (ensure-ad-hoc alist) + (if (assq-ref alist 'ad-hoc?) + alist + `((ad-hoc? . #t) ,@alist))) + +(define (wrapped-option opt) + "Wrap OPT, a SRFI-37 option, such that its processor always adds the +'ad-hoc?' flag to the resulting alist." + (option (option-names opt) + (option-required-arg? opt) + (option-optional-arg? opt) + (compose ensure-ad-hoc (option-processor opt)))) + +(define %options + ;; Specification of the command-line options. + (let ((to-remove '("ad-hoc" "inherit" "load" "help" "version"))) + (append + (list (option '(#\h "help") #f #f + (lambda args + (show-help) + (exit 0))) + (option '(#\V "version") #f #f + (lambda args + (show-version-and-exit "guix shell"))) + + (option '(#\D "development") #f #f + (lambda (opt name arg result) + ;; Temporarily remove the 'ad-hoc?' flag from result. + ;; The next option will put it back thanks to + ;; 'wrapped-option'. + (alist-delete 'ad-hoc? result))) + + ;; For consistency with 'guix package', support '-f' rather than + ;; '-l' like 'guix environment' does. + (option '(#\f "install-from-file") #t #f + (lambda (opt name arg result) + (alist-cons 'load (tag-package-arg result arg) + result)))) + (filter-map (lambda (opt) + (and (not (any (lambda (name) + (member name to-remove)) + (option-names opt))) + (wrapped-option opt))) + %environment-options)))) + +(define %default-options + `((ad-hoc? . #t) ;always true + ,@%environment-default-options)) + +(define (parse-args args) + "Parse the list of command line arguments ARGS." + (define (handle-argument arg result) + (alist-cons 'package (tag-package-arg result arg) + (ensure-ad-hoc result))) + + ;; The '--' token is used to separate the command to run from the rest of + ;; the operands. + (let ((args command (break (cut string=? "--" <>) args))) + (let ((opts (parse-command-line args %options (list %default-options) + #:argument-handler handle-argument))) + (match command + (() opts) + (("--") opts) + (("--" command ...) (alist-cons 'exec command opts)))))) + + +(define-command (guix-shell . args) + (category development) + (synopsis "spawn one-off software environments") + + (guix-environment* (parse-args args))) diff --git a/po/guix/POTFILES.in b/po/guix/POTFILES.in index f5b76bf582..f8abeb2d38 100644 --- a/po/guix/POTFILES.in +++ b/po/guix/POTFILES.in @@ -99,6 +99,7 @@ guix/derivations.scm guix/scripts/archive.scm guix/scripts/build.scm guix/scripts/environment.scm +guix/scripts/shell.scm guix/scripts/time-machine.scm guix/scripts/import/cpan.scm guix/scripts/import/crate.scm diff --git a/tests/guix-shell.sh b/tests/guix-shell.sh new file mode 100644 index 0000000000..f08637f7ff --- /dev/null +++ b/tests/guix-shell.sh @@ -0,0 +1,54 @@ +# GNU Guix --- Functional package management for GNU +# Copyright © 2021 Ludovic Courtès +# +# This file is part of GNU Guix. +# +# GNU Guix is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# GNU Guix is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Guix. If not, see . + +# +# Test the 'guix shell' alias. +# + +guix shell --version + +tmpdir="t-guix-shell-$$" +trap 'rm -r "$tmpdir"' EXIT +mkdir "$tmpdir" + +guix shell --bootstrap --pure guile-bootstrap -- guile --version + +# '--ad-hoc' is a thing of the past. +! guix shell --ad-hoc guile-bootstrap + +if guile -c '(getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)' 2> /dev/null +then + # Compute the build environment for the initial GNU Make. + guix shell --bootstrap --no-substitutes --search-paths --pure \ + -D -e '(@ (guix tests) gnu-make-for-tests)' > "$tmpdir/a" + + # Make sure bootstrap binaries are in the profile. + profile=`grep "^export PATH" "$tmpdir/a" | sed -r 's|^.*="(.*)/bin"|\1|'` + + # Make sure the bootstrap binaries are all listed where they belong. + grep -E "^export PATH=\"$profile/bin\"" "$tmpdir/a" + grep -E "^export CPATH=\"$profile/include\"" "$tmpdir/a" + grep -E "^export LIBRARY_PATH=\"$profile/lib\"" "$tmpdir/a" + for dep in bootstrap-binaries-0 gcc-bootstrap-0 glibc-bootstrap-0 + do + guix gc --references "$profile" | grep "$dep" + done + + # 'make-boot0' itself must not be listed. + ! guix gc --references "$profile" | grep make-boot0 +fi