Subject: [bug#60521] [PATCH] home: Add home-stow-migration-service.

From: Ludovic Courtès <[email-masked]>
Date: Mon, 24 Apr 2023 22:33:57 +0200

Hi Giacomo,

Giacomo Leidi <[email-masked]> skribis:

> * gnu/home/services.scm (dotfiles-for-app): New variable;
> (home-dotfiles-configuration): new variable;
> (home-dotfiles-service-type): new variable.
> * doc/guix.texi: Document it.

Apologies for the loong delay.

> +The @code{home-dotfiles-service-type} is designed to ease the way into using
> +Guix Home for this kind of users, allowing them to point the service to their
> +dotfiles directory (which must follow
> +@uref{https://www.gnu.org/software/stow/, GNU Stow}'s layout) and have their

Rather, for proper rendering:

  dotfiles directory, which must follow the layout prescribed by
  @uref{https://…, GNU Stow}, and have their …

> +For a more formal specification please refer to the
> +@pxref{Top,,, stow, GNU Stow Manual}.

Rather: please refer to the Stow manual (@pxref{…}).

Maybe a node other than “Top” would be advisable?  I can’t see where
that formal spec might be at
<https://www.gnu.org/software/stow/manual/html_node/>.

> +@lisp
> +  (simple-service 'home-dotfiles
> +                  home-dotfiles-service-type
> +                  (list (string-append (getcwd)
> +                                       "/.dotfiles")))

Replace (getcwd) by (current-source-directory), though hmm that’s part
of (guix utils).

(Using (getcwd) is wrong because it gives the current directory of the
‘guix’ command that evaluates this code, not the directory the file
lives in.)

> +(define (dotfiles-for-app directory)
> +  "Return a list of objects compatible with @code{home-files-service-type}'s
> +value.  Each object is a pair where the first element is the relative path
> +of a file and the second is a gexp representing the file content.  Objects are
> +generated by recursively visiting DIRECTORY and mapping its contents to the
> +user's home directory."
> +  (map (lambda (file)
> +         (let ((file-relative-path
> +                (string-drop file (1+ (string-length directory)))))
> +           (list file-relative-path
> +                 (local-file file
> +                             (string-append "home-dotfiles-"
> +                                            (string-replace-substring
> +                                             file-relative-path
> +                                             "/" "-"))))))
> +       (find-files directory)))

In general, use the term “file name”, not “path”.

The variable name can become, say, ‘file-relative’.

Maybe s/dotfiles-for-app/import-dotfiles/ ?  But see below.

(Sorry for not noticing these earlier!)

> +(define-public (home-dotfiles-configuration dotfiles-directories)

s/define-public/define/ since it’s already exported at the top.

> +  "Return a list of objects compatible with @code{home-files-service-type}'s
> +value, generated following GNU Stow's algorithm for each of the
> +DOTFILES-DIRECTORIES."
> +  (define (directory-contents directories)
> +    (append-map
> +     (lambda (directory)
> +       (map
> +        (lambda (content)
> +          (with-directory-excursion directory
> +              (canonicalize-path content)))
> +        (scandir directory
> +          (lambda (name)
> +            (not (member name '("." "..")))))))
> +     directories))
> +  (append-map
> +   dotfiles-for-app
> +   (directory-contents dotfiles-directories)))

Am I right that this is the same as:

  (append-map (lambda (directory)
                (let ((parent (basename directory))
                      (files (find-files directory)))
                  (define (strip file)
                    (string-drop file (+ 1 (string-length directory))))

                  (map (lambda (file)
                         (list (strip file) (local-file file)))
                       (find-files directory))))
              directories)

?

(In that case, we wouldn’t even need ‘dotfiles-for-app’.)

Also, should we pass ‘find-files’ a predicate to exclude editor backup
files, VCS files, etc.?

Thanks,
Ludo’.