Subject: [bug#77201] [PATCH] guix: substitute-key-authorization: Fix case when acl symlink is broken

From: Rutherther <[email-masked]>
Date: Tue, 15 Apr 2025 20:26:19 +0200

Hi Ludo,

Ludovic Courtès <[email-masked]> writes:

> Hello,
>
> Ian Eure <[email-masked]> writes:
>
>>> -        (if (file-exists? acl-file)
>>> +        (if (or (file-exists? acl-file) (symbolic-link? acl-file))
>>
>> Guile semantics are unhelpful here: `file-exists?' returns #f for a
>> broken symlink, but `symbolic-link?' raises an exception if given a
>> nonexistent path.
>
> I would go back to the fundamentals:
>
>   (match (and=> (false-if-exception (lstat acl-file)) stat:type)
>     (#f ;file does not exist
>      …)
>     ('symlink
>      …)
>     (_
>      …))

This definitely helps, thanks, I am still not that skilled in Scheme, so
I wouldn't think about false-if-exception, and using match would also be
hard for me to figure out.

I have this now (untested for now)
```
(match (and=> (false-if-exception (lstat acl-file)) stat:type)
          (#f #f) ; File doesn't exist
          ('symlink ; Delete symlink pointing to store; backup otherwise.
           (if (or (store-file-name? (readlink acl-file)) ; Store symlink
                   (not (file-exists? acl-file))) ; Broken symlink
               (delete-file acl-file)
               (rename-file acl-file (string-append acl-file ".bak"))))
          (_ ; Backup
           (rename-file acl-file (string-append acl-file ".bak"))))
```
I will probably also make this into a reusable function in guix utils
build, but I have been thinking about a good name and couldn't come up with
one for a week! Programmers problems, I guess.

WDYT

Thanks,
Rutherther