(current-filename) is #f when guix pull'ing

  • Open
  • quality assurance status badge
Details
2 participants
  • Attila Lendvai
  • Ludovic Courtès
Owner
unassigned
Submitted by
Attila Lendvai
Severity
normal
A
A
Attila Lendvai wrote on 16 May 2022 23:04
(name . bug-guix@gnu.org)(address . bug-guix@gnu.org)
625DOHHScuzJjNNfdQOqaLqGWVTmXC-S9PcF2xU3nzsFYG4XYTSEt0NGXDSXnBqVHqYqr6AsEbTysg7y_fxoqeBkbEtCqMZrx9muo3DlvS0=@lendvai.name
the actual context where i'm encountering this is a package definition where i want to load some hashes from a file relative the to the .scm file:

(define-public foo
(let ((hashes
(with-input-from-file
(string-append (dirname (current-filename))
"/foo.hashes")
read)))
(package ...)))

this works fine in a `./pre-inst-env build foo`, but i think there's something special in how `guix pull` compiles the scm files, and (c-f) expands to #f. guix pull works, but afterwards:

$ guix system --on-error=backtrace reconfigure --allow-downgrades /etc/guix/config.scm
guix system: error: failed to load '/etc/guix/config.scm':
guix-crypto/packages/ethereum.scm:47:36: In procedure scm_to_utf8_stringn: Wrong type argument in position 1 (expecting string): #f

