summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludovic.courtes@inria.fr>2021-10-01 15:19:54 +0200
committerLudovic Courtès <ludo@gnu.org>2021-10-25 18:58:18 +0200
commit80edb7df6586464aa40e84e103f0045452de95db (patch)
tree25bbaf44555a8152e7b4ab513b789cf7b5a22c29
parent23f99f1a299ed0e19d926a0f719980b3c151c9c0 (diff)
Add 'guix shell'.
* 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. * doc/guix.texi (Features): Refer to "guix shell" (Invoking guix package): Likewise. (Development): Likewise. (Invoking guix shell): New node. (Invoking guix environment): Add deprecation warning. (Debugging Build Failures): Use 'guix shell' in examples. (Invoking guix container): Refer to 'guix shell'. (Invoking guix processes, Virtualization Services): Adjust examples to use 'guix shell'. * doc/contributing.texi (Building from Git): Refer to 'guix shell'. * etc/completion/bash/guix: Handle "shell".
-rw-r--r--Makefile.am2
-rw-r--r--doc/contributing.texi8
-rw-r--r--doc/guix.texi368
-rw-r--r--etc/completion/bash/guix6
-rw-r--r--guix/scripts/environment.scm52
-rw-r--r--guix/scripts/shell.scm135
-rw-r--r--po/guix/POTFILES.in1
-rw-r--r--tests/guix-shell.sh54
8 files changed, 579 insertions, 47 deletions
diff --git a/Makefile.am b/Makefile.am
index 41ec19eb892..239387c2f44 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -316,6 +316,7 @@ MODULES = \
316 guix/scripts/import/stackage.scm \ 316 guix/scripts/import/stackage.scm \
317 guix/scripts/import/texlive.scm \ 317 guix/scripts/import/texlive.scm \
318 guix/scripts/environment.scm \ 318 guix/scripts/environment.scm \
319 guix/scripts/shell.scm \
319 guix/scripts/publish.scm \ 320 guix/scripts/publish.scm \
320 guix/scripts/edit.scm \ 321 guix/scripts/edit.scm \
321 guix/scripts/size.scm \ 322 guix/scripts/size.scm \
@@ -552,6 +553,7 @@ SH_TESTS = \
552 tests/guix-authenticate.sh \ 553 tests/guix-authenticate.sh \
553 tests/guix-environment.sh \ 554 tests/guix-environment.sh \
554 tests/guix-environment-container.sh \ 555 tests/guix-environment-container.sh \
556 tests/guix-shell.sh \
555 tests/guix-graph.sh \ 557 tests/guix-graph.sh \
556 tests/guix-describe.sh \ 558 tests/guix-describe.sh \
557 tests/guix-repl.sh \ 559 tests/guix-repl.sh \
diff --git a/doc/contributing.texi b/doc/contributing.texi
index 76ab913b0de..db0f8361577 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -73,10 +73,10 @@ all the dependencies and appropriate environment variables are set up to
73hack on Guix: 73hack on Guix:
74 74
75@example 75@example
76guix environment guix --pure 76guix shell -D guix --pure
77@end example 77@end example
78 78
79@xref{Invoking guix environment}, for more information on that command. 79@xref{Invoking guix shell}, for more information on that command.
80 80
81If you are unable to use Guix when building Guix from a checkout, the 81If you are unable to use Guix when building Guix from a checkout, the
82following are the required packages in addition to those mentioned in the 82following are the required packages in addition to those mentioned in the
@@ -92,10 +92,10 @@ installation instructions (@pxref{Requirements}).
92@end itemize 92@end itemize
93 93
94On Guix, extra dependencies can be added by instead running @command{guix 94On Guix, extra dependencies can be added by instead running @command{guix
95environment} with @option{--ad-hoc}: 95shell}:
96 96
97@example 97@example
98guix environment guix --pure --ad-hoc help2man git strace 98guix shell -D guix help2man git strace --pure
99@end example 99@end example
100 100
101Run @command{./bootstrap} to generate the build system infrastructure 101Run @command{./bootstrap} to generate the build system infrastructure
diff --git a/doc/guix.texi b/doc/guix.texi
index 37d31d5fa97..f5bfb592293 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -119,6 +119,7 @@ Documentation License''.
119 119
120@dircategory Software development 120@dircategory Software development
121@direntry 121@direntry
122* guix shell: (guix)Invoking guix shell. Creating software environments.
122* guix environment: (guix)Invoking guix environment. Building development environments with Guix. 123* guix environment: (guix)Invoking guix environment. Building development environments with Guix.
123* guix build: (guix)Invoking guix build. Building packages. 124* guix build: (guix)Invoking guix build. Building packages.
124* guix pack: (guix)Invoking guix pack. Creating binary bundles. 125* guix pack: (guix)Invoking guix pack. Creating binary bundles.
@@ -262,6 +263,7 @@ Channels
262 263
263Development 264Development
264 265
266* Invoking guix shell:: Spawning one-off software environments.
265* Invoking guix environment:: Setting up development environments. 267* Invoking guix environment:: Setting up development environments.
266* Invoking guix pack:: Creating software bundles. 268* Invoking guix pack:: Creating software bundles.
267* The GCC toolchain:: Working with languages supported by GCC. 269* The GCC toolchain:: Working with languages supported by GCC.
@@ -3067,10 +3069,10 @@ substitutes: they can force a local build and @emph{challenge} providers
3067(@pxref{Invoking guix challenge}). 3069(@pxref{Invoking guix challenge}).
3068 3070
3069Control over the build environment is a feature that is also useful for 3071Control over the build environment is a feature that is also useful for
3070developers. The @command{guix environment} command allows developers of 3072developers. The @command{guix shell} command allows developers of
3071a package to quickly set up the right development environment for their 3073a package to quickly set up the right development environment for their
3072package, without having to manually install the dependencies of the 3074package, without having to manually install the dependencies of the
3073package into their profile (@pxref{Invoking guix environment}). 3075package into their profile (@pxref{Invoking guix shell}).
3074 3076
3075@cindex replication, of software environments 3077@cindex replication, of software environments
3076@cindex provenance tracking, of software artifacts 3078@cindex provenance tracking, of software artifacts
@@ -3234,7 +3236,7 @@ As an example, @var{file} might contain a definition like this
3234Developers may find it useful to include such a @file{guix.scm} file 3236Developers may find it useful to include such a @file{guix.scm} file
3235in the root of their project source tree that can be used to test 3237in the root of their project source tree that can be used to test
3236development snapshots and create reproducible development environments 3238development snapshots and create reproducible development environments
3237(@pxref{Invoking guix environment}). 3239(@pxref{Invoking guix shell}).
3238 3240
3239The @var{file} may also contain a JSON representation of one or more 3241The @var{file} may also contain a JSON representation of one or more
3240package definitions. Running @code{guix package -f} on 3242package definitions. Running @code{guix package -f} on
@@ -5559,31 +5561,352 @@ If you are a software developer, Guix provides tools that you should find
5559helpful---independently of the language you're developing in. This is what 5561helpful---independently of the language you're developing in. This is what
5560this chapter is about. 5562this chapter is about.
5561 5563
5562The @command{guix environment} command provides a convenient way to set up 5564The @command{guix shell} command provides a convenient way to set up
5563@dfn{development environments} containing all the dependencies and tools 5565one-off software environments, be it for development purposes or to run
5564necessary to work on the software package of your choice. The @command{guix 5566a command without installing it in your profile. The @command{guix
5565pack} command allows you to create @dfn{application bundles} that can be 5567pack} command allows you to create @dfn{application bundles} that can be
5566easily distributed to users who do not run Guix. 5568easily distributed to users who do not run Guix.
5567 5569
5568@menu 5570@menu
5571* Invoking guix shell:: Spawning one-off software environments.
5569* Invoking guix environment:: Setting up development environments. 5572* Invoking guix environment:: Setting up development environments.
5570* Invoking guix pack:: Creating software bundles. 5573* Invoking guix pack:: Creating software bundles.
5571* The GCC toolchain:: Working with languages supported by GCC. 5574* The GCC toolchain:: Working with languages supported by GCC.
5572* Invoking guix git authenticate:: Authenticating Git repositories. 5575* Invoking guix git authenticate:: Authenticating Git repositories.
5573@end menu 5576@end menu
5574 5577
5575@node Invoking guix environment 5578@node Invoking guix shell
5576@section Invoking @command{guix environment} 5579@section Invoking @command{guix shell}
5577 5580
5578@cindex reproducible build environments 5581@cindex reproducible build environments
5579@cindex development environments 5582@cindex development environments
5580@cindex @command{guix environment} 5583@cindex @command{guix environment}
5581@cindex environment, package build environment 5584@cindex environment, package build environment
5582The purpose of @command{guix environment} is to assist hackers in 5585The purpose of @command{guix shell} is to make it easy to create one-off
5583creating reproducible development environments without polluting their 5586software environments, without changing one's profile. It is typically
5584package profile. The @command{guix environment} tool takes one or more 5587used to create development environments; it is also a convenient way to
5585packages, builds all of their inputs, and creates a shell 5588run applications without ``polluting'' your profile.
5586environment to use them. 5589
5590@quotation Note
5591The @command{guix shell} command was recently introduced to supersede
5592@command{guix environment} (@pxref{Invoking guix environment}). If you
5593are familiar with @command{guix environment}, you will notice that it is
5594similar but also---we hope!---more convenient.
5595@end quotation
5596
5597The general syntax is:
5598
5599@example
5600guix shell [@var{options}] [@var{package}@dots{}]
5601@end example
5602
5603The following example creates an environment containing Python and NumPy,
5604building or downloading any missing package, and runs the
5605@command{python3} command in that environment:
5606
5607@example
5608guix shell python python-numpy -- python3
5609@end example
5610
5611Development environments can be created as in the example below, which
5612spawns an interactive shell containing all the dependencies and
5613environment variables needed to work on Inkscape:
5614
5615@example
5616guix shell --development inkscape
5617@end example
5618
5619Exiting the shell places the user back in the original environment
5620before @command{guix shell} was invoked. The next garbage collection
5621(@pxref{Invoking guix gc}) may clean up packages that were installed in
5622the environment and that are no longer used outside of it.
5623
5624By default, the shell session or command runs in an @emph{augmented}
5625environment, where the new packages are added to search path environment
5626variables such as @code{PATH}. You can, instead, choose to create an
5627@emph{isolated} environment containing nothing but the packages you
5628asked for. Passing the @option{--pure} option clears environment
5629variable definitions found in the parent environment@footnote{Users
5630sometimes wrongfully augment environment variables such as @env{PATH} in
5631their @file{~/.bashrc} file. As a consequence, when @command{guix
5632environment} launches it, Bash may read @file{~/.bashrc}, thereby
5633introducing ``impurities'' in these environment variables. It is an
5634error to define such environment variables in @file{.bashrc}; instead,
5635they should be defined in @file{.bash_profile}, which is sourced only by
5636log-in shells. @xref{Bash Startup Files,,, bash, The GNU Bash Reference
5637Manual}, for details on Bash start-up files.}; passing
5638@option{--container} goes one step further by spawning a @dfn{container}
5639isolated from the rest of the system:
5640
5641@example
5642guix shell --container emacs gcc-toolchain
5643@end example
5644
5645The command above spawns an interactive shell in a container when
5646nothing but @code{emacs}, @code{gcc-toolchain}, and their dependencies
5647is available. The container lacks network access and shares no files
5648other than the current working directory with the surrounding
5649environment. This is useful to prevent access to system-wide resources
5650such as @file{/usr/bin} on foreign distros.
5651
5652This @option{--container} option can also prove useful if you wish to
5653run a security-sensitive application, such as a web browser, in an
5654isolated environment. For example, the command below launches
5655Ungoogled-Chromium in an isolated environment, this time sharing network
5656access with the host and preserving its @code{DISPLAY} environment
5657variable, but without even sharing the current directory:
5658
5659@example
5660guix shell --container --network --no-cwd ungoogled-chromium \
5661 --preserve='^DISPLAY$' -- chromium
5662@end example
5663
5664@vindex GUIX_ENVIRONMENT
5665@command{guix shell} defines the @env{GUIX_ENVIRONMENT}
5666variable in the shell it spawns; its value is the file name of the
5667profile of this environment. This allows users to, say, define a
5668specific prompt for development environments in their @file{.bashrc}
5669(@pxref{Bash Startup Files,,, bash, The GNU Bash Reference Manual}):
5670
5671@example
5672if [ -n "$GUIX_ENVIRONMENT" ]
5673then
5674 export PS1="\u@@\h \w [dev]\$ "
5675fi
5676@end example
5677
5678@noindent
5679...@: or to browse the profile:
5680
5681@example
5682$ ls "$GUIX_ENVIRONMENT/bin"
5683@end example
5684
5685The available options are summarized below.
5686
5687@table @code
5688@item --development
5689@itemx -D
5690Cause @command{guix shell} to include in the environment the
5691dependencies of the following package rather than the package itself.
5692This can be combined with other packages. For instance, the command
5693below starts an interactive shell containing the build-time dependencies
5694of GNU@tie{}Guile, plus Autoconf, Automake, and Libtool:
5695
5696@example
5697guix shell -D guile autoconf automake libtool
5698@end example
5699
5700@item --expression=@var{expr}
5701@itemx -e @var{expr}
5702Create an environment for the package or list of packages that
5703@var{expr} evaluates to.
5704
5705For example, running:
5706
5707@example
5708guix shell -D -e '(@@ (gnu packages maths) petsc-openmpi)'
5709@end example
5710
5711starts a shell with the environment for this specific variant of the
5712PETSc package.
5713
5714Running:
5715
5716@example
5717guix shell -e '(@@ (gnu) %base-packages)'
5718@end example
5719
5720starts a shell with all the base system packages available.
5721
5722The above commands only use the default output of the given packages.
5723To select other outputs, two element tuples can be specified:
5724
5725@example
5726guix shell -e '(list (@@ (gnu packages bash) bash) "include")'
5727@end example
5728
5729@item --file=@var{file}
5730@itemx -f @var{file}
5731Create an environment containing the package or list of packages that
5732the code within @var{file} evaluates to.
5733
5734As an example, @var{file} might contain a definition like this
5735(@pxref{Defining Packages}):
5736
5737@lisp
5738@verbatiminclude environment-gdb.scm
5739@end lisp
5740
5741With the file above, you can enter a development environment for GDB by
5742running:
5743
5744@example
5745guix shell -D -f gdb-devel.scm
5746@end example
5747
5748@item --manifest=@var{file}
5749@itemx -m @var{file}
5750Create an environment for the packages contained in the manifest object
5751returned by the Scheme code in @var{file}. This option can be repeated
5752several times, in which case the manifests are concatenated.
5753
5754This is similar to the same-named option in @command{guix package}
5755(@pxref{profile-manifest, @option{--manifest}}) and uses the same
5756manifest files.
5757
5758@item --pure
5759Unset existing environment variables when building the new environment, except
5760those specified with @option{--preserve} (see below). This has the effect of
5761creating an environment in which search paths only contain package inputs.
5762
5763@item --preserve=@var{regexp}
5764@itemx -E @var{regexp}
5765When used alongside @option{--pure}, preserve the environment variables
5766matching @var{regexp}---in other words, put them on a ``white list'' of
5767environment variables that must be preserved. This option can be repeated
5768several times.
5769
5770@example
5771guix shell --pure --preserve=^SLURM openmpi @dots{} \
5772 -- mpirun @dots{}
5773@end example
5774
5775This example runs @command{mpirun} in a context where the only environment
5776variables defined are @env{PATH}, environment variables whose name starts
5777with @samp{SLURM}, as well as the usual ``precious'' variables (@env{HOME},
5778@env{USER}, etc.).
5779
5780@item --search-paths
5781Display the environment variable definitions that make up the
5782environment.
5783
5784@item --system=@var{system}
5785@itemx -s @var{system}
5786Attempt to build for @var{system}---e.g., @code{i686-linux}.
5787
5788@item --container
5789@itemx -C
5790@cindex container
5791Run @var{command} within an isolated container. The current working
5792directory outside the container is mapped inside the container.
5793Additionally, unless overridden with @option{--user}, a dummy home
5794directory is created that matches the current user's home directory, and
5795@file{/etc/passwd} is configured accordingly.
5796
5797The spawned process runs as the current user outside the container. Inside
5798the container, it has the same UID and GID as the current user, unless
5799@option{--user} is passed (see below).
5800
5801@item --network
5802@itemx -N
5803For containers, share the network namespace with the host system.
5804Containers created without this flag only have access to the loopback
5805device.
5806
5807@item --link-profile
5808@itemx -P
5809For containers, link the environment profile to @file{~/.guix-profile}
5810within the container and set @code{GUIX_ENVIRONMENT} to that.
5811This is equivalent to making @file{~/.guix-profile} a symlink to the
5812actual profile within the container.
5813Linking will fail and abort the environment if the directory already
5814exists, which will certainly be the case if @command{guix shell}
5815was invoked in the user's home directory.
5816
5817Certain packages are configured to look in @file{~/.guix-profile} for
5818configuration files and data;@footnote{For example, the
5819@code{fontconfig} package inspects @file{~/.guix-profile/share/fonts}
5820for additional fonts.} @option{--link-profile} allows these programs to
5821behave as expected within the environment.
5822
5823@item --user=@var{user}
5824@itemx -u @var{user}
5825For containers, use the username @var{user} in place of the current
5826user. The generated @file{/etc/passwd} entry within the container will
5827contain the name @var{user}, the home directory will be
5828@file{/home/@var{user}}, and no user GECOS data will be copied. Furthermore,
5829the UID and GID inside the container are 1000. @var{user}
5830need not exist on the system.
5831
5832Additionally, any shared or exposed path (see @option{--share} and
5833@option{--expose} respectively) whose target is within the current user's
5834home directory will be remapped relative to @file{/home/USER}; this
5835includes the automatic mapping of the current working directory.
5836
5837@example
5838# will expose paths as /home/foo/wd, /home/foo/test, and /home/foo/target
5839cd $HOME/wd
5840guix shell --container --user=foo \
5841 --expose=$HOME/test \
5842 --expose=/tmp/target=$HOME/target
5843@end example
5844
5845While this will limit the leaking of user identity through home paths
5846and each of the user fields, this is only one useful component of a
5847broader privacy/anonymity solution---not one in and of itself.
5848
5849@item --no-cwd
5850For containers, the default behavior is to share the current working
5851directory with the isolated container and immediately change to that
5852directory within the container. If this is undesirable,
5853@option{--no-cwd} will cause the current working directory to @emph{not}
5854be automatically shared and will change to the user's home directory
5855within the container instead. See also @option{--user}.
5856
5857@item --expose=@var{source}[=@var{target}]
5858@itemx --share=@var{source}[=@var{target}]
5859For containers, @option{--expose} (resp. @option{--share}) exposes the
5860file system @var{source} from the host system as the read-only
5861(resp. writable) file system @var{target} within the container. If
5862@var{target} is not specified, @var{source} is used as the target mount
5863point in the container.
5864
5865The example below spawns a Guile REPL in a container in which the user's
5866home directory is accessible read-only via the @file{/exchange}
5867directory:
5868
5869@example
5870guix shell --container --expose=$HOME=/exchange guile -- guile
5871@end example
5872
5873@item --root=@var{file}
5874@itemx -r @var{file}
5875@cindex persistent environment
5876@cindex garbage collector root, for environments
5877Make @var{file} a symlink to the profile for this environment, and
5878register it as a garbage collector root.
5879
5880This is useful if you want to protect your environment from garbage
5881collection, to make it ``persistent''.
5882
5883When this option is omitted, the environment is protected from garbage
5884collection only for the duration of the @command{guix shell}
5885session. This means that next time you recreate the same environment,
5886you could have to rebuild or re-download packages. @xref{Invoking guix
5887gc}, for more on GC roots.
5888@end table
5889
5890@command{guix shell} also supports all of the common build options that
5891@command{guix build} supports (@pxref{Common Build Options}) as well as
5892package transformation options (@pxref{Package Transformation Options}).
5893
5894@node Invoking guix environment
5895@section Invoking @command{guix environment}
5896
5897The purpose of @command{guix environment} is to assist in creating
5898development environments.
5899
5900@quotation Deprecation warning
5901The @command{guix environment} command is deprecated in favor of
5902@command{guix shell}, which performs similar functions but is more
5903convenient to use. @xref{Invoking guix shell}.
5904
5905Being deprecated, @command{guix environment} is slated for eventual
5906removal, but the Guix project is committed to keeping it until May 1st,
59072023. Please get in touch with us at @email{guix-devel@@gnu.org} if you
5908would like to discuss it.
5909@end quotation
5587 5910
5588The general syntax is: 5911The general syntax is:
5589 5912
@@ -11099,14 +11422,14 @@ a container similar to the one the build daemon creates:
11099$ guix build -K foo 11422$ guix build -K foo
11100@dots{} 11423@dots{}
11101$ cd /tmp/guix-build-foo.drv-0 11424$ cd /tmp/guix-build-foo.drv-0
11102$ guix environment --no-grafts -C foo --ad-hoc strace gdb 11425$ guix shell --no-grafts -C foo strace gdb
11103[env]# source ./environment-variables 11426[env]# source ./environment-variables
11104[env]# cd foo-1.2 11427[env]# cd foo-1.2
11105@end example 11428@end example
11106 11429
11107Here, @command{guix environment -C} creates a container and spawns a new 11430Here, @command{guix shell -C} creates a container and spawns a new
11108shell in it (@pxref{Invoking guix environment}). The @command{--ad-hoc 11431shell in it (@pxref{Invoking guix shell}). The @command{strace gdb}
11109strace gdb} part adds the @command{strace} and @command{gdb} commands to 11432part adds the @command{strace} and @command{gdb} commands to
11110the container, which you may find handy while debugging. The 11433the container, which you may find handy while debugging. The
11111@option{--no-grafts} option makes sure we get the exact same 11434@option{--no-grafts} option makes sure we get the exact same
11112environment, with ungrafted packages (@pxref{Security Updates}, for more 11435environment, with ungrafted packages (@pxref{Security Updates}, for more
@@ -11120,7 +11443,7 @@ remove @file{/bin/sh}:
11120@end example 11443@end example
11121 11444
11122(Don't worry, this is harmless: this is all happening in the throw-away 11445(Don't worry, this is harmless: this is all happening in the throw-away
11123container created by @command{guix environment}.) 11446container created by @command{guix shell}.)
11124 11447
11125The @command{strace} command is probably not in the search path, but we 11448The @command{strace} command is probably not in the search path, but we
11126can run: 11449can run:
@@ -13316,8 +13639,8 @@ is subject to radical change in the future.
13316 13639
13317The purpose of @command{guix container} is to manipulate processes 13640The purpose of @command{guix container} is to manipulate processes
13318running within an isolated environment, commonly known as a 13641running within an isolated environment, commonly known as a
13319``container'', typically created by the @command{guix environment} 13642``container'', typically created by the @command{guix shell}
13320(@pxref{Invoking guix environment}) and @command{guix system container} 13643(@pxref{Invoking guix shell}) and @command{guix system container}
13321(@pxref{Invoking guix system}) commands. 13644(@pxref{Invoking guix system}) commands.
13322 13645
13323The general syntax is: 13646The general syntax is:
@@ -13503,7 +13826,7 @@ listed.}. Here's an example of the information it returns:
13503$ sudo guix processes 13826$ sudo guix processes
13504SessionPID: 19002 13827SessionPID: 19002
13505ClientPID: 19090 13828ClientPID: 19090
13506ClientCommand: guix environment --ad-hoc python 13829ClientCommand: guix shell python
13507 13830
13508SessionPID: 19402 13831SessionPID: 19402
13509ClientPID: 19367 13832ClientPID: 19367
@@ -29699,8 +30022,7 @@ When the service is running, you can view its console by connecting to
29699it with a VNC client, for example with: 30022it with a VNC client, for example with:
29700 30023
29701@example 30024@example
29702guix environment --ad-hoc tigervnc-client -- \ 30025guix shell tigervnc-client -- vncviewer localhost:5900
29703 vncviewer localhost:5900
29704@end example 30026@end example
29705 30027
29706The default configuration (see @code{hurd-vm-configuration} below) 30028The default configuration (see @code{hurd-vm-configuration} below)
diff --git a/etc/completion/bash/guix b/etc/completion/bash/guix
index 87d9911e53a..ec6adfdb22b 100644
--- a/etc/completion/bash/guix
+++ b/etc/completion/bash/guix
@@ -1,5 +1,5 @@
1# GNU Guix --- Functional package management for GNU 1# GNU Guix --- Functional package management for GNU
2# Copyright © 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org> 2# Copyright © 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
3# Copyright © 2021 Tobias Geerinck-Rice <me@tobias.gr> 3# Copyright © 2021 Tobias Geerinck-Rice <me@tobias.gr>
4# 4#
5# This file is part of GNU Guix. 5# This file is part of GNU Guix.
@@ -215,7 +215,7 @@ _guix_complete ()
215 if [[ "$word" = "--" ]] 215 if [[ "$word" = "--" ]]
216 then 216 then
217 case "$command" in 217 case "$command" in
218 environment) 218 environment|shell)
219 break 219 break
220 ;; 220 ;;
221 time-machine) 221 time-machine)
@@ -265,7 +265,7 @@ _guix_complete ()
265 else 265 else
266 _guix_complete_available_package_or_store_file "$word_at_point" 266 _guix_complete_available_package_or_store_file "$word_at_point"
267 fi 267 fi
268 elif [[ "$command" = "environment" ]] 268 elif [[ "$command" = "environment" || "$command" = "shell" ]]
269 then 269 then
270 if _guix_is_dash_L || _guix_is_dash_m || _guix_is_dash_p || _guix_is_dash_l 270 if _guix_is_dash_L || _guix_is_dash_m || _guix_is_dash_p || _guix_is_dash_l
271 then 271 then
diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
index 54f48a7482b..77956fc018b 100644
--- a/guix/scripts/environment.scm
+++ b/guix/scripts/environment.scm
@@ -50,7 +50,11 @@
50 #:use-module (srfi srfi-37) 50 #:use-module (srfi srfi-37)
51 #:use-module (srfi srfi-98) 51 #:use-module (srfi srfi-98)
52 #:export (assert-container-features 52 #:export (assert-container-features
53 guix-environment)) 53 guix-environment
54 guix-environment*
55 show-environment-options-help
56 (%options . %environment-options)
57 (%default-options . %environment-default-options)))
54 58
55(define %default-shell 59(define %default-shell
56 (or (getenv "SHELL") "/bin/sh")) 60 (or (getenv "SHELL") "/bin/sh"))
@@ -66,24 +70,17 @@ do not augment existing environment variables with additional search paths."
66 (newline))) 70 (newline)))
67 (profile-search-paths profile manifest))) 71 (profile-search-paths profile manifest)))
68 72
69(define (show-help) 73(define (show-environment-options-help)
70 (display (G_ "Usage: guix environment [OPTION]... PACKAGE... [-- COMMAND...] 74 "Print help about options shared between 'guix environment' and 'guix
71Build an environment that includes the dependencies of PACKAGE and execute 75shell'."
72COMMAND or an interactive shell in that environment.\n"))
73 (display (G_ " 76 (display (G_ "
74 -e, --expression=EXPR create environment for the package that EXPR 77 -e, --expression=EXPR create environment for the package that EXPR
75 evaluates to")) 78 evaluates to"))
76 (display (G_ " 79 (display (G_ "
77 -l, --load=FILE create environment for the package that the code within
78 FILE evaluates to"))
79 (display (G_ "
80 -m, --manifest=FILE create environment with the manifest from FILE")) 80 -m, --manifest=FILE create environment with the manifest from FILE"))
81 (display (G_ " 81 (display (G_ "
82 -p, --profile=PATH create environment from profile at PATH")) 82 -p, --profile=PATH create environment from profile at PATH"))
83 (display (G_ " 83 (display (G_ "
84 --ad-hoc include all specified packages in the environment instead
85 of only their inputs"))
86 (display (G_ "
87 --pure unset existing environment variables")) 84 --pure unset existing environment variables"))
88 (display (G_ " 85 (display (G_ "
89 -E, --preserve=REGEXP preserve environment variables that match REGEXP")) 86 -E, --preserve=REGEXP preserve environment variables that match REGEXP"))
@@ -118,7 +115,24 @@ COMMAND or an interactive shell in that environment.\n"))
118 (display (G_ " 115 (display (G_ "
119 -v, --verbosity=LEVEL use the given verbosity LEVEL")) 116 -v, --verbosity=LEVEL use the given verbosity LEVEL"))
120 (display (G_ " 117 (display (G_ "
121 --bootstrap use bootstrap binaries to build the environment")) 118 --bootstrap use bootstrap binaries to build the environment")))
119
120(define (show-help)
121 (display (G_ "Usage: guix environment [OPTION]... PACKAGE... [-- COMMAND...]
122Build an environment that includes the dependencies of PACKAGE and execute
123COMMAND or an interactive shell in that environment.\n"))
124 (warning (G_ "This command is deprecated in favor of 'guix shell'.\n"))
125 (newline)
126
127 ;; These two options are left out in 'guix shell'.
128 (display (G_ "
129 -l, --load=FILE create environment for the package that the code within
130 FILE evaluates to"))
131 (display (G_ "
132 --ad-hoc include all specified packages in the environment instead
133 of only their inputs"))
134
135 (show-environment-options-help)
122 (newline) 136 (newline)
123 (show-build-options-help) 137 (show-build-options-help)
124 (newline) 138 (newline)
@@ -649,11 +663,15 @@ message if any test fails."
649 663
650(define-command (guix-environment . args) 664(define-command (guix-environment . args)
651 (category development) 665 (category development)
652 (synopsis "spawn one-off software environments") 666 (synopsis "spawn one-off software environments (deprecated)")
667
668 (guix-environment* (parse-args args)))
653 669
670(define (guix-environment* opts)
671 "Run the 'guix environment' command on OPTS, an alist resulting for
672command-line option processing with 'parse-command-line'."
654 (with-error-handling 673 (with-error-handling
655 (let* ((opts (parse-args args)) 674 (let* ((pure? (assoc-ref opts 'pure))
656 (pure? (assoc-ref opts 'pure))
657 (container? (assoc-ref opts 'container?)) 675 (container? (assoc-ref opts 'container?))
658 (link-prof? (assoc-ref opts 'link-profile?)) 676 (link-prof? (assoc-ref opts 'link-profile?))
659 (network? (assoc-ref opts 'network?)) 677 (network? (assoc-ref opts 'network?))
@@ -724,8 +742,8 @@ message if any test fails."
724 (prof-drv (manifest->derivation 742 (prof-drv (manifest->derivation
725 manifest system bootstrap?)) 743 manifest system bootstrap?))
726 (profile -> (if profile 744 (profile -> (if profile
727 (readlink* profile) 745 (readlink* profile)
728 (derivation->output-path prof-drv))) 746 (derivation->output-path prof-drv)))
729 (gc-root -> (assoc-ref opts 'gc-root))) 747 (gc-root -> (assoc-ref opts 'gc-root)))
730 748
731 ;; First build the inputs. This is necessary even for 749 ;; 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 00000000000..190dd8837d5
--- /dev/null
+++ b/guix/scripts/shell.scm
@@ -0,0 +1,135 @@
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2021 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (guix scripts shell)
20 #:use-module (guix ui)
21 #:use-module (guix scripts environment)
22 #:autoload (guix scripts build) (show-build-options-help)
23 #:autoload (guix transformations) (show-transformation-options-help)
24 #:use-module (guix scripts)
25 #:use-module (srfi srfi-1)
26 #:use-module (srfi srfi-26)
27 #:use-module (srfi srfi-37)
28 #:use-module (srfi srfi-71)
29 #:use-module (ice-9 match)
30 #:export (guix-shell))
31
32(define (show-help)
33 (display (G_ "Usage: guix shell [OPTION] PACKAGES... [-- COMMAND...]
34Build an environment that includes PACKAGES and execute COMMAND or an
35interactive shell in that environment.\n"))
36 (newline)
37
38 ;; These two options differ from 'guix environment'.
39 (display (G_ "
40 -D, --development include the development inputs of the next package"))
41 (display (G_ "
42 -f, --file=FILE create environment for the package that the code within
43 FILE evaluates to"))
44
45 (show-environment-options-help)
46 (newline)
47 (show-build-options-help)
48 (newline)
49 (show-transformation-options-help)
50 (newline)
51 (display (G_ "
52 -h, --help display this help and exit"))
53 (display (G_ "
54 -V, --version display version information and exit"))
55 (newline)
56 (show-bug-report-information))
57
58(define (tag-package-arg opts arg)
59 "Return a two-element list with the form (TAG ARG) that tags ARG with either
60'ad-hoc' in OPTS has the 'ad-hoc?' key set to #t, or 'inputs' otherwise."
61 (if (assoc-ref opts 'ad-hoc?)
62 `(ad-hoc-package ,arg)
63 `(package ,arg)))
64
65(define (ensure-ad-hoc alist)
66 (if (assq-ref alist 'ad-hoc?)
67 alist
68 `((ad-hoc? . #t) ,@alist)))
69
70(define (wrapped-option opt)
71 "Wrap OPT, a SRFI-37 option, such that its processor always adds the
72'ad-hoc?' flag to the resulting alist."
73 (option (option-names opt)
74 (option-required-arg? opt)
75 (option-optional-arg? opt)
76 (compose ensure-ad-hoc (option-processor opt))))
77
78(define %options
79 ;; Specification of the command-line options.
80 (let ((to-remove '("ad-hoc" "inherit" "load" "help" "version")))
81 (append
82 (list (option '(#\h "help") #f #f
83 (lambda args
84 (show-help)
85 (exit 0)))
86 (option '(#\V "version") #f #f
87 (lambda args
88 (show-version-and-exit "guix shell")))
89
90 (option '(#\D "development") #f #f
91 (lambda (opt name arg result)
92 ;; Temporarily remove the 'ad-hoc?' flag from result.
93 ;; The next option will put it back thanks to
94 ;; 'wrapped-option'.
95 (alist-delete 'ad-hoc? result)))
96
97 ;; For consistency with 'guix package', support '-f' rather than
98 ;; '-l' like 'guix environment' does.
99 (option '(#\f "file") #t #f
100 (lambda (opt name arg result)
101 (alist-cons 'load (tag-package-arg result arg)
102 result))))
103 (filter-map (lambda (opt)
104 (and (not (any (lambda (name)
105 (member name to-remove))
106 (option-names opt)))
107 (wrapped-option opt)))
108 %environment-options))))
109
110(define %default-options
111 `((ad-hoc? . #t) ;always true
112 ,@%environment-default-options))
113
114(define (parse-args args)
115 "Parse the list of command line arguments ARGS."
116 (define (handle-argument arg result)
117 (alist-cons 'package (tag-package-arg result arg)
118 (ensure-ad-hoc result)))
119
120 ;; The '--' token is used to separate the command to run from the rest of
121 ;; the operands.
122 (let ((args command (break (cut string=? "--" <>) args)))
123 (let ((opts (parse-command-line args %options (list %default-options)
124 #:argument-handler handle-argument)))
125 (match command
126 (() opts)
127 (("--") opts)
128 (("--" command ...) (alist-cons 'exec command opts))))))
129
130
131(define-command (guix-shell . args)
132 (category development)
133 (synopsis "spawn one-off software environments")
134
135 (guix-environment* (parse-args args)))
diff --git a/po/guix/POTFILES.in b/po/guix/POTFILES.in
index 5e77b3c2307..ee0adbcf3c7 100644
--- a/po/guix/POTFILES.in
+++ b/po/guix/POTFILES.in
@@ -140,5 +140,6 @@ guix/scripts/offload.scm
140guix/scripts/perform-download.scm 140guix/scripts/perform-download.scm
141guix/scripts/refresh.scm 141guix/scripts/refresh.scm
142guix/scripts/repl.scm 142guix/scripts/repl.scm
143guix/scripts/shell.scm
143guix/scripts/system/reconfigure.scm 144guix/scripts/system/reconfigure.scm
144nix/nix-daemon/guix-daemon.cc 145nix/nix-daemon/guix-daemon.cc
diff --git a/tests/guix-shell.sh b/tests/guix-shell.sh
new file mode 100644
index 00000000000..f08637f7ff5
--- /dev/null
+++ b/tests/guix-shell.sh
@@ -0,0 +1,54 @@
1# GNU Guix --- Functional package management for GNU
2# Copyright © 2021 Ludovic Courtès <ludo@gnu.org>
3#
4# This file is part of GNU Guix.
5#
6# GNU Guix is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 3 of the License, or (at
9# your option) any later version.
10#
11# GNU Guix is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19#
20# Test the 'guix shell' alias.
21#
22
23guix shell --version
24
25tmpdir="t-guix-shell-$$"
26trap 'rm -r "$tmpdir"' EXIT
27mkdir "$tmpdir"
28
29guix shell --bootstrap --pure guile-bootstrap -- guile --version
30
31# '--ad-hoc' is a thing of the past.
32! guix shell --ad-hoc guile-bootstrap
33
34if guile -c '(getaddrinfo "www.gnu.org" "80" AI_NUMERICSERV)' 2> /dev/null
35then
36 # Compute the build environment for the initial GNU Make.
37 guix shell --bootstrap --no-substitutes --search-paths --pure \
38 -D -e '(@ (guix tests) gnu-make-for-tests)' > "$tmpdir/a"
39
40 # Make sure bootstrap binaries are in the profile.
41 profile=`grep "^export PATH" "$tmpdir/a" | sed -r 's|^.*="(.*)/bin"|\1|'`
42
43 # Make sure the bootstrap binaries are all listed where they belong.
44 grep -E "^export PATH=\"$profile/bin\"" "$tmpdir/a"
45 grep -E "^export CPATH=\"$profile/include\"" "$tmpdir/a"
46 grep -E "^export LIBRARY_PATH=\"$profile/lib\"" "$tmpdir/a"
47 for dep in bootstrap-binaries-0 gcc-bootstrap-0 glibc-bootstrap-0
48 do
49 guix gc --references "$profile" | grep "$dep"
50 done
51
52 # 'make-boot0' itself must not be listed.
53 ! guix gc --references "$profile" | grep make-boot0
54fi