* [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header
@ 2022-05-14 23:00 Fredrik Salomonsson
2022-05-14 23:05 ` [bug#55420] [PATCH 1/2] guix: emacs-utils: Add emacs-batch-script Fredrik Salomonsson
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Fredrik Salomonsson @ 2022-05-14 23:00 UTC (permalink / raw)
To: 55420; +Cc: Fredrik Salomonsson
When writing a guix.scm file for an emacs packages, I wanted a way to fetch
the version I specify in the header of the elisp file. I found that I could do
that with the lisp-mnt library in emacs. Unfortunately none of the emacs
utility functions in guix/build/emacs-utils.scm return the output of an
elisp expression.
With these two patches I aim to add that functionality.
I spilt it in two functions:
emacs-batch-script: Run an arbitrary elisp expression and return the output as
a string.
emacs-header-parse: Given a header section and a file it will return the value
of that section.
For example (emacs-header-parse "version" "path/to/an/elisp/package.el")
Reason for the spilt is that people might want to run other elisp snippets.
Fredrik Salomonsson (2):
guix: emacs-utils: Add emacs-batch-script.
guix: emacs-utils: Add emacs-header-parse.
guix/build/emacs-utils.scm | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
base-commit: 3935451f63c078cae9a928d87c6838ec3138abc0
--
2.36.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH 1/2] guix: emacs-utils: Add emacs-batch-script.
2022-05-14 23:00 [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header Fredrik Salomonsson
@ 2022-05-14 23:05 ` Fredrik Salomonsson
2022-05-14 23:05 ` [bug#55420] [PATCH 2/2] guix: emacs-utils: Add emacs-header-parse Fredrik Salomonsson
2022-06-01 20:38 ` Ludovic Courtès
2022-06-05 0:19 ` [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script Fredrik Salomonsson
2022-06-05 19:51 ` [bug#55420] [PATCH v3 " Fredrik Salomonsson
2 siblings, 2 replies; 15+ messages in thread
From: Fredrik Salomonsson @ 2022-05-14 23:05 UTC (permalink / raw)
To: 55420; +Cc: Fredrik Salomonsson
* guix/build/emacs-utils.scm (emacs-batch-script): New procedure.
---
guix/build/emacs-utils.scm | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/guix/build/emacs-utils.scm b/guix/build/emacs-utils.scm
index 60a754b9e9..8d40b9e139 100644
--- a/guix/build/emacs-utils.scm
+++ b/guix/build/emacs-utils.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2014 Alex Kost <alezost@gmail.com>
;;; Copyright © 2018, 2020, 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2019 Liliana Marie Prikler <liliana.prikler@gmail.com>
+;;; Copyright © 2022 Fredrik Salomonsson <plattfot@posteo.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -22,10 +23,13 @@
(define-module (guix build emacs-utils)
#:use-module (guix build utils)
#:use-module (ice-9 format)
+ #:use-module (ice-9 popen)
+ #:use-module (ice-9 rdelim)
#:export (%emacs
emacs-batch-eval
emacs-batch-edit-file
emacs-batch-disable-compilation
+ emacs-batch-script
emacs-generate-autoloads
emacs-byte-compile-directory
@@ -69,6 +73,15 @@ (define (emacs-batch-disable-compilation file)
(add-file-local-variable 'no-byte-compile t)
(basic-save-buffer))))
+(define (emacs-batch-script expr)
+ "Execute the Elisp code EXPR in Emacs batch mode and return output."
+ (call-with-port
+ (open-pipe*
+ OPEN_READ
+ (%emacs) "--quick" "--batch"
+ (string-append "--eval=" (expr->string expr)))
+ read-string))
+
(define (emacs-generate-autoloads name directory)
"Generate autoloads for Emacs package NAME placed in DIRECTORY."
(let* ((file (string-append directory "/" name "-autoloads.el"))
--
2.36.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH 2/2] guix: emacs-utils: Add emacs-header-parse.
2022-05-14 23:05 ` [bug#55420] [PATCH 1/2] guix: emacs-utils: Add emacs-batch-script Fredrik Salomonsson
@ 2022-05-14 23:05 ` Fredrik Salomonsson
2022-06-01 20:39 ` [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header Ludovic Courtès
2022-06-01 20:38 ` Ludovic Courtès
1 sibling, 1 reply; 15+ messages in thread
From: Fredrik Salomonsson @ 2022-05-14 23:05 UTC (permalink / raw)
To: 55420; +Cc: Fredrik Salomonsson
* guix/build/emacs-utils.scm (emacs-header-parse): New procedure.
---
guix/build/emacs-utils.scm | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/guix/build/emacs-utils.scm b/guix/build/emacs-utils.scm
index 8d40b9e139..76d9464806 100644
--- a/guix/build/emacs-utils.scm
+++ b/guix/build/emacs-utils.scm
@@ -32,6 +32,7 @@ (define-module (guix build emacs-utils)
emacs-batch-script
emacs-generate-autoloads
emacs-byte-compile-directory
+ emacs-header-parse
as-display
emacs-substitute-sexps
@@ -97,6 +98,14 @@ (define* (emacs-byte-compile-directory dir)
(byte-recompile-directory (file-name-as-directory ,dir) 0 1))))
(emacs-batch-eval expr)))
+(define (emacs-header-parse section file)
+ "Parse the header SECTION in FILE and return it as a string."
+ (emacs-batch-script
+ `(progn
+ (require 'lisp-mnt)
+ (find-file ,file)
+ (princ (lm-header ,section)))))
+
(define as-display ;syntactic keyword for 'emacs-substitute-sexps'
'(as display))
--
2.36.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header
2022-05-14 23:05 ` [bug#55420] [PATCH 1/2] guix: emacs-utils: Add emacs-batch-script Fredrik Salomonsson
2022-05-14 23:05 ` [bug#55420] [PATCH 2/2] guix: emacs-utils: Add emacs-header-parse Fredrik Salomonsson
@ 2022-06-01 20:38 ` Ludovic Courtès
2022-06-02 2:53 ` Fredrik Salomonsson
1 sibling, 1 reply; 15+ messages in thread
From: Ludovic Courtès @ 2022-06-01 20:38 UTC (permalink / raw)
To: Fredrik Salomonsson; +Cc: 55420
Hi Fredrik,
The patches LGTM modulo cosmetic issues:
Fredrik Salomonsson <plattfot@posteo.net> skribis:
> * guix/build/emacs-utils.scm (emacs-batch-script): New procedure.
[...]
> +(define (emacs-batch-script expr)
> + "Execute the Elisp code EXPR in Emacs batch mode and return output."
> + (call-with-port
> + (open-pipe*
> + OPEN_READ
> + (%emacs) "--quick" "--batch"
> + (string-append "--eval=" (expr->string expr)))
> + read-string))
I suggest something like:
(let* ((pipe (open-pipe* …))
(output (read-string pipe))
(status (close-pipe pipe)))
(unless (zero? status)
;; Use SRFI-34 + either a &message condition or (better)
;; a dedicate SRFI-35 condition type for the error.
(raise (condition …)))
output)
That way, execution failures would be caught and reported.
Ludo’.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header
2022-05-14 23:05 ` [bug#55420] [PATCH 2/2] guix: emacs-utils: Add emacs-header-parse Fredrik Salomonsson
@ 2022-06-01 20:39 ` Ludovic Courtès
0 siblings, 0 replies; 15+ messages in thread
From: Ludovic Courtès @ 2022-06-01 20:39 UTC (permalink / raw)
To: Fredrik Salomonsson; +Cc: 55420
Fredrik Salomonsson <plattfot@posteo.net> skribis:
> * guix/build/emacs-utils.scm (emacs-header-parse): New procedure.
LGTM!
Could you send a v2 of these patches?
Thanks in advance,
Ludo’.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header
2022-06-01 20:38 ` Ludovic Courtès
@ 2022-06-02 2:53 ` Fredrik Salomonsson
2022-06-02 13:44 ` Ludovic Courtès
0 siblings, 1 reply; 15+ messages in thread
From: Fredrik Salomonsson @ 2022-06-02 2:53 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: 55420
Hi Ludo,
Ludovic Courtès <ludo@gnu.org> writes:
> Hi Fredrik,
>
> The patches LGTM modulo cosmetic issues:
>
> Fredrik Salomonsson <plattfot@posteo.net> skribis:
>
>> * guix/build/emacs-utils.scm (emacs-batch-script): New procedure.
>
> [...]
>
>> +(define (emacs-batch-script expr)
>> + "Execute the Elisp code EXPR in Emacs batch mode and return output."
>> + (call-with-port
>> + (open-pipe*
>> + OPEN_READ
>> + (%emacs) "--quick" "--batch"
>> + (string-append "--eval=" (expr->string expr)))
>> + read-string))
>
> I suggest something like:
>
> (let* ((pipe (open-pipe* …))
> (output (read-string pipe))
> (status (close-pipe pipe)))
> (unless (zero? status)
> ;; Use SRFI-34 + either a &message condition or (better)
> ;; a dedicate SRFI-35 condition type for the error.
> (raise (condition …)))
> output)
>
> That way, execution failures would be caught and reported.
Thank you for the feedback. I update the procedure to use a dedicated
SRFI-35 condition type. But I cannot figure out how to capture the error
message from emacs, as I want the condition type to contain both the
expression as well as the error you get from emacs.
Here is what I have so far:
(define-condition-type &emacs-batch-error &error
emacs-batch-error?
(expression emacs-batch-error-expression)
(message emacs-batch-error-message))
(define (emacs-batch-script expr)
"Execute the Elisp code EXPR in Emacs batch mode and return output."
(let* ((error-pipe (open-output-string))
(pipe (with-error-to-port error-pipe
(lambda ()
(open-pipe*
OPEN_READ
(%emacs) "--quick" "--batch"
(string-append "--eval=" (expr->string expr))))))
(output (read-string pipe))
(error (get-output-string error-pipe))
(status (close-pipe pipe)))
(unless (zero? status)
(raise (condition (&emacs-batch-error
(expression expr)
(message error)))))
output))
Here is the output when I test it out in the guix repl:
--------------------------------------------------------------------------------
scheme@(guix-user)> (use-modules (guix build emacs-utils))
(use-modules (guix build emacs-utils))
scheme@(guix-user)> (emacs-batch-script '(prog (princ "hello")))
(emacs-batch-script '(prog (princ "hello")))
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
Wrong type (expecting exact integer): #<&emacs-batch-error expression: (prog (princ "hello")) message: "">
Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue.
scheme@(guix-user) [1]>
--------------------------------------------------------------------------------
Note the message is empty in #<&emacs-batch-error…>. It should contain:
Debugger entered--Lisp error: (void-function prog)
(prog (princ "hello"))
command-line-1(("--eval=(prog (princ \"hello\"))"))
command-line()
normal-top-level()
Any idea what I'm doing wrong?
Thanks
--
s/Fred[re]+i[ck]+/Fredrik/g
^ permalink raw reply [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header
2022-06-02 2:53 ` Fredrik Salomonsson
@ 2022-06-02 13:44 ` Ludovic Courtès
2022-06-05 0:42 ` Fredrik Salomonsson
0 siblings, 1 reply; 15+ messages in thread
From: Ludovic Courtès @ 2022-06-02 13:44 UTC (permalink / raw)
To: Fredrik Salomonsson; +Cc: 55420
Hi,
Fredrik Salomonsson <plattfot@posteo.net> skribis:
> Here is what I have so far:
>
> (define-condition-type &emacs-batch-error &error
> emacs-batch-error?
> (expression emacs-batch-error-expression)
> (message emacs-batch-error-message))
>
> (define (emacs-batch-script expr)
> "Execute the Elisp code EXPR in Emacs batch mode and return output."
> (let* ((error-pipe (open-output-string))
> (pipe (with-error-to-port error-pipe
> (lambda ()
> (open-pipe*
> OPEN_READ
> (%emacs) "--quick" "--batch"
> (string-append "--eval=" (expr->string expr))))))
> (output (read-string pipe))
> (error (get-output-string error-pipe))
> (status (close-pipe pipe)))
> (unless (zero? status)
> (raise (condition (&emacs-batch-error
> (expression expr)
> (message error)))))
> output))
Unfortunately ‘open-pipe*’ is not smart enough to redirect stderr to a
non-file port (a string port in this case).
One way around it would be to merge stdout and stderr, like so:
(parameterize ((current-error-port (current-output-port)))
(open-pipe* …))
but then you get both on the same stream, which could be a problem for
instance if Emacs emits warnings and such.
You could work around it by establishing a second pipe:
(match (pipe)
((stderr-input . stderr-output)
(parameterize ((current-error-port stderr-output))
(open-pipe* …))))
Here you should be able to read, in the parent process, from
‘stderr-input’.
Another option is to not try to capture stderr: after all, that’ll get
printed on the screen anyway.
HTH,
Ludo’.
^ permalink raw reply [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script.
2022-05-14 23:00 [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header Fredrik Salomonsson
2022-05-14 23:05 ` [bug#55420] [PATCH 1/2] guix: emacs-utils: Add emacs-batch-script Fredrik Salomonsson
@ 2022-06-05 0:19 ` Fredrik Salomonsson
2022-06-05 0:19 ` [bug#55420] [PATCH v2 2/2] guix: emacs-utils: Add emacs-header-parse Fredrik Salomonsson
2022-06-05 9:52 ` [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script Maxime Devos
2022-06-05 19:51 ` [bug#55420] [PATCH v3 " Fredrik Salomonsson
2 siblings, 2 replies; 15+ messages in thread
From: Fredrik Salomonsson @ 2022-06-05 0:19 UTC (permalink / raw)
To: 55420; +Cc: Fredrik Salomonsson
* guix/build/emacs-utils.scm (emacs-batch-script): New procedure.
* tests/build-emacs-utils.scm: New file.
* Makefile.am (TESTS): Add `tests/build-emacs-utils.scm'.
---
Makefile.am | 1 +
guix/build/emacs-utils.scm | 30 +++++++++++++++++++++++++++
tests/build-emacs-utils.scm | 41 +++++++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+)
create mode 100644 tests/build-emacs-utils.scm
diff --git a/Makefile.am b/Makefile.am
index e8d4b7ef8a..4a8514ea3a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -469,6 +469,7 @@ SCM_TESTS = \
tests/boot-parameters.scm \
tests/bournish.scm \
tests/builders.scm \
+ tests/build-emacs-utils.scm \
tests/build-utils.scm \
tests/cache.scm \
tests/challenge.scm \
diff --git a/guix/build/emacs-utils.scm b/guix/build/emacs-utils.scm
index 60a754b9e9..1684bf3262 100644
--- a/guix/build/emacs-utils.scm
+++ b/guix/build/emacs-utils.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2014 Alex Kost <alezost@gmail.com>
;;; Copyright © 2018, 2020, 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2019 Liliana Marie Prikler <liliana.prikler@gmail.com>
+;;; Copyright © 2022 Fredrik Salomonsson <plattfot@posteo.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -22,10 +23,19 @@
(define-module (guix build emacs-utils)
#:use-module (guix build utils)
#:use-module (ice-9 format)
+ #:use-module (ice-9 popen)
+ #:use-module (ice-9 rdelim)
+ #:use-module (srfi srfi-34)
+ #:use-module (srfi srfi-35)
#:export (%emacs
emacs-batch-eval
emacs-batch-edit-file
emacs-batch-disable-compilation
+ emacs-batch-script
+
+ emacs-batch-error?
+ emacs-batch-error-message
+
emacs-generate-autoloads
emacs-byte-compile-directory
@@ -69,6 +79,26 @@ (define (emacs-batch-disable-compilation file)
(add-file-local-variable 'no-byte-compile t)
(basic-save-buffer))))
+(define-condition-type &emacs-batch-error &error
+ emacs-batch-error?
+ (message emacs-batch-error-message))
+
+(define (emacs-batch-script expr)
+ "Execute the Elisp code EXPR in Emacs batch mode and return output."
+ (let* ((error-pipe (pipe))
+ (port (parameterize ((current-error-port (cdr error-pipe)))
+ (open-pipe*
+ OPEN_READ
+ (%emacs) "--quick" "--batch"
+ (string-append "--eval=" (expr->string expr)))))
+ (output (read-string port))
+ (status (close-pipe port)))
+ (close-port (cdr error-pipe))
+ (unless (zero? status)
+ (raise (condition (&emacs-batch-error
+ (message (read-string (car error-pipe)))))))
+ output))
+
(define (emacs-generate-autoloads name directory)
"Generate autoloads for Emacs package NAME placed in DIRECTORY."
(let* ((file (string-append directory "/" name "-autoloads.el"))
diff --git a/tests/build-emacs-utils.scm b/tests/build-emacs-utils.scm
new file mode 100644
index 0000000000..03b73b1fed
--- /dev/null
+++ b/tests/build-emacs-utils.scm
@@ -0,0 +1,41 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2022 Fredrik Salomonsson <plattfot@posteo.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 (test build-emacs-utils)
+ #:use-module (guix tests)
+ #:use-module (guix build emacs-utils)
+ #:use-module (guix build utils)
+ #:use-module ((guix utils)
+ #:select (call-with-temporary-directory))
+ #:use-module (srfi srfi-34)
+ #:use-module (srfi srfi-64))
+
+(test-begin "build-emacs-utils")
+
+(test-equal "print foo from emacs"
+ "foo"
+ (emacs-batch-script '(princ "foo")))
+
+(test-assert "emacs-batch-script: raise &emacs-batch-error on failure"
+ (guard (c ((emacs-batch-error? c)
+ (string-contains (emacs-batch-error-message c)
+ "Lisp error: (wrong-type-argument numberp \"three\")")))
+ (emacs-batch-script '(mapcar 'number-to-string (list 1 2 "three")))))
+
+(test-end "build-emacs-utils")
base-commit: 271736117e3f09b616a2dbd5d74c9595926c9297
--
2.36.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH v2 2/2] guix: emacs-utils: Add emacs-header-parse.
2022-06-05 0:19 ` [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script Fredrik Salomonsson
@ 2022-06-05 0:19 ` Fredrik Salomonsson
2022-06-05 9:52 ` [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script Maxime Devos
1 sibling, 0 replies; 15+ messages in thread
From: Fredrik Salomonsson @ 2022-06-05 0:19 UTC (permalink / raw)
To: 55420; +Cc: Fredrik Salomonsson
* guix/build/emacs-utils.scm (emacs-header-parse): New procedure.
* tests/build-emacs-utils.scm ("emacs-header-parse: fetch version",
"emacs-header-parse: fetch keywords", "emacs-header-parse: fetch
nonexistent author"): New tests.
---
guix/build/emacs-utils.scm | 9 +++++++++
tests/build-emacs-utils.scm | 30 ++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/guix/build/emacs-utils.scm b/guix/build/emacs-utils.scm
index 1684bf3262..8ee547f2b3 100644
--- a/guix/build/emacs-utils.scm
+++ b/guix/build/emacs-utils.scm
@@ -38,6 +38,7 @@ (define-module (guix build emacs-utils)
emacs-generate-autoloads
emacs-byte-compile-directory
+ emacs-header-parse
as-display
emacs-substitute-sexps
@@ -114,6 +115,14 @@ (define* (emacs-byte-compile-directory dir)
(byte-recompile-directory (file-name-as-directory ,dir) 0 1))))
(emacs-batch-eval expr)))
+(define (emacs-header-parse section file)
+ "Parse the header SECTION in FILE and return it as a string."
+ (emacs-batch-script
+ `(progn
+ (require 'lisp-mnt)
+ (find-file ,file)
+ (princ (lm-header ,section)))))
+
(define as-display ;syntactic keyword for 'emacs-substitute-sexps'
'(as display))
diff --git a/tests/build-emacs-utils.scm b/tests/build-emacs-utils.scm
index 03b73b1fed..57647caaa2 100644
--- a/tests/build-emacs-utils.scm
+++ b/tests/build-emacs-utils.scm
@@ -38,4 +38,34 @@ (define-module (test build-emacs-utils)
"Lisp error: (wrong-type-argument numberp \"three\")")))
(emacs-batch-script '(mapcar 'number-to-string (list 1 2 "three")))))
+(define (test-emacs-header-parse section)
+ (call-with-temporary-directory
+ (lambda (directory)
+ (let ((mock-elisp-file (string-append directory "/foo.el")))
+ (call-with-output-file mock-elisp-file
+ (lambda (port)
+ (display ";;; foo --- mock emacs package -*- lexical-binding: t -*-
+
+;; Created: 4 Jun 2022
+;; Keywords: lisp test
+;; Version: 1.0.0
+;;; Commentary:
+;;; Code:
+;;; foo.el ends here
+"
+ port)))
+ (emacs-header-parse section mock-elisp-file)))))
+
+(test-equal "emacs-header-parse: fetch version"
+ "1.0.0"
+ (test-emacs-header-parse "version"))
+
+(test-equal "emacs-header-parse: fetch keywords"
+ "lisp test"
+ (test-emacs-header-parse "keywords"))
+
+(test-equal "emacs-header-parse: fetch nonexistent author"
+ "nil"
+ (test-emacs-header-parse "author"))
+
(test-end "build-emacs-utils")
--
2.36.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header
2022-06-02 13:44 ` Ludovic Courtès
@ 2022-06-05 0:42 ` Fredrik Salomonsson
0 siblings, 0 replies; 15+ messages in thread
From: Fredrik Salomonsson @ 2022-06-05 0:42 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: 55420
Hi Ludo,
Ludovic Courtès <ludo@gnu.org> writes:
> Hi,
>
> Fredrik Salomonsson <plattfot@posteo.net> skribis:
>
>> Here is what I have so far:
>>
>> (define-condition-type &emacs-batch-error &error
>> emacs-batch-error?
>> (expression emacs-batch-error-expression)
>> (message emacs-batch-error-message))
>>
>> (define (emacs-batch-script expr)
>> "Execute the Elisp code EXPR in Emacs batch mode and return output."
>> (let* ((error-pipe (open-output-string))
>> (pipe (with-error-to-port error-pipe
>> (lambda ()
>> (open-pipe*
>> OPEN_READ
>> (%emacs) "--quick" "--batch"
>> (string-append "--eval=" (expr->string expr))))))
>> (output (read-string pipe))
>> (error (get-output-string error-pipe))
>> (status (close-pipe pipe)))
>> (unless (zero? status)
>> (raise (condition (&emacs-batch-error
>> (expression expr)
>> (message error)))))
>> output))
>
> Unfortunately ‘open-pipe*’ is not smart enough to redirect stderr to a
> non-file port (a string port in this case).
>
> One way around it would be to merge stdout and stderr, like so:
>
> (parameterize ((current-error-port (current-output-port)))
> (open-pipe* …))
>
> but then you get both on the same stream, which could be a problem for
> instance if Emacs emits warnings and such.
>
> You could work around it by establishing a second pipe:
>
> (match (pipe)
> ((stderr-input . stderr-output)
> (parameterize ((current-error-port stderr-output))
> (open-pipe* …))))
>
> Here you should be able to read, in the parent process, from
> ‘stderr-input’.
>
> Another option is to not try to capture stderr: after all, that’ll get
> printed on the screen anyway.
I just sent in v2 of the patches. Changes are:
- emacs-batch-script will now raise an &emacs-batch-error if emacs batch
script fails. I opted to capture the stderr and package that up in the
condition. Thank you for the pointers! I removed the expression slot I
had in my prototype. It felt redundant, emacs error message should be
enough.
- tests/build-emacs-utils.scm: I added tests for the two new procedures.
It was good that I added the tests as I had missed to use (srfi srfi-34)
in build/emacs-utils.scm during my prototyping and that generated the
cryptic error:
Wrong type (expecting exact integer): #<&emacs-batch-error…>
Took me a while to figure that one out. But now all is good. The tests
are passing.
Thanks again.
--
s/Fred[re]+i[ck]+/Fredrik/g
^ permalink raw reply [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script.
2022-06-05 0:19 ` [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script Fredrik Salomonsson
2022-06-05 0:19 ` [bug#55420] [PATCH v2 2/2] guix: emacs-utils: Add emacs-header-parse Fredrik Salomonsson
@ 2022-06-05 9:52 ` Maxime Devos
2022-06-05 20:02 ` Fredrik Salomonsson
1 sibling, 1 reply; 15+ messages in thread
From: Maxime Devos @ 2022-06-05 9:52 UTC (permalink / raw)
To: Fredrik Salomonsson, 55420
[-- Attachment #1: Type: text/plain, Size: 398 bytes --]
Fredrik Salomonsson schreef op zo 05-06-2022 om 00:19 [+0000]:
> +(test-equal "print foo from emacs"
> + "foo"
> + (emacs-batch-script '(princ "foo")))
IIUC, this can only be run if emacs is in $PATH when running the tests,
so sometimes the test needs to be skipped. As an example on how to do
this, see the "pypi->guix-package, wheels" test in tests/pypi.scm.
Greetings,
Maxime.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 260 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH v3 1/2] guix: emacs-utils: Add emacs-batch-script.
2022-05-14 23:00 [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header Fredrik Salomonsson
2022-05-14 23:05 ` [bug#55420] [PATCH 1/2] guix: emacs-utils: Add emacs-batch-script Fredrik Salomonsson
2022-06-05 0:19 ` [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script Fredrik Salomonsson
@ 2022-06-05 19:51 ` Fredrik Salomonsson
2022-06-05 19:51 ` [bug#55420] [PATCH v3 2/2] guix: emacs-utils: Add emacs-header-parse Fredrik Salomonsson
2022-06-17 20:29 ` bug#55420: [PATCH 0/2] Add a function to parse emacs elisp's package header Ludovic Courtès
2 siblings, 2 replies; 15+ messages in thread
From: Fredrik Salomonsson @ 2022-06-05 19:51 UTC (permalink / raw)
To: 55420; +Cc: Fredrik Salomonsson
* guix/build/emacs-utils.scm (emacs-batch-script): New procedure.
* tests/build-emacs-utils.scm: New file.
* Makefile.am (TESTS): Add `tests/build-emacs-utils.scm'.
---
Makefile.am | 1 +
guix/build/emacs-utils.scm | 30 ++++++++++++++++++++++++++
tests/build-emacs-utils.scm | 43 +++++++++++++++++++++++++++++++++++++
3 files changed, 74 insertions(+)
create mode 100644 tests/build-emacs-utils.scm
diff --git a/Makefile.am b/Makefile.am
index e8d4b7ef8a..4a8514ea3a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -469,6 +469,7 @@ SCM_TESTS = \
tests/boot-parameters.scm \
tests/bournish.scm \
tests/builders.scm \
+ tests/build-emacs-utils.scm \
tests/build-utils.scm \
tests/cache.scm \
tests/challenge.scm \
diff --git a/guix/build/emacs-utils.scm b/guix/build/emacs-utils.scm
index 60a754b9e9..1684bf3262 100644
--- a/guix/build/emacs-utils.scm
+++ b/guix/build/emacs-utils.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2014 Alex Kost <alezost@gmail.com>
;;; Copyright © 2018, 2020, 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2019 Liliana Marie Prikler <liliana.prikler@gmail.com>
+;;; Copyright © 2022 Fredrik Salomonsson <plattfot@posteo.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -22,10 +23,19 @@
(define-module (guix build emacs-utils)
#:use-module (guix build utils)
#:use-module (ice-9 format)
+ #:use-module (ice-9 popen)
+ #:use-module (ice-9 rdelim)
+ #:use-module (srfi srfi-34)
+ #:use-module (srfi srfi-35)
#:export (%emacs
emacs-batch-eval
emacs-batch-edit-file
emacs-batch-disable-compilation
+ emacs-batch-script
+
+ emacs-batch-error?
+ emacs-batch-error-message
+
emacs-generate-autoloads
emacs-byte-compile-directory
@@ -69,6 +79,26 @@ (define (emacs-batch-disable-compilation file)
(add-file-local-variable 'no-byte-compile t)
(basic-save-buffer))))
+(define-condition-type &emacs-batch-error &error
+ emacs-batch-error?
+ (message emacs-batch-error-message))
+
+(define (emacs-batch-script expr)
+ "Execute the Elisp code EXPR in Emacs batch mode and return output."
+ (let* ((error-pipe (pipe))
+ (port (parameterize ((current-error-port (cdr error-pipe)))
+ (open-pipe*
+ OPEN_READ
+ (%emacs) "--quick" "--batch"
+ (string-append "--eval=" (expr->string expr)))))
+ (output (read-string port))
+ (status (close-pipe port)))
+ (close-port (cdr error-pipe))
+ (unless (zero? status)
+ (raise (condition (&emacs-batch-error
+ (message (read-string (car error-pipe)))))))
+ output))
+
(define (emacs-generate-autoloads name directory)
"Generate autoloads for Emacs package NAME placed in DIRECTORY."
(let* ((file (string-append directory "/" name "-autoloads.el"))
diff --git a/tests/build-emacs-utils.scm b/tests/build-emacs-utils.scm
new file mode 100644
index 0000000000..27cff46c38
--- /dev/null
+++ b/tests/build-emacs-utils.scm
@@ -0,0 +1,43 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2022 Fredrik Salomonsson <plattfot@posteo.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 (test build-emacs-utils)
+ #:use-module (guix tests)
+ #:use-module (guix build emacs-utils)
+ #:use-module (guix build utils)
+ #:use-module ((guix utils)
+ #:select (call-with-temporary-directory))
+ #:use-module (srfi srfi-34)
+ #:use-module (srfi srfi-64))
+
+(test-begin "build-emacs-utils")
+;; Only run the following tests if emacs is present.
+(test-skip (if (which "emacs") 0 2))
+
+(test-equal "emacs-batch-script: print foo from emacs"
+ "foo"
+ (emacs-batch-script '(princ "foo")))
+
+(test-assert "emacs-batch-script: raise &emacs-batch-error on failure"
+ (guard (c ((emacs-batch-error? c)
+ (string-contains (emacs-batch-error-message c)
+ "Lisp error: (wrong-type-argument numberp \"three\")")))
+ (emacs-batch-script '(mapcar 'number-to-string (list 1 2 "three")))))
+
+(test-end "build-emacs-utils")
base-commit: 271736117e3f09b616a2dbd5d74c9595926c9297
--
2.36.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH v3 2/2] guix: emacs-utils: Add emacs-header-parse.
2022-06-05 19:51 ` [bug#55420] [PATCH v3 " Fredrik Salomonsson
@ 2022-06-05 19:51 ` Fredrik Salomonsson
2022-06-17 20:29 ` bug#55420: [PATCH 0/2] Add a function to parse emacs elisp's package header Ludovic Courtès
1 sibling, 0 replies; 15+ messages in thread
From: Fredrik Salomonsson @ 2022-06-05 19:51 UTC (permalink / raw)
To: 55420; +Cc: Fredrik Salomonsson
* guix/build/emacs-utils.scm (emacs-header-parse): New procedure.
* tests/build-emacs-utils.scm ("emacs-header-parse: fetch version",
"emacs-header-parse: fetch keywords", "emacs-header-parse: fetch
nonexistent author"): New tests.
---
guix/build/emacs-utils.scm | 9 +++++++++
tests/build-emacs-utils.scm | 27 ++++++++++++++++++++++++++-
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/guix/build/emacs-utils.scm b/guix/build/emacs-utils.scm
index 1684bf3262..8ee547f2b3 100644
--- a/guix/build/emacs-utils.scm
+++ b/guix/build/emacs-utils.scm
@@ -38,6 +38,7 @@ (define-module (guix build emacs-utils)
emacs-generate-autoloads
emacs-byte-compile-directory
+ emacs-header-parse
as-display
emacs-substitute-sexps
@@ -114,6 +115,14 @@ (define* (emacs-byte-compile-directory dir)
(byte-recompile-directory (file-name-as-directory ,dir) 0 1))))
(emacs-batch-eval expr)))
+(define (emacs-header-parse section file)
+ "Parse the header SECTION in FILE and return it as a string."
+ (emacs-batch-script
+ `(progn
+ (require 'lisp-mnt)
+ (find-file ,file)
+ (princ (lm-header ,section)))))
+
(define as-display ;syntactic keyword for 'emacs-substitute-sexps'
'(as display))
diff --git a/tests/build-emacs-utils.scm b/tests/build-emacs-utils.scm
index 27cff46c38..081032285a 100644
--- a/tests/build-emacs-utils.scm
+++ b/tests/build-emacs-utils.scm
@@ -28,7 +28,7 @@ (define-module (test build-emacs-utils)
(test-begin "build-emacs-utils")
;; Only run the following tests if emacs is present.
-(test-skip (if (which "emacs") 0 2))
+(test-skip (if (which "emacs") 0 5))
(test-equal "emacs-batch-script: print foo from emacs"
"foo"
@@ -40,4 +40,29 @@ (define-module (test build-emacs-utils)
"Lisp error: (wrong-type-argument numberp \"three\")")))
(emacs-batch-script '(mapcar 'number-to-string (list 1 2 "three")))))
+(call-with-temporary-directory
+ (lambda (directory)
+ (let ((mock-elisp-file (string-append directory "/foo.el")))
+ (call-with-output-file mock-elisp-file
+ (lambda (port)
+ (display ";;; foo --- mock emacs package -*- lexical-binding: t -*-
+
+;; Created: 4 Jun 2022
+;; Keywords: lisp test
+;; Version: 1.0.0
+;;; Commentary:
+;;; Code:
+;;; foo.el ends here
+"
+ port)))
+ (test-equal "emacs-header-parse: fetch version"
+ "1.0.0"
+ (emacs-header-parse "version" mock-elisp-file))
+ (test-equal "emacs-header-parse: fetch keywords"
+ "lisp test"
+ (emacs-header-parse "keywords" mock-elisp-file))
+ (test-equal "emacs-header-parse: fetch nonexistent author"
+ "nil"
+ (emacs-header-parse "author" mock-elisp-file)))))
+
(test-end "build-emacs-utils")
--
2.36.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script.
2022-06-05 9:52 ` [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script Maxime Devos
@ 2022-06-05 20:02 ` Fredrik Salomonsson
0 siblings, 0 replies; 15+ messages in thread
From: Fredrik Salomonsson @ 2022-06-05 20:02 UTC (permalink / raw)
To: Maxime Devos, 55420
Hi Maxime,
Maxime Devos <maximedevos@telenet.be> writes:
> Fredrik Salomonsson schreef op zo 05-06-2022 om 00:19 [+0000]:
>> +(test-equal "print foo from emacs"
>> + "foo"
>> + (emacs-batch-script '(princ "foo")))
>
> IIUC, this can only be run if emacs is in $PATH when running the tests,
> so sometimes the test needs to be skipped. As an example on how to do
> this, see the "pypi->guix-package, wheels" test in tests/pypi.scm.
Yes, you are correct. All my tests started to fail when I added `--pure`
to my test command.
I just sent in a v3 of the patches when I skip the tests if emacs is not
in the PATH.
I also changed the tests for the `emacs-header-parse` to be wrapped by
`call-with-temporary-directory`. It felt wasteful to create and destroy that
file for each test when the file is static.
I opted to just have one test-skip and skip all five of them. Although
that migth be too fragile. Would be great to have something like:
(unless (which "emacs")
(test-skip "emacs-batch-script:")
(test-skip "emacs-header-parse:"))
But the docs just mention a counter or the full name of a test.
--
s/Fred[re]+i[ck]+/Fredrik/g
^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#55420: [PATCH 0/2] Add a function to parse emacs elisp's package header
2022-06-05 19:51 ` [bug#55420] [PATCH v3 " Fredrik Salomonsson
2022-06-05 19:51 ` [bug#55420] [PATCH v3 2/2] guix: emacs-utils: Add emacs-header-parse Fredrik Salomonsson
@ 2022-06-17 20:29 ` Ludovic Courtès
1 sibling, 0 replies; 15+ messages in thread
From: Ludovic Courtès @ 2022-06-17 20:29 UTC (permalink / raw)
To: Fredrik Salomonsson; +Cc: 55420-done
Hi Fredrik,
Fredrik Salomonsson <plattfot@posteo.net> skribis:
> * guix/build/emacs-utils.scm (emacs-batch-script): New procedure.
>
> * tests/build-emacs-utils.scm: New file.
>
> * Makefile.am (TESTS): Add `tests/build-emacs-utils.scm'.
[...]
> * guix/build/emacs-utils.scm (emacs-header-parse): New procedure.
>
> * tests/build-emacs-utils.scm ("emacs-header-parse: fetch version",
> "emacs-header-parse: fetch keywords", "emacs-header-parse: fetch
> nonexistent author"): New tests.
Thanks, applied. Apologies for the delay!
Ludo’.
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2022-06-17 20:30 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-05-14 23:00 [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header Fredrik Salomonsson
2022-05-14 23:05 ` [bug#55420] [PATCH 1/2] guix: emacs-utils: Add emacs-batch-script Fredrik Salomonsson
2022-05-14 23:05 ` [bug#55420] [PATCH 2/2] guix: emacs-utils: Add emacs-header-parse Fredrik Salomonsson
2022-06-01 20:39 ` [bug#55420] [PATCH 0/2] Add a function to parse emacs elisp's package header Ludovic Courtès
2022-06-01 20:38 ` Ludovic Courtès
2022-06-02 2:53 ` Fredrik Salomonsson
2022-06-02 13:44 ` Ludovic Courtès
2022-06-05 0:42 ` Fredrik Salomonsson
2022-06-05 0:19 ` [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script Fredrik Salomonsson
2022-06-05 0:19 ` [bug#55420] [PATCH v2 2/2] guix: emacs-utils: Add emacs-header-parse Fredrik Salomonsson
2022-06-05 9:52 ` [bug#55420] [PATCH v2 1/2] guix: emacs-utils: Add emacs-batch-script Maxime Devos
2022-06-05 20:02 ` Fredrik Salomonsson
2022-06-05 19:51 ` [bug#55420] [PATCH v3 " Fredrik Salomonsson
2022-06-05 19:51 ` [bug#55420] [PATCH v3 2/2] guix: emacs-utils: Add emacs-header-parse Fredrik Salomonsson
2022-06-17 20:29 ` bug#55420: [PATCH 0/2] Add a function to parse emacs elisp's package header Ludovic Courtès
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.