* [bug#40373] [PATCH] guix: new command "guix run-script" @ 2020-04-01 14:09 Konrad Hinsen 2020-04-01 21:00 ` Ludovic Courtès 2020-04-02 9:08 ` [bug#40373] " zimoun 0 siblings, 2 replies; 23+ messages in thread From: Konrad Hinsen @ 2020-04-01 14:09 UTC (permalink / raw) To: 40373 * guix/scripts/run-script.scm: New file. * Makefile.am: (MODULES): Add it. * doc/guix.texi: Document "guix time-machine" --- Makefile.am | 1 + doc/guix.texi | 32 +++++++++++ guix/scripts/run-script.scm | 106 ++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 guix/scripts/run-script.scm diff --git a/Makefile.am b/Makefile.am index 344ecdbc42..28ac7344e8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -283,6 +283,7 @@ MODULES = \ guix/scripts/container/exec.scm \ guix/scripts/deploy.scm \ guix/scripts/time-machine.scm \ + guix/scripts/run-script.scm \ guix.scm \ $(GNU_SYSTEM_MODULES) diff --git a/doc/guix.texi b/doc/guix.texi index 8cb85fe62c..0a64af24dc 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -235,6 +235,7 @@ Programming Interface * The Store Monad:: Purely functional interface to the store. * G-Expressions:: Manipulating build expressions. * Invoking guix repl:: Fiddling with Guix interactively. +* Invoking guix run-script:: Running Guix scripts. Defining Packages @@ -5347,6 +5348,7 @@ package definitions. * The Store Monad:: Purely functional interface to the store. * G-Expressions:: Manipulating build expressions. * Invoking guix repl:: Fiddling with Guix interactively. +* Invoking guix run-script:: Running Guix scripts. @end menu @node Package Modules @@ -8121,6 +8123,36 @@ Inhibit loading of the @file{~/.guile} file. By default, that configuration file is loaded when spawning a @code{guile} REPL. @end table +@node Invoking guix run-script +@section Invoking @command{guix run-script} + +@cindex script + +The @command{guix run-script} command executes a Guile script +(@pxref{Running Guile Scripts,,, guile, GNU Guile Reference Manual}). +Compared to just launching the @command{guile} command, +@command{guix run-script} guarantees that all the Guix modules +and all its dependencies are available in the search path. + +The general syntax is: + +@example +guix run-script @var{options} @var{file} +@end example + +The available options are as follows: + +@table @code +@item --load-path=@var{directory} +@itemx -L @var{directory} +Add @var{directory} to the front of the package module search path +(@pxref{Package Modules}). + +@item -q +Inhibit loading of the @file{~/.guile} file. By default, that +configuration file is loaded before executing the script. +@end table + @c ********************************************************************* @node Utilities @chapter Utilities diff --git a/guix/scripts/run-script.scm b/guix/scripts/run-script.scm new file mode 100644 index 0000000000..2e948da85f --- /dev/null +++ b/guix/scripts/run-script.scm @@ -0,0 +1,106 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org> +;;; 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/>. + +(define-module (guix scripts run-script) + #:use-module (guix ui) + #:use-module (guix scripts) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-37) + #:use-module (ice-9 match) + #:export (guix-run-script)) + +;;; Commentary: +;;; +;;; This command allows to run Guile scripts in an environment +;;; that contains all the modules comprising Guix. + +(define %default-options + '()) + +(define %options + (list (option '(#\h "help") #f #f + (lambda args + (show-help) + (exit 0))) + (option '(#\V "version") #f #f + (lambda args + (show-version-and-exit "guix run-script"))) + (option '(#\q) #f #f + (lambda (opt name arg result) + (alist-cons 'ignore-dot-guile? #t result))) + (option '(#\L "load-path") #t #f + (lambda (opt name arg result) + ;; XXX: Imperatively modify the search paths. + (set! %load-path (cons arg %load-path)) + (set! %load-compiled-path (cons arg %load-compiled-path)) + result)))) + + +(define (show-help) + (display (G_ "Usage: guix run-script [OPTIONS...] FILE +Run FILE as a Guile script in the Guix execution environment.\n")) + (display (G_ " + -q inhibit loading of ~/.guile")) + (newline) + (display (G_ " + -L, --load-path=DIR prepend DIR to the package module search path")) + (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 user-module + ;; Module where we execute user code. + (let ((module (resolve-module '(guix-user) #f #f #:ensure #t))) + (beautify-user-module! module) + module)) + +\f +(define (guix-run-script . args) + (define opts + (args-fold* args %options + (lambda (opt name arg result) + (leave (G_ "~A: unrecognized option~%") name)) + (lambda (arg result) + (when (assq 'argument result) + (leave (G_ "~A: extraneous argument~%") arg)) + (alist-cons 'argument arg result)) + %default-options)) + + (define script + (or (assq-ref opts 'argument) + (leave (G_ "no script filename specified~%")))) + + (define user-config + (and=> (getenv "HOME") + (lambda (home) + (string-append home "/.guile")))) + + (with-error-handling + (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)) + (load script))))) -- 2.26.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-01 14:09 [bug#40373] [PATCH] guix: new command "guix run-script" Konrad Hinsen @ 2020-04-01 21:00 ` Ludovic Courtès 2020-04-02 7:13 ` Konrad Hinsen 2020-04-02 9:08 ` [bug#40373] " zimoun 1 sibling, 1 reply; 23+ messages in thread From: Ludovic Courtès @ 2020-04-01 21:00 UTC (permalink / raw) To: Konrad Hinsen; +Cc: 40373 Hi Konrad, Konrad Hinsen <konrad.hinsen@fastmail.net> skribis: > +The @command{guix run-script} command executes a Guile script > +(@pxref{Running Guile Scripts,,, guile, GNU Guile Reference Manual}). > +Compared to just launching the @command{guile} command, > +@command{guix run-script} guarantees that all the Guix modules > +and all its dependencies are available in the search path. What about making that just a new ‘-s’ flag for ‘guix repl’ (just like Guile’s ‘-s’ flag)? ‘-q’ should always be implied when doing that. Now, this wouldn’t be usable as a shebang due to the fact that only one argument is allowed, unless we do some extra argument tokenizing. Thanks, Ludo’. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-01 21:00 ` Ludovic Courtès @ 2020-04-02 7:13 ` Konrad Hinsen 2020-04-02 9:17 ` zimoun 2020-04-03 9:51 ` [bug#40373] [PATCH] guix: new command "guix run-script" Ludovic Courtès 0 siblings, 2 replies; 23+ messages in thread From: Konrad Hinsen @ 2020-04-02 7:13 UTC (permalink / raw) To: Ludovic Courtès; +Cc: 40373 Hi Ludo, > What about making that just a new ‘-s’ flag for ‘guix repl’ (just like > Guile’s ‘-s’ flag)? ‘-q’ should always be implied when doing that. > > Now, this wouldn’t be usable as a shebang due to the fact that only one > argument is allowed, unless we do some extra argument tokenizing. That is one reason why I opted for a separate command. The other is that I am in tutorial-driven development mode: I need "guix run-script" in order to be able to insert my own scripts (for analyzing dependencies) into a Guix tutorial for an upcoming MOOC. So I need to make sure that people can run my scripts easily, but also that they understand what they are doing. A command that does something else than its name suggests, with a similarity that is only visible to experts, is no good for use in a tutorial. BTW, I opted for a lengthy name ("run-script" rather than just "run" or "script") according to the principle that short words should be left for frequently used concepts (a principle respected by human languages, but also by Lisp tradition). I am of course aware that much of the code in "run-script" is the same as in "repl", which is not good. But I'd rather think about a better framework for code sharing among Guix scripts than about pushing too much semantic differences into obscure options. An example would be reusable "option clusters", such as "options for Guile" or "options for channels". Cheers, Konrad. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-02 7:13 ` Konrad Hinsen @ 2020-04-02 9:17 ` zimoun 2020-04-02 9:37 ` Konrad Hinsen 2020-04-03 9:51 ` [bug#40373] [PATCH] guix: new command "guix run-script" Ludovic Courtès 1 sibling, 1 reply; 23+ messages in thread From: zimoun @ 2020-04-02 9:17 UTC (permalink / raw) To: Konrad Hinsen; +Cc: Ludovic Courtès, 40373 Hi Konrad, On Thu, 2 Apr 2020 at 09:14, Konrad Hinsen <konrad.hinsen@fastmail.net> wrote: > > What about making that just a new ‘-s’ flag for ‘guix repl’ (just like > > Guile’s ‘-s’ flag)? ‘-q’ should always be implied when doing that. > > > > Now, this wouldn’t be usable as a shebang due to the fact that only one > > argument is allowed, unless we do some extra argument tokenizing. > > That is one reason why I opted for a separate command. > > The other is that I am in tutorial-driven development mode: I need "guix > run-script" in order to be able to insert my own scripts (for analyzing > dependencies) into a Guix tutorial for an upcoming MOOC. So I need to > make sure that people can run my scripts easily, but also that they > understand what they are doing. A command that does something else than > its name suggests, with a similarity that is only visible to experts, > is no good for use in a tutorial. > > BTW, I opted for a lengthy name ("run-script" rather than just "run" or > "script") according to the principle that short words should be left for > frequently used concepts (a principle respected by human languages, but > also by Lisp tradition). > > I am of course aware that much of the code in "run-script" is the same > as in "repl", which is not good. But I'd rather think about a better > framework for code sharing among Guix scripts than about pushing too > much semantic differences into obscure options. An example would be > reusable "option clusters", such as "options for Guile" or "options for > channels". Initially, I thought the same as Ludo: "run-script" should be an option to "repl". And I understand your UI concerns. Maybe, we could deprecated "repl" and add "run" with: - guix run <file> (same than the "guix run-script" proposal) - guix run or guix run --repl doing the what "guix repl" does. The new command "guix run" could have more or less the same option than "guile" but prepending all the paths correctly. I mean we need something like "guix name-it <otpions>" mimicking "guile <options>" adding the correct Guix modules, IMHO. BTW, thank you for this. Because it was missing in my toolbox and I was annoyed until now. Cheers, simon ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-02 9:17 ` zimoun @ 2020-04-02 9:37 ` Konrad Hinsen 2020-04-03 9:17 ` Konrad Hinsen 2020-04-03 9:19 ` [bug#40373] [PATCH] guix: new command "guix run" generalizes "guix repl" Konrad Hinsen 0 siblings, 2 replies; 23+ messages in thread From: Konrad Hinsen @ 2020-04-02 9:37 UTC (permalink / raw) To: zimoun; +Cc: Ludovic Courtès, 40373 Hi Simon, > Maybe, we could deprecated "repl" and add "run" with: > - guix run <file> (same than the "guix run-script" proposal) > - guix run or guix run --repl doing the what "guix repl" does. Yes, unifying the two functionalities under a new name is an interesting options. Could we go for "guix guile" and make it option-compatible with plain Guile as much as possible? Just an idea, I am not sure it's a good one! Guile can already be a pain in a shebang line. Cheers, Konrad ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-02 9:37 ` Konrad Hinsen @ 2020-04-03 9:17 ` Konrad Hinsen 2020-04-03 9:48 ` Ludovic Courtès 2020-04-03 9:19 ` [bug#40373] [PATCH] guix: new command "guix run" generalizes "guix repl" Konrad Hinsen 1 sibling, 1 reply; 23+ messages in thread From: Konrad Hinsen @ 2020-04-03 9:17 UTC (permalink / raw) To: 40373; +Cc: Ludovic Courtès, zimoun Konrad Hinsen <konrad.hinsen@fastmail.net> writes: > Could we go for "guix guile" and make it option-compatible with plain > Guile as much as possible? Just an idea, I am not sure it's a good one! > Guile can already be a pain in a shebang line. After some exploration, that kind of compatibility doesn't seem worth the effort. I will send another patch that implements Simon's proposal: - New command "guix run" that extends "guix repl" by an optional file argument for running a script. - "guix repl" becomes an alias for "guix run" (and could in the long run be declared obsolete). Cheers, Konrad. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-03 9:17 ` Konrad Hinsen @ 2020-04-03 9:48 ` Ludovic Courtès 0 siblings, 0 replies; 23+ messages in thread From: Ludovic Courtès @ 2020-04-03 9:48 UTC (permalink / raw) To: Konrad Hinsen; +Cc: 40373, zimoun Hi Konrad, Konrad Hinsen <konrad.hinsen@fastmail.net> skribis: > Konrad Hinsen <konrad.hinsen@fastmail.net> writes: > >> Could we go for "guix guile" and make it option-compatible with plain >> Guile as much as possible? Just an idea, I am not sure it's a good one! >> Guile can already be a pain in a shebang line. > > After some exploration, that kind of compatibility doesn't seem worth > the effort. > > I will send another patch that implements Simon's proposal: > > - New command "guix run" that extends "guix repl" by an optional > file argument for running a script. “guix run” was sort of reserved for something else: https://lists.gnu.org/archive/html/help-guix/2018-01/msg00118.html The idea is still floating around so perhaps we should keep that name. > - "guix repl" becomes an alias for "guix run" (and could in the > long run be declared obsolete). I’m worried about a possible increase of the deprecation rate. I understand the rationale, I think it makes sense, but still, I’m not sure we need to deprecate “guix repl” already. In fact, since it’s used by inferiors, we must pay extra attention to keep it as-is as much as possible or we’ll make communication between old and new Guixes difficult. Thoughts? Thanks, Ludo’. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run" generalizes "guix repl" 2020-04-02 9:37 ` Konrad Hinsen 2020-04-03 9:17 ` Konrad Hinsen @ 2020-04-03 9:19 ` Konrad Hinsen 1 sibling, 0 replies; 23+ messages in thread From: Konrad Hinsen @ 2020-04-03 9:19 UTC (permalink / raw) To: 40373 * guix/scripts/run.scm: New file. * Makefile.am: (MODULES): Add it. * guix/scripts/repl.scm: Make "guix repl" an alias for "guix run". * doc/guix.texi: Document "guix run" --- Makefile.am | 1 + doc/guix.texi | 51 ++++++++---- guix/scripts/repl.scm | 157 +---------------------------------- guix/scripts/run.scm | 189 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 229 insertions(+), 169 deletions(-) create mode 100644 guix/scripts/run.scm diff --git a/Makefile.am b/Makefile.am index 344ecdbc42..db91c4f5da 100644 --- a/Makefile.am +++ b/Makefile.am @@ -255,6 +255,7 @@ MODULES = \ guix/scripts/authenticate.scm \ guix/scripts/refresh.scm \ guix/scripts/repl.scm \ + guix/scripts/run.scm \ guix/scripts/describe.scm \ guix/scripts/system.scm \ guix/scripts/system/search.scm \ diff --git a/doc/guix.texi b/doc/guix.texi index 8cb85fe62c..4e4c12866a 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -234,7 +234,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 run:: Programming Guix in Guile Defining Packages @@ -1154,7 +1154,7 @@ The @command{guix} command must be in the search path on the build machines. You can check whether this is the case by running: @example -ssh build-machine guix repl --version +ssh build-machine guix run --version @end example There is one last thing to do once @file{machines.scm} is in place. As @@ -4259,7 +4259,7 @@ revisions in arbitrary ways. @cindex inferior packages Technically, an ``inferior'' is essentially a separate Guix process connected -to your main Guix process through a REPL (@pxref{Invoking guix repl}). The +to your main Guix process through a REPL (@pxref{Invoking guix run}). The @code{(guix inferior)} module allows you to create inferiors and to communicate with them. It also provides a high-level interface to browse and manipulate the packages that an inferior provides---@dfn{inferior packages}. @@ -4318,7 +4318,7 @@ As a side effect, this procedure may build or substitute binaries for @deffn {Scheme Procedure} open-inferior @var{directory} @ [#:command "bin/guix"] Open the inferior Guix in @var{directory}, running -@code{@var{directory}/@var{command} repl} or equivalent. Return @code{#f} if +@code{@var{directory}/@var{command} run} or equivalent. Return @code{#f} if the inferior could not be launched. @end deffn @@ -5346,7 +5346,8 @@ 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 run:: Programming Guix in Guile + @end menu @node Package Modules @@ -8057,25 +8058,43 @@ corresponding to @var{obj} for @var{system}, cross-compiling for has an associated gexp compiler, such as a @code{<package>}. @end deffn -@node Invoking guix repl -@section Invoking @command{guix repl} +@node Invoking guix run +@section Invoking @command{guix run} + +@cindex script, REPL, read-eval-print loop +The @command{guix run} command makes it easier to program Guix in Guile, +either by running Guile scripts (@pxref{Running Guile Scripts,,, guile, +GNU Guile Reference Manual}) or by launching 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} +command, @command{guix run} guarantees that all the Guix modules and all its +dependencies are available in the search path. + +The general syntax is: + +@example +guix run @var{options} @var{file} +@end example + +When a @var{file} argument is provided, @var{file} is executed as a Guile +script: + +@example +$ guix run my-script.scm +@end example -@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} -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: +Otherwise a Guile REPL is started: @example -$ guix repl +$ guix run scheme@@(guile-user)> ,use (gnu packages base) scheme@@(guile-user)> coreutils $1 = #<package coreutils@@8.29 gnu/packages/base.scm:327 3e28300> @end example @cindex inferiors -In addition, @command{guix repl} implements a simple machine-readable REPL +In addition, @command{guix run} implements a simple machine-readable REPL protocol for use by @code{(guix inferior)}, a facility to interact with @dfn{inferiors}, separate processes running a potentially different revision of Guix. @@ -8114,7 +8133,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 command-line tool. @item -q Inhibit loading of the @file{~/.guile} file. By default, that diff --git a/guix/scripts/repl.scm b/guix/scripts/repl.scm index ff1f208894..4feca9140a 100644 --- a/guix/scripts/repl.scm +++ b/guix/scripts/repl.scm @@ -1,6 +1,5 @@ ;;; 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. ;;; @@ -18,159 +17,11 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (guix scripts repl) - #:use-module (guix ui) - #:use-module (guix scripts) - #:use-module (guix repl) - #:use-module (srfi srfi-1) - #:use-module (srfi srfi-37) - #:use-module (ice-9 match) - #:use-module (rnrs bytevectors) - #:autoload (system repl repl) (start-repl) - #:autoload (system repl server) - (make-tcp-server-socket make-unix-domain-server-socket) + #:use-module (guix scripts run) #:export (guix-repl)) ;;; Commentary: ;;; -;;; This command provides a Guile REPL +;;; This is an alias for "guix run", for backwards compatibility -(define %default-options - `((type . guile))) - -(define %options - (list (option '(#\h "help") #f #f - (lambda args - (show-help) - (exit 0))) - (option '(#\V "version") #f #f - (lambda args - (show-version-and-exit "guix repl"))) - (option '(#\t "type") #t #f - (lambda (opt name arg result) - (alist-cons 'type (string->symbol arg) result))) - (option '("listen") #t #f - (lambda (opt name arg result) - (alist-cons 'listen arg result))) - (option '(#\q) #f #f - (lambda (opt name arg result) - (alist-cons 'ignore-dot-guile? #t result))) - (option '(#\L "load-path") #t #f - (lambda (opt name arg result) - ;; XXX: Imperatively modify the search paths. - (set! %load-path (cons arg %load-path)) - (set! %load-compiled-path (cons arg %load-compiled-path)) - result)))) - - -(define (show-help) - (display (G_ "Usage: guix repl [OPTIONS...] -Start a Guile REPL in the Guix execution environment.\n")) - (display (G_ " - -t, --type=TYPE start a REPL of the given TYPE")) - (display (G_ " - --listen=ENDPOINT listen to ENDPOINT instead of standard input")) - (display (G_ " - -q inhibit loading of ~/.guile")) - (newline) - (display (G_ " - -L, --load-path=DIR prepend DIR to the package module search path")) - (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 user-module - ;; Module where we execute user code. - (let ((module (resolve-module '(guix-user) #f #f #:ensure #t))) - (beautify-user-module! module) - module)) - -(define (call-with-connection spec thunk) - "Dynamically-bind the current input and output ports according to SPEC and -call THUNK." - (if (not spec) - (thunk) - - ;; Note: the "PROTO:" prefix in SPEC is here so that we can eventually - ;; parse things like "fd:123" in a non-ambiguous way. - (match (string-index spec #\:) - (#f - (leave (G_ "~A: invalid listen specification~%") spec)) - (index - (let ((protocol (string-take spec index)) - (address (string-drop spec (+ index 1)))) - (define socket - (match protocol - ("tcp" - (make-tcp-server-socket #:port (string->number address))) - ("unix" - (make-unix-domain-server-socket #:path address)) - (_ - (leave (G_ "~A: unsupported protocol family~%") - protocol)))) - - (listen socket 10) - (let loop () - (match (accept socket) - ((connection . address) - (if (= AF_UNIX (sockaddr:fam address)) - (info (G_ "accepted connection~%")) - (info (G_ "accepted connection from ~a~%") - (inet-ntop (sockaddr:fam address) - (sockaddr:addr address)))) - (dynamic-wind - (const #t) - (lambda () - (parameterize ((current-input-port connection) - (current-output-port connection)) - (thunk))) - (lambda () - (false-if-exception (close-port connection)) - (info (G_ "connection closed~%")))))) - (loop))))))) - -\f -(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)) - %default-options)) - - (define user-config - (and=> (getenv "HOME") - (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)) - - ;; 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: +(define guix-repl guix-run) diff --git a/guix/scripts/run.scm b/guix/scripts/run.scm new file mode 100644 index 0000000000..4f3cfb2c47 --- /dev/null +++ b/guix/scripts/run.scm @@ -0,0 +1,189 @@ +;;; 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. +;;; +;;; 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/>. + +(define-module (guix scripts run) + #:use-module (guix ui) + #:use-module (guix scripts) + #:use-module (guix repl) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-37) + #:use-module (ice-9 match) + #:use-module (rnrs bytevectors) + #:autoload (system repl repl) (start-repl) + #:autoload (system repl server) + (make-tcp-server-socket make-unix-domain-server-socket) + #:export (guix-run)) + +;;; Commentary: +;;; +;;; This command provides a Guile script runner and REPL in an environment +;;; that contains all the modules comprising Guix. + +(define %default-options + `((type . guile))) + +(define %options + (list (option '(#\h "help") #f #f + (lambda args + (show-help) + (exit 0))) + (option '(#\V "version") #f #f + (lambda args + (show-version-and-exit "guix repl"))) + (option '(#\t "type") #t #f + (lambda (opt name arg result) + (alist-cons 'type (string->symbol arg) result))) + (option '("listen") #t #f + (lambda (opt name arg result) + (alist-cons 'listen arg result))) + (option '(#\q) #f #f + (lambda (opt name arg result) + (alist-cons 'ignore-dot-guile? #t result))) + (option '(#\L "load-path") #t #f + (lambda (opt name arg result) + ;; XXX: Imperatively modify the search paths. + (set! %load-path (cons arg %load-path)) + (set! %load-compiled-path (cons arg %load-compiled-path)) + result)))) + + +(define (show-help) + (display (G_ "Usage: guix run [OPTIONS...] [FILE] +Run FILE as a Guile script, or start a Guile REPL, in the Guix +execution environment.\n")) + (display (G_ " + -t, --type=TYPE start a REPL of the given TYPE")) + (display (G_ " + --listen=ENDPOINT listen to ENDPOINT instead of standard input")) + (display (G_ " + -q inhibit loading of ~/.guile")) + (newline) + (display (G_ " + -L, --load-path=DIR prepend DIR to the package module search path")) + (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 user-module + ;; Module where we execute user code. + (let ((module (resolve-module '(guix-user) #f #f #:ensure #t))) + (beautify-user-module! module) + module)) + +(define (call-with-connection spec thunk) + "Dynamically-bind the current input and output ports according to SPEC and +call THUNK." + (if (not spec) + (thunk) + + ;; Note: the "PROTO:" prefix in SPEC is here so that we can eventually + ;; parse things like "fd:123" in a non-ambiguous way. + (match (string-index spec #\:) + (#f + (leave (G_ "~A: invalid listen specification~%") spec)) + (index + (let ((protocol (string-take spec index)) + (address (string-drop spec (+ index 1)))) + (define socket + (match protocol + ("tcp" + (make-tcp-server-socket #:port (string->number address))) + ("unix" + (make-unix-domain-server-socket #:path address)) + (_ + (leave (G_ "~A: unsupported protocol family~%") + protocol)))) + + (listen socket 10) + (let loop () + (match (accept socket) + ((connection . address) + (if (= AF_UNIX (sockaddr:fam address)) + (info (G_ "accepted connection~%")) + (info (G_ "accepted connection from ~a~%") + (inet-ntop (sockaddr:fam address) + (sockaddr:addr address)))) + (dynamic-wind + (const #t) + (lambda () + (parameterize ((current-input-port connection) + (current-output-port connection)) + (thunk))) + (lambda () + (false-if-exception (close-port connection)) + (info (G_ "connection closed~%")))))) + (loop))))))) + +\f +(define (guix-run . args) + (define opts + (args-fold* args %options + (lambda (opt name arg result) + (leave (G_ "~A: unrecognized option~%") name)) + (lambda (arg result) + (when (assq 'argument result) + (leave (G_ "~A: extraneous argument~%") arg)) + (alist-cons 'argument arg result)) + %default-options)) + + (define user-config + (and=> (getenv "HOME") + (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 ((script (assoc-ref opts 'argument)) + (type (assoc-ref opts 'type))) + (if script + (save-module-excursion + (lambda () + (set-user-module) + (load script))) + (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: + ) -- 2.26.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-02 7:13 ` Konrad Hinsen 2020-04-02 9:17 ` zimoun @ 2020-04-03 9:51 ` Ludovic Courtès 2020-04-07 9:10 ` Konrad Hinsen 1 sibling, 1 reply; 23+ messages in thread From: Ludovic Courtès @ 2020-04-03 9:51 UTC (permalink / raw) To: Konrad Hinsen; +Cc: 40373 Hello, Konrad Hinsen <konrad.hinsen@fastmail.net> skribis: > The other is that I am in tutorial-driven development mode: I need "guix > run-script" in order to be able to insert my own scripts (for analyzing > dependencies) into a Guix tutorial for an upcoming MOOC. So I need to > make sure that people can run my scripts easily, but also that they > understand what they are doing. A command that does something else than > its name suggests, with a similarity that is only visible to experts, > is no good for use in a tutorial. I see. (I have to ponder this a bit more.) > I am of course aware that much of the code in "run-script" is the same > as in "repl", which is not good. Yes, we can probably factorize a bit. We must make sure ‘-q’ is not implemented by this command; ‘-t’ is also useless. > But I'd rather think about a better framework for code sharing among > Guix scripts than about pushing too much semantic differences into > obscure options. An example would be reusable "option clusters", such > as "options for Guile" or "options for channels". We do have that with ‘%standard-build-options’, for instance, although not as nicely-structured as we’d like (in general, I’d prefer to have a GNU argp-style command-line API than what we have). Ludo’. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-03 9:51 ` [bug#40373] [PATCH] guix: new command "guix run-script" Ludovic Courtès @ 2020-04-07 9:10 ` Konrad Hinsen 2020-04-07 10:36 ` Ludovic Courtès 0 siblings, 1 reply; 23+ messages in thread From: Konrad Hinsen @ 2020-04-07 9:10 UTC (permalink / raw) To: Ludovic Courtès; +Cc: 40373 Hi Ludo, >> I am of course aware that much of the code in "run-script" is the same >> as in "repl", which is not good. > > Yes, we can probably factorize a bit. We must make sure ‘-q’ is not > implemented by this command; ‘-t’ is also useless. Right. > We do have that with ‘%standard-build-options’, for instance, although > not as nicely-structured as we’d like (in general, I’d prefer to have a > GNU argp-style command-line API than what we have). It would also be nice to share the documentation for these options among different scripts. That's actually more lines of code than the code itself. More generally, it would be nice to decouple implementation decisions from user interface decisions. Git provides a nice example of what happens when user interface design follows ease of implementation criteria for a while. It's probably the most hated essential piece of software by now. From a user interface point of view, it is preferable to have many commands with clear names, rather than few commands overloaded with multiple functions selected by cryptic options. Cheers, Konrad ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-07 9:10 ` Konrad Hinsen @ 2020-04-07 10:36 ` Ludovic Courtès 2020-04-17 11:21 ` zimoun 0 siblings, 1 reply; 23+ messages in thread From: Ludovic Courtès @ 2020-04-07 10:36 UTC (permalink / raw) To: Konrad Hinsen; +Cc: 40373 Hello, Konrad Hinsen <konrad.hinsen@fastmail.net> skribis: > From a user interface point of view, it is preferable to have many > commands with clear names, rather than few commands overloaded with > multiple functions selected by cryptic options. I agree overall, though it’s not black and white: the benefit of having separate commands weakens as they proliferate. A new command may be more difficult to discover than an option to an existing command. But anyway, let’s see how we can get ‘run-script’ in! :-) Thanks, Ludo’. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-07 10:36 ` Ludovic Courtès @ 2020-04-17 11:21 ` zimoun 2020-04-23 10:12 ` Konrad Hinsen 0 siblings, 1 reply; 23+ messages in thread From: zimoun @ 2020-04-17 11:21 UTC (permalink / raw) To: Ludovic Courtès; +Cc: Konrad Hinsen, 40373 Dear, Naming is hard. :-) Why not simply add an option to "guix repl"? For example "--batch", mimicking "emacs --batch". Or "--script". Or "guix repl <file>" just run the <file> as the proposed "guix run-script"? I do not have the feeling that adding a new subcommand is mandatory. But running a script using the Guix modules is really useful, I always complain to myself of this lacking feature. :-) Cheers, simon ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-17 11:21 ` zimoun @ 2020-04-23 10:12 ` Konrad Hinsen 2020-04-23 14:41 ` zimoun 0 siblings, 1 reply; 23+ messages in thread From: Konrad Hinsen @ 2020-04-23 10:12 UTC (permalink / raw) To: zimoun, Ludovic Courtès; +Cc: 40373 Hi Simon, > Why not simply add an option to "guix repl"? > For example "--batch", mimicking "emacs --batch". > Or "--script". Do you have a suggestion for explaining such a command to someone who want to run a script bu (1) doesn't know what a REPL is, (2) doesn't need to know what a REPL is, (3) would be mystified by the behavior resulting from forgetting the –script argument? I agree of course that naming is hard, but it is also important. Git should be a sufficient demonstration of what happens when you design command-line interfaces by a sequence of cumulative least-effort decisions. Cheers, Konrad ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-23 10:12 ` Konrad Hinsen @ 2020-04-23 14:41 ` zimoun 2020-04-29 16:04 ` Konrad Hinsen 0 siblings, 1 reply; 23+ messages in thread From: zimoun @ 2020-04-23 14:41 UTC (permalink / raw) To: Konrad Hinsen; +Cc: Ludovic Courtès, 40373 Hi Konrad, On Thu, 23 Apr 2020 at 12:13, Konrad Hinsen <konrad.hinsen@fastmail.net> wrote: > > Why not simply add an option to "guix repl"? > > For example "--batch", mimicking "emacs --batch". > > Or "--script". > > Do you have a suggestion for explaining such a command to someone who > want to run a script bu (1) doesn't know what a REPL is, (2) doesn't > need to know what a REPL is, (3) would be mystified by the behavior > resulting from forgetting the –script argument? If I understand well guix run-script file1 file2 is becoming: guix repl --script=file1,file2,... right? Well, I would say that --8<---------------cut here---------------start------------->8--- the keyword "repl" stand for Read-Eval-Print-Loop therefore the command will: - read the script file1, - eval it, - print the results if they are, - and finally loop if there is more than one script file. --8<---------------cut here---------------end--------------->8--- this fills the condition (1) and (2); at least to me. ;-) I agree that forgetting the argument '--script' could mystified the learner. But applying the same principles, the command guix environment --ad-hoc python -- python could mystified the learner too, if for example they forgets --ad-hoc or '-- python'. Well, this kind of disconcerting "mistakes" is part of the learning process, IMHO. Others call that "discoverability". ;-) > I agree of course that naming is hard, but it is also important. Git > should be a sufficient demonstration of what happens when you design > command-line interfaces by a sequence of cumulative least-effort > decisions. I agree. And I still have in my stack how to propose another CLI naming as we discussed earlier, e.g., environment, package, etc. reorganized into profile, install, search, etc. Cheers, sion ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-23 14:41 ` zimoun @ 2020-04-29 16:04 ` Konrad Hinsen 2020-04-30 12:42 ` zimoun 0 siblings, 1 reply; 23+ messages in thread From: Konrad Hinsen @ 2020-04-29 16:04 UTC (permalink / raw) To: zimoun; +Cc: Ludovic Courtès, 40373 Hi Simon, > If I understand well > guix run-script file1 file2 > is becoming: > guix repl --script=file1,file2,... > right? > > Well, I would say that > > --8<---------------cut here---------------start------------->8--- > the keyword "repl" stand for Read-Eval-Print-Loop > therefore the command will: > - read the script file1, > - eval it, > - print the results if they are, > - and finally loop if there is more than one script file. > --8<---------------cut here---------------end--------------->8--- That's very clever! The weak spot is the P, as script evaluation does not print anything. We could make it print the script's return code ;-) > But applying the same principles, the command > guix environment --ad-hoc python -- python > could mystified the learner too, if for example they forgets --ad-hoc > or '-- python'. Indeed. I never said that existing Guix commands are perfect ;-) In fact, I remember some debate about precisely the case of "guix environment". > And I still have in my stack how to propose another CLI naming as we > discussed earlier, e.g., > environment, package, etc. > reorganized into > profile, install, search, etc. The CLI as an eternal construction site ;-) Cheers, Konrad ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-29 16:04 ` Konrad Hinsen @ 2020-04-30 12:42 ` zimoun 2020-05-04 13:54 ` Konrad Hinsen 0 siblings, 1 reply; 23+ messages in thread From: zimoun @ 2020-04-30 12:42 UTC (permalink / raw) To: Konrad Hinsen; +Cc: Ludovic Courtès, 40373 Hi Konrad, On Wed, 29 Apr 2020 at 18:04, Konrad Hinsen <konrad.hinsen@fastmail.net> wrote: > That's very clever! The weak spot is the P, as script evaluation does > not print anything. We could make it print the script's return code ;-) Hum? The usual REPL neither. :-) Quoting Wikipedia: "print function takes the result yielded by eval" but from my understanding 'eval' does not always yield a "printable" result, e.g., "(define foo 42)". Cheers, simon ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-30 12:42 ` zimoun @ 2020-05-04 13:54 ` Konrad Hinsen 2020-05-04 17:48 ` zimoun 0 siblings, 1 reply; 23+ messages in thread From: Konrad Hinsen @ 2020-05-04 13:54 UTC (permalink / raw) To: zimoun; +Cc: Ludovic Courtès, 40373 Hi Simon, >> That's very clever! The weak spot is the P, as script evaluation does >> not print anything. We could make it print the script's return code ;-) > > Hum? The usual REPL neither. :-) You mean... they have been LYING to us all the time... about the REPL? > Quoting Wikipedia: "print function takes the result yielded by eval" > but from my understanding 'eval' does not always yield a "printable" > result, e.g., "(define foo 42)". True, not always. But for scripts it's never. We have to find some nice three-valued logic rhetoric that applies to all situations ;-) Command line: - read an expression, - eval it, - print the result of the evaluation (if any), - and finally loop to process the next expression Scripts: - read the script file1, - eval it, - print the textual output of the script (if any), - and finally loop if there is more than one script file. That makes "print" look optional in both cases. Cheers, Konrad. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-05-04 13:54 ` Konrad Hinsen @ 2020-05-04 17:48 ` zimoun 2020-05-14 9:29 ` Konrad Hinsen 0 siblings, 1 reply; 23+ messages in thread From: zimoun @ 2020-05-04 17:48 UTC (permalink / raw) To: Konrad Hinsen; +Cc: Ludovic Courtès, 40373 Hi Konrad, On Mon, 4 May 2020 at 15:55, Konrad Hinsen <konrad.hinsen@fastmail.net> wrote: > True, not always. But for scripts it's never. We have to find some nice > three-valued logic rhetoric that applies to all situations ;-) > > Command line: > - read an expression, > - eval it, > - print the result of the evaluation (if any), > - and finally loop to process the next expression > > Scripts: > - read the script file1, > - eval it, > - print the textual output of the script (if any), > - and finally loop if there is more than one script file. > > That makes "print" look optional in both cases. It is how I personally understand all that. :-) So that's why I proposed "guix repl --script" (in short '-s') ;-) In this frame of "guix repl", the future additions/evolution could be: --eval,-e for evaluating one expression just after the script is loaded --debug for starting the "debugging" VM engine (personally never used with Guile) --language for switching to WISP (optimistic evolution of GWL :-)) --use-srfi for loading SRFI modules So it ends up with this kind of command-line: guix repl -L /path/to/stuff --use-srfi=9 guix repl -L /path/to/custom -s file.scm guix repl --language=wisp --script file.wsp guix repl -s file.scm -e '(package-name foo)' Well, 'repl' meaning "use the interpreter in the context of Guix". Is 'repl' enough meaningful for these use cases? Personally, I think so. :-) All the best, simon ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-05-04 17:48 ` zimoun @ 2020-05-14 9:29 ` Konrad Hinsen 2020-05-14 9:44 ` bug#40373: " zimoun 0 siblings, 1 reply; 23+ messages in thread From: Konrad Hinsen @ 2020-05-14 9:29 UTC (permalink / raw) To: 40373 Hi everyone, Since this proposition does not seem to be going anywhere, I have submitted an alternative patch as bug#41253 which simply adds script execution to "guix repl", with no changes to the existing behavior, nor any new command. For my tutorial, I will use shell scripts that hide the guix command line from view, so that I do not have to explain it. This bug can thus be closed, and I'd have done it already if I knew how. I couldn't find any instructions. Cheers, Konrad. ^ permalink raw reply [flat|nested] 23+ messages in thread
* bug#40373: [PATCH] guix: new command "guix run-script" 2020-05-14 9:29 ` Konrad Hinsen @ 2020-05-14 9:44 ` zimoun 0 siblings, 0 replies; 23+ messages in thread From: zimoun @ 2020-05-14 9:44 UTC (permalink / raw) To: Konrad Hinsen; +Cc: 40373-done Hi Konrad, On Thu, 14 May 2020 at 11:30, Konrad Hinsen <konrad.hinsen@fastmail.net> wrote: > Since this proposition does not seem to be going anywhere, I have > submitted an alternative patch as bug#41253 which simply adds script > execution to "guix repl", with no changes to the existing behavior, nor > any new command. For my tutorial, I will use shell scripts that hide the > guix command line from view, so that I do not have to explain it. Cool! > This bug can thus be closed, and I'd have done it already if I knew > how. I couldn't find any instructions. Two ways: - answer to 40373-done@debbugs.gnu.org; as it is done here. - send to controls@debbugs.gnu.org with the body: close 30373 thanks https://debbugs.gnu.org/server-control.html Cheers, simon ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-01 14:09 [bug#40373] [PATCH] guix: new command "guix run-script" Konrad Hinsen 2020-04-01 21:00 ` Ludovic Courtès @ 2020-04-02 9:08 ` zimoun 2020-04-02 9:21 ` Konrad Hinsen 2020-04-02 9:25 ` Konrad Hinsen 1 sibling, 2 replies; 23+ messages in thread From: zimoun @ 2020-04-02 9:08 UTC (permalink / raw) To: Konrad Hinsen; +Cc: 40373 Hi Konrad, On Wed, 1 Apr 2020 at 16:10, Konrad Hinsen <konrad.hinsen@fastmail.net> wrote: > > * guix/scripts/run-script.scm: New file. > * Makefile.am: (MODULES): Add it. > * doc/guix.texi: Document "guix time-machine" Wrong copy/paste? Is it not "run-script" instead of "time-machine"? > --- /dev/null > +++ b/guix/scripts/run-script.scm > @@ -0,0 +1,106 @@ > +;;; GNU Guix --- Functional package management for GNU > +;;; Copyright © 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org> > +;;; Copyright © 2020 Konrad Hinsen <konrad.hinsen@fastmail.net> Why Copyright 2018, 2019 is the file is new? And why Ludo is mentioned here? Cheers, simon ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-02 9:08 ` [bug#40373] " zimoun @ 2020-04-02 9:21 ` Konrad Hinsen 2020-04-02 9:25 ` Konrad Hinsen 1 sibling, 0 replies; 23+ messages in thread From: Konrad Hinsen @ 2020-04-02 9:21 UTC (permalink / raw) To: zimoun; +Cc: 40373 Hi Simon, > Wrong copy/paste? Exactly. Same for the next point. Update coming. Cheers, Konrad. ^ permalink raw reply [flat|nested] 23+ messages in thread
* [bug#40373] [PATCH] guix: new command "guix run-script" 2020-04-02 9:08 ` [bug#40373] " zimoun 2020-04-02 9:21 ` Konrad Hinsen @ 2020-04-02 9:25 ` Konrad Hinsen 1 sibling, 0 replies; 23+ messages in thread From: Konrad Hinsen @ 2020-04-02 9:25 UTC (permalink / raw) To: 40373 * guix/scripts/run-script.scm: New file. * Makefile.am: (MODULES): Add it. * doc/guix.texi: Document "guix run-script" --- Makefile.am | 1 + doc/guix.texi | 32 +++++++++++ guix/scripts/run-script.scm | 105 ++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 guix/scripts/run-script.scm diff --git a/Makefile.am b/Makefile.am index 344ecdbc42..28ac7344e8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -283,6 +283,7 @@ MODULES = \ guix/scripts/container/exec.scm \ guix/scripts/deploy.scm \ guix/scripts/time-machine.scm \ + guix/scripts/run-script.scm \ guix.scm \ $(GNU_SYSTEM_MODULES) diff --git a/doc/guix.texi b/doc/guix.texi index 8cb85fe62c..0a64af24dc 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -235,6 +235,7 @@ Programming Interface * The Store Monad:: Purely functional interface to the store. * G-Expressions:: Manipulating build expressions. * Invoking guix repl:: Fiddling with Guix interactively. +* Invoking guix run-script:: Running Guix scripts. Defining Packages @@ -5347,6 +5348,7 @@ package definitions. * The Store Monad:: Purely functional interface to the store. * G-Expressions:: Manipulating build expressions. * Invoking guix repl:: Fiddling with Guix interactively. +* Invoking guix run-script:: Running Guix scripts. @end menu @node Package Modules @@ -8121,6 +8123,36 @@ Inhibit loading of the @file{~/.guile} file. By default, that configuration file is loaded when spawning a @code{guile} REPL. @end table +@node Invoking guix run-script +@section Invoking @command{guix run-script} + +@cindex script + +The @command{guix run-script} command executes a Guile script +(@pxref{Running Guile Scripts,,, guile, GNU Guile Reference Manual}). +Compared to just launching the @command{guile} command, +@command{guix run-script} guarantees that all the Guix modules +and all its dependencies are available in the search path. + +The general syntax is: + +@example +guix run-script @var{options} @var{file} +@end example + +The available options are as follows: + +@table @code +@item --load-path=@var{directory} +@itemx -L @var{directory} +Add @var{directory} to the front of the package module search path +(@pxref{Package Modules}). + +@item -q +Inhibit loading of the @file{~/.guile} file. By default, that +configuration file is loaded before executing the script. +@end table + @c ********************************************************************* @node Utilities @chapter Utilities diff --git a/guix/scripts/run-script.scm b/guix/scripts/run-script.scm new file mode 100644 index 0000000000..2e0ef2aff3 --- /dev/null +++ b/guix/scripts/run-script.scm @@ -0,0 +1,105 @@ +;;; GNU Guix --- Functional package management for GNU +;;; 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/>. + +(define-module (guix scripts run-script) + #:use-module (guix ui) + #:use-module (guix scripts) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-37) + #:use-module (ice-9 match) + #:export (guix-run-script)) + +;;; Commentary: +;;; +;;; This command allows to run Guile scripts in an environment +;;; that contains all the modules comprising Guix. + +(define %default-options + '()) + +(define %options + (list (option '(#\h "help") #f #f + (lambda args + (show-help) + (exit 0))) + (option '(#\V "version") #f #f + (lambda args + (show-version-and-exit "guix run-script"))) + (option '(#\q) #f #f + (lambda (opt name arg result) + (alist-cons 'ignore-dot-guile? #t result))) + (option '(#\L "load-path") #t #f + (lambda (opt name arg result) + ;; XXX: Imperatively modify the search paths. + (set! %load-path (cons arg %load-path)) + (set! %load-compiled-path (cons arg %load-compiled-path)) + result)))) + + +(define (show-help) + (display (G_ "Usage: guix run-script [OPTIONS...] FILE +Run FILE as a Guile script in the Guix execution environment.\n")) + (display (G_ " + -q inhibit loading of ~/.guile")) + (newline) + (display (G_ " + -L, --load-path=DIR prepend DIR to the package module search path")) + (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 user-module + ;; Module where we execute user code. + (let ((module (resolve-module '(guix-user) #f #f #:ensure #t))) + (beautify-user-module! module) + module)) + +\f +(define (guix-run-script . args) + (define opts + (args-fold* args %options + (lambda (opt name arg result) + (leave (G_ "~A: unrecognized option~%") name)) + (lambda (arg result) + (when (assq 'argument result) + (leave (G_ "~A: extraneous argument~%") arg)) + (alist-cons 'argument arg result)) + %default-options)) + + (define script + (or (assq-ref opts 'argument) + (leave (G_ "no script filename specified~%")))) + + (define user-config + (and=> (getenv "HOME") + (lambda (home) + (string-append home "/.guile")))) + + (with-error-handling + (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)) + (load script))))) -- 2.26.0 ^ permalink raw reply related [flat|nested] 23+ messages in thread
end of thread, other threads:[~2020-05-14 9:46 UTC | newest] Thread overview: 23+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-04-01 14:09 [bug#40373] [PATCH] guix: new command "guix run-script" Konrad Hinsen 2020-04-01 21:00 ` Ludovic Courtès 2020-04-02 7:13 ` Konrad Hinsen 2020-04-02 9:17 ` zimoun 2020-04-02 9:37 ` Konrad Hinsen 2020-04-03 9:17 ` Konrad Hinsen 2020-04-03 9:48 ` Ludovic Courtès 2020-04-03 9:19 ` [bug#40373] [PATCH] guix: new command "guix run" generalizes "guix repl" Konrad Hinsen 2020-04-03 9:51 ` [bug#40373] [PATCH] guix: new command "guix run-script" Ludovic Courtès 2020-04-07 9:10 ` Konrad Hinsen 2020-04-07 10:36 ` Ludovic Courtès 2020-04-17 11:21 ` zimoun 2020-04-23 10:12 ` Konrad Hinsen 2020-04-23 14:41 ` zimoun 2020-04-29 16:04 ` Konrad Hinsen 2020-04-30 12:42 ` zimoun 2020-05-04 13:54 ` Konrad Hinsen 2020-05-04 17:48 ` zimoun 2020-05-14 9:29 ` Konrad Hinsen 2020-05-14 9:44 ` bug#40373: " zimoun 2020-04-02 9:08 ` [bug#40373] " zimoun 2020-04-02 9:21 ` Konrad Hinsen 2020-04-02 9:25 ` Konrad Hinsen
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/guix.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).