mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-23 21:17:11 -05:00
guix repl: Add script execution.
* guix/scripts/repl.scm: Add filename options for script execution. * doc/guix.texi (Invoking guix repl): Document it. * tests/guix-repl.sh: Test it. * Makefile.am: (SH_TESTS): Add it. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
parent
1b917f99b5
commit
c924e54139
4 changed files with 179 additions and 34 deletions
|
@ -477,6 +477,7 @@ SH_TESTS = \
|
|||
tests/guix-environment-container.sh \
|
||||
tests/guix-graph.sh \
|
||||
tests/guix-describe.sh \
|
||||
tests/guix-repl.sh \
|
||||
tests/guix-lint.sh
|
||||
|
||||
TESTS = $(SCM_TESTS) $(SH_TESTS)
|
||||
|
|
|
@ -239,7 +239,7 @@ Programming Interface
|
|||
* Derivations:: Low-level interface to package derivations.
|
||||
* The Store Monad:: Purely functional interface to the store.
|
||||
* G-Expressions:: Manipulating build expressions.
|
||||
* Invoking guix repl:: Fiddling with Guix interactively.
|
||||
* Invoking guix repl:: Programming Guix in Guile
|
||||
|
||||
Defining Packages
|
||||
|
||||
|
@ -5474,7 +5474,7 @@ package definitions.
|
|||
* Derivations:: Low-level interface to package derivations.
|
||||
* The Store Monad:: Purely functional interface to the store.
|
||||
* G-Expressions:: Manipulating build expressions.
|
||||
* Invoking guix repl:: Fiddling with Guix interactively.
|
||||
* Invoking guix repl:: Programming Guix in Guile
|
||||
@end menu
|
||||
|
||||
@node Package Modules
|
||||
|
@ -8248,12 +8248,47 @@ has an associated gexp compiler, such as a @code{<package>}.
|
|||
@node Invoking guix repl
|
||||
@section Invoking @command{guix repl}
|
||||
|
||||
@cindex REPL, read-eval-print loop
|
||||
The @command{guix repl} command spawns a Guile @dfn{read-eval-print loop}
|
||||
(REPL) for interactive programming (@pxref{Using Guile Interactively,,, guile,
|
||||
GNU Guile Reference Manual}). Compared to just launching the @command{guile}
|
||||
@cindex REPL, read-eval-print loop, script
|
||||
The @command{guix repl} command makes it easier to program Guix in Guile
|
||||
by launching a Guile @dfn{read-eval-print loop} (REPL) for interactive
|
||||
programming (@pxref{Using Guile Interactively,,, guile,
|
||||
GNU Guile Reference Manual}), or by running Guile scripts
|
||||
(@pxref{Running Guile Scripts,,, guile,
|
||||
GNU Guile Reference Manual}).
|
||||
Compared to just launching the @command{guile}
|
||||
command, @command{guix repl} guarantees that all the Guix modules and all its
|
||||
dependencies are available in the search path. You can use it this way:
|
||||
dependencies are available in the search path.
|
||||
|
||||
The general syntax is:
|
||||
|
||||
@example
|
||||
guix repl @var{options} [@var{file} @var{args}]
|
||||
@end example
|
||||
|
||||
When a @var{file} argument is provided, @var{file} is
|
||||
executed as a Guile scripts:
|
||||
|
||||
@example
|
||||
guix repl my-script.scm
|
||||
@end example
|
||||
|
||||
To pass arguments to the script, use @code{--} to prevent them from
|
||||
being interpreted as arguments to @command{guix repl} itself:
|
||||
|
||||
@example
|
||||
guix repl -- my-script.scm --input=foo.txt
|
||||
@end example
|
||||
|
||||
To make a script executable directly from the shell, using the guix
|
||||
executable that is on the user's search path, add the following two
|
||||
lines at the top of the script:
|
||||
|
||||
@example
|
||||
@code{#!/usr/bin/env -S guix repl --}
|
||||
@code{!#}
|
||||
@end example
|
||||
|
||||
Without a file name argument, a Guile REPL is started:
|
||||
|
||||
@example
|
||||
$ guix repl
|
||||
|
@ -8302,7 +8337,7 @@ Add @var{directory} to the front of the package module search path
|
|||
(@pxref{Package Modules}).
|
||||
|
||||
This allows users to define their own packages and make them visible to
|
||||
the command-line tool.
|
||||
the script or REPL.
|
||||
|
||||
@item -q
|
||||
Inhibit loading of the @file{~/.guile} file. By default, that
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2020 Simon Tournier <zimon.toutoune@gmail.com>
|
||||
;;; Copyright © 2020 Konrad Hinsen <konrad.hinsen@fastmail.net>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
|
@ -22,6 +23,7 @@ (define-module (guix scripts repl)
|
|||
#:use-module (guix scripts)
|
||||
#:use-module (guix repl)
|
||||
#:use-module (srfi srfi-1)
|
||||
#:use-module (srfi srfi-26)
|
||||
#:use-module (srfi srfi-37)
|
||||
#:use-module (ice-9 match)
|
||||
#:use-module (rnrs bytevectors)
|
||||
|
@ -32,7 +34,8 @@ (define-module (guix scripts repl)
|
|||
|
||||
;;; Commentary:
|
||||
;;;
|
||||
;;; This command provides a Guile REPL
|
||||
;;; This command provides a Guile script runner and REPL in an environment
|
||||
;;; that contains all the modules comprising Guix.
|
||||
|
||||
(define %default-options
|
||||
`((type . guile)))
|
||||
|
@ -63,8 +66,9 @@ (define %options
|
|||
|
||||
|
||||
(define (show-help)
|
||||
(display (G_ "Usage: guix repl [OPTIONS...]
|
||||
Start a Guile REPL in the Guix execution environment.\n"))
|
||||
(display (G_ "Usage: guix repl [OPTIONS...] [-- FILE ARGS...]
|
||||
In the Guix execution environment, run FILE as a Guile script with
|
||||
command-line arguments ARGS. If no FILE is given, start a Guile REPL.\n"))
|
||||
(display (G_ "
|
||||
-t, --type=TYPE start a REPL of the given TYPE"))
|
||||
(display (G_ "
|
||||
|
@ -135,12 +139,13 @@ (define socket
|
|||
|
||||
(define (guix-repl . args)
|
||||
(define opts
|
||||
;; Return the list of package names.
|
||||
(args-fold* args %options
|
||||
(lambda (opt name arg result)
|
||||
(leave (G_ "~A: unrecognized option~%") name))
|
||||
(lambda (arg result)
|
||||
(leave (G_ "~A: extraneous argument~%") arg))
|
||||
(append `((script . ,arg)
|
||||
(ignore-dot-guile . #t))
|
||||
result))
|
||||
%default-options))
|
||||
|
||||
(define user-config
|
||||
|
@ -148,28 +153,48 @@ (define user-config
|
|||
(lambda (home)
|
||||
(string-append home "/.guile"))))
|
||||
|
||||
(with-error-handling
|
||||
(let ((type (assoc-ref opts 'type)))
|
||||
(call-with-connection (assoc-ref opts 'listen)
|
||||
(lambda ()
|
||||
(case type
|
||||
((guile)
|
||||
(save-module-excursion
|
||||
(lambda ()
|
||||
(set-current-module user-module)
|
||||
(when (and (not (assoc-ref opts 'ignore-dot-guile?))
|
||||
user-config
|
||||
(file-exists? user-config))
|
||||
(load user-config))
|
||||
(define (set-user-module)
|
||||
(set-current-module user-module)
|
||||
(when (and (not (assoc-ref opts 'ignore-dot-guile?))
|
||||
user-config
|
||||
(file-exists? user-config))
|
||||
(load user-config)))
|
||||
|
||||
;; Do not exit repl on SIGINT.
|
||||
((@@ (ice-9 top-repl) call-with-sigint)
|
||||
(lambda ()
|
||||
(start-repl))))))
|
||||
((machine)
|
||||
(machine-repl))
|
||||
(else
|
||||
(leave (G_ "~a: unknown type of REPL~%") type))))))))
|
||||
(define script
|
||||
(reverse
|
||||
(filter-map (match-lambda
|
||||
(('script . script) script)
|
||||
(_ #f))
|
||||
opts)))
|
||||
|
||||
(with-error-handling
|
||||
|
||||
(unless (null? script)
|
||||
;; Run script
|
||||
(save-module-excursion
|
||||
(lambda ()
|
||||
(set-program-arguments script)
|
||||
(set-user-module)
|
||||
(load-in-vicinity "." (car script)))))
|
||||
|
||||
(when (null? script)
|
||||
;; Start REPL
|
||||
(let ((type (assoc-ref opts 'type)))
|
||||
(call-with-connection (assoc-ref opts 'listen)
|
||||
(lambda ()
|
||||
(case type
|
||||
((guile)
|
||||
(save-module-excursion
|
||||
(lambda ()
|
||||
(set-user-module)
|
||||
;; Do not exit repl on SIGINT.
|
||||
((@@ (ice-9 top-repl) call-with-sigint)
|
||||
(lambda ()
|
||||
(start-repl))))))
|
||||
((machine)
|
||||
(machine-repl))
|
||||
(else
|
||||
(leave (G_ "~a: unknown type of REPL~%") type)))))))))
|
||||
|
||||
;; Local Variables:
|
||||
;; eval: (put 'call-with-connection 'scheme-indent-function 1)
|
||||
|
|
84
tests/guix-repl.sh
Normal file
84
tests/guix-repl.sh
Normal file
|
@ -0,0 +1,84 @@
|
|||
# GNU Guix --- Functional package management for GNU
|
||||
# Copyright © 2020 Simon Tournier <zimon.toutoune@gmail.com>
|
||||
# Copyright © 2020 Konrad Hinsen <konrad.hinsen@fastmail.net>
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# Test the `guix repl' command-line utility.
|
||||
#
|
||||
|
||||
guix repl --version
|
||||
|
||||
test_directory="`mktemp -d`"
|
||||
export test_directory
|
||||
trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_directory"' EXIT
|
||||
|
||||
tmpfile="$test_directory/foo.scm"
|
||||
rm -f "$tmpfile"
|
||||
trap 'rm -f "$tmpfile"' EXIT
|
||||
|
||||
module_dir="t-guix-repl-$$"
|
||||
mkdir "$module_dir"
|
||||
trap 'rm -rf "$module_dir"' EXIT
|
||||
|
||||
|
||||
cat > "$tmpfile"<<EOF
|
||||
(use-modules (guix packages)
|
||||
(gnu packages base))
|
||||
|
||||
(format #t "~a\n" (package-name coreutils))
|
||||
EOF
|
||||
|
||||
test "`guix repl "$tmpfile"`" = "coreutils"
|
||||
|
||||
|
||||
cat > "$module_dir/foo.scm"<<EOF
|
||||
(define-module (foo)
|
||||
#:use-module (guix packages)
|
||||
#:use-module (gnu packages base))
|
||||
|
||||
(define-public dummy
|
||||
(package (inherit hello)
|
||||
(name "dummy")
|
||||
(version "42")
|
||||
(synopsis "dummy package")
|
||||
(description "dummy package. Only used for testing purposes.")))
|
||||
EOF
|
||||
|
||||
cat > "$tmpfile"<<EOF
|
||||
(use-modules (guix packages)
|
||||
(foo))
|
||||
|
||||
(format #t "~a\n" (package-version dummy))
|
||||
EOF
|
||||
|
||||
test "`guix repl "$tmpfile" -L "$module_dir"`" = "42"
|
||||
|
||||
cat > "$tmpfile"<<EOF
|
||||
(format #t "~a\n" (cdr (command-line)))
|
||||
EOF
|
||||
|
||||
test "`guix repl -- "$tmpfile" -a b --input=foo.txt`" = "(-a b --input=foo.txt)"
|
||||
|
||||
cat > "$tmpfile"<<EOF
|
||||
#!$(type -P env) -S guix repl --
|
||||
!#
|
||||
(format #t "~a\n" (cdr (command-line)))
|
||||
EOF
|
||||
chmod 755 $tmpfile
|
||||
|
||||
test "`"$tmpfile" -a b --input=foo.txt`" = "(-a b --input=foo.txt)"
|
Loading…
Reference in a new issue