In ice-9/boot-9.scm:
222:29 19 (map1 (((gnu)) ((gnu system)) ((gnu system #)) ((# …)) …))
222:29 18 (map1 (((gnu system)) ((gnu system file-systems)) (#) …))
222:29 17 (map1 (((gnu system file-systems)) ((oop goops)) ((…)) …))
222:29 16 (map1 (((oop goops)) ((shepherd service)) ((nongnu …)) …))
222:29 15 (map1 (((shepherd service)) ((nongnu packages linux)) …))
222:29 14 (map1 (((nongnu packages linux)) ((guix-crypto # #)) # …))
222:17 13 (map1 (((guix-crypto packages ethereum)) ((# # #)) (#) …))
3936:31 12 (_ ((guix-crypto packages ethereum)))
3327:17 11 (resolve-interface (guix-crypto packages ethereum) # _ # …)
In ice-9/threads.scm:
390:8 10 (_ _)
In ice-9/boot-9.scm:
3253:13 9 (_)
In ice-9/threads.scm:
390:8 8 (_ _)
In ice-9/boot-9.scm:
3544:20 7 (_)
2836:4 6 (save-module-excursion #<procedure 7f056144d810 at ice-…>)
3564:26 5 (_)
In unknown file:
4 (primitive-load-path "guix-crypto/packages/ethereum" #<…>)
In guix-crypto/packages/ethereum.scm:
47:36 3 (_)
In unknown file:
2 (dirname #f)
In ice-9/boot-9.scm:
1685:16 1 (raise-exception _ #:continuable? _)
1780:13 0 (_ #<&compound-exception components: (#<&assertion-fail…>)

i would be happy to avoid using (c-f), but i failed to find a way in Guile's module reflection API.

--
• attila lendvai
• PGP: 963F 5D5F 45C7 DFCD 0A39
--
“People who have never gone to school have never developed negative attitudes toward exploring their world.”
— Grace Llewellyn
A
A
Attila Lendvai wrote on 17 May 2022 02:09
alternative way
(name . 55464@debbugs.gnu.org)(address . 55464@debbugs.gnu.org)
d88ruR0MIQx5-PtTF8RaHdg15TJ3ItvylaHxhkm4cAMZp_AhKjAZmtYFC6u-X0zaInJLgOcmor783ZQiNRwhzLTeBFU8VVEMMPcvv7n0zwE=@lendvai.name
as Ludovic kindly pointed out on IRC, i can use this instead:

(module-filename (current-module))

unfortunately, this returns a relative path, which is only useful using (search-path %load-path ...), which introduces some uncertainty about what actually gets loaded depending on the runtime value of %load-path... :|

therefore, i decided to read the file at macroexpand-time. after some struggle with hygienic macros:

(define-syntax read-module-relative-file
(lambda (syn)
(syntax-case syn ()
((_ filename)
(with-syntax
;; Read the file at compile time and macroexpand to the first form.
((form (%read-module-relative-file (current-module)
(syntax->datum #'filename))))
#''form)))))

(define (%read-module-relative-file module filename)
(with-input-from-file
(or (search-path %load-path
(string-append (dirname (module-filename module))
"/" filename))
(error "%read-module-relative-file failed for" filename))
read))

not beautiful, but works.

--
• attila lendvai
• PGP: 963F 5D5F 45C7 DFCD 0A39
--
“It is just as difficult and dangerous to try to free a people that wants to remain servile as it is to enslave a people that wants to remain free.”
— Niccolò Machiavelli (1469–1527)
L
L
Ludovic Courtès wrote on 18 May 2022 11:14
Re: bug#55464: (current-filename) is #f when guix pull'ing
(name . Attila Lendvai)(address . attila@lendvai.name)(address . 55464@debbugs.gnu.org)
87ee0r42ze.fsf@gnu.org
Hi,

Attila Lendvai <attila@lendvai.name> skribis:

Toggle quote (10 lines)
> the actual context where i'm encountering this is a package definition where i want to load some hashes from a file relative the to the .scm file:
>
> (define-public foo
> (let ((hashes
> (with-input-from-file
> (string-append (dirname (current-filename))
> "/foo.hashes")
> read)))
> (package ...)))

Not fully answering your question, but if “foo.hashes” contains hashes
for origins and similar, you could make “foo.hashes” contain something
like:

(list (base32 …) …)

and, in the .scm, write:

(include "foo.hashes")

The ‘include’ directive includes the file at macro-expansion time,
similar to #include in C.

Back to the original issue, I suppose ‘current-filename’ return #f when
this .scm is first loaded, before it’s compiled. Anyway, it’s probably
best to load it at macro-expansion time as you suggested.

HTH,
Ludo’.
A
A
Attila Lendvai wrote on 19 May 2022 15:32
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 55464@debbugs.gnu.org)
tBSTE5N8NWJIWIIr3W0VBG9aUjGdWsKFUTgSrjGbYVI91hTDrHGg0SQ3UyG606XDPo37sTYLIfRNbvt-HRU1tDbjHlc7C9KBABKlQeF8edM=@lendvai.name
Toggle quote (23 lines)
> > (define-public foo
> > (let ((hashes
> > (with-input-from-file
> > (string-append (dirname (current-filename))
> > "/foo.hashes")
> > read)))
> > (package ...)))
>
>
> Not fully answering your question, but if “foo.hashes” contains hashes
> for origins and similar, you could make “foo.hashes” contain something
> like:
>
> (list (base32 …) …)
>
> and, in the .scm, write:
>
> (include "foo.hashes")
>
> The ‘include’ directive includes the file at macro-expansion time,
> similar to #include in C.


i did find guile's INCLUDE and tried to use it, but it also didn't work when guix pull'ing it. see the attached, now abandoned commit.

IIRC the issue is that the implementation of INCLUDE tries to load the file relative to the cwd, but cwd is not changed by the code that is driving the compilation when guix pull'ing the code. (does each thread has its own cwd at all...?)

it works when i build it using `./pre-inst-env guix build foo`. i briefly tried to analyse what's the difference between the two situations, but i ran out of steam.

it is the same reason i need to call READ like below in my current implementation:

(define (%read-module-relative-file module filename)
(with-input-from-file
(or (search-path
%load-path
(string-append (dirname (module-filename module))
"/" filename))
(error "%read-module-relative-file failed for" filename))
read))


...which is not beautiful.


Toggle quote (5 lines)
> Back to the original issue, I suppose ‘current-filename’ return #f when
> this .scm is first loaded, before it’s compiled. Anyway, it’s probably
> best to load it at macro-expansion time as you suggested.


is my analysis is correct, namely that cwd is not (always?) changed at macroexpand time, and thus the implementation of INCLUDE is broken for relative paths? is this a bug to be fixed in guile? if so, shall i try to add a test case for this somewhere?

--
• attila lendvai
• PGP: 963F 5D5F 45C7 DFCD 0A39
--
“The saddest aspect of life right now is that science gathers knowledge faster than society gathers wisdom.”
— Isaac Asimov (1920–1992)
L
L
Ludovic Courtès wrote on 21 May 2022 18:39
(name . Attila Lendvai)(address . attila@lendvai.name)(address . 55464@debbugs.gnu.org)
87mtfau9g3.fsf@gnu.org
Hi,

Attila Lendvai <attila@lendvai.name> skribis:

Toggle quote (2 lines)
> is my analysis is correct, namely that cwd is not (always?) changed at macroexpand time, and thus the implementation of INCLUDE is broken for relative paths? is this a bug to be fixed in guile? if so, shall i try to add a test case for this somewhere?

‘include’ does all its work at macro-expansion time. It’s documented
like so (info "(guile) Local Inclusion"):

-- Scheme Syntax: include file-name
Open FILE-NAME, at expansion-time, and read the Scheme forms that
it contains, splicing them into the location of the ‘include’,
within a ‘begin’.

If FILE-NAME is a relative path, it is searched for relative to the
path that contains the file that the ‘include’ form appears in.

And I believe that’s what it does—see ‘psyntax.scm’ for the actual code.

Now, if source location info were to be missing, it wouldn’t be able to
work for relative file names because it wouldn’t know the name of the
source file that contains the ‘include’ form.

HTH!

Ludo’.
?