diff options
| -rw-r--r-- | doc/guix.texi | 16 | ||||
| -rw-r--r-- | guix/scripts/environment.scm | 40 | ||||
| -rw-r--r-- | tests/guix-environment.sh | 12 |
3 files changed, 43 insertions, 25 deletions
diff --git a/doc/guix.texi b/doc/guix.texi index 6da72815665..39b76c7bf69 100644 --- a/doc/guix.texi +++ b/doc/guix.texi | |||
| @@ -4538,11 +4538,12 @@ and Emacs are available: | |||
| 4538 | guix environment guile emacs | 4538 | guix environment guile emacs |
| 4539 | @end example | 4539 | @end example |
| 4540 | 4540 | ||
| 4541 | Sometimes an interactive shell session is not desired. The | 4541 | Sometimes an interactive shell session is not desired. An arbitrary |
| 4542 | @code{--exec} option can be used to specify the command to run instead. | 4542 | command may be invoked by placing the @code{--} token to separate the |
| 4543 | command from the rest of the arguments: | ||
| 4543 | 4544 | ||
| 4544 | @example | 4545 | @example |
| 4545 | guix environment guile --exec=make | 4546 | guix environment guile -- make -j4 |
| 4546 | @end example | 4547 | @end example |
| 4547 | 4548 | ||
| 4548 | In other situations, it is more convenient to specify the list of | 4549 | In other situations, it is more convenient to specify the list of |
| @@ -4551,7 +4552,7 @@ runs @command{python} from an environment containing Python@tie{}2.7 and | |||
| 4551 | NumPy: | 4552 | NumPy: |
| 4552 | 4553 | ||
| 4553 | @example | 4554 | @example |
| 4554 | guix environment --ad-hoc python2-numpy python-2.7 -E python | 4555 | guix environment --ad-hoc python2-numpy python-2.7 -- python |
| 4555 | @end example | 4556 | @end example |
| 4556 | 4557 | ||
| 4557 | The available options are summarized below. | 4558 | The available options are summarized below. |
| @@ -4582,11 +4583,6 @@ As an example, @var{file} might contain a definition like this | |||
| 4582 | @verbatiminclude environment-gdb.scm | 4583 | @verbatiminclude environment-gdb.scm |
| 4583 | @end example | 4584 | @end example |
| 4584 | 4585 | ||
| 4585 | |||
| 4586 | @item --exec=@var{command} | ||
| 4587 | @item -E @var{command} | ||
| 4588 | Execute @var{command} in the new environment. | ||
| 4589 | |||
| 4590 | @item --ad-hoc | 4586 | @item --ad-hoc |
| 4591 | Include all specified packages in the resulting environment, as if an | 4587 | Include all specified packages in the resulting environment, as if an |
| 4592 | @i{ad hoc} package were defined with them as inputs. This option is | 4588 | @i{ad hoc} package were defined with them as inputs. This option is |
| @@ -4596,7 +4592,7 @@ package expression to contain the desired inputs. | |||
| 4596 | For instance, the command: | 4592 | For instance, the command: |
| 4597 | 4593 | ||
| 4598 | @example | 4594 | @example |
| 4599 | guix environment --ad-hoc guile guile-sdl -E guile | 4595 | guix environment --ad-hoc guile guile-sdl -- guile |
| 4600 | @end example | 4596 | @end example |
| 4601 | 4597 | ||
| 4602 | runs @command{guile} in an environment where Guile and Guile-SDL are | 4598 | runs @command{guile} in an environment where Guile and Guile-SDL are |
diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm index 7aa52e8a8aa..2408420e18d 100644 --- a/guix/scripts/environment.scm +++ b/guix/scripts/environment.scm | |||
| @@ -57,6 +57,9 @@ OUTPUT) tuples." | |||
| 57 | (define %precious-variables | 57 | (define %precious-variables |
| 58 | '("HOME" "USER" "LOGNAME" "DISPLAY" "TERM" "TZ" "PAGER")) | 58 | '("HOME" "USER" "LOGNAME" "DISPLAY" "TERM" "TZ" "PAGER")) |
| 59 | 59 | ||
| 60 | (define %default-shell | ||
| 61 | (or (getenv "SHELL") "/bin/sh")) | ||
| 62 | |||
| 60 | (define (purify-environment) | 63 | (define (purify-environment) |
| 61 | "Unset almost all environment variables. A small number of variables such | 64 | "Unset almost all environment variables. A small number of variables such |
| 62 | as 'HOME' and 'USER' are left untouched." | 65 | as 'HOME' and 'USER' are left untouched." |
| @@ -103,9 +106,9 @@ existing environment variables with additional search paths." | |||
| 103 | ,@(package-transitive-propagated-inputs package))) | 106 | ,@(package-transitive-propagated-inputs package))) |
| 104 | 107 | ||
| 105 | (define (show-help) | 108 | (define (show-help) |
| 106 | (display (_ "Usage: guix environment [OPTION]... PACKAGE... | 109 | (display (_ "Usage: guix environment [OPTION]... PACKAGE... [-- COMMAND...] |
| 107 | Build an environment that includes the dependencies of PACKAGE and execute a | 110 | Build an environment that includes the dependencies of PACKAGE and execute |
| 108 | shell command in that environment.\n")) | 111 | COMMAND or an interactive shell in that environment.\n")) |
| 109 | (display (_ " | 112 | (display (_ " |
| 110 | -e, --expression=EXPR create environment for the package that EXPR | 113 | -e, --expression=EXPR create environment for the package that EXPR |
| 111 | evaluates to")) | 114 | evaluates to")) |
| @@ -113,8 +116,6 @@ shell command in that environment.\n")) | |||
| 113 | -l, --load=FILE create environment for the package that the code within | 116 | -l, --load=FILE create environment for the package that the code within |
| 114 | FILE evaluates to")) | 117 | FILE evaluates to")) |
| 115 | (display (_ " | 118 | (display (_ " |
| 116 | -E, --exec=COMMAND execute COMMAND in new environment")) | ||
| 117 | (display (_ " | ||
| 118 | --ad-hoc include all specified packages in the environment instead | 119 | --ad-hoc include all specified packages in the environment instead |
| 119 | of only their inputs")) | 120 | of only their inputs")) |
| 120 | (display (_ " | 121 | (display (_ " |
| @@ -135,7 +136,7 @@ shell command in that environment.\n")) | |||
| 135 | 136 | ||
| 136 | (define %default-options | 137 | (define %default-options |
| 137 | ;; Default to opening a new shell. | 138 | ;; Default to opening a new shell. |
| 138 | `((exec . ,(or (getenv "SHELL") "/bin/sh")) | 139 | `((exec . (,%default-shell)) |
| 139 | (system . ,(%current-system)) | 140 | (system . ,(%current-system)) |
| 140 | (substitutes? . #t) | 141 | (substitutes? . #t) |
| 141 | (max-silent-time . 3600) | 142 | (max-silent-time . 3600) |
| @@ -153,9 +154,9 @@ shell command in that environment.\n")) | |||
| 153 | (option '("pure") #f #f | 154 | (option '("pure") #f #f |
| 154 | (lambda (opt name arg result) | 155 | (lambda (opt name arg result) |
| 155 | (alist-cons 'pure #t result))) | 156 | (alist-cons 'pure #t result))) |
| 156 | (option '(#\E "exec") #t #f | 157 | (option '(#\E "exec") #t #f ; deprecated |
| 157 | (lambda (opt name arg result) | 158 | (lambda (opt name arg result) |
| 158 | (alist-cons 'exec arg result))) | 159 | (alist-cons 'exec (list %default-shell "-c" arg) result))) |
| 159 | (option '("search-paths") #f #f | 160 | (option '("search-paths") #f #f |
| 160 | (lambda (opt name arg result) | 161 | (lambda (opt name arg result) |
| 161 | (alist-cons 'search-paths #t result))) | 162 | (alist-cons 'search-paths #t result))) |
| @@ -230,14 +231,24 @@ OUTPUT) tuples, using the build options in OPTS." | |||
| 230 | (built-derivations derivations) | 231 | (built-derivations derivations) |
| 231 | (return derivations)))))))) | 232 | (return derivations)))))))) |
| 232 | 233 | ||
| 233 | ;; Entry point. | 234 | (define (parse-args args) |
| 234 | (define (guix-environment . args) | 235 | "Parse the list of command line arguments ARGS." |
| 235 | (define (handle-argument arg result) | 236 | (define (handle-argument arg result) |
| 236 | (alist-cons 'package arg result)) | 237 | (alist-cons 'package arg result)) |
| 237 | 238 | ||
| 239 | ;; The '--' token is used to separate the command to run from the rest of | ||
| 240 | ;; the operands. | ||
| 241 | (let-values (((args command) (split args "--"))) | ||
| 242 | (let ((opts (parse-command-line args %options (list %default-options) | ||
| 243 | #:argument-handler handle-argument))) | ||
| 244 | (if (null? command) | ||
| 245 | opts | ||
| 246 | (alist-cons 'exec command opts))))) | ||
| 247 | |||
| 248 | ;; Entry point. | ||
| 249 | (define (guix-environment . args) | ||
| 238 | (with-error-handling | 250 | (with-error-handling |
| 239 | (let* ((opts (parse-command-line args %options (list %default-options) | 251 | (let* ((opts (parse-args args)) |
| 240 | #:argument-handler handle-argument)) | ||
| 241 | (pure? (assoc-ref opts 'pure)) | 252 | (pure? (assoc-ref opts 'pure)) |
| 242 | (ad-hoc? (assoc-ref opts 'ad-hoc?)) | 253 | (ad-hoc? (assoc-ref opts 'ad-hoc?)) |
| 243 | (command (assoc-ref opts 'exec)) | 254 | (command (assoc-ref opts 'exec)) |
| @@ -282,4 +293,7 @@ OUTPUT) tuples, using the build options in OPTS." | |||
| 282 | (return #t)) | 293 | (return #t)) |
| 283 | (else | 294 | (else |
| 284 | (create-environment inputs paths pure?) | 295 | (create-environment inputs paths pure?) |
| 285 | (return (exit (status:exit-val (system command))))))))))))) | 296 | (return |
| 297 | (exit | ||
| 298 | (status:exit-val | ||
| 299 | (apply system* command))))))))))))) | ||
diff --git a/tests/guix-environment.sh b/tests/guix-environment.sh index 32faf71a4eb..f91c78a8014 100644 --- a/tests/guix-environment.sh +++ b/tests/guix-environment.sh | |||
| @@ -40,7 +40,15 @@ test "`wc -l < "$tmpdir/a"`" = 1 | |||
| 40 | cmp "$tmpdir/a" "$tmpdir/b" | 40 | cmp "$tmpdir/a" "$tmpdir/b" |
| 41 | 41 | ||
| 42 | # Make sure the exit value is preserved. | 42 | # Make sure the exit value is preserved. |
| 43 | if guix environment --ad-hoc guile-bootstrap --pure -E 'guile -c "(exit 42)"' | 43 | if guix environment --ad-hoc guile-bootstrap --pure -- guile -c '(exit 42)' |
| 44 | then | ||
| 45 | false | ||
| 46 | else | ||
| 47 | test $? = 42 | ||
| 48 | fi | ||
| 49 | |||
| 50 | # Same as above, but with deprecated -E flag. | ||
| 51 | if guix environment --ad-hoc guile-bootstrap --pure -E "guile -c '(exit 42)'" | ||
| 44 | then | 52 | then |
| 45 | false | 53 | false |
| 46 | else | 54 | else |
| @@ -66,7 +74,7 @@ then | |||
| 66 | # as returned by '--search-paths'. | 74 | # as returned by '--search-paths'. |
| 67 | guix environment -e '(@@ (gnu packages commencement) gnu-make-boot0)' \ | 75 | guix environment -e '(@@ (gnu packages commencement) gnu-make-boot0)' \ |
| 68 | --no-substitutes --pure \ | 76 | --no-substitutes --pure \ |
| 69 | --exec='echo $PATH $CPATH $LIBRARY_PATH' > "$tmpdir/b" | 77 | -- /bin/sh -c 'echo $PATH $CPATH $LIBRARY_PATH' > "$tmpdir/b" |
| 70 | ( . "$tmpdir/a" ; echo $PATH $CPATH $LIBRARY_PATH ) > "$tmpdir/c" | 78 | ( . "$tmpdir/a" ; echo $PATH $CPATH $LIBRARY_PATH ) > "$tmpdir/c" |
| 71 | cmp "$tmpdir/b" "$tmpdir/c" | 79 | cmp "$tmpdir/b" "$tmpdir/c" |
| 72 | 80 | ||
