Subject: bug#74584: wrong pull/time-machine message when channels.scm does not exit

From: Simon Tournier <[email-masked]>
Date: Thu, 28 Nov 2024 02:26:16 +0100

Hi,

The “bug“:

--8<---------------cut here---------------start------------->8---
$ ls channels.scm
ls: cannot access 'channels.scm': No such file or directory

$ guix time-machine -q -C channels.scm -- help
guix time-machine: error: 'channels.scm' did not return a list of channels
--8<---------------cut here---------------end--------------->8---

That’s incorrect.  What I expect is something as:

--8<---------------cut here---------------start------------->8---
$ ls foo.scm
ls: cannot access 'foo.scm': No such file or directory

$ guix time-machine -q -C foo.scm -- help
guix time-machine: error: failed to load 'foo.scm':
ice-9/boot-9.scm:2190:9: In procedure primitive-load-path: Unable to find file "guix/foo.scm" in load path
--8<---------------cut here---------------end--------------->8---

Although the second part can be confusing for regular user.  And
although I think the message is also incorrect.

Well, the story is about ’load*’ from module (guix ui).  Using this
trivial patch with some ’pk’.

diff --git a/guix/scripts/pull.scm b/guix/scripts/pull.scm
index 58d3cd7e83..d294df4f37 100644
--- a/guix/scripts/pull.scm
+++ b/guix/scripts/pull.scm
@@ -752,6 +752,7 @@ (define (channel-list opts)
 
   (define (load-channels file)
     (let ((result (load* file (make-user-module '((guix channels))))))
+      (pk 'load-channels result)
       (if (and (list? result) (every channel? result))
           result
           (leave (G_ "'~a' did not return a list of channels~%") file))))
diff --git a/guix/ui.scm b/guix/ui.scm
index eba12c8616..651cea4ff7 100644
--- a/guix/ui.scm
+++ b/guix/ui.scm
@@ -250,7 +250,11 @@ (define* (load* file user-module
                ;; 'primitive-load', so that FILE is compiled, which then allows
                ;; us to provide better error reporting with source line numbers.
                (without-compiler-optimizations
-                (load (try-canonicalize-path file))))
+                (begin
+                  (pk 'file file)
+                  (pk 'try-canonicalize-path (try-canonicalize-path file))
+                  (pk 'load-file (load file))
+                  (load (try-canonicalize-path file)))))
              (const #f))))))
     (lambda _
       ;; XXX: Errors are reported from the pre-unwind handler below, but
@@ -262,6 +266,7 @@ (define* (load* file user-module
          (let* ((stack (make-stack #t handle-error tag))
                 (frame (last-frame-with-source stack)))
 
+           (pk 'let-raise-error)
            (report-load-error file args frame)
 
            (case on-error

It reads:

--8<---------------cut here---------------start------------->8---
$ ./pre-inst-env guix time-machine -q -C channels.scm -- help

;;; (file "channels.scm")

;;; (try-canonicalize-path "channels.scm")

;;; (load-file #<unspecified>)

;;; (load-channels #<unspecified>)
guix time-machine: error: 'channels.scm' did not return a list of channels
--8<---------------cut here---------------end--------------->8---

In other words, instead of raising an error, it returns #<unspecified>
and thus because ’load-channels’ tests against ’list?’ which
#<unspecified> is obviously not then bang!

Bah the easy fix is to check with ’unspecified?’ directly in
’load-channels’.  But that does not really fix the issue, IMHO.

The issue is that because a file named channels.scm is around in
load-path.  For instance, let say the non-existent file is named
’packages.scm’:

--8<---------------cut here---------------start------------->8---
$ ls packages.scm
ls: cannot access 'packages.scm': No such file or directory

$ guix time-machine -q -C packages.scm -- help
guix time-machine: error: 'packages.scm' did not return a list of channels
--8<---------------cut here---------------end--------------->8---

In other words, is the comment accurate

               ;; Give 'load' an absolute file name so that it doesn't try to
               ;; search for FILE in %LOAD-PATH.

?

Well, since I am not sure to get the use case of
’try-canonicalize-path’, then I don’t know what could be the best fix.
But I guess ’canonicalize-path’ is not doing what we expect, right?

Cheers,
simon