Subject: bug#22629: [PATCH v2 2/3] Add (guix describe) and use it to initialize '%package-search-path'.

From: [email-masked] (Ludovic Courtès)
Date: Fri, 31 Aug 2018 15:56:33 +0200

Hi Ricardo,

Ricardo Wurmus <[email-masked]> skribis:

>>  (define %package-module-path
>>    ;; Search path for package modules.  Each item must be either a directory
>>    ;; name or a pair whose car is a directory and whose cdr is a sub-directory
>>    ;; to narrow the search.
>>    (let* ((not-colon   (char-set-complement (char-set #\:)))
>>           (environment (string-tokenize (or (getenv "GUIX_PACKAGE_PATH") "")
>> -                                       not-colon)))
>> -    ;; Automatically add items from $GUIX_PACKAGE_PATH to Guile's search path.
>> -    (for-each (lambda (directory)
>> -                (set! %load-path (cons directory %load-path))
>> -                (set! %load-compiled-path
>> -                      (cons directory %load-compiled-path)))
>> -              environment)
>> +                                       not-colon))
>> +         (channels    (package-path-entries)))
>> +    ;; Automatically add channels and items from $GUIX_PACKAGE_PATH to Guile's
>> +    ;; search path.  For historical reasons, $GUIX_PACKAGE_PATH goes to the
>> +    ;; front; channels go to the back so that they don't override Guix' own
>> +    ;; modules.
>> +    (set! %load-path
>> +      (append environment %load-path channels))
>> +    (set! %load-compiled-path
>> +      (append environment %load-compiled-path channels))
>>
>>      (make-parameter
>> -     (append environment `((,%distro-root-directory . "gnu/packages"))))))
>> +     (append environment
>> +             %default-package-module-path
>> +             channels))))
>
> I’m not sure I understand the reason to add channels to the end of the
> search path.  Could it not be desirable in some use-cases to override
> certain Guix modules?  Should the order be made explicit in the channel
> to avoid having to accomodate “historical reasons” in the future? :)

For %load-path and %load-compiled-path, I thought it may be safer to
always keep Guix in front of the rest.  It means that channels cannot
override, say, (guix scripts package) or (guix derivations) or (gnu
packages base).  That’s mostly to be on the safe side, and because I
think this is not “the right way” to customize things; it’d be just too
brittle.

Regarding %package-module-path itself, whether channels come first or
not doesn’t actually make much of a difference at this point since
‘fold-packages’ traverses everything anyway.  Maybe in the future
‘fold-packages’ could make some distinction though.  Dunno.

>> diff --git a/guix/describe.scm b/guix/describe.scm
>> new file mode 100644
>> index 000000000..3122a762f
>> --- /dev/null
>> +++ b/guix/describe.scm
> […]
>> +(define current-profile
>> +  (mlambda ()
>> +    "Return the profile (created by 'guix pull') the calling process lives in,
>> +or #f if this is not applicable."
>> +    (match (command-line)
>> +      ((program . _)
>> +       (and (string-suffix? "/bin/guix" program)
>> +            ;; Note: We want to do _lexical dot-dot resolution_.  Using ".."
>> +            ;; for real would instead take us into the /gnu/store directory
>> +            ;; that ~/.config/guix/current/bin points to, whereas we want to
>> +            ;; obtain ~/.config/guix/current.
>> +            (let ((candidate (dirname (dirname program))))
>> +              (and (file-exists? (string-append candidate "/manifest"))
>> +                   candidate)))))))
>
> I don’t know… there’s something about this file system traversal that
> doesn’t sit right with me.  I’m not sure about (command-line) — when
> …/bin/guix is executed by a wrapper, will the wrapper be the “program”
> that we match against or the target?  (This is a concern for wrappers
> that set up site-wide default channels or a remote daemon, for example.)

The ‘guix’ command is a script starting with:

  #!/gnu/store/…-guile-2.2.4/bin/guile --no-auto-compile

‘guile’ receives the ‘guix’ file name as its argv[1].  Since the ‘guix’
file name was passed as the first argument to ‘execve’, it is
necessarily valid (either it’s relative to $PWD or, in the likely case
where ‘guix’ was searched for in $PATH, it’s an absolute file name.)

In addition (ice-9 command-line) arranges to make the first non-hyphen
argument the first element of what ‘command-line’ returns.

If you have a wrapper that execs ‘guix’ or whatever, it’ll still work.
Of course, the trick doesn’t work if you do things like:

  guile -L ~/.config/guix/current/share/guile/site/2.2

but I think that’s OK.

(I hadn’t realized the trick about execve’s first argument becoming a
valid file name in the interpreter’s argv[1].  Handy!)

Ludo’.