diff mbox series

[bug#41253] guix: add script execution to "guix repl"

Message ID m1k11eg9ho.fsf@khs-macbook.home
State Accepted
Headers show
Series [bug#41253] guix: add script execution to "guix repl" | expand

Checks

Context Check Description
cbaines/comparison success View comparision
cbaines/git branch success View Git branch
cbaines/applying patch success View Laminar job

Commit Message

Konrad Hinsen May 14, 2020, 9:18 a.m. UTC
* guix/scripts/repl.scm: Add filename options for script execution.
* doc/guix.texi: Document script execution by "guix repl"
---
 doc/guix.texi         | 38 +++++++++++++++-----
 guix/scripts/repl.scm | 80 ++++++++++++++++++++++++++-----------------
 2 files changed, 78 insertions(+), 40 deletions(-)

Comments

Simon Tournier May 14, 2020, 4:31 p.m. UTC | #1
Dear Konrad,

Nice!
Thank you!

On Thu, 14 May 2020 at 11:19, Konrad Hinsen <konrad.hinsen@fastmail.net> wrote:
>
> * guix/scripts/repl.scm: Add filename options for script execution.
> * doc/guix.texi: Document script execution by "guix repl"

I have sent a v2 adding tests and rewording the commit message -- to
be what I understand the compliance; sorry if I did a mistake.
Well, I am not sure by the tests.

Last,  I am not convinced by the @cindex term and I think "@cindex
repl, guix repl" or "@cindex REPL, guix repl" is better.  But that's
only matter of taste. :-)


All the best,
simon
Konrad Hinsen May 29, 2020, 10:16 a.m. UTC | #2
Hi Simon,

> I have sent a v2 adding tests and rewording the commit message -- to
> be what I understand the compliance; sorry if I did a mistake.
> Well, I am not sure by the tests.

Way better than no tests!

I just submitted a v3, following a thread on help-guix
(see https://www.mail-archive.com/help-guix@gnu.org/msg09328.html).
The v3 patch allows

   guix repl script.scm

but also

   guix repl –  script.scm -a -b –-input=foo.txt

In exchange, only a single script can be run. This is perfectly
in line with how Guile works, but it breaks your nice interpretation
of "REPL" as applying to script execution ;-)

Cheers,
  Konrad
Simon Tournier May 29, 2020, 1:53 p.m. UTC | #3
Hi Konrad,

On Fri, 29 May 2020 at 12:16, Konrad Hinsen <konrad.hinsen@fastmail.net> wrote:

> I just submitted a v3, following a thread on help-guix
> (see https://www.mail-archive.com/help-guix@gnu.org/msg09328.html).

May I ask why this mai-archive.com instead of
lists.gnu.org/archive/html/help-guix?


> The v3 patch allows
>
>    guix repl script.scm
>
> but also
>
>    guix repl –  script.scm -a -b –-input=foo.txt

Nice!

> In exchange, only a single script can be run. This is perfectly

Do you mean that

   guix repl script_1.scm script_2.scm

does not work?


> in line with how Guile works, but it breaks your nice interpretation
> of "REPL" as applying to script execution ;-)

I can live with that. :-)


Thank you for the patch!!
Hope it will be merged soon. :-)


Cheers,
simon


ps:
Do you know why "M-x debbugs-gnu" is doing a mess with this thread?
Konrad Hinsen May 29, 2020, 5:21 p.m. UTC | #4
Hi Simon,

> May I ask why this mai-archive.com instead of
> lists.gnu.org/archive/html/help-guix?

Because that's what DuckDuckGo found for me. I can't remember where
all those list archives are, I just search!

>> In exchange, only a single script can be run. This is perfectly
>
> Do you mean that
>
>    guix repl script_1.scm script_2.scm
>
> does not work?

Well, it does in a way, but differently from before: it runs script₁.scm
and passes it script₂.scm as its (only) argument.

> Do you know why "M-x debbugs-gnu" is doing a mess with this thread?

No, I have never heard about "M-x debbugs-gnu". Sounds interesting
though...

Cheers,
  Konrad
diff mbox series

Patch

diff --git a/doc/guix.texi b/doc/guix.texi
index d6fbd85fde..68f1a8bba3 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -238,7 +238,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
 
@@ -5415,7 +5415,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
@@ -8134,12 +8134,31 @@  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{files}
+@end example
+
+When at least one @var{files} argument is provided, @var{files} are
+executed as Guile scripts in the given order:
+
+@example
+$ guix repl my-script.scm
+@end example
+
+Otherwise a Guile REPL is started:
 
 @example
 $ guix repl
@@ -8188,11 +8207,12 @@  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 scripts or REPL.
 
 @item -q
 Inhibit loading of the @file{~/.guile} file.  By default, that
-configuration file is loaded when spawning a @code{guile} REPL.
+configuration file is loaded when executing scripts or spawning
+a @code{guile} REPL.
 @end table
 
 @c *********************************************************************
diff --git a/guix/scripts/repl.scm b/guix/scripts/repl.scm
index ff1f208894..f4cb744bbd 100644
--- a/guix/scripts/repl.scm
+++ b/guix/scripts/repl.scm
@@ -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.
 ;;;
@@ -32,10 +33,12 @@ 
 
 ;;; 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)))
+  `((scripts . ())
+    (type . guile)))
 
 (define %options
   (list (option '(#\h "help") #f #f
@@ -63,8 +66,9 @@ 
 
 
 (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...] [FILES...]
+In the Guix execution environment, run FILES as Guile scripts,
+or start a Guile REPL if no FILES are given,\n"))
   (display (G_ "
   -t, --type=TYPE        start a REPL of the given TYPE"))
   (display (G_ "
@@ -135,12 +139,13 @@  call THUNK."
 
 (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))
+                  (alist-cons 'scripts
+                              (cons arg (cdr (assq 'scripts result)))
+                              result))
                 %default-options))
 
   (define user-config
@@ -148,29 +153,42 @@  call THUNK."
            (lambda (home)
              (string-append home "/.guile"))))
 
+  (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)))
+
   (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))
-
-                ;; 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)
-;; End:
+    (let ((scripts (reverse (assoc-ref opts 'scripts))))
+
+      (for-each (lambda (script)
+                  (save-module-excursion
+                   (lambda ()
+                     (set-user-module)
+                     (load script))))
+                scripts)
+
+      (when (null? scripts)
+        (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)
+  ;; End:
+  )