[PATCH] home: Add home-stow-migration-service.

  • Done
  • quality assurance status badge
Details
8 participants
  • Andrew Tropin
  • goodoldpaul
  • Janneke Nieuwenhuizen
  • Ludovic Courtès
  • Bruno Victal
  • Nicolas Odermatt-Lemay
  • Sergey Trofimov
  • Feng Shu
Owner
unassigned
Submitted by
goodoldpaul
Severity
normal
G
G
goodoldpaul wrote on 3 Jan 2023 17:51
(address . guix-patches@gnu.org)
0a8d7bce31856292baa06a08260494c0@autistici.org
Dear Guixers,

I'm upstreaming a Guix Home service I've been using for quite some time
in my personal channel (
) with some small improvements to make it suitable for Guix mainline.

The point of this service is to allow GNU Stow users to switch to Guix
Home without any change to their Stow directory structure, in the hope
of easing the way into Guix Home allowing users to avoid convert all of
their dotfiles to Guix native configurations.

Thank you for your time and efforts,

giacomo
G
G
Giacomo Leidi wrote on 3 Jan 2023 17:55
(address . 60521@debbugs.gnu.org)(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)
20230103165534.25644-1-goodoldpaul@autistici.org
* gnu/home/services.scm (dotfiles-for-app): New variable;
(home-stow-migration-configuration): new variable;
(home-stow-migration-service): new variable.
* doc/guix.texi: Document it.
---
doc/guix.texi | 50 +++++++++++++++++++++++++++++++++++++++++++
gnu/home/services.scm | 49 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+)

Toggle diff (167 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 5c85680831..40c36f65c4 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -109,6 +109,7 @@ Copyright @copyright{} 2022 Reily Siegel@*
Copyright @copyright{} 2022 Simon Streit@*
Copyright @copyright{} 2022 (@*
Copyright @copyright{} 2022 John Kehayias@*
+Copyright @copyright{} 2023 Giacomo Leidi@*
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -41119,6 +41120,55 @@ to use alternative services to implement more advanced use cases like
read-only home. Feel free to experiment and share your results.
@end defvr
+@deffn {Scheme Procedure} home-stow-migration-service
+Return a service which is very similiar to @code{home-files-service-type}
+(and actually extends it), but designed to ease the way into using Guix
+Home for GNU Stow users. This service allows users to point Guix Home to
+their Stow directory and have their file automatically deployed to their home
+directory just like Stow would, without migrating all of their dotfiles to Guix
+native configurations.
+
+A typical Stow setup consists of a source directory and a target directory.
+The source directory must be structured as follows:
+
+@example
+~$ tree -a .dotfiles/
+.dotfiles/
+??? git
+? ??? .gitconfig
+??? gpg
+? ??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? guile
+? ??? .guile
+??? guix
+? ??? .config
+? ??? guix
+? ??? channels.scm
+? ??? .gitignore
+??? nix
+? ??? .config
+? ? ??? nixpkgs
+? ? ??? config.nix
+? ??? .nix-channels
+??? tmux
+? ??? .tmux.conf
+??? vim
+ ??? .vimrc
+
+13 directories, 10 files
+@end example
+
+A suitable configuration would then be:
+
+@lisp
+ (home-stow-migration-service
+ (string-append (getenv "HOME")
+ "/.dotfiles"))
+@end lisp
+@end deffn
+
@defvr {Scheme Variable} home-xdg-configuration-files-service-type
The service is very similiar to @code{home-files-service-type} (and
actually extends it), but used for defining files, which will go to
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index 99035686f1..996647c592 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
+;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -21,6 +22,7 @@ (define-module (gnu home services)
#:use-module (gnu services)
#:use-module ((gnu packages package-management) #:select (guix))
#:use-module ((gnu packages base) #:select (coreutils))
+ #:use-module (guix build utils)
#:use-module (guix channels)
#:use-module (guix monads)
#:use-module (guix store)
@@ -33,13 +35,16 @@ (define-module (gnu home services)
#:use-module (guix i18n)
#:use-module (guix modules)
#:use-module (srfi srfi-1)
+ #:use-module (ice-9 ftw)
#:use-module (ice-9 match)
+ #:use-module (ice-9 string-fun)
#:use-module (ice-9 vlist)
#:export (home-service-type
home-profile-service-type
home-environment-variables-service-type
home-files-service-type
+ home-stow-migration-service
home-xdg-configuration-files-service-type
home-xdg-data-files-service-type
home-run-on-first-login-service-type
@@ -49,6 +54,7 @@ (define-module (gnu home services)
environment-variable-shell-definitions
home-files-directory
+ home-stow-migration-configuration
xdg-configuration-files-directory
xdg-data-files-directory
@@ -315,6 +321,49 @@ (define home-files-service-type
(description "Files that will be put in
@file{~~/.guix-home/files}, and further processed during activation.")))
+(define (dotfiles-for-app app-dir)
+ "Return a list of objects compatible with @{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 APP-DIR and mapping its contents to the
+user's home directory."
+ (let ((app-absolute-path (canonicalize-path app-dir)))
+ (map (lambda (path)
+ (let ((app-file-relative-path
+ (string-replace-substring path
+ (string-append app-absolute-path "/")
+ "")))
+ (list app-file-relative-path
+ (local-file path
+ (string-append "home-stow-migration-"
+ (string-replace-substring
+ app-file-relative-path
+ "/" "-"))))))
+ (find-files app-absolute-path))))
+
+(define (home-stow-migration-configuration stow-dir)
+ "Return a list of objects compatible with @{home-files-service-type}'s
+value, generated following GNU Stow's algorithm using STOW-DIR as input
+directory."
+ (define (dir-contents dir)
+ (scandir dir
+ (lambda (name)
+ (not (member name '("." ".."))))))
+ (fold append
+ '()
+ (map (lambda (app-dir)
+ (dotfiles-for-app
+ (string-append stow-dir "/" app-dir)))
+ (dir-contents stow-dir))))
+
+(define-public (home-stow-migration-service stow-dir)
+ "Return a service extending @{home-files-service-type} with files from
+STOW-DIR. Files will be put in the user's home directory following GNU
+Stow's algorithm, and further processed during activation."
+ (simple-service 'home-stow-migration-service
+ home-files-service-type
+ (home-stow-migration-configuration stow-dir)))
+
(define xdg-configuration-files-directory ".config")
(define (xdg-configuration-files files)

base-commit: 473692b812b4ab4267d9bddad0fb27787d2112ff
--
2.38.1
L
L
Ludovic Courtès wrote on 17 Jan 2023 14:09
(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)(address . 60521@debbugs.gnu.org)
87o7qxi9ym.fsf_-_@gnu.org
Hi!

Giacomo Leidi <goodoldpaul@autistici.org> skribis:

Toggle quote (5 lines)
> * gnu/home/services.scm (dotfiles-for-app): New variable;
> (home-stow-migration-configuration): new variable;
> (home-stow-migration-service): new variable.
> * doc/guix.texi: Document it.

That looks very useful!

Toggle quote (6 lines)
> @@ -41119,6 +41120,55 @@ to use alternative services to implement more advanced use cases like
> read-only home. Feel free to experiment and share your results.
> @end defvr
>
> +@deffn {Scheme Procedure} home-stow-migration-service

Perhaps write a short intro (one or two sentences) above?

Toggle quote (47 lines)
> +Return a service which is very similiar to @code{home-files-service-type}
> +(and actually extends it), but designed to ease the way into using Guix
> +Home for GNU Stow users. This service allows users to point Guix Home to
> +their Stow directory and have their file automatically deployed to their home
> +directory just like Stow would, without migrating all of their dotfiles to Guix
> +native configurations.
> +
> +A typical Stow setup consists of a source directory and a target directory.
> +The source directory must be structured as follows:
> +
> +@example
> +~$ tree -a .dotfiles/
> +.dotfiles/
> +??? git
> +? ??? .gitconfig
> +??? gpg
> +? ??? .gnupg
> +? ??? gpg-agent.conf
> +? ??? gpg.conf
> +??? guile
> +? ??? .guile
> +??? guix
> +? ??? .config
> +? ??? guix
> +? ??? channels.scm
> +? ??? .gitignore
> +??? nix
> +? ??? .config
> +? ? ??? nixpkgs
> +? ? ??? config.nix
> +? ??? .nix-channels
> +??? tmux
> +? ??? .tmux.conf
> +??? vim
> + ??? .vimrc
> +
> +13 directories, 10 files
> +@end example
> +
> +A suitable configuration would then be:
> +
> +@lisp
> + (home-stow-migration-service
> + (string-append (getenv "HOME")
> + "/.dotfiles"))
> +@end lisp

Maybe add a description of what it’s going to do with those files? It’s
kinda implicit but better be clear.

Also, I feel like there’s nothing really Stow-specific here; it just
happens to be a file layout convention that’s used by Stow, right? So I
wonder if could frame it differently, by describing the expected file
tree structure first, and mentioning Stow only then?

Last, I suggest adding a cross-reference to the Stow manual, as in:

@pxref{Top,,, stow, GNU Stow Manual}

Toggle quote (2 lines)
> +(define (dotfiles-for-app app-dir)
> + "Return a list of objects compatible with @{home-files-service-type}'s
^
Typo, should be @code.

Toggle quote (11 lines)
> +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 APP-DIR and mapping its contents to the
> +user's home directory."
> + (let ((app-absolute-path (canonicalize-path app-dir)))
> + (map (lambda (path)
> + (let ((app-file-relative-path
> + (string-replace-substring path
> + (string-append app-absolute-path "/")
> + "")))

Or just (string-drop path (string-length app-absolute-path)).

Toggle quote (8 lines)
> + (list app-file-relative-path
> + (local-file path
> + (string-append "home-stow-migration-"
> + (string-replace-substring
> + app-file-relative-path
> + "/" "-"))))))
> + (find-files app-absolute-path))))

Nitpick: by convention, the term “path” refers to “search paths”; here
we’d instead use “file name”, but you can also call the variable just
‘file’.

The other convention is to avoid abbreviations in identifiers, and to
avoid long identifiers for local variables.

So s/app-dir/directory/ etc.

Toggle quote (15 lines)
> +(define (home-stow-migration-configuration stow-dir)
> + "Return a list of objects compatible with @{home-files-service-type}'s
> +value, generated following GNU Stow's algorithm using STOW-DIR as input
> +directory."
> + (define (dir-contents dir)
> + (scandir dir
> + (lambda (name)
> + (not (member name '("." ".."))))))
> + (fold append
> + '()
> + (map (lambda (app-dir)
> + (dotfiles-for-app
> + (string-append stow-dir "/" app-dir)))
> + (dir-contents stow-dir))))

You can replace (fold append …) with (append-map …).

Toggle quote (2 lines)
> +(define-public (home-stow-migration-service stow-dir)

You can drop this procedure. Users are expected to write:

(service home-stow-migration-service)

Could you send an updated patch?

Thanks!

Ludo’.
A
A
Andrew Tropin wrote on 17 Jan 2023 16:21
Re: [bug#60521] [PATCH] home: Add home-stow-migration-service.
(address . 60521@debbugs.gnu.org)
87tu0p89wf.fsf@trop.in
On 2023-01-17 14:09, Ludovic Courtès wrote:

Toggle quote (66 lines)
> Hi!
>
> Giacomo Leidi <goodoldpaul@autistici.org> skribis:
>
>> * gnu/home/services.scm (dotfiles-for-app): New variable;
>> (home-stow-migration-configuration): new variable;
>> (home-stow-migration-service): new variable.
>> * doc/guix.texi: Document it.
>
> That looks very useful!
>
>> @@ -41119,6 +41120,55 @@ to use alternative services to implement more advanced use cases like
>> read-only home. Feel free to experiment and share your results.
>> @end defvr
>>
>> +@deffn {Scheme Procedure} home-stow-migration-service
>
> Perhaps write a short intro (one or two sentences) above?
>
>> +Return a service which is very similiar to @code{home-files-service-type}
>> +(and actually extends it), but designed to ease the way into using Guix
>> +Home for GNU Stow users. This service allows users to point Guix Home to
>> +their Stow directory and have their file automatically deployed to their home
>> +directory just like Stow would, without migrating all of their dotfiles to Guix
>> +native configurations.
>> +
>> +A typical Stow setup consists of a source directory and a target directory.
>> +The source directory must be structured as follows:
>> +
>> +@example
>> +~$ tree -a .dotfiles/
>> +.dotfiles/
>> +??? git
>> +? ??? .gitconfig
>> +??? gpg
>> +? ??? .gnupg
>> +? ??? gpg-agent.conf
>> +? ??? gpg.conf
>> +??? guile
>> +? ??? .guile
>> +??? guix
>> +? ??? .config
>> +? ??? guix
>> +? ??? channels.scm
>> +? ??? .gitignore
>> +??? nix
>> +? ??? .config
>> +? ? ??? nixpkgs
>> +? ? ??? config.nix
>> +? ??? .nix-channels
>> +??? tmux
>> +? ??? .tmux.conf
>> +??? vim
>> + ??? .vimrc
>> +
>> +13 directories, 10 files
>> +@end example
>> +
>> +A suitable configuration would then be:
>> +
>> +@lisp
>> + (home-stow-migration-service
>> + (string-append (getenv "HOME")
>> + "/.dotfiles"))
>> +@end lisp

The service looks neat! Thank you, Giacomo.

Ludo, wouldn't it be better and safer to use (local-file "./dotfiles"
#:recursive? #t) here? I find it kinda dangerous for reproducibility to
reference local files and make logic inside the service to depend on it.

Toggle quote (80 lines)
>
> Maybe add a description of what it’s going to do with those files? It’s
> kinda implicit but better be clear.
>
> Also, I feel like there’s nothing really Stow-specific here; it just
> happens to be a file layout convention that’s used by Stow, right? So I
> wonder if could frame it differently, by describing the expected file
> tree structure first, and mentioning Stow only then?
>
> Last, I suggest adding a cross-reference to the Stow manual, as in:
>
> @pxref{Top,,, stow, GNU Stow Manual}
>
>> +(define (dotfiles-for-app app-dir)
>> + "Return a list of objects compatible with @{home-files-service-type}'s
> ^
> Typo, should be @code.
>
>> +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 APP-DIR and mapping its contents to the
>> +user's home directory."
>> + (let ((app-absolute-path (canonicalize-path app-dir)))
>> + (map (lambda (path)
>> + (let ((app-file-relative-path
>> + (string-replace-substring path
>> + (string-append app-absolute-path "/")
>> + "")))
>
> Or just (string-drop path (string-length app-absolute-path)).
>
>> + (list app-file-relative-path
>> + (local-file path
>> + (string-append "home-stow-migration-"
>> + (string-replace-substring
>> + app-file-relative-path
>> + "/" "-"))))))
>> + (find-files app-absolute-path))))
>
> Nitpick: by convention, the term “path” refers to “search paths”; here
> we’d instead use “file name”, but you can also call the variable just
> ‘file’.
>
> The other convention is to avoid abbreviations in identifiers, and to
> avoid long identifiers for local variables.
>
> So s/app-dir/directory/ etc.
>
>> +(define (home-stow-migration-configuration stow-dir)
>> + "Return a list of objects compatible with @{home-files-service-type}'s
>> +value, generated following GNU Stow's algorithm using STOW-DIR as input
>> +directory."
>> + (define (dir-contents dir)
>> + (scandir dir
>> + (lambda (name)
>> + (not (member name '("." ".."))))))
>> + (fold append
>> + '()
>> + (map (lambda (app-dir)
>> + (dotfiles-for-app
>> + (string-append stow-dir "/" app-dir)))
>> + (dir-contents stow-dir))))
>
> You can replace (fold append …) with (append-map …).
>
>> +(define-public (home-stow-migration-service stow-dir)
>
> You can drop this procedure. Users are expected to write:
>
> (service home-stow-migration-service)
>
> Could you send an updated patch?
>
> Thanks!
>
> Ludo’.
>
>
>

--
Best regards,
Andrew Tropin
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEKEGaxlA4dEDH6S/6IgjSCVjB3rAFAmPGvOAACgkQIgjSCVjB
3rD4BA//fWFIt2fMw42Pd/Fag7aiHJL6QDvgo0fSNRvbrf7mySUlGfbDrJBX6mn7
DvQ6GnuiNr6y/PPswA3kIUaODwxlAeB1bHX1QU3S7Kjk3GCdi/h53rLFhlO4hXxj
g+PJ5pJ/ATr5+zd9XdekhT6a1aIPZYGqJHfNM7nMFQeoH+qptgvlkEUqqqdILyxi
1NJJgQUIxyuCGDqqW9RmjKN6b7kN9dIag0F8mRFcReIkBwknwTf9ohGeDcBU5i8T
GUVbp/5NGDs7cErsz8Lu9uS0GQpKVbcpnoLnMrnlxAGVJU6Caexen06LR1wUDXnS
WJ7MeOaeuJ3BRcODZJqMlOSf6kI68KeSmjHQIwZ80j7ui6EhtEsbjjx3bf93wxe8
arUGJo/mXLaJj7w7W2Xv8Ke+1EXY0WBr0x89ZEoQf5LZWVeCrz255+mXDsQDleFa
0REDqiXvoHGAbGfW3D7A6B157it1J4BUzeghp9irSFBZD2RYhgMExChAbvMD3ZU8
VfUe0rOi2Y1yofqS/eFNme4SiE4BxhjlNhSEuut2Ljb05fiXIYe4iwfBzCm/Ly+x
qMT+/6AA5cyZGdzcZLA4CjNFduoVmG0XRrqFW8NKNb19KncQrWpwVxjszdB8Cisq
B/fqVUMxg0W1kUPHiJKxgZj/nyaxiozoWL6mTpcsr0yPtPPxjZk=
=Zozo
-----END PGP SIGNATURE-----

B
B
Bruno Victal wrote on 17 Jan 2023 18:09
(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)(address . 60521@debbugs.gnu.org)
c8c49872-37f1-a0e0-46a1-91942023f00b@makinata.eu
On 2023-01-03 16:55, Giacomo Leidi via Guix-patches via wrote:
Toggle quote (29 lines)
> * gnu/home/services.scm (dotfiles-for-app): New variable;
> (home-stow-migration-configuration): new variable;
> (home-stow-migration-service): new variable.
> * doc/guix.texi: Document it.
> ---
> doc/guix.texi | 50 +++++++++++++++++++++++++++++++++++++++++++
> gnu/home/services.scm | 49 ++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 99 insertions(+)
>
> diff --git a/doc/guix.texi b/doc/guix.texi
> index 5c85680831..40c36f65c4 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -109,6 +109,7 @@ Copyright @copyright{} 2022 Reily Siegel@*
> Copyright @copyright{} 2022 Simon Streit@*
> Copyright @copyright{} 2022 (@*
> Copyright @copyright{} 2022 John Kehayias@*
> +Copyright @copyright{} 2023 Giacomo Leidi@*
>
> Permission is granted to copy, distribute and/or modify this document
> under the terms of the GNU Free Documentation License, Version 1.3 or
> @@ -41119,6 +41120,55 @@ to use alternative services to implement more advanced use cases like
> read-only home. Feel free to experiment and share your results.
> @end defvr
>
> +@deffn {Scheme Procedure} home-stow-migration-service
> +Return a service which is very similiar to @code{home-files-service-type}
> +(and actually extends it), but designed to ease the way into using Guix

Procedures in Guix are almost always Scheme functions, perhaps you could write this as:
@defun home-stow-migration-service

Toggle quote (50 lines)
> +Home for GNU Stow users. This service allows users to point Guix Home to
> +their Stow directory and have their file automatically deployed to their home
> +directory just like Stow would, without migrating all of their dotfiles to Guix
> +native configurations.
> +
> +A typical Stow setup consists of a source directory and a target directory.
> +The source directory must be structured as follows:
> +
> +@example
> +~$ tree -a .dotfiles/
> +.dotfiles/
> +??? git
> +? ??? .gitconfig
> +??? gpg
> +? ??? .gnupg
> +? ??? gpg-agent.conf
> +? ??? gpg.conf
> +??? guile
> +? ??? .guile
> +??? guix
> +? ??? .config
> +? ??? guix
> +? ??? channels.scm
> +? ??? .gitignore
> +??? nix
> +? ??? .config
> +? ? ??? nixpkgs
> +? ? ??? config.nix
> +? ??? .nix-channels
> +??? tmux
> +? ??? .tmux.conf
> +??? vim
> + ??? .vimrc
> +
> +13 directories, 10 files
> +@end example
> +
> +A suitable configuration would then be:
> +
> +@lisp
> + (home-stow-migration-service
> + (string-append (getenv "HOME")
> + "/.dotfiles"))
> +@end lisp
> +@end deffn
> +
> @defvr {Scheme Variable} home-xdg-configuration-files-service-type
> The service is very similiar to @code{home-files-service-type} (and
> actually extends it), but used for defining files, which will go to

In a similar vein, this could be written as:
@defvar home-xdg-configuration-files-service-type

Toggle quote (55 lines)
> diff --git a/gnu/home/services.scm b/gnu/home/services.scm
> index 99035686f1..996647c592 100644
> --- a/gnu/home/services.scm
> +++ b/gnu/home/services.scm
> @@ -1,6 +1,7 @@
> ;;; GNU Guix --- Functional package management for GNU
> ;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
> ;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
> +;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
> ;;;
> ;;; This file is part of GNU Guix.
> ;;;
> @@ -21,6 +22,7 @@ (define-module (gnu home services)
> #:use-module (gnu services)
> #:use-module ((gnu packages package-management) #:select (guix))
> #:use-module ((gnu packages base) #:select (coreutils))
> + #:use-module (guix build utils)
> #:use-module (guix channels)
> #:use-module (guix monads)
> #:use-module (guix store)
> @@ -33,13 +35,16 @@ (define-module (gnu home services)
> #:use-module (guix i18n)
> #:use-module (guix modules)
> #:use-module (srfi srfi-1)
> + #:use-module (ice-9 ftw)
> #:use-module (ice-9 match)
> + #:use-module (ice-9 string-fun)
> #:use-module (ice-9 vlist)
>
> #:export (home-service-type
> home-profile-service-type
> home-environment-variables-service-type
> home-files-service-type
> + home-stow-migration-service
> home-xdg-configuration-files-service-type
> home-xdg-data-files-service-type
> home-run-on-first-login-service-type
> @@ -49,6 +54,7 @@ (define-module (gnu home services)
>
> environment-variable-shell-definitions
> home-files-directory
> + home-stow-migration-configuration
> xdg-configuration-files-directory
> xdg-data-files-directory
>
> @@ -315,6 +321,49 @@ (define home-files-service-type
> (description "Files that will be put in
> @file{~~/.guix-home/files}, and further processed during activation.")))
>
> +(define (dotfiles-for-app app-dir)
> + "Return a list of objects compatible with @{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 APP-DIR and mapping its contents to the

Instead of `APP-DIR', you can use the @var command:
@var{app-dir}

Toggle quote (20 lines)
> +user's home directory."
> + (let ((app-absolute-path (canonicalize-path app-dir)))
> + (map (lambda (path)
> + (let ((app-file-relative-path
> + (string-replace-substring path
> + (string-append app-absolute-path "/")
> + "")))
> + (list app-file-relative-path
> + (local-file path
> + (string-append "home-stow-migration-"
> + (string-replace-substring
> + app-file-relative-path
> + "/" "-"))))))
> + (find-files app-absolute-path))))
> +
> +(define (home-stow-migration-configuration stow-dir)
> + "Return a list of objects compatible with @{home-files-service-type}'s
> +value, generated following GNU Stow's algorithm using STOW-DIR as input
> +directory."

Same as above.

Toggle quote (15 lines)
> + (define (dir-contents dir)
> + (scandir dir
> + (lambda (name)
> + (not (member name '("." ".."))))))
> + (fold append
> + '()
> + (map (lambda (app-dir)
> + (dotfiles-for-app
> + (string-append stow-dir "/" app-dir)))
> + (dir-contents stow-dir))))
> +
> +(define-public (home-stow-migration-service stow-dir)
> + "Return a service extending @{home-files-service-type} with files from
> +STOW-DIR. Files will be put in the user's home directory following GNU

Same as above.

Toggle quote (12 lines)
> +Stow's algorithm, and further processed during activation."
> + (simple-service 'home-stow-migration-service
> + home-files-service-type
> + (home-stow-migration-configuration stow-dir)))
> +
> (define xdg-configuration-files-directory ".config")
>
> (define (xdg-configuration-files files)
>
> base-commit: 473692b812b4ab4267d9bddad0fb27787d2112ff


Cheers,
Bruno
L
L
Ludovic Courtès wrote on 23 Jan 2023 11:23
(name . Andrew Tropin)(address . andrew@trop.in)
87edrl4kio.fsf@gnu.org
Hi,

Andrew Tropin <andrew@trop.in> skribis:

Toggle quote (14 lines)
>>> +A suitable configuration would then be:
>>> +
>>> +@lisp
>>> + (home-stow-migration-service
>>> + (string-append (getenv "HOME")
>>> + "/.dotfiles"))
>>> +@end lisp
>
> The service looks neat! Thank you, Giacomo.
>
> Ludo, wouldn't it be better and safer to use (local-file "./dotfiles"
> #:recursive? #t) here? I find it kinda dangerous for reproducibility to
> reference local files and make logic inside the service to depend on it.

Currently I don’t think that’s possible because the service imports
those files at configuration time, but the end result is the same: those
dot files are copied to the store and that’s what’s referenced.

I think it’s okay like this, but I don’t have a strong opinion.

That said, from a usability viewpoint, it does mean that users would
typically have to version-controlled directories (one with the Home
config file, and one with the Stow-style dot file tree), which is not
great. Perhaps the manual could say something about it.

Thanks,
Ludo’.
A
A
Andrew Tropin wrote on 25 Jan 2023 07:32
(name . Ludovic Courtès)(address . ludo@gnu.org)
874jsft98i.fsf@trop.in
On 2023-01-23 11:23, Ludovic Courtès wrote:

Toggle quote (30 lines)
> Hi,
>
> Andrew Tropin <andrew@trop.in> skribis:
>
>>>> +A suitable configuration would then be:
>>>> +
>>>> +@lisp
>>>> + (home-stow-migration-service
>>>> + (string-append (getenv "HOME")
>>>> + "/.dotfiles"))
>>>> +@end lisp
>>
>> The service looks neat! Thank you, Giacomo.
>>
>> Ludo, wouldn't it be better and safer to use (local-file "./dotfiles"
>> #:recursive? #t) here? I find it kinda dangerous for reproducibility to
>> reference local files and make logic inside the service to depend on it.
>
> Currently I don’t think that’s possible because the service imports
> those files at configuration time, but the end result is the same: those
> dot files are copied to the store and that’s what’s referenced.
>
> I think it’s okay like this, but I don’t have a strong opinion.
>
> That said, from a usability viewpoint, it does mean that users would
> typically have to version-controlled directories (one with the Home
> config file, and one with the Stow-style dot file tree), which is not
> great. Perhaps the manual could say something about it.
>

The long-term idea I have is to provide a hermetic evaluation mode (not
only for home environments, but for guix in general), which allows to
make sure programmatically that all files referenced comes from either
origins with hash explicitly specified or commited in the current vcs
repository. This way by changing things like

(local-file "./dotfiles" #:recursive? #t) to something like
(file-append (current-repo) "/dotfiles") or
(vcs-file "dotfiles" #:recursive? #t)

we will be able to guarantee that one didn't forget to copy all needed
dependencies for the configuration and to keep API "future compatible"
looks like a good idea.

Just thinking out loud, someday will make a separate
thread/note/prototype on this topic.

Anyway, this service looks good enough to me with the current
implementation and seems potentially helpful.

--
Best regards,
Andrew Tropin
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEKEGaxlA4dEDH6S/6IgjSCVjB3rAFAmPQzP0ACgkQIgjSCVjB
3rAy0g//fVupV4O+bUINCEZFcfV8sPddnl89rEdJ9nISb/XlcHEiMMqRZ9x8d2mk
tLGU/SlW9ZydZn5UQCGt5WsXFR0O9Pc1lpJCcBhOVudbNpR7c+FDBMd5KhfeSEae
paYeT1w6UtD+rhKU2n6Y8cNDa8YmYwWvz1XQBU56nsRZlVRN76n4522fLAw4QgeQ
QspAdPhY91V13+cAGrbc6ksNfzCM/n9M+sCnN9kH+scpawBIkLR5UboFvtGOSWGY
MPVWzLVA7EXcGX8mZb+bIyEDSRfLAPFYhOG1HZ3cCjbnPaZ1nnEDfy/uJuJLqYKj
nh6ryD66ErdL3r4O52ycqSg9DAT+3MEBPvRzwp8kBJW2ynKbMjNNtsGf22g/C+tN
KyR22U3V1I9Jgh8uzLRzMxAcwuhLYLVM8nDVjU3bfxwbm384+AjAjm7kb4nJXZWH
S4f18MvZ8lqvJr/zDdscgxomlNKXe7pnnoDpcqkYF7RiEbFCu+62iTuL7t4B1Y6j
o8DO60BMGnx3pHCb3sMljimIcMpeGGH4ooDIEHSkPURy9ocmS2VjEikwRP2E09Zc
1x8yEpK8i3GgIwv1XBoaoNc5Rs/rYpwHo87KWTShSpYzZwZXnzI/keDddzg0Jb+Q
iRnjRA7oR9m+AW0A3jDwufAZkd/Hcf6bhzcUf8Fd01Cfz50cYoE=
=jT1l
-----END PGP SIGNATURE-----

L
L
Ludovic Courtès wrote on 31 Jan 2023 22:54
control message for bug #60521
(address . control@debbugs.gnu.org)
87cz6utlnv.fsf@gnu.org
tags 60521 + moreinfo
quit
G
G
goodoldpaul wrote on 12 Feb 2023 18:36
Re: [PATCH] home: Add home-stow-migration-service.
(name . 60521)(address . 60521@debbugs.gnu.org)
a1a16eaeb8c5e311bcb1f7d3ffae1807@autistici.org
Dear Ludo, Andy and Bruno,
I apologize for the delay. I'm sending a v2, I should have addressed all
of your concerns:

- I agree with you that this is not really Stow specific, so I renamed
the service to home-dotfiles-service-type.
- I didn't think about this last time, but the way I use this service is
by having an etc/ directory in my Guix Home git repository. I specified
this in the manual to address reproducibility concerns.
- In general i gave some polish to everything.
- a nice future improvement could be adding an optional flag to guix
home import to have your Stow directory automatically configured in your
home-environment definition.

I hope everything is okay, thank you for your time.

giacomo
G
G
Giacomo Leidi wrote on 12 Feb 2023 18:36
[v2] home: Add home-dotfiles-service.
(address . 60521@debbugs.gnu.org)(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)
20230212173640.12008-1-goodoldpaul@autistici.org
* 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.
---
doc/guix.texi | 85 ++++++++++++++++++++++++++++++++++++++++++-
gnu/home/services.scm | 54 +++++++++++++++++++++++++++
2 files changed, 138 insertions(+), 1 deletion(-)

Toggle diff (202 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 44e2165a82..a6223d69eb 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -111,9 +111,9 @@ Copyright @copyright{} 2022 (@*
Copyright @copyright{} 2022 John Kehayias@*
Copyright @copyright{} 2022 Bruno Victal@*
Copyright @copyright{} 2022 Ivan Vilata-i-Balaguer@*
-Copyright @copyright{} 2023 Giacomo Leidi@*
Copyright @copyright{} 2022 Antero Mejr@*
Copyright @copyright{} 2023 Bruno Victal@*
+Copyright @copyright{} 2023 Giacomo Leidi@*
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -41620,6 +41620,89 @@ to use alternative services to implement more advanced use cases like
read-only home. Feel free to experiment and share your results.
@end defvar
+It is often the case that Guix Home users already have a setup for versioning
+their user configuration files (also known as @emph{dotfiles}) in a single
+directory, and some way of automatically deploy changes to their user home.
+
+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
+dotfiles automatically deployed to their user home, without migrating them to
+Guix native configurations.
+
+The dotfiles directory layout is expected to be structured as follows:
+
+@example
+~$ tree -a .dotfiles/
+.dotfiles/
+??? git
+? ??? .gitconfig
+??? gpg
+? ??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? guile
+? ??? .guile
+??? guix
+? ??? .config
+? ??? guix
+? ??? channels.scm
+??? nix
+? ??? .config
+? ? ??? nixpkgs
+? ? ??? config.nix
+? ??? .nix-channels
+??? tmux
+? ??? .tmux.conf
+??? vim
+ ??? .vimrc
+
+13 directories, 10 files
+@end example
+
+For a more formal specification please refer to the
+@pxref{Top,,, stow, GNU Stow Manual}. It is advisable to keep your dotfiles
+directories under version control, for example in the same repository where
+you'd track your Guix Home configuration. A suitable configuration would then
+be:
+
+@lisp
+ (simple-service 'home-dotfiles
+ home-dotfiles-service-type
+ (list (string-append (getcwd)
+ "/.dotfiles")))
+@end lisp
+
+The expected home directory state would be:
+
+@example
+.
+??? .config
+? ??? guix
+? ? ??? channels.scm
+? ??? nixpkgs
+? ??? config.nix
+??? .gitconfig
+??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? .guile
+??? .nix-channels
+??? .tmux.conf
+??? .vimrc
+@end example
+
+@defvar home-dotfiles-service-type
+Return a service which is very similiar to @code{home-files-service-type}
+(and actually extends it), but designed to ease the way into using Guix
+Home for users that already track their dotfiles under some kind of version
+control. This service allows users to point Guix Home to their dotfiles
+directory and have their file automatically deployed to their home directory
+just like Stow would, without migrating all of their dotfiles to Guix native
+configurations.
+@end defvar
+
@defvar home-xdg-configuration-files-service-type
The service is very similiar to @code{home-files-service-type} (and
actually extends it), but used for defining files, which will go to
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index b17a34d19d..c45b8cbe24 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2021-2023 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2022-2023 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -22,6 +23,7 @@ (define-module (gnu home services)
#:use-module (gnu services)
#:use-module ((gnu packages package-management) #:select (guix))
#:use-module ((gnu packages base) #:select (coreutils))
+ #:use-module (guix build utils)
#:use-module (guix channels)
#:use-module (guix monads)
#:use-module (guix store)
@@ -35,13 +37,17 @@ (define-module (gnu home services)
#:use-module (guix modules)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
+ #:use-module (ice-9 ftw)
#:use-module (ice-9 match)
+ #:use-module (ice-9 string-fun)
#:use-module (ice-9 vlist)
#:export (home-service-type
home-profile-service-type
home-environment-variables-service-type
home-files-service-type
+ home-dotfiles-service-type
+ home-dotfiles-configuration
home-xdg-configuration-files-service-type
home-xdg-data-files-service-type
home-run-on-first-login-service-type
@@ -341,6 +347,54 @@ (define home-files-service-type
(description "Files that will be put in
@file{~/.guix-home/files}, and further processed during activation.")))
+(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)))
+
+(define-public (home-dotfiles-configuration dotfiles-directories)
+ "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)))
+
+(define-public home-dotfiles-service-type
+ (service-type (name 'home-dotfiles)
+ (extensions
+ (list (service-extension home-files-service-type
+ home-dotfiles-configuration)))
+ (default-value '())
+ (extend append)
+ (compose concatenate)
+ (description "Files contained is these directories will be put
+in the user's home directory according to GNU Stow's algorithm, and further
+processed during activation.")))
+
(define xdg-configuration-files-directory ".config")
(define (xdg-configuration-files files)

base-commit: 2b1383c0a2f79117103b142440c64f6a751d545d
--
2.39.1
G
G
goodoldpaul wrote on 12 Apr 2023 22:31
Re: [PATCH] home: Add home-stow-migration-service.
13cf3fe05ad572d3385b7e8a16317478@autistici.org
Dear Guixers,

this is a friendly ping :) . I'm sending an updated patchset.

Thank you for your time and efforts,

giacomo
G
G
Giacomo Leidi wrote on 12 Apr 2023 22:32
[v3] home: Add home-dotfiles-service.
(address . 60521@debbugs.gnu.org)(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)
20230412203217.32606-1-goodoldpaul@autistici.org
* 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.
---
doc/guix.texi | 85 ++++++++++++++++++++++++++++++++++++++++++-
gnu/home/services.scm | 54 +++++++++++++++++++++++++++
2 files changed, 138 insertions(+), 1 deletion(-)

Toggle diff (202 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index acb6f0c2e1..b95053039f 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -111,9 +111,9 @@ Copyright @copyright{} 2022 (@*
Copyright @copyright{} 2022 John Kehayias@*
Copyright @copyright{} 2022?–?2023 Bruno Victal@*
Copyright @copyright{} 2022 Ivan Vilata-i-Balaguer@*
-Copyright @copyright{} 2023 Giacomo Leidi@*
Copyright @copyright{} 2022 Antero Mejr@*
Copyright @copyright{} 2023 Karl Hallsby
+Copyright @copyright{} 2023 Giacomo Leidi@*
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -42029,6 +42029,89 @@ to use alternative services to implement more advanced use cases like
read-only home. Feel free to experiment and share your results.
@end defvar
+It is often the case that Guix Home users already have a setup for versioning
+their user configuration files (also known as @emph{dotfiles}) in a single
+directory, and some way of automatically deploy changes to their user home.
+
+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
+dotfiles automatically deployed to their user home, without migrating them to
+Guix native configurations.
+
+The dotfiles directory layout is expected to be structured as follows:
+
+@example
+~$ tree -a .dotfiles/
+.dotfiles/
+??? git
+? ??? .gitconfig
+??? gpg
+? ??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? guile
+? ??? .guile
+??? guix
+? ??? .config
+? ??? guix
+? ??? channels.scm
+??? nix
+? ??? .config
+? ? ??? nixpkgs
+? ? ??? config.nix
+? ??? .nix-channels
+??? tmux
+? ??? .tmux.conf
+??? vim
+ ??? .vimrc
+
+13 directories, 10 files
+@end example
+
+For a more formal specification please refer to the
+@pxref{Top,,, stow, GNU Stow Manual}. It is advisable to keep your dotfiles
+directories under version control, for example in the same repository where
+you'd track your Guix Home configuration. A suitable configuration would then
+be:
+
+@lisp
+ (simple-service 'home-dotfiles
+ home-dotfiles-service-type
+ (list (string-append (getcwd)
+ "/.dotfiles")))
+@end lisp
+
+The expected home directory state would be:
+
+@example
+.
+??? .config
+? ??? guix
+? ? ??? channels.scm
+? ??? nixpkgs
+? ??? config.nix
+??? .gitconfig
+??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? .guile
+??? .nix-channels
+??? .tmux.conf
+??? .vimrc
+@end example
+
+@defvar home-dotfiles-service-type
+Return a service which is very similiar to @code{home-files-service-type}
+(and actually extends it), but designed to ease the way into using Guix
+Home for users that already track their dotfiles under some kind of version
+control. This service allows users to point Guix Home to their dotfiles
+directory and have their file automatically deployed to their home directory
+just like Stow would, without migrating all of their dotfiles to Guix native
+configurations.
+@end defvar
+
@defvar home-xdg-configuration-files-service-type
The service is very similiar to @code{home-files-service-type} (and
actually extends it), but used for defining files, which will go to
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index b17a34d19d..c45b8cbe24 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2021-2023 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2022-2023 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -22,6 +23,7 @@ (define-module (gnu home services)
#:use-module (gnu services)
#:use-module ((gnu packages package-management) #:select (guix))
#:use-module ((gnu packages base) #:select (coreutils))
+ #:use-module (guix build utils)
#:use-module (guix channels)
#:use-module (guix monads)
#:use-module (guix store)
@@ -35,13 +37,17 @@ (define-module (gnu home services)
#:use-module (guix modules)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
+ #:use-module (ice-9 ftw)
#:use-module (ice-9 match)
+ #:use-module (ice-9 string-fun)
#:use-module (ice-9 vlist)
#:export (home-service-type
home-profile-service-type
home-environment-variables-service-type
home-files-service-type
+ home-dotfiles-service-type
+ home-dotfiles-configuration
home-xdg-configuration-files-service-type
home-xdg-data-files-service-type
home-run-on-first-login-service-type
@@ -341,6 +347,54 @@ (define home-files-service-type
(description "Files that will be put in
@file{~/.guix-home/files}, and further processed during activation.")))
+(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)))
+
+(define-public (home-dotfiles-configuration dotfiles-directories)
+ "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)))
+
+(define-public home-dotfiles-service-type
+ (service-type (name 'home-dotfiles)
+ (extensions
+ (list (service-extension home-files-service-type
+ home-dotfiles-configuration)))
+ (default-value '())
+ (extend append)
+ (compose concatenate)
+ (description "Files contained is these directories will be put
+in the user's home directory according to GNU Stow's algorithm, and further
+processed during activation.")))
+
(define xdg-configuration-files-directory ".config")
(define (xdg-configuration-files files)

base-commit: dd3e5e71104a2bcbad80e52e062a144ea96b8c6a
--
2.39.2
L
L
Ludovic Courtès wrote on 24 Apr 2023 22:33
Re: bug#60521: [PATCH] home: Add home-stow-migration-service.
(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)(address . 60521@debbugs.gnu.org)
87zg6x10lm.fsf_-_@gnu.org
Hi Giacomo,

Giacomo Leidi <goodoldpaul@autistici.org> skribis:

Toggle quote (5 lines)
> * 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.

Toggle quote (5 lines)
> +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 …

Toggle quote (3 lines)
> +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

Toggle quote (6 lines)
> +@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.)

Toggle quote (17 lines)
> +(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!)

Toggle quote (2 lines)
> +(define-public (home-dotfiles-configuration dotfiles-directories)

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

Toggle quote (18 lines)
> + "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’.
P
e4e11cee-8728-0c92-6d5c-64e77dc3a874@autistici.org
Dear Ludo,

I apologize for the long delay. I did not receive a notification of your
post somehow, I may need to change email provider.

> Maybe a node other than “Top” would be advisable? I can’t see where
that formal spec might be at

There may have been a misunderstanding here, I didn't want to imply that
there was a formal specification. I just assumed that being a GNU
project it would have been documented. Anyway I tried to get to the
bottom of this and the only mention/apparent endorsement from the Stow
manual to this layout is in the Introduction [0], which references [1]
as the original source.

[1] explains pretty clearly the layout in a natural language informal
fashion, but searching for "stow" and "dotfiles" on the internet it
appears to be an established de-facto standard. I changed the manual to
"which must follow the layout suggested by". What do you think?

> Am I right that this is the same as:

> [ ... ]

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

It's not the same I believe. The whole (string-append "home-dotfiles"
... is there because at guix/nix/libstore/store-api.cc line 64 and 71
for . and / respectively an exception is thrown if those characters are
in first position or inside the store name. (append-map ...
(dir-contents ... is needed due to the Stow layout: suppose you have a
directory like this one

.dotfiles/
??? git
?     ??? .gitconfig
??? gpg
?     ??? .gnupg
?     ??? gpg-agent.conf
?     ??? gpg.conf
??? guile
?     ??? .guile
??? guix
?     ??? .config
?     ??? guix
?     ??? channels.scm
??? nix
?     ??? .config
?     ?     ??? nixpkgs
?     ?     ??? config.nix
?     ??? .nix-channels
??? tmux
?     ??? .tmux.conf
??? vim
       ??? .vimrc

The most common Stow workflow would be to have this directory at
~/.dotfiles and then


$ cd ~/.dotfiles

$ stow git

$ stow nix

This additional git,nix,gpg,guile etc... layer is not covered by your
code, but I tried my best to simplify import-dotfiles. Please let me
know what are your feeling about the current state of the service.

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

Yes, that's an awesome idea. I implemented a simple filter (currently
'("\\.gitignore" ".*\\.swp" ".*~") ) since I wasn't sure how much we can
assume about this use case.


I should have addressed all of your suggestions, thank you for your time
and help Ludo’ ! I'm sending an update patch.


giacomo


[0]:

[1]:

Attachment: file
G
G
Giacomo Leidi wrote on 24 Jun 2023 18:01
[PATCH-v4] home: Add home-dotfiles-service.
(address . 60521@debbugs.gnu.org)(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)
b85ed5e41596e6035669cf826df19e7913ceda15.1687622514.git.goodoldpaul@autistici.org
* 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.
---
doc/guix.texi | 108 ++++++++++++++++++++++++++++++++++++++++++
gnu/home/services.scm | 78 ++++++++++++++++++++++++++++++
2 files changed, 186 insertions(+)

Toggle diff (242 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index c961f706ec..cb3b0d05b0 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -42659,6 +42659,114 @@ Essential Home Services
read-only home. Feel free to experiment and share your results.
@end defvar
+It is often the case that Guix Home users already have a setup for versioning
+their user configuration files (also known as @emph{dotfiles}) in a single
+directory, and some way of automatically deploy changes to their user home.
+
+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 the layout suggested by
+@uref{https://www.gnu.org/software/stow/, GNU Stow},
+and have their dotfiles automatically deployed to their user home, without
+migrating them to Guix native configurations.
+
+The dotfiles directory layout is expected to be structured as follows. Please
+keep in mind that it is advisable to keep your dotfiles directories under
+version control, for example in the same repository where you'd track your
+Guix Home configuration.
+
+@example
+~$ tree -a .dotfiles/
+.dotfiles/
+??? git
+? ??? .gitconfig
+??? gpg
+? ??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? guile
+? ??? .guile
+??? guix
+? ??? .config
+? ??? guix
+? ??? channels.scm
+??? nix
+? ??? .config
+? ? ??? nixpkgs
+? ? ??? config.nix
+? ??? .nix-channels
+??? tmux
+? ??? .tmux.conf
+??? vim
+ ??? .vimrc
+
+13 directories, 10 files
+@end example
+
+For an informal specification please refer to the Stow manual
+(@pxref{Top,,, stow, Introduction}). A suitable configuration would then
+be:
+
+@lisp
+(use-modules (guix utils))
+
+(home-environment
+
+ [...]
+
+ (services
+ (service home-dotfiles-service-type
+ (home-dotfiles-configuration
+ (directories
+ (list (string-append (current-source-directory)
+ "/.dotfiles")))))))
+@end lisp
+
+The expected home directory state would be:
+
+@example
+.
+??? .config
+? ??? guix
+? ? ??? channels.scm
+? ??? nixpkgs
+? ??? config.nix
+??? .gitconfig
+??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? .guile
+??? .nix-channels
+??? .tmux.conf
+??? .vimrc
+@end example
+
+@defvar home-dotfiles-service-type
+Return a service which is very similiar to @code{home-files-service-type}
+(and actually extends it), but designed to ease the way into using Guix
+Home for users that already track their dotfiles under some kind of version
+control. This service allows users to point Guix Home to their dotfiles
+directory and have their file automatically deployed to their home directory
+just like Stow would, without migrating all of their dotfiles to Guix native
+configurations.
+@end defvar
+
+@deftp {Data Type} home-dotfiles-configuration
+Available @code{home-dotfiles-configuration} fields are:
+
+@table @asis
+@item @code{directories} (type: list-of-strings)
+The list of dotfiles directories where @code{home-dotfiles-service-type} will
+look for application dotfiles.
+
+@item @code{exclude} (default: @code{'(".*~" ".*\\.swp" "\\.gitignore")})
+The list of file patterns @code{home-dotfiles-service-type} will exclude while
+visiting @code{directories}.
+
+@end table
+
+@end deftp
+
@defvar home-xdg-configuration-files-service-type
The service is very similar to @code{home-files-service-type} (and
actually extends it), but used for defining files, which will go to
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index b17a34d19d..2fe6508a9a 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2021-2023 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2022-2023 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -22,6 +23,7 @@ (define-module (gnu home services)
#:use-module (gnu services)
#:use-module ((gnu packages package-management) #:select (guix))
#:use-module ((gnu packages base) #:select (coreutils))
+ #:use-module (guix build utils)
#:use-module (guix channels)
#:use-module (guix monads)
#:use-module (guix store)
@@ -33,15 +35,24 @@ (define-module (gnu home services)
#:use-module (guix diagnostics)
#:use-module (guix i18n)
#:use-module (guix modules)
+ #:use-module (guix records)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
+ #:use-module (ice-9 ftw)
#:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 string-fun)
#:use-module (ice-9 vlist)
#:export (home-service-type
home-profile-service-type
home-environment-variables-service-type
home-files-service-type
+ home-dotfiles-service-type
+ home-dotfiles-configuration
+ home-dotfiles-configuration?
+ home-dotfiles-configuration-directories
+ home-dotfiles-configuration-excluded
home-xdg-configuration-files-service-type
home-xdg-data-files-service-type
home-run-on-first-login-service-type
@@ -341,6 +352,73 @@ (define home-files-service-type
(description "Files that will be put in
@file{~/.guix-home/files}, and further processed during activation.")))
+(define %home-dotfiles-excluded
+ '(".*~"
+ ".*\\.swp"
+ "\\.gitignore"))
+
+(define-record-type* <home-dotfiles-configuration>
+ home-dotfiles-configuration make-home-dotfiles-configuration
+ home-dotfiles-configuration?
+ (directories home-dotfiles-configuration-directories ;list of strings
+ (default '()))
+ (excluded home-dotfiles-configuration-excluded ;list of strings
+ (default %home-dotfiles-excluded)))
+
+(define* (import-dotfiles directory excluded)
+ "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, excluding files that match any of the patterns in EXCLUDED."
+ (define filtered
+ (find-files directory
+ (lambda (file stat)
+ (not (string-match
+ (string-append
+ "^.*(" (string-join excluded "|") ")$") file)))))
+ (define (strip file)
+ (string-drop file (+ 1 (string-length directory))))
+ (define (format file)
+ (string-append "home-dotfiles-"
+ (string-replace-substring file "/" "-")))
+
+ (map (lambda (file)
+ (let* ((stripped (strip file)))
+ (list stripped
+ (local-file file (format stripped)))))
+ filtered))
+
+(define (home-dotfiles-configuration->files config)
+ "Return a list of objects compatible with @code{home-files-service-type}'s
+value, generated following GNU Stow's algorithm for each of the
+directories in CONFIG, excluding files that match any of the patterns configured."
+ (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
+ (lambda (app)
+ (import-dotfiles app (home-dotfiles-configuration-excluded config)))
+ (directory-contents
+ (home-dotfiles-configuration-directories config))))
+
+(define-public home-dotfiles-service-type
+ (service-type (name 'home-dotfiles)
+ (extensions
+ (list (service-extension home-files-service-type
+ home-dotfiles-configuration->files)))
+ (default-value (home-dotfiles-configuration))
+ (description "Files that will be put in the user's home directory
+following GNU Stow's algorithm, and further processed during activation.")))
+
(define xdg-configuration-files-directory ".config")
(define (xdg-configuration-files files)

base-commit: d6dc82e8cdb2d6114a12b06d449ce7f1150c7f70
--
2.40.1
G
G
goodoldpaul wrote on 26 Aug 2023 11:34
Re: bug#60521: [PATCH] home: Add home-stow-migration-service.
6178cf42812efc69a1eb22a04994c2e7@autistici.org
Hi,

I'm sending an updated patchset based on the latest master.

Thank you for your time!

giacomo
G
G
Giacomo Leidi wrote on 26 Aug 2023 11:39
[PATCH-v4] home: Add home-dotfiles-service.
(address . 60521@debbugs.gnu.org)(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)
cd829d7c1a963205e916102ef224f7983e6e79ff.1693042740.git.goodoldpaul@autistici.org
* 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.
---
doc/guix.texi | 108 ++++++++++++++++++++++++++++++++++++++++++
gnu/home/services.scm | 78 ++++++++++++++++++++++++++++++
2 files changed, 186 insertions(+)

Toggle diff (242 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 6105195bd9..87f0fdf8a1 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -43153,6 +43153,114 @@ Essential Home Services
read-only home. Feel free to experiment and share your results.
@end defvar
+It is often the case that Guix Home users already have a setup for versioning
+their user configuration files (also known as @emph{dotfiles}) in a single
+directory, and some way of automatically deploy changes to their user home.
+
+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 the layout suggested by
+@uref{https://www.gnu.org/software/stow/, GNU Stow},
+and have their dotfiles automatically deployed to their user home, without
+migrating them to Guix native configurations.
+
+The dotfiles directory layout is expected to be structured as follows. Please
+keep in mind that it is advisable to keep your dotfiles directories under
+version control, for example in the same repository where you'd track your
+Guix Home configuration.
+
+@example
+~$ tree -a .dotfiles/
+.dotfiles/
+??? git
+? ??? .gitconfig
+??? gpg
+? ??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? guile
+? ??? .guile
+??? guix
+? ??? .config
+? ??? guix
+? ??? channels.scm
+??? nix
+? ??? .config
+? ? ??? nixpkgs
+? ? ??? config.nix
+? ??? .nix-channels
+??? tmux
+? ??? .tmux.conf
+??? vim
+ ??? .vimrc
+
+13 directories, 10 files
+@end example
+
+For an informal specification please refer to the Stow manual
+(@pxref{Top,,, stow, Introduction}). A suitable configuration would then
+be:
+
+@lisp
+(use-modules (guix utils))
+
+(home-environment
+
+ [...]
+
+ (services
+ (service home-dotfiles-service-type
+ (home-dotfiles-configuration
+ (directories
+ (list (string-append (current-source-directory)
+ "/.dotfiles")))))))
+@end lisp
+
+The expected home directory state would be:
+
+@example
+.
+??? .config
+? ??? guix
+? ? ??? channels.scm
+? ??? nixpkgs
+? ??? config.nix
+??? .gitconfig
+??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? .guile
+??? .nix-channels
+??? .tmux.conf
+??? .vimrc
+@end example
+
+@defvar home-dotfiles-service-type
+Return a service which is very similiar to @code{home-files-service-type}
+(and actually extends it), but designed to ease the way into using Guix
+Home for users that already track their dotfiles under some kind of version
+control. This service allows users to point Guix Home to their dotfiles
+directory and have their file automatically deployed to their home directory
+just like Stow would, without migrating all of their dotfiles to Guix native
+configurations.
+@end defvar
+
+@deftp {Data Type} home-dotfiles-configuration
+Available @code{home-dotfiles-configuration} fields are:
+
+@table @asis
+@item @code{directories} (type: list-of-strings)
+The list of dotfiles directories where @code{home-dotfiles-service-type} will
+look for application dotfiles.
+
+@item @code{exclude} (default: @code{'(".*~" ".*\\.swp" "\\.gitignore")})
+The list of file patterns @code{home-dotfiles-service-type} will exclude while
+visiting @code{directories}.
+
+@end table
+
+@end deftp
+
@defvar home-xdg-configuration-files-service-type
The service is very similar to @code{home-files-service-type} (and
actually extends it), but used for defining files, which will go to
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index 8d53f2f4d3..8a74052b5a 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2021-2023 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2022-2023 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -22,6 +23,7 @@ (define-module (gnu home services)
#:use-module (gnu services)
#:use-module ((gnu packages package-management) #:select (guix))
#:use-module ((gnu packages base) #:select (coreutils))
+ #:use-module (guix build utils)
#:use-module (guix channels)
#:use-module (guix monads)
#:use-module (guix store)
@@ -34,15 +36,24 @@ (define-module (gnu home services)
#:use-module (guix i18n)
#:use-module (guix modules)
#:use-module (guix memoization)
+ #:use-module (guix records)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
+ #:use-module (ice-9 ftw)
#:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 string-fun)
#:use-module (ice-9 vlist)
#:export (home-service-type
home-profile-service-type
home-environment-variables-service-type
home-files-service-type
+ home-dotfiles-service-type
+ home-dotfiles-configuration
+ home-dotfiles-configuration?
+ home-dotfiles-configuration-directories
+ home-dotfiles-configuration-excluded
home-xdg-configuration-files-service-type
home-xdg-data-files-service-type
home-run-on-first-login-service-type
@@ -354,6 +365,73 @@ (define home-files-service-type
(description "Files that will be put in
@file{~/.guix-home/files}, and further processed during activation.")))
+(define %home-dotfiles-excluded
+ '(".*~"
+ ".*\\.swp"
+ "\\.gitignore"))
+
+(define-record-type* <home-dotfiles-configuration>
+ home-dotfiles-configuration make-home-dotfiles-configuration
+ home-dotfiles-configuration?
+ (directories home-dotfiles-configuration-directories ;list of strings
+ (default '()))
+ (excluded home-dotfiles-configuration-excluded ;list of strings
+ (default %home-dotfiles-excluded)))
+
+(define* (import-dotfiles directory excluded)
+ "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, excluding files that match any of the patterns in EXCLUDED."
+ (define filtered
+ (find-files directory
+ (lambda (file stat)
+ (not (string-match
+ (string-append
+ "^.*(" (string-join excluded "|") ")$") file)))))
+ (define (strip file)
+ (string-drop file (+ 1 (string-length directory))))
+ (define (format file)
+ (string-append "home-dotfiles-"
+ (string-replace-substring file "/" "-")))
+
+ (map (lambda (file)
+ (let* ((stripped (strip file)))
+ (list stripped
+ (local-file file (format stripped)))))
+ filtered))
+
+(define (home-dotfiles-configuration->files config)
+ "Return a list of objects compatible with @code{home-files-service-type}'s
+value, generated following GNU Stow's algorithm for each of the
+directories in CONFIG, excluding files that match any of the patterns configured."
+ (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
+ (lambda (app)
+ (import-dotfiles app (home-dotfiles-configuration-excluded config)))
+ (directory-contents
+ (home-dotfiles-configuration-directories config))))
+
+(define-public home-dotfiles-service-type
+ (service-type (name 'home-dotfiles)
+ (extensions
+ (list (service-extension home-files-service-type
+ home-dotfiles-configuration->files)))
+ (default-value (home-dotfiles-configuration))
+ (description "Files that will be put in the user's home directory
+following GNU Stow's algorithm, and further processed during activation.")))
+
(define xdg-configuration-files-directory ".config")
(define (xdg-configuration-files files)

base-commit: eeb71d778f149834015858467fbeeb1276d96d1d
--
2.41.0
P
Re: bug#60521: [PATCH] home: Add home-stow-migration-service.
96a1d2be-bf39-f15c-1947-0a6ddeb2e44b@autistici.org
Hi,

I'm sending an updated patchset rebased on current master.


Thank you for your time,


giacomo
G
G
Giacomo Leidi wrote on 22 Sep 2023 15:01
[PATCH] home: Add home-dotfiles-service.
(address . 60521@debbugs.gnu.org)(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)
88eee8890b69cd58052188348f89fc673fa1c922.1695387663.git.goodoldpaul@autistici.org
* 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.
---
doc/guix.texi | 108 ++++++++++++++++++++++++++++++++++++++++++
gnu/home/services.scm | 78 ++++++++++++++++++++++++++++++
2 files changed, 186 insertions(+)

Toggle diff (242 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 617b8463e3..9d75253c2b 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -43239,6 +43239,114 @@ Essential Home Services
read-only home. Feel free to experiment and share your results.
@end defvar
+It is often the case that Guix Home users already have a setup for versioning
+their user configuration files (also known as @emph{dotfiles}) in a single
+directory, and some way of automatically deploy changes to their user home.
+
+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 the layout suggested by
+@uref{https://www.gnu.org/software/stow/, GNU Stow},
+and have their dotfiles automatically deployed to their user home, without
+migrating them to Guix native configurations.
+
+The dotfiles directory layout is expected to be structured as follows. Please
+keep in mind that it is advisable to keep your dotfiles directories under
+version control, for example in the same repository where you'd track your
+Guix Home configuration.
+
+@example
+~$ tree -a .dotfiles/
+.dotfiles/
+??? git
+? ??? .gitconfig
+??? gpg
+? ??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? guile
+? ??? .guile
+??? guix
+? ??? .config
+? ??? guix
+? ??? channels.scm
+??? nix
+? ??? .config
+? ? ??? nixpkgs
+? ? ??? config.nix
+? ??? .nix-channels
+??? tmux
+? ??? .tmux.conf
+??? vim
+ ??? .vimrc
+
+13 directories, 10 files
+@end example
+
+For an informal specification please refer to the Stow manual
+(@pxref{Top,,, stow, Introduction}). A suitable configuration would then
+be:
+
+@lisp
+(use-modules (guix utils))
+
+(home-environment
+
+ [...]
+
+ (services
+ (service home-dotfiles-service-type
+ (home-dotfiles-configuration
+ (directories
+ (list (string-append (current-source-directory)
+ "/.dotfiles")))))))
+@end lisp
+
+The expected home directory state would be:
+
+@example
+.
+??? .config
+? ??? guix
+? ? ??? channels.scm
+? ??? nixpkgs
+? ??? config.nix
+??? .gitconfig
+??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? .guile
+??? .nix-channels
+??? .tmux.conf
+??? .vimrc
+@end example
+
+@defvar home-dotfiles-service-type
+Return a service which is very similiar to @code{home-files-service-type}
+(and actually extends it), but designed to ease the way into using Guix
+Home for users that already track their dotfiles under some kind of version
+control. This service allows users to point Guix Home to their dotfiles
+directory and have their file automatically deployed to their home directory
+just like Stow would, without migrating all of their dotfiles to Guix native
+configurations.
+@end defvar
+
+@deftp {Data Type} home-dotfiles-configuration
+Available @code{home-dotfiles-configuration} fields are:
+
+@table @asis
+@item @code{directories} (type: list-of-strings)
+The list of dotfiles directories where @code{home-dotfiles-service-type} will
+look for application dotfiles.
+
+@item @code{exclude} (default: @code{'(".*~" ".*\\.swp" "\\.gitignore")})
+The list of file patterns @code{home-dotfiles-service-type} will exclude while
+visiting @code{directories}.
+
+@end table
+
+@end deftp
+
@defvar home-xdg-configuration-files-service-type
The service is very similar to @code{home-files-service-type} (and
actually extends it), but used for defining files, which will go to
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index 8d53f2f4d3..8a74052b5a 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2021-2023 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2022-2023 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -22,6 +23,7 @@ (define-module (gnu home services)
#:use-module (gnu services)
#:use-module ((gnu packages package-management) #:select (guix))
#:use-module ((gnu packages base) #:select (coreutils))
+ #:use-module (guix build utils)
#:use-module (guix channels)
#:use-module (guix monads)
#:use-module (guix store)
@@ -34,15 +36,24 @@ (define-module (gnu home services)
#:use-module (guix i18n)
#:use-module (guix modules)
#:use-module (guix memoization)
+ #:use-module (guix records)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
+ #:use-module (ice-9 ftw)
#:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 string-fun)
#:use-module (ice-9 vlist)
#:export (home-service-type
home-profile-service-type
home-environment-variables-service-type
home-files-service-type
+ home-dotfiles-service-type
+ home-dotfiles-configuration
+ home-dotfiles-configuration?
+ home-dotfiles-configuration-directories
+ home-dotfiles-configuration-excluded
home-xdg-configuration-files-service-type
home-xdg-data-files-service-type
home-run-on-first-login-service-type
@@ -354,6 +365,73 @@ (define home-files-service-type
(description "Files that will be put in
@file{~/.guix-home/files}, and further processed during activation.")))
+(define %home-dotfiles-excluded
+ '(".*~"
+ ".*\\.swp"
+ "\\.gitignore"))
+
+(define-record-type* <home-dotfiles-configuration>
+ home-dotfiles-configuration make-home-dotfiles-configuration
+ home-dotfiles-configuration?
+ (directories home-dotfiles-configuration-directories ;list of strings
+ (default '()))
+ (excluded home-dotfiles-configuration-excluded ;list of strings
+ (default %home-dotfiles-excluded)))
+
+(define* (import-dotfiles directory excluded)
+ "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, excluding files that match any of the patterns in EXCLUDED."
+ (define filtered
+ (find-files directory
+ (lambda (file stat)
+ (not (string-match
+ (string-append
+ "^.*(" (string-join excluded "|") ")$") file)))))
+ (define (strip file)
+ (string-drop file (+ 1 (string-length directory))))
+ (define (format file)
+ (string-append "home-dotfiles-"
+ (string-replace-substring file "/" "-")))
+
+ (map (lambda (file)
+ (let* ((stripped (strip file)))
+ (list stripped
+ (local-file file (format stripped)))))
+ filtered))
+
+(define (home-dotfiles-configuration->files config)
+ "Return a list of objects compatible with @code{home-files-service-type}'s
+value, generated following GNU Stow's algorithm for each of the
+directories in CONFIG, excluding files that match any of the patterns configured."
+ (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
+ (lambda (app)
+ (import-dotfiles app (home-dotfiles-configuration-excluded config)))
+ (directory-contents
+ (home-dotfiles-configuration-directories config))))
+
+(define-public home-dotfiles-service-type
+ (service-type (name 'home-dotfiles)
+ (extensions
+ (list (service-extension home-files-service-type
+ home-dotfiles-configuration->files)))
+ (default-value (home-dotfiles-configuration))
+ (description "Files that will be put in the user's home directory
+following GNU Stow's algorithm, and further processed during activation.")))
+
(define xdg-configuration-files-directory ".config")
(define (xdg-configuration-files files)

base-commit: f45c0c82289d409b4fac00464ea8b323839ba53f
--
2.41.0
N
N
Nicolas Odermatt-Lemay wrote on 2 Oct 2023 04:19
(address . 60521@debbugs.gnu.org)
CAC-BrWq8YQrOgWGqBsJBDDxiQZOuyVGayEt0X=WQsy_2=-vsNg@mail.gmail.com
Hi ! I've been playing with the code from this patch and I'd suggest adding
the .git directory to %home-dotfiles-excluded
Attachment: file
P
(name . Ludovic Courtès)(address . ludo@gnu.org)
3a46ad25-5d49-f121-6910-8582aa2bdff7@autistici.org
Hi Nicolas, nice catch. I'm sending a patchset rebased on current master
Attachment: file
G
G
Giacomo Leidi wrote on 6 Oct 2023 23:22
[PATCH] home: Add home-dotfiles-service.
(address . 60521@debbugs.gnu.org)(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)
6455ef24879021f0d1cb1f302d40df1ed5aa4370.1696627320.git.goodoldpaul@autistici.org
* 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.
---
doc/guix.texi | 108 ++++++++++++++++++++++++++++++++++++++++++
gnu/home/services.scm | 79 ++++++++++++++++++++++++++++++
2 files changed, 187 insertions(+)

Toggle diff (243 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index 52a573f0d8..56ec1f4d7c 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -43348,6 +43348,114 @@ Essential Home Services
read-only home. Feel free to experiment and share your results.
@end defvar
+It is often the case that Guix Home users already have a setup for versioning
+their user configuration files (also known as @emph{dotfiles}) in a single
+directory, and some way of automatically deploy changes to their user home.
+
+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 the layout suggested by
+@uref{https://www.gnu.org/software/stow/, GNU Stow},
+and have their dotfiles automatically deployed to their user home, without
+migrating them to Guix native configurations.
+
+The dotfiles directory layout is expected to be structured as follows. Please
+keep in mind that it is advisable to keep your dotfiles directories under
+version control, for example in the same repository where you'd track your
+Guix Home configuration.
+
+@example
+~$ tree -a .dotfiles/
+.dotfiles/
+??? git
+? ??? .gitconfig
+??? gpg
+? ??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? guile
+? ??? .guile
+??? guix
+? ??? .config
+? ??? guix
+? ??? channels.scm
+??? nix
+? ??? .config
+? ? ??? nixpkgs
+? ? ??? config.nix
+? ??? .nix-channels
+??? tmux
+? ??? .tmux.conf
+??? vim
+ ??? .vimrc
+
+13 directories, 10 files
+@end example
+
+For an informal specification please refer to the Stow manual
+(@pxref{Top,,, stow, Introduction}). A suitable configuration would then
+be:
+
+@lisp
+(use-modules (guix utils))
+
+(home-environment
+
+ [...]
+
+ (services
+ (service home-dotfiles-service-type
+ (home-dotfiles-configuration
+ (directories
+ (list (string-append (current-source-directory)
+ "/.dotfiles")))))))
+@end lisp
+
+The expected home directory state would be:
+
+@example
+.
+??? .config
+? ??? guix
+? ? ??? channels.scm
+? ??? nixpkgs
+? ??? config.nix
+??? .gitconfig
+??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? .guile
+??? .nix-channels
+??? .tmux.conf
+??? .vimrc
+@end example
+
+@defvar home-dotfiles-service-type
+Return a service which is very similiar to @code{home-files-service-type}
+(and actually extends it), but designed to ease the way into using Guix
+Home for users that already track their dotfiles under some kind of version
+control. This service allows users to point Guix Home to their dotfiles
+directory and have their file automatically deployed to their home directory
+just like Stow would, without migrating all of their dotfiles to Guix native
+configurations.
+@end defvar
+
+@deftp {Data Type} home-dotfiles-configuration
+Available @code{home-dotfiles-configuration} fields are:
+
+@table @asis
+@item @code{directories} (type: list-of-strings)
+The list of dotfiles directories where @code{home-dotfiles-service-type} will
+look for application dotfiles.
+
+@item @code{exclude} (default: @code{'(".*~" ".*\\.swp" "\\.gitignore")})
+The list of file patterns @code{home-dotfiles-service-type} will exclude while
+visiting @code{directories}.
+
+@end table
+
+@end deftp
+
@defvar home-xdg-configuration-files-service-type
The service is very similar to @code{home-files-service-type} (and
actually extends it), but used for defining files, which will go to
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index 8d53f2f4d3..87c4a95da3 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2021-2023 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2022-2023 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -22,6 +23,7 @@ (define-module (gnu home services)
#:use-module (gnu services)
#:use-module ((gnu packages package-management) #:select (guix))
#:use-module ((gnu packages base) #:select (coreutils))
+ #:use-module (guix build utils)
#:use-module (guix channels)
#:use-module (guix monads)
#:use-module (guix store)
@@ -34,15 +36,24 @@ (define-module (gnu home services)
#:use-module (guix i18n)
#:use-module (guix modules)
#:use-module (guix memoization)
+ #:use-module (guix records)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
+ #:use-module (ice-9 ftw)
#:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 string-fun)
#:use-module (ice-9 vlist)
#:export (home-service-type
home-profile-service-type
home-environment-variables-service-type
home-files-service-type
+ home-dotfiles-service-type
+ home-dotfiles-configuration
+ home-dotfiles-configuration?
+ home-dotfiles-configuration-directories
+ home-dotfiles-configuration-excluded
home-xdg-configuration-files-service-type
home-xdg-data-files-service-type
home-run-on-first-login-service-type
@@ -354,6 +365,74 @@ (define home-files-service-type
(description "Files that will be put in
@file{~/.guix-home/files}, and further processed during activation.")))
+(define %home-dotfiles-excluded
+ '(".*~"
+ ".*\\.swp"
+ "\\.git"
+ "\\.gitignore"))
+
+(define-record-type* <home-dotfiles-configuration>
+ home-dotfiles-configuration make-home-dotfiles-configuration
+ home-dotfiles-configuration?
+ (directories home-dotfiles-configuration-directories ;list of strings
+ (default '()))
+ (excluded home-dotfiles-configuration-excluded ;list of strings
+ (default %home-dotfiles-excluded)))
+
+(define* (import-dotfiles directory excluded)
+ "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, excluding files that match any of the patterns in EXCLUDED."
+ (define filtered
+ (find-files directory
+ (lambda (file stat)
+ (not (string-match
+ (string-append
+ "^.*(" (string-join excluded "|") ")$") file)))))
+ (define (strip file)
+ (string-drop file (+ 1 (string-length directory))))
+ (define (format file)
+ (string-append "home-dotfiles-"
+ (string-replace-substring file "/" "-")))
+
+ (map (lambda (file)
+ (let* ((stripped (strip file)))
+ (list stripped
+ (local-file file (format stripped)))))
+ filtered))
+
+(define (home-dotfiles-configuration->files config)
+ "Return a list of objects compatible with @code{home-files-service-type}'s
+value, generated following GNU Stow's algorithm for each of the
+directories in CONFIG, excluding files that match any of the patterns configured."
+ (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
+ (lambda (app)
+ (import-dotfiles app (home-dotfiles-configuration-excluded config)))
+ (directory-contents
+ (home-dotfiles-configuration-directories config))))
+
+(define-public home-dotfiles-service-type
+ (service-type (name 'home-dotfiles)
+ (extensions
+ (list (service-extension home-files-service-type
+ home-dotfiles-configuration->files)))
+ (default-value (home-dotfiles-configuration))
+ (description "Files that will be put in the user's home directory
+following GNU Stow's algorithm, and further processed during activation.")))
+
(define xdg-configuration-files-directory ".config")
(define (xdg-configuration-files files)

base-commit: add2a22ad7bcca2521432e3f486460138401d5a5
--
2.41.0
P
[60521] Add home-dotfiles-service-type - Rebased on master
(address . 60521@debbugs.gnu.org)
0a34b882-cb82-cbb2-50fe-f85725acf024@autistici.org
Hi,

I'm sending an updated patchset rebased on current master.


Thank you for your time,


giacomo
G
G
Giacomo Leidi wrote on 29 Oct 2023 13:59
[PATCH v4] home: Add home-dotfiles-service.
(address . 60521@debbugs.gnu.org)(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)
e4a9099751cbb2b592b5e74b3c8ec14ccfbd4795.1698584366.git.goodoldpaul@autistici.org
* 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.
---
doc/guix.texi | 108 ++++++++++++++++++++++++++++++++++++++++++
gnu/home/services.scm | 79 ++++++++++++++++++++++++++++++
2 files changed, 187 insertions(+)

Toggle diff (243 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index b90078be06..7ef75d09da 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -43502,6 +43502,114 @@ Essential Home Services
read-only home. Feel free to experiment and share your results.
@end defvar
+It is often the case that Guix Home users already have a setup for versioning
+their user configuration files (also known as @emph{dotfiles}) in a single
+directory, and some way of automatically deploy changes to their user home.
+
+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 the layout suggested by
+@uref{https://www.gnu.org/software/stow/, GNU Stow},
+and have their dotfiles automatically deployed to their user home, without
+migrating them to Guix native configurations.
+
+The dotfiles directory layout is expected to be structured as follows. Please
+keep in mind that it is advisable to keep your dotfiles directories under
+version control, for example in the same repository where you'd track your
+Guix Home configuration.
+
+@example
+~$ tree -a .dotfiles/
+.dotfiles/
+??? git
+? ??? .gitconfig
+??? gpg
+? ??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? guile
+? ??? .guile
+??? guix
+? ??? .config
+? ??? guix
+? ??? channels.scm
+??? nix
+? ??? .config
+? ? ??? nixpkgs
+? ? ??? config.nix
+? ??? .nix-channels
+??? tmux
+? ??? .tmux.conf
+??? vim
+ ??? .vimrc
+
+13 directories, 10 files
+@end example
+
+For an informal specification please refer to the Stow manual
+(@pxref{Top,,, stow, Introduction}). A suitable configuration would then
+be:
+
+@lisp
+(use-modules (guix utils))
+
+(home-environment
+
+ [...]
+
+ (services
+ (service home-dotfiles-service-type
+ (home-dotfiles-configuration
+ (directories
+ (list (string-append (current-source-directory)
+ "/.dotfiles")))))))
+@end lisp
+
+The expected home directory state would be:
+
+@example
+.
+??? .config
+? ??? guix
+? ? ??? channels.scm
+? ??? nixpkgs
+? ??? config.nix
+??? .gitconfig
+??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? .guile
+??? .nix-channels
+??? .tmux.conf
+??? .vimrc
+@end example
+
+@defvar home-dotfiles-service-type
+Return a service which is very similiar to @code{home-files-service-type}
+(and actually extends it), but designed to ease the way into using Guix
+Home for users that already track their dotfiles under some kind of version
+control. This service allows users to point Guix Home to their dotfiles
+directory and have their file automatically deployed to their home directory
+just like Stow would, without migrating all of their dotfiles to Guix native
+configurations.
+@end defvar
+
+@deftp {Data Type} home-dotfiles-configuration
+Available @code{home-dotfiles-configuration} fields are:
+
+@table @asis
+@item @code{directories} (type: list-of-strings)
+The list of dotfiles directories where @code{home-dotfiles-service-type} will
+look for application dotfiles.
+
+@item @code{exclude} (default: @code{'(".*~" ".*\\.swp" "\\.git" "\\.gitignore")})
+The list of file patterns @code{home-dotfiles-service-type} will exclude while
+visiting each one of the @code{directories}.
+
+@end table
+
+@end deftp
+
@defvar home-xdg-configuration-files-service-type
The service is very similar to @code{home-files-service-type} (and
actually extends it), but used for defining files, which will go to
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index 44f585aff5..ff649e9612 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2022-2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2023 Carlo Zancanaro <carlo@zancanaro.id.au>
+;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -23,6 +24,7 @@ (define-module (gnu home services)
#:use-module (gnu services)
#:use-module ((gnu packages package-management) #:select (guix))
#:use-module ((gnu packages base) #:select (coreutils))
+ #:use-module (guix build utils)
#:use-module (guix channels)
#:use-module (guix monads)
#:use-module (guix store)
@@ -35,15 +37,24 @@ (define-module (gnu home services)
#:use-module (guix i18n)
#:use-module (guix modules)
#:use-module (guix memoization)
+ #:use-module (guix records)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
+ #:use-module (ice-9 ftw)
#:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 string-fun)
#:use-module (ice-9 vlist)
#:export (home-service-type
home-profile-service-type
home-environment-variables-service-type
home-files-service-type
+ home-dotfiles-service-type
+ home-dotfiles-configuration
+ home-dotfiles-configuration?
+ home-dotfiles-configuration-directories
+ home-dotfiles-configuration-excluded
home-xdg-configuration-files-service-type
home-xdg-data-files-service-type
home-run-on-first-login-service-type
@@ -355,6 +366,74 @@ (define home-files-service-type
(description "Files that will be put in
@file{~/.guix-home/files}, and further processed during activation.")))
+(define %home-dotfiles-excluded
+ '(".*~"
+ ".*\\.swp"
+ "\\.git"
+ "\\.gitignore"))
+
+(define-record-type* <home-dotfiles-configuration>
+ home-dotfiles-configuration make-home-dotfiles-configuration
+ home-dotfiles-configuration?
+ (directories home-dotfiles-configuration-directories ;list of strings
+ (default '()))
+ (excluded home-dotfiles-configuration-excluded ;list of strings
+ (default %home-dotfiles-excluded)))
+
+(define* (import-dotfiles directory excluded)
+ "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, excluding files that match any of the patterns in EXCLUDED."
+ (define filtered
+ (find-files directory
+ (lambda (file stat)
+ (not (string-match
+ (string-append
+ "^.*(" (string-join excluded "|") ")$") file)))))
+ (define (strip file)
+ (string-drop file (+ 1 (string-length directory))))
+ (define (format file)
+ (string-append "home-dotfiles-"
+ (string-replace-substring file "/" "-")))
+
+ (map (lambda (file)
+ (let* ((stripped (strip file)))
+ (list stripped
+ (local-file file (format stripped)))))
+ filtered))
+
+(define (home-dotfiles-configuration->files config)
+ "Return a list of objects compatible with @code{home-files-service-type}'s
+value, generated following GNU Stow's algorithm for each of the
+directories in CONFIG, excluding files that match any of the patterns configured."
+ (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
+ (lambda (app)
+ (import-dotfiles app (home-dotfiles-configuration-excluded config)))
+ (directory-contents
+ (home-dotfiles-configuration-directories config))))
+
+(define-public home-dotfiles-service-type
+ (service-type (name 'home-dotfiles)
+ (extensions
+ (list (service-extension home-files-service-type
+ home-dotfiles-configuration->files)))
+ (default-value (home-dotfiles-configuration))
+ (description "Files that will be put in the user's home directory
+following GNU Stow's algorithm, and further processed during activation.")))
+
(define xdg-configuration-files-directory ".config")
(define (xdg-configuration-files files)

base-commit: 2b5c6e1a41e4ddcf4cfa53a319ed784a856eac5d
--
2.41.0
F
F
Feng Shu wrote on 6 Nov 2023 01:55
[PATCH] home: Add home-stow-migration-service.
(address . 60521@debbugs.gnu.org)
87a5rrk8dx.fsf@163.com
This feature is very useful for me, thanks very much.

I have faced a small bug when try it.

if a softlink to direcory in dotfiles dir, it will show error,
softlink to file have not this problem.

```
dotfiles
rime
.config/ibus/rime
.emacs.d/rime -> ../.config/ibus/rime

```
F
F
Feng Shu wrote on 7 Nov 2023 09:58
(address . 60521@debbugs.gnu.org)
87ttpyueh7.fsf@163.com
Another small issue is that filename with space can not be handle
properly :-)
F
F
Feng Shu wrote on 9 Nov 2023 01:59
(address . 60521@debbugs.gnu.org)
87zfznd9mr.fsf@163.com
Hello, What about add template feature to home-dotfiles-service-type.
for example, if I have a stow file like below.

.Xresources
```
xft.dpi: $MYDPI
```

I can config home-dotfiles-service-type to replace $MYDPI to a value.

maybe we can add a converter argument and let user define a converter
function to handle all text file before local-file.

--
P
Re: [60521] Add home-dotfiles-service-type - Rebased on master
2882eccf-000b-3db4-b2da-2dcb5c68e8ff@autistici.org
Hello Feng Shu,

Apologies for the delay. I fixed the bug you pointed out for symlinks
and spaces in file names. Thank you for catching them!

About templating I would suggest you to use mixed-text-file or computed
file from (guix gexp) and pass them directly to them
home-files-service-type. It is possible to use it together with
home-dotfiles-service-type.

giacomo
Attachment: file
P
(address . 60521@debbugs.gnu.org)
ca18b1e9-06df-73e6-d9bf-e1e1f0fa20e7@autistici.org
Hello,

I'm sending an updated patchset rebased on current master.


Thank you for your time,


giacomo
G
G
Giacomo Leidi wrote on 21 Jan 18:08 +0100
[PATCH v5] home: Add home-dotfiles-service.
(address . 60521@debbugs.gnu.org)(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)
20240121170802.13719-1-goodoldpaul@autistici.org
* 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.
---
doc/guix.texi | 108 ++++++++++++++++++++++++++++++++++++++++++
gnu/home/services.scm | 88 ++++++++++++++++++++++++++++++++++
2 files changed, 196 insertions(+)

Toggle diff (252 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index ac17f91f7d..68697a041e 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -43961,6 +43961,114 @@ to use alternative services to implement more advanced use cases like
read-only home. Feel free to experiment and share your results.
@end defvar
+It is often the case that Guix Home users already have a setup for versioning
+their user configuration files (also known as @emph{dotfiles}) in a single
+directory, and some way of automatically deploy changes to their user home.
+
+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 the layout suggested by
+@uref{https://www.gnu.org/software/stow/, GNU Stow},
+and have their dotfiles automatically deployed to their user home, without
+migrating them to Guix native configurations.
+
+The dotfiles directory layout is expected to be structured as follows. Please
+keep in mind that it is advisable to keep your dotfiles directories under
+version control, for example in the same repository where you'd track your
+Guix Home configuration.
+
+@example
+~$ tree -a .dotfiles/
+.dotfiles/
+??? git
+? ??? .gitconfig
+??? gpg
+? ??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? guile
+? ??? .guile
+??? guix
+? ??? .config
+? ??? guix
+? ??? channels.scm
+??? nix
+? ??? .config
+? ? ??? nixpkgs
+? ? ??? config.nix
+? ??? .nix-channels
+??? tmux
+? ??? .tmux.conf
+??? vim
+ ??? .vimrc
+
+13 directories, 10 files
+@end example
+
+For an informal specification please refer to the Stow manual
+(@pxref{Top,,, stow, Introduction}). A suitable configuration would then
+be:
+
+@lisp
+(use-modules (guix utils))
+
+(home-environment
+
+ [...]
+
+ (services
+ (service home-dotfiles-service-type
+ (home-dotfiles-configuration
+ (directories
+ (list (string-append (current-source-directory)
+ "/.dotfiles")))))))
+@end lisp
+
+The expected home directory state would be:
+
+@example
+.
+??? .config
+? ??? guix
+? ? ??? channels.scm
+? ??? nixpkgs
+? ??? config.nix
+??? .gitconfig
+??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? .guile
+??? .nix-channels
+??? .tmux.conf
+??? .vimrc
+@end example
+
+@defvar home-dotfiles-service-type
+Return a service which is very similiar to @code{home-files-service-type}
+(and actually extends it), but designed to ease the way into using Guix
+Home for users that already track their dotfiles under some kind of version
+control. This service allows users to point Guix Home to their dotfiles
+directory and have their file automatically deployed to their home directory
+just like Stow would, without migrating all of their dotfiles to Guix native
+configurations.
+@end defvar
+
+@deftp {Data Type} home-dotfiles-configuration
+Available @code{home-dotfiles-configuration} fields are:
+
+@table @asis
+@item @code{directories} (type: list-of-strings)
+The list of dotfiles directories where @code{home-dotfiles-service-type} will
+look for application dotfiles.
+
+@item @code{exclude} (default: @code{'(".*~" ".*\\.swp" "\\.git" "\\.gitignore")})
+The list of file patterns @code{home-dotfiles-service-type} will exclude while
+visiting each one of the @code{directories}.
+
+@end table
+
+@end deftp
+
@defvar home-xdg-configuration-files-service-type
The service is very similar to @code{home-files-service-type} (and
actually extends it), but used for defining files, which will go to
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index 44f585aff5..aece51cde4 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2022-2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2023 Carlo Zancanaro <carlo@zancanaro.id.au>
+;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -23,6 +24,7 @@ (define-module (gnu home services)
#:use-module (gnu services)
#:use-module ((gnu packages package-management) #:select (guix))
#:use-module ((gnu packages base) #:select (coreutils))
+ #:use-module (guix build utils)
#:use-module (guix channels)
#:use-module (guix monads)
#:use-module (guix store)
@@ -35,15 +37,24 @@ (define-module (gnu home services)
#:use-module (guix i18n)
#:use-module (guix modules)
#:use-module (guix memoization)
+ #:use-module (guix records)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
+ #:use-module (ice-9 ftw)
#:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 string-fun)
#:use-module (ice-9 vlist)
#:export (home-service-type
home-profile-service-type
home-environment-variables-service-type
home-files-service-type
+ home-dotfiles-service-type
+ home-dotfiles-configuration
+ home-dotfiles-configuration?
+ home-dotfiles-configuration-directories
+ home-dotfiles-configuration-excluded
home-xdg-configuration-files-service-type
home-xdg-data-files-service-type
home-run-on-first-login-service-type
@@ -355,6 +366,83 @@ (define home-files-service-type
(description "Files that will be put in
@file{~/.guix-home/files}, and further processed during activation.")))
+(define %home-dotfiles-excluded
+ '(".*~"
+ ".*\\.swp"
+ "\\.git"
+ "\\.gitignore"))
+
+(define-record-type* <home-dotfiles-configuration>
+ home-dotfiles-configuration make-home-dotfiles-configuration
+ home-dotfiles-configuration?
+ (directories home-dotfiles-configuration-directories ;list of strings
+ (default '()))
+ (excluded home-dotfiles-configuration-excluded ;list of strings
+ (default %home-dotfiles-excluded)))
+
+(define* (import-dotfiles directory excluded)
+ "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, excluding files that match any of the patterns in EXCLUDED."
+ (define filtered
+ (find-files directory
+ (lambda (file stat)
+ (not (string-match
+ (string-append
+ "^.*(" (string-join excluded "|") ")$") file)))))
+ (define (strip file)
+ (string-drop file (+ 1 (string-length directory))))
+ (define (resolve file)
+ (if (eq? 'symlink (stat:type (lstat file)))
+ (let ((resolved (readlink file)))
+ (with-directory-excursion (dirname file)
+ (canonicalize-path resolved)))
+ file))
+ (define (format file)
+ (let* ((without-spaces
+ (string-replace-substring file " " "_"))
+ (without-slashes-and-spaces
+ (string-replace-substring without-spaces "/" "-")))
+ (string-append "home-dotfiles-" without-slashes-and-spaces)))
+
+ (map (lambda (file)
+ (let* ((stripped (strip file)))
+ (list stripped
+ (local-file (resolve file) (format stripped)))))
+ filtered))
+
+(define (home-dotfiles-configuration->files config)
+ "Return a list of objects compatible with @code{home-files-service-type}'s
+value, generated following GNU Stow's algorithm for each of the
+directories in CONFIG, excluding files that match any of the patterns configured."
+ (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
+ (lambda (app)
+ (import-dotfiles app (home-dotfiles-configuration-excluded config)))
+ (directory-contents
+ (home-dotfiles-configuration-directories config))))
+
+(define-public home-dotfiles-service-type
+ (service-type (name 'home-dotfiles)
+ (extensions
+ (list (service-extension home-files-service-type
+ home-dotfiles-configuration->files)))
+ (default-value (home-dotfiles-configuration))
+ (description "Files that will be put in the user's home directory
+following GNU Stow's algorithm, and further processed during activation.")))
+
(define xdg-configuration-files-directory ".config")
(define (xdg-configuration-files files)

base-commit: 121de47decc1029c06f6e46e5f06d7fefe8e85ec
--
2.41.0
T
T
tumashu wrote on 22 Jan 01:16 +0100
Re:Re: [60521] Add home-dotfiles-service-type - Rebased on master
(name . paul)(address . goodoldpaul@autistici.org)(address . 60521@debbugs.gnu.org)
1dfe3e4f.1d9.18d2e86320b.Coremail.tumashu@163.com
It is possible to use it together with home-dotfiles- service-type.


can you give a simple example? thanks






--
?????????????



? 2024-01-22 01:06:19?paul <goodoldpaul@autistici.org> ???


Hello Feng Shu,

Apologies for the delay. I fixed the bug you pointed out for symlinks and spaces in file names. Thank you for catching them!

About templating I would suggest you to use mixed-text-file or computed file from (guix gexp) and pass them directly to them home-files-service-type. It is possible to use it together with home-dotfiles-service-type.








giacomo
Attachment: file
G
G
Giacomo wrote on 22 Jan 09:12 +0100
(name . tumashu)(address . tumashu@163.com)(address . 60521@debbugs.gnu.org)
772A4BF6-A930-44D6-B0D5-44922FD7908C@autistici.org
Hello,

This is what I tried in my configuration. It should work:

(define mydpi "192")

(home-environment
[...]
(services
(list
[...]
(service home-files-service-type
`((".Xresources" ,(mixed-text-file "Xresources" "xft.dpi:" mydpi))))
(service home-dotfiles-service-type
(home-dotfiles-configuration
(directories
(list "/home/myself/guix-conf/.dotfiles")))))))

Hope this helps,

giacomo

Il 22 gennaio 2024 01:16:03 CET, tumashu <tumashu@163.com> ha scritto:
Toggle quote (32 lines)
> It is possible to use it together with home-dotfiles- service-type.
>
>
>can you give a simple example? thanks
>
>
>
>
>
>
>--
>?????????????
>
>
>
>? 2024-01-22 01:06:19?paul <goodoldpaul@autistici.org> ???
>
>
>Hello Feng Shu,
>
>Apologies for the delay. I fixed the bug you pointed out for symlinks and spaces in file names. Thank you for catching them!
>
>About templating I would suggest you to use mixed-text-file or computed file from (guix gexp) and pass them directly to them home-files-service-type. It is possible to use it together with home-dotfiles-service-type.
>
>
>
>
>
>
>
>
>giacomo
Attachment: file
F
F
Feng Shu wrote on 22 Jan 13:36 +0100
Re: [60521] Add home-dotfiles-service-type - Rebased on master
(name . paul)(address . goodoldpaul@autistici.org)(address . 60521@debbugs.gnu.org)
87zfwxzgrm.fsf@163.com
paul <goodoldpaul@autistici.org> writes:

Toggle quote (5 lines)
> Hello Feng Shu,
>
> Apologies for the delay. I fixed the bug you pointed out for symlinks and spaces in file names. Thank you for
> catching them!

I have tested symlinks like below:
feng@Guix ~/geeguix/geehome/dotfiles/rime/.emacs.d$ ls -al
drwxr-xr-x 2 feng users 4096 1?22? 20:26 ./
drwxr-xr-x 5 feng users 4096 11? 6? 19:20 ../
lrwxrwxrwx 1 feng users 20 1?22? 20:26 rime -> ../.config/ibus/rime

and ../.config/ibus/rime is a directory, show error:

guix home: error: regular file expected


Toggle quote (6 lines)
>
> About templating I would suggest you to use mixed-text-file or computed file from (guix gexp) and pass them
> directly to them home-files-service-type. It is possible to use it together with home-dotfiles-service-type.
>
> giacomo

--
P
(name . Feng Shu)(address . tumashu@163.com)(address . 60521@debbugs.gnu.org)
151fb78b-ed1a-e2c0-036d-c927d6c7429d@autistici.org
Hello,

the following works for me with the attached configuration.

$ tree -a .

.

??? guix-home-project

    ??? .dotfiles

    ?   ??? rime

    ?       ??? .config

    ?       ?   ??? ibus

    ?       ??? .emacs.d

    ??? test-config.scm

7 directories, 1 file

$ echo hello > guix-home-project/.dotfiles/rime/.config/ibus/rime

$ cd guix-home-project/.dotfiles/rime/.emacs.d/ && ln -s ../.config/ibus/rime ./

$ ls -al
total 4
drwxr-xr-x 1 paul users  8 Jan 22 17:37 ./
drwxr-xr-x 1 paul users 30 Jan 22 17:31 ../
lrwxrwxrwx 1 paul users 20 Jan 22 17:37 rime -> ../.config/ibus/rime

 $ cd ../.. && guix home container --share=`pwd`/..=$HOME test-config.scm
WARNING: (guile-user): imported module (guix build utils) overrides core binding `delete'
WARNING: (guile-user): imported module (guix build utils) overrides core binding `delete'
Cleaning up symlinks from previous home at /gnu/store/hpnywydkrfygcl2qplxwgypqqwny16x5-home.

Removing /home/paul/.profile... done
Removing /home/paul/.emacs.d/rime... done
Removed /home/paul/.emacs.d.
Removing /home/paul/.config/fontconfig/fonts.conf... done
Removed /home/paul/.config/fontconfig.
Removing /home/paul/.config/ibus/rime... done
Removed /home/paul/.config/ibus.
Removed /home/paul/.config.
Cleanup finished.

Symlinking /home/paul/.profile -> /gnu/store/l27r8vj94ggr3na9pb1snizsmvh0zrxl-shell-profile... done
Symlinking /home/paul/.emacs.d/rime -> /gnu/store/05v76y32j495v8dw6aaknp91k0371q34-home-dotfiles-.emacs.d-rime... done
Symlinking /home/paul/.config/fontconfig/fonts.conf -> /gnu/store/sfj8h6zbacaz3y3gqzxqsbz3621nq4jv-fonts.conf... done
Symlinking /home/paul/.config/ibus/rime -> /gnu/store/lfw0i01pmwzaia6f7lb9c4p84y357pbd-home-dotfiles-.config-ibus-rime... done
 done
Finished updating symlinks.

Comparing /gnu/store/hpnywydkrfygcl2qplxwgypqqwny16x5-home/profile/share/fonts and
          /gnu/store/hpnywydkrfygcl2qplxwgypqqwny16x5-home/profile/share/fonts... done (same)
Evaluating on-change gexps.

On-change gexps evaluation finished.

warning: XDG_RUNTIME_DIR doesn't exists, on-first-login script
won't execute anything.  You can check if xdg runtime directory exists,
XDG_RUNTIME_DIR variable is set to appropriate value and manually execute the
-bash-5.1$  cat .emacs.d/rimex-home/on-first-login'-bash-5.1$  cat .emacs.d/rime
hello
-bash-5.1$ ls -al .emacs.d/
total 4
drwxr-xr-x 1 paul users   8 Jan 22 16:42 .
drwxr-xr-x 1 paul users 234 Jan 22 16:42 ..
lrwxrwxrwx 1 paul users  71 Jan 22 16:42 rime -> /gnu/store/05v76y32j495v8dw6aaknp91k0371q34-home-dotfiles-.emacs.d-rime
-bash-5.1$

Hope this helps,

giacomo
Attachment: file
(use-modules (gnu home) (gnu home services) (small-guix home services dotfiles-v2) (guix utils)) (home-environment (services (list (service home-dotfiles-service-type (home-dotfiles-configuration (directories (list (string-append (current-source-directory) "/.dotfiles"))))))))
F
F
Feng Shu wrote on 23 Jan 13:14 +0100
(name . paul)(address . goodoldpaul@autistici.org)(address . 60521@debbugs.gnu.org)
87sf2o9rhe.fsf@163.com
paul <goodoldpaul@autistici.org> writes:

Toggle quote (17 lines)
> Hello,
>
> the following works for me with the attached configuration.
>
> $ tree -a .
> .
> ??? guix-home-project
> ??? .dotfiles
> ? ??? rime
> ? ??? .config
> ? ? ??? ibus
> ? ??? .emacs.d
> ??? test-config.scm
>
> 7 directories, 1 file
> $ echo hello > guix-home-project/.dotfiles/rime/.config/ibus/rime

In my machine, rime is a directory and not a file.

If this situation is hard to support, maybe we should add note to document.


Toggle quote (51 lines)
> $ cd guix-home-project/.dotfiles/rime/.emacs.d/ && ln -s ../.config/ibus/rime ./
> $ ls -al
> total 4
> drwxr-xr-x 1 paul users 8 Jan 22 17:37 ./
> drwxr-xr-x 1 paul users 30 Jan 22 17:31 ../
> lrwxrwxrwx 1 paul users 20 Jan 22 17:37 rime -> ../.config/ibus/rime
> $ cd ../.. && guix home container --share=`pwd`/..=$HOME test-config.scm
> WARNING: (guile-user): imported module (guix build utils) overrides core binding `delete'
> WARNING: (guile-user): imported module (guix build utils) overrides core binding `delete'
> Cleaning up symlinks from previous home at /gnu/store/hpnywydkrfygcl2qplxwgypqqwny16x5-home.
>
> Removing /home/paul/.profile... done
> Removing /home/paul/.emacs.d/rime... done
> Removed /home/paul/.emacs.d.
> Removing /home/paul/.config/fontconfig/fonts.conf... done
> Removed /home/paul/.config/fontconfig.
> Removing /home/paul/.config/ibus/rime... done
> Removed /home/paul/.config/ibus.
> Removed /home/paul/.config.
> Cleanup finished.
>
> Symlinking /home/paul/.profile -> /gnu/store/l27r8vj94ggr3na9pb1snizsmvh0zrxl-shell-profile... done
> Symlinking /home/paul/.emacs.d/rime -> /gnu/store/05v76y32j495v8dw6aaknp91k0371q34-home-dotfiles-.emacs.d-rime... done
> Symlinking /home/paul/.config/fontconfig/fonts.conf -> /gnu/store/sfj8h6zbacaz3y3gqzxqsbz3621nq4jv-fonts.conf... done
> Symlinking /home/paul/.config/ibus/rime -> /gnu/store/lfw0i01pmwzaia6f7lb9c4p84y357pbd-home-dotfiles-.config-ibus-rime... done
> done
> Finished updating symlinks.
>
> Comparing /gnu/store/hpnywydkrfygcl2qplxwgypqqwny16x5-home/profile/share/fonts and
> /gnu/store/hpnywydkrfygcl2qplxwgypqqwny16x5-home/profile/share/fonts... done (same)
> Evaluating on-change gexps.
>
> On-change gexps evaluation finished.
>
> warning: XDG_RUNTIME_DIR doesn't exists, on-first-login script
> won't execute anything. You can check if xdg runtime directory exists,
> XDG_RUNTIME_DIR variable is set to appropriate value and manually execute the
> -bash-5.1$ cat .emacs.d/rimex-home/on-first-login'-bash-5.1$ cat .emacs.d/rime
> hello
> -bash-5.1$ ls -al .emacs.d/
> total 4
> drwxr-xr-x 1 paul users 8 Jan 22 16:42 .
> drwxr-xr-x 1 paul users 234 Jan 22 16:42 ..
> lrwxrwxrwx 1 paul users 71 Jan 22 16:42 rime -> /gnu/store/05v76y32j495v8dw6aaknp91k0371q34-home-dotfiles-.emacs.d-rime
> -bash-5.1$
>
> Hope this helps,
>
> giacomo
>

--
F
F
Feng Shu wrote on 24 Jan 12:58 +0100
(name . paul)(address . goodoldpaul@autistici.org)(address . 60521@debbugs.gnu.org)
871qa7kkof.fsf@163.com
paul <goodoldpaul@autistici.org> writes:

Toggle quote (8 lines)
> Hello Feng Shu,
>
> Apologies for the delay. I fixed the bug you pointed out for symlinks and spaces in file names. Thank you for
> catching them!
>
> About templating I would suggest you to use mixed-text-file or computed file from (guix gexp) and pass them
> directly to them home-files-service-type. It is possible to use it together with home-dotfiles-service-type.

At the moment, I use the below code, seem to work well:


(service
home-dotfiles-service-type
(home-dotfiles-configuration
(directories
(list (string-append
(current-source-directory)
"/dotfiles")))
(template-config
'((".home-dotfiles-template"
("var1" . "hello")
("var2" . "world"))))))


----------------------------------------------------------


(define-module (gee home services)
#:use-module (gnu home services)
#:use-module (guix build utils)
#:use-module (guix gexp)
#:use-module (guix records)
#:use-module (srfi srfi-1)
#:use-module (ice-9 ftw)
#:use-module (ice-9 regex)
#:use-module (ice-9 string-fun)
#:use-module (ice-9 textual-ports)

#:export (home-dotfiles-service-type
home-dotfiles-configuration
home-dotfiles-configuration?
home-dotfiles-configuration-directories
home-dotfiles-configuration-excluded))

(define %home-dotfiles-excluded
'(".*~"
".*\\.swp"
"\\.git"
"\\.gitignore"))

(define-record-type* <home-dotfiles-configuration>
home-dotfiles-configuration make-home-dotfiles-configuration
home-dotfiles-configuration?
(directories home-dotfiles-configuration-directories ;list of strings
(default '()))
(excluded home-dotfiles-configuration-excluded ;list of strings
(default %home-dotfiles-excluded))
(template-config home-dotfiles-configuration-template-config
(default '())))

(define* (import-dotfiles directory excluded template-config)
"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, excluding files that match any of the patterns in EXCLUDED."
(define filtered
(find-files directory
(lambda (file stat)
(not (string-match
(string-append
"^.*(" (string-join excluded "|") ")$") file)))))
(define (strip file)
(string-drop file (+ 1 (string-length directory))))
(define (resolve file)
(if (eq? 'symlink (stat:type (lstat file)))
(let ((resolved (readlink file)))
(with-directory-excursion (dirname file)
(canonicalize-path resolved)))
file))
(define (format file)
(let* ((without-spaces
(string-replace-substring file " " "_"))
(without-slashes-and-spaces
(string-replace-substring without-spaces "/" "-")))
(string-append "home-dotfiles-" without-slashes-and-spaces)))

(map (lambda (file)
(let* ((stripped (strip file))
(template-vars (assoc-ref template-config stripped)))
(list stripped
(if template-vars
(plain-file (format stripped)
(template-generate (resolve file) template-vars))
(local-file (resolve file) (format stripped))))))
filtered))

(define (template-generate template-file template-variables)
(let ((string (call-with-input-file template-file get-string-all)))
(map (lambda (x)
(let ((var (string-append "{{{" (car x) "}}}"))
(value (cdr x)))
(set! string (string-replace-substring string var value))))
template-variables)
string))

(define (home-dotfiles-configuration->files config)
"Return a list of objects compatible with @code{home-files-service-type}'s
value, generated following GNU Stow's algorithm for each of the
directories in CONFIG, excluding files that match any of the patterns configured."
(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
(lambda (app)
(import-dotfiles
app
(home-dotfiles-configuration-excluded config)
(home-dotfiles-configuration-template-config config)))
(directory-contents
(home-dotfiles-configuration-directories config))))

(define-public home-dotfiles-service-type
(service-type (name 'home-dotfiles)
(extensions
(list (service-extension home-files-service-type
home-dotfiles-configuration->files)))
(default-value (home-dotfiles-configuration))
(description "Files that will be put in the user's home directory
following GNU Stow's algorithm, and further processed during activation.")))




Toggle quote (3 lines)
>
> giacomo

--
P
(name . Feng Shu)(address . tumashu@163.com)(address . 60521@debbugs.gnu.org)
4fa19dc8-dc0b-5fc0-c762-ea2805c14f0d@autistici.org
Hi,

On 1/24/24 12:58, Feng Shu wrote:
Toggle quote (2 lines)
> At the moment, I use the below code, seem to work well:

I understand it's possible but it's really more easy and consistent to
use gexp, for longer files you can import them with local-file and
process them inside computed-file for example with substitute* from
(guix build utils) i believe.

But I should have fixed the bug for symlinks for real this time :) I'm
sending an updated patchset, please let me know if v6 works for your use
case.

giacomo
G
G
Giacomo Leidi wrote on 26 Jan 18:48 +0100
[PATCH v6] home: Add home-dotfiles-service.
(address . 60521@debbugs.gnu.org)(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)
20240126174850.9671-1-goodoldpaul@autistici.org
* 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.
---
doc/guix.texi | 108 ++++++++++++++++++++++++++++++++++++++++++
gnu/home/services.scm | 89 ++++++++++++++++++++++++++++++++++
2 files changed, 197 insertions(+)

Toggle diff (253 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index db0c751ded..a555900f07 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -44204,6 +44204,114 @@ to use alternative services to implement more advanced use cases like
read-only home. Feel free to experiment and share your results.
@end defvar
+It is often the case that Guix Home users already have a setup for versioning
+their user configuration files (also known as @emph{dotfiles}) in a single
+directory, and some way of automatically deploy changes to their user home.
+
+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 the layout suggested by
+@uref{https://www.gnu.org/software/stow/, GNU Stow},
+and have their dotfiles automatically deployed to their user home, without
+migrating them to Guix native configurations.
+
+The dotfiles directory layout is expected to be structured as follows. Please
+keep in mind that it is advisable to keep your dotfiles directories under
+version control, for example in the same repository where you'd track your
+Guix Home configuration.
+
+@example
+~$ tree -a .dotfiles/
+.dotfiles/
+??? git
+? ??? .gitconfig
+??? gpg
+? ??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? guile
+? ??? .guile
+??? guix
+? ??? .config
+? ??? guix
+? ??? channels.scm
+??? nix
+? ??? .config
+? ? ??? nixpkgs
+? ? ??? config.nix
+? ??? .nix-channels
+??? tmux
+? ??? .tmux.conf
+??? vim
+ ??? .vimrc
+
+13 directories, 10 files
+@end example
+
+For an informal specification please refer to the Stow manual
+(@pxref{Top,,, stow, Introduction}). A suitable configuration would then
+be:
+
+@lisp
+(use-modules (guix utils))
+
+(home-environment
+
+ [...]
+
+ (services
+ (service home-dotfiles-service-type
+ (home-dotfiles-configuration
+ (directories
+ (list (string-append (current-source-directory)
+ "/.dotfiles")))))))
+@end lisp
+
+The expected home directory state would be:
+
+@example
+.
+??? .config
+? ??? guix
+? ? ??? channels.scm
+? ??? nixpkgs
+? ??? config.nix
+??? .gitconfig
+??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? .guile
+??? .nix-channels
+??? .tmux.conf
+??? .vimrc
+@end example
+
+@defvar home-dotfiles-service-type
+Return a service which is very similiar to @code{home-files-service-type}
+(and actually extends it), but designed to ease the way into using Guix
+Home for users that already track their dotfiles under some kind of version
+control. This service allows users to point Guix Home to their dotfiles
+directory and have their file automatically deployed to their home directory
+just like Stow would, without migrating all of their dotfiles to Guix native
+configurations.
+@end defvar
+
+@deftp {Data Type} home-dotfiles-configuration
+Available @code{home-dotfiles-configuration} fields are:
+
+@table @asis
+@item @code{directories} (type: list-of-strings)
+The list of dotfiles directories where @code{home-dotfiles-service-type} will
+look for application dotfiles.
+
+@item @code{exclude} (default: @code{'(".*~" ".*\\.swp" "\\.git" "\\.gitignore")})
+The list of file patterns @code{home-dotfiles-service-type} will exclude while
+visiting each one of the @code{directories}.
+
+@end table
+
+@end deftp
+
@defvar home-xdg-configuration-files-service-type
The service is very similar to @code{home-files-service-type} (and
actually extends it), but used for defining files, which will go to
diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index 44f585aff5..3e925c07c8 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2022-2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2023 Carlo Zancanaro <carlo@zancanaro.id.au>
+;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -23,6 +24,7 @@ (define-module (gnu home services)
#:use-module (gnu services)
#:use-module ((gnu packages package-management) #:select (guix))
#:use-module ((gnu packages base) #:select (coreutils))
+ #:use-module (guix build utils)
#:use-module (guix channels)
#:use-module (guix monads)
#:use-module (guix store)
@@ -35,15 +37,24 @@ (define-module (gnu home services)
#:use-module (guix i18n)
#:use-module (guix modules)
#:use-module (guix memoization)
+ #:use-module (guix records)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
+ #:use-module (ice-9 ftw)
#:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 string-fun)
#:use-module (ice-9 vlist)
#:export (home-service-type
home-profile-service-type
home-environment-variables-service-type
home-files-service-type
+ home-dotfiles-service-type
+ home-dotfiles-configuration
+ home-dotfiles-configuration?
+ home-dotfiles-configuration-directories
+ home-dotfiles-configuration-excluded
home-xdg-configuration-files-service-type
home-xdg-data-files-service-type
home-run-on-first-login-service-type
@@ -355,6 +366,84 @@ (define home-files-service-type
(description "Files that will be put in
@file{~/.guix-home/files}, and further processed during activation.")))
+(define %home-dotfiles-excluded
+ '(".*~"
+ ".*\\.swp"
+ "\\.git"
+ "\\.gitignore"))
+
+(define-record-type* <home-dotfiles-configuration>
+ home-dotfiles-configuration make-home-dotfiles-configuration
+ home-dotfiles-configuration?
+ (directories home-dotfiles-configuration-directories ;list of strings
+ (default '()))
+ (excluded home-dotfiles-configuration-excluded ;list of strings
+ (default %home-dotfiles-excluded)))
+
+(define* (import-dotfiles directory excluded)
+ "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, excluding files that match any of the patterns in EXCLUDED."
+ (define filtered
+ (find-files directory
+ (lambda (file stat)
+ (not (string-match
+ (string-append
+ "^.*(" (string-join excluded "|") ")$") file)))))
+ (define (strip file)
+ (string-drop file (+ 1 (string-length directory))))
+ (define (resolve file)
+ (if (eq? 'symlink (stat:type (lstat file)))
+ (let ((resolved (readlink file)))
+ (with-directory-excursion (dirname file)
+ (canonicalize-path resolved)))
+ file))
+ (define (format file)
+ (let* ((without-spaces
+ (string-replace-substring file " " "_"))
+ (without-slashes-and-spaces
+ (string-replace-substring without-spaces "/" "-")))
+ (string-append "home-dotfiles-" without-slashes-and-spaces)))
+
+ (map (lambda (file)
+ (let* ((stripped (strip file)))
+ (list stripped
+ (local-file (resolve file) (format stripped)
+ #:recursive? #t))))
+ filtered))
+
+(define (home-dotfiles-configuration->files config)
+ "Return a list of objects compatible with @code{home-files-service-type}'s
+value, generated following GNU Stow's algorithm for each of the
+directories in CONFIG, excluding files that match any of the patterns configured."
+ (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
+ (lambda (app)
+ (import-dotfiles app (home-dotfiles-configuration-excluded config)))
+ (directory-contents
+ (home-dotfiles-configuration-directories config))))
+
+(define-public home-dotfiles-service-type
+ (service-type (name 'home-dotfiles)
+ (extensions
+ (list (service-extension home-files-service-type
+ home-dotfiles-configuration->files)))
+ (default-value (home-dotfiles-configuration))
+ (description "Files that will be put in the user's home directory
+following GNU Stow's algorithm, and further processed during activation.")))
+
(define xdg-configuration-files-directory ".config")
(define (xdg-configuration-files files)

base-commit: 8ae8b9804fa4aef23d4028563559bf7bec52fec2
--
2.41.0
F
F
Feng Shu wrote on 27 Jan 03:54 +0100
Re: [60521] Add home-dotfiles-service-type - Rebased on master
(name . paul)(address . goodoldpaul@autistici.org)(address . 60521@debbugs.gnu.org)
87cytn7afe.fsf@163.com
paul <goodoldpaul@autistici.org> writes:

Toggle quote (10 lines)
> Hi,
>
> On 1/24/24 12:58, Feng Shu wrote:
>> At the moment, I use the below code, seem to work well:
>
> I understand it's possible but it's really more easy and consistent to
> use gexp, for longer files you can import them with local-file and
> process them inside computed-file for example with substitute* from
> (guix build utils) i believe.

I will try gexp approach in the future.

Toggle quote (5 lines)
>
> But I should have fixed the bug for symlinks for real this time :) I'm
> sending an updated patchset, please let me know if v6 works for your
> use case.

Works, thanks!

Toggle quote (4 lines)
>
> giacomo
>

--
S
S
Sergey Trofimov wrote on 27 Jan 21:21 +0100
Re: [bug#60521] [PATCH] home: Add home-stow-migration-service.
(name . Ludovic Courtès)(address . ludo@gnu.org)
87h6iy7ca7.fsf@sarg.org.ru
Ludovic Courtès <ludo@gnu.org> writes:

Toggle quote (11 lines)
> Hi!
>
> Giacomo Leidi <goodoldpaul@autistici.org> skribis:
>
>> * gnu/home/services.scm (dotfiles-for-app): New variable;
>> (home-stow-migration-configuration): new variable;
>> (home-stow-migration-service): new variable.
>> * doc/guix.texi: Document it.
>
> That looks very useful!
>
Does it really warrant a new service, when what's needed is a
procedure which traverses a directory recursively and returns a
list of file-likes.

I have this in my home.scm:

Toggle snippet (29 lines)
(define (del-prefix p str)
(if (string-prefix? p str)
(substring/shared str (string-length p))
str))

(define* (as-local-files dir #:optional (trim-prefix dir))
(let ((absolute-dir (string-append (getcwd) "/" dir))
(to-trim (string-append (getcwd) "/" trim-prefix "/")))
(map (lambda (fn)
(list
(del-prefix to-trim fn)
(local-file (canonicalize-path fn) (del-prefix "."
(basename fn)) #:recursive? #t)))
(find-files absolute-dir))))

(simple-service 'configs
home-files-service-type
append!
(with-directory-excursion
(current-source-directory)
`(,@(as-local-files "../backup")
,@(as-local-files "../android")
,@(as-local-files "../email")
,@(as-local-files "../xsession")
,@(as-local-files "../git")
,@(as-local-files "../qutebrowser")
,@(as-local-files "../desktop"))))

And the only need for this snippet is because there are filenames
starting with dot and they can't be put in store as is.
S
S
Sergey Trofimov wrote on 27 Jan 21:21 +0100
(name . Ludovic Courtès)(address . ludo@gnu.org)
87ede27c9f.fsf@sarg.org.ru
Ludovic Courtès <ludo@gnu.org> writes:

Toggle quote (11 lines)
> Hi!
>
> Giacomo Leidi <goodoldpaul@autistici.org> skribis:
>
>> * gnu/home/services.scm (dotfiles-for-app): New variable;
>> (home-stow-migration-configuration): new variable;
>> (home-stow-migration-service): new variable.
>> * doc/guix.texi: Document it.
>
> That looks very useful!
>
Does it really warrant a new service, when what's needed is a
procedure which traverses a directory recursively and returns a
list of file-likes?

I have this in my home.scm:

Toggle snippet (29 lines)
(define (del-prefix p str)
(if (string-prefix? p str)
(substring/shared str (string-length p))
str))

(define* (as-local-files dir #:optional (trim-prefix dir))
(let ((absolute-dir (string-append (getcwd) "/" dir))
(to-trim (string-append (getcwd) "/" trim-prefix "/")))
(map (lambda (fn)
(list
(del-prefix to-trim fn)
(local-file (canonicalize-path fn) (del-prefix "."
(basename fn)) #:recursive? #t)))
(find-files absolute-dir))))

(simple-service 'configs
home-files-service-type
append!
(with-directory-excursion
(current-source-directory)
`(,@(as-local-files "../backup")
,@(as-local-files "../android")
,@(as-local-files "../email")
,@(as-local-files "../xsession")
,@(as-local-files "../git")
,@(as-local-files "../qutebrowser")
,@(as-local-files "../desktop"))))

And the only need for this snippet is because there are filenames
starting with dot and they can't be put in store as is.
L
L
Ludovic Courtès wrote on 27 Jan 23:56 +0100
Re: [bug#60521] [PATCH v6] home: Add home-dotfiles-service.
(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)(address . 60521@debbugs.gnu.org)
874jeyjsgy.fsf@gnu.org
Hi Giacomo,

Giacomo Leidi <goodoldpaul@autistici.org> skribis:

Toggle quote (5 lines)
> * 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 again for the long delay.

The patch looks great to me and I think the functionality is there.

I gave it a try for my own config, and that has led me to make the
attached changes, which can be summarized as follows:

• The dotfile directories are resolved relative the source location
where ‘home-dotfiles-configuration’ appears. The advantage is that
users do not need to fiddle with (current-source-directory).

• As a consequence, all ‘with-directory-excursion’ and
‘canonicalize-path’ calls are gone. (Those should only be used with
great care.)

• The dotfile directories are traversed only once, using ‘find-files’.

• The exclusion regexp is compiled only once (with ‘make-regexp’) and
then reused (with ‘regexp-exec’ calls), which is more efficient
than repeated ‘string-match’ calls.

• Use ‘string-map’ instead of ‘string-replace-substring’ (it’s simpler
and more efficient).

If that’s fine with you, please feel free to apply these changes.

One last thing I should have suggested earlier: how about moving it to
(gnu home services dotfiles)? That would keep the scope of (gnu home
services) limited to essential services.

Please send one last version when you’re ready; I’m eager to use it for
my own config actually. :-)

Thank you!

Ludo’.
Attachment: file
P
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 60521@debbugs.gnu.org)
f8934384-99c7-53d7-a405-8cf956e10810@autistici.org
Hi Ludo’ ,

Thank you for your help and nice explanations , I often try and figure
out things from other examples in the code base but it's often difficult
to understand why certain choices were made.

I applied your patch manually because it wouldn't apply somehow with git
apply -3 file.patch , am I doing something wrong?

Anyway I'm sending a patch integrating all your work, thank you!

giacomo
G
G
Giacomo Leidi wrote on 28 Jan 16:37 +0100
[PATCH v7] home: Add home-dotfiles-service.
(address . 60521@debbugs.gnu.org)
20240128153716.20514-1-goodoldpaul@autistici.org
* gnu/home/services.scm: New file;
(dotfiles-for-app): new variable;
(home-dotfiles-configuration): new variable;
(home-dotfiles-service-type): new variable.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
* po/guix/POTFILES.in: Add it.
* doc/guix.texi: Document it.

Change-Id: I6769169cfacefc3842faa5b31bee081c56c28743
Co-authored-by: Ludovic Courtès <ludo@gnu.org>
---
doc/guix.texi | 108 +++++++++++++++++++++++++++++
gnu/home/services/dotfiles.scm | 120 +++++++++++++++++++++++++++++++++
gnu/local.mk | 1 +
po/guix/POTFILES.in | 1 +
4 files changed, 230 insertions(+)
create mode 100644 gnu/home/services/dotfiles.scm

Toggle diff (273 lines)
diff --git a/doc/guix.texi b/doc/guix.texi
index db0c751ded..c723631abe 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -44204,6 +44204,114 @@ to use alternative services to implement more advanced use cases like
read-only home. Feel free to experiment and share your results.
@end defvar
+It is often the case that Guix Home users already have a setup for versioning
+their user configuration files (also known as @emph{dotfiles}) in a single
+directory, and some way of automatically deploy changes to their user home.
+
+The @code{home-dotfiles-service-type} from @code{(gnu home services dotfiles)}
+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 the layout suggested by
+@uref{https://www.gnu.org/software/stow/, GNU Stow},
+and have their dotfiles automatically deployed to their user home, without
+migrating them to Guix native configurations.
+
+The dotfiles directory layout is expected to be structured as follows. Please
+keep in mind that it is advisable to keep your dotfiles directories under
+version control, for example in the same repository where you'd track your
+Guix Home configuration.
+
+@example
+~$ tree -a ./dotfiles/
+dotfiles/
+??? git
+? ??? .gitconfig
+??? gpg
+? ??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? guile
+? ??? .guile
+??? guix
+? ??? .config
+? ??? guix
+? ??? channels.scm
+??? nix
+? ??? .config
+? ? ??? nixpkgs
+? ? ??? config.nix
+? ??? .nix-channels
+??? tmux
+? ??? .tmux.conf
+??? vim
+ ??? .vimrc
+
+13 directories, 10 files
+@end example
+
+For an informal specification please refer to the Stow manual
+(@pxref{Top,,, stow, Introduction}). A suitable configuration would then
+be:
+
+@lisp
+(home-environment
+ ;; @dots{}
+ (services
+ (service home-dotfiles-service-type
+ (home-dotfiles-configuration
+ (directories (list "./dotfiles"))))))
+@end lisp
+
+The expected home directory state would then be:
+
+@example
+.
+??? .config
+? ??? guix
+? ? ??? channels.scm
+? ??? nixpkgs
+? ??? config.nix
+??? .gitconfig
+??? .gnupg
+? ??? gpg-agent.conf
+? ??? gpg.conf
+??? .guile
+??? .nix-channels
+??? .tmux.conf
+??? .vimrc
+@end example
+
+@defvar home-dotfiles-service-type
+Return a service which is very similiar to @code{home-files-service-type}
+(and actually extends it), but designed to ease the way into using Guix
+Home for users that already track their dotfiles under some kind of version
+control. This service allows users to point Guix Home to their dotfiles
+directory and have their files automatically deployed to their home directory
+just like Stow would, without migrating all of their dotfiles to Guix native
+configurations.
+@end defvar
+
+@deftp {Data Type} home-dotfiles-configuration
+Available @code{home-dotfiles-configuration} fields are:
+
+@table @asis
+@item @code{source-directory} (default: @code{(current-source-directory)})
+The path where dotfile directories are resolved. By default dotfile directories
+are resolved relative the source location where
+@code{home-dotfiles-configuration} appears.
+
+@item @code{directories} (type: list-of-strings)
+The list of dotfiles directories where @code{home-dotfiles-service-type} will
+look for application dotfiles.
+
+@item @code{exclude} (default: @code{'(".*~" ".*\\.swp" "\\.git" "\\.gitignore")})
+The list of file patterns @code{home-dotfiles-service-type} will exclude while
+visiting each one of the @code{directories}.
+
+@end table
+
+@end deftp
+
@defvar home-xdg-configuration-files-service-type
The service is very similar to @code{home-files-service-type} (and
actually extends it), but used for defining files, which will go to
diff --git a/gnu/home/services/dotfiles.scm b/gnu/home/services/dotfiles.scm
new file mode 100644
index 0000000000..7226b6bcff
--- /dev/null
+++ b/gnu/home/services/dotfiles.scm
@@ -0,0 +1,120 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2024 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2024 Giacomo Leidi <goodoldpaul@autistici.org>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu home services dotfiles)
+ #:use-module (gnu home services)
+ #:use-module (gnu services)
+ #:autoload (guix build utils) (find-files)
+ #:use-module (guix gexp)
+ #:use-module (guix records)
+ #:use-module ((guix utils) #:select (current-source-directory))
+ #:use-module (srfi srfi-1)
+ #:use-module (ice-9 ftw)
+ #:use-module (ice-9 regex)
+ #:export (home-dotfiles-service-type
+ home-dotfiles-configuration
+ home-dotfiles-configuration?
+ home-dotfiles-configuration-source-directory
+ home-dotfiles-configuration-directories
+ home-dotfiles-configuration-excluded))
+
+(define %home-dotfiles-excluded
+ '(".*~"
+ ".*\\.swp"
+ "\\.git"
+ "\\.gitignore"))
+
+(define-record-type* <home-dotfiles-configuration>
+ home-dotfiles-configuration make-home-dotfiles-configuration
+ home-dotfiles-configuration?
+ (source-directory home-dotfiles-configuration-source-directory
+ (default (current-source-directory))
+ (innate))
+ (directories home-dotfiles-configuration-directories ;list of strings
+ (default '()))
+ (excluded home-dotfiles-configuration-excluded ;list of strings
+ (default %home-dotfiles-excluded)))
+
+(define (import-dotfiles directory files)
+ "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, excluding files that match any of the patterns in EXCLUDED."
+ (define (strip file)
+ (string-join
+ (cdr
+ (string-split (string-drop file (+ 1 (string-length directory)))
+ #\/))
+ "/"))
+ (define (format file)
+ ;; Remove from FILE characters that cannot be used in the store.
+ (string-append
+ "home-dotfiles-"
+ (string-map (lambda (chr)
+ (if (and (char-set-contains? char-set:ascii chr)
+ (char-set-contains? char-set:graphic chr)
+ (not (memv chr '(#\. #\/ #\space))))
+ chr
+ #\-))
+ file)))
+
+ (map (lambda (file)
+ (let ((stripped (strip file)))
+ (list stripped
+ (local-file file (format stripped)
+ #:recursive? #t))))
+ files))
+
+(define (home-dotfiles-configuration->files config)
+ "Return a list of objects compatible with @code{home-files-service-type}'s
+value, generated following GNU Stow's algorithm for each of the
+directories in CONFIG, excluding files that match any of the patterns configured."
+ (define excluded
+ (home-dotfiles-configuration-excluded config))
+ (define exclusion-rx
+ (make-regexp (string-append "^.*(" (string-join excluded "|") ")$")))
+
+ (define (directory-contents directory)
+ (find-files directory
+ (lambda (file stat)
+ (not (regexp-exec exclusion-rx
+ (basename file))))))
+
+ (define (resolve directory)
+ ;; Resolve DIRECTORY relative to the 'source-directory' field of CONFIG.
+ (if (string-prefix? "/" directory)
+ directory
+ (in-vicinity (home-dotfiles-configuration-source-directory config)
+ directory)))
+
+ (append-map (lambda (directory)
+ (let* ((directory (resolve directory))
+ (contents (directory-contents directory)))
+ (import-dotfiles directory contents)))
+ (home-dotfiles-configuration-directories config)))
+
+(define-public home-dotfiles-service-type
+ (service-type (name 'home-dotfiles)
+ (extensions
+ (list (service-extension home-files-service-type
+ home-dotfiles-configuration->files)))
+ (default-value (home-dotfiles-configuration))
+ (description "Files that will be put in the user's home directory
+following GNU Stow's algorithm, and further processed during activation.")))
diff --git a/gnu/local.mk b/gnu/local.mk
index ab63bd5881..f11c65277e 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -96,6 +96,7 @@ GNU_SYSTEM_MODULES = \
%D%/home/services.scm \
%D%/home/services/desktop.scm \
%D%/home/services/dict.scm \
+ %D%/home/services/dotfiles.scm \
%D%/home/services/symlink-manager.scm \
%D%/home/services/fontutils.scm \
%D%/home/services/gnupg.scm \
diff --git a/po/guix/POTFILES.in b/po/guix/POTFILES.in
index 154ad4e530..d13e19619d 100644
--- a/po/guix/POTFILES.in
+++ b/po/guix/POTFILES.in
@@ -14,6 +14,7 @@ gnu/services/samba.scm
gnu/services/version-control.scm
gnu/home/services.scm
gnu/home/services/desktop.scm
+gnu/home/services/dotfiles.scm
gnu/home/services/fontutils.scm
gnu/home/services/gnupg.scm
gnu/home/services/guix.scm

base-commit: 8ae8b9804fa4aef23d4028563559bf7bec52fec2
--
2.41.0
L
L
Ludovic Courtès wrote on 28 Jan 22:02 +0100
(name . Giacomo Leidi)(address . goodoldpaul@autistici.org)(address . 60521-done@debbugs.gnu.org)
877cjtf9y0.fsf@gnu.org
Hi,

Giacomo Leidi <goodoldpaul@autistici.org> skribis:

Toggle quote (11 lines)
> * gnu/home/services.scm: New file;
> (dotfiles-for-app): new variable;
> (home-dotfiles-configuration): new variable;
> (home-dotfiles-service-type): new variable.
> * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
> * po/guix/POTFILES.in: Add it.
> * doc/guix.texi: Document it.
>
> Change-Id: I6769169cfacefc3842faa5b31bee081c56c28743
> Co-authored-by: Ludovic Courtès <ludo@gnu.org>

Committed with the change below (perhaps a mistake I had introduced
myself before) and with a slightly modified commit log.

I’m switching my laptop’s config now. :-)

Thanks for all the work, and thanks for your patience!

Ludo’.
Toggle diff (18 lines)
diff --git a/gnu/home/services/dotfiles.scm b/gnu/home/services/dotfiles.scm
index 7226b6bcff..6a740c42ce 100644
--- a/gnu/home/services/dotfiles.scm
+++ b/gnu/home/services/dotfiles.scm
@@ -58,11 +58,8 @@ (define (import-dotfiles directory files)
generated by recursively visiting DIRECTORY and mapping its contents to the
user's home directory, excluding files that match any of the patterns in EXCLUDED."
(define (strip file)
- (string-join
- (cdr
- (string-split (string-drop file (+ 1 (string-length directory)))
- #\/))
- "/"))
+ (string-drop file (+ 1 (string-length directory))))
+
(define (format file)
;; Remove from FILE characters that cannot be used in the store.
(string-append
Closed
P
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 60521-done@debbugs.gnu.org)
2f62f4fa-9a3e-ea69-54e3-0b5ddfbf3336@autistici.org
Hi Ludo' ,

that was an intentional fix I introduced after trying your code and
having my home break :) . I just believe we are not aligned on the
requirements. Does a tree -a call to your dotfiles directory resemble
what is documented in the manual?

We either need to change the manual or the code, I don't have a clear
preference . At this point I'm just happy this is in Guix but right now
the manual matches Stow's usual directory layout. The code in this state
contradicts the documentation and does not take into account the
additional "git" directory given dotfiles directory that looks like this:

 tree -a dotfiles/
dotfiles/
??? git
    ??? .gitconfig

2 directories, 1 file

Thank you for your time,

giacomo
Closed
P
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 60521-done@debbugs.gnu.org)
180136e2-75cb-79dc-54e7-44dd5ae1e41d@autistici.org
If I can add this is [0] the layout that is documented in the manual,
that Stow suggests and that I'm trying to implement. If you have
something else in mind could you please share your layout?

Thank you

giacomo


Closed
L
L
Ludovic Courtès wrote on 29 Jan 14:20 +0100
Re: [bug#60521] [PATCH] home: Add home-stow-migration-service.
(name . Sergey Trofimov)(address . sarg@sarg.org.ru)
87a5ooqnsl.fsf@gnu.org
Sergey Trofimov <sarg@sarg.org.ru> skribis:

Toggle quote (10 lines)
> (define* (as-local-files dir #:optional (trim-prefix dir))
> (let ((absolute-dir (string-append (getcwd) "/" dir))
> (to-trim (string-append (getcwd) "/" trim-prefix "/")))
> (map (lambda (fn)
> (list
> (del-prefix to-trim fn)
> (local-file (canonicalize-path fn) (del-prefix "."
> (basename fn)) #:recursive? #t)))
> (find-files absolute-dir))))

As you saw, I proposed a different solution: capturing
(current-source-directory) in ‘home-dotfiles-configuration’ and using
that to compute absolute file names (without ever calling
‘canonicalize-path’).

Using ‘getcwd’ would be incorrect or at least surprising: it would
resolve file names relative to the current directory instead of relative
to the directory that contains the source file.

Ludo’.
S
S
Sergey Trofimov wrote on 29 Jan 14:40 +0100
(name . Ludovic Courtès)(address . ludo@gnu.org)
878r48451r.fsf@sarg.org.ru
Ludovic Courtès <ludo@gnu.org> writes:

Toggle quote (25 lines)
> Sergey Trofimov <sarg@sarg.org.ru> skribis:
>
>> (define* (as-local-files dir #:optional (trim-prefix dir))
>> (let ((absolute-dir (string-append (getcwd) "/" dir))
>> (to-trim (string-append (getcwd) "/" trim-prefix "/")))
>> (map (lambda (fn)
>> (list
>> (del-prefix to-trim fn)
>> (local-file (canonicalize-path fn) (del-prefix "."
>> (basename fn)) #:recursive? #t)))
>> (find-files absolute-dir))))
>
> As you saw, I proposed a different solution: capturing
> (current-source-directory) in ‘home-dotfiles-configuration’ and
> using
> that to compute absolute file names (without ever calling
> ‘canonicalize-path’).
>
> Using ‘getcwd’ would be incorrect or at least surprising: it
> would
> resolve file names relative to the current directory instead of
> relative
> to the directory that contains the source file.
>

Sure, in my config I use `with-directory-excursion`, so `getcwd`
returns correct values.

Anyway, the reason I replied was that I am also a former Stow user
and in my eyes we should've extended existing
`home-files-service-type` instead of making a specialized new one.
If you check `stow` manual
it should be invoked with the names of packages to be
installed/removed. `home-dotfiles-service` doesn't have a
parameter for the list of packages and assumes that everything in
the specified directory should be installed, a limitation that
prevents me to start using it. In my dotfiles I have optional
packages which I install depending on OS or machine's purpose.
Sure the service could be amended with the said parameter, but why
adding a new service when a more generic one exists and is fitting
the use case?
G
G
Giacomo wrote on 29 Jan 15:23 +0100
F2B6720E-65D3-47BC-8133-5BAADBECA9E5@autistici.org
Hi Ludo' and Sergey,
I'm not sure my previous emails reached you since I sent them to the -done address of the bug. I'm pasting

The code that was reverted was an intentional fix I introduced after trying the latest revision and having my home break :) . I just believe we are not aligned on the requirements. Ludo': does a tree -a call to your dotfiles directory resemble what is documented in the manual?

We either need to change the manual or the code, I don't have a clear preference . At this point I'm just happy this is in Guix but right now the manual matches Stow's usual directory layout. The code in this state contradicts the documentation and does not take into account the additional "git" directory given dotfiles directory that looks like this:

tree -a dotfiles/
dotfiles/
??? git
??? .gitconfig

2 directories, 1 file

this is [0] the layout that is documented in the manual, that Stow suggests and that I'm trying to implement. If you have something else in mind could you please share your layout?

Thank you

giacomo


Attachment: file
S
S
Sergey Trofimov wrote on 29 Jan 16:19 +0100
(name . Giacomo)(address . goodoldpaul@autistici.org)
874jew405c.fsf@sarg.org.ru
Giacomo <goodoldpaul@autistici.org> writes:

Toggle quote (22 lines)
> Hi Ludo' and Sergey,
> I'm not sure my previous emails reached you since I sent them to
> the -done address of the bug. I'm pasting
>
> We either need to change the manual or the code, I don't have a
> clear preference . At this point I'm just happy this is in Guix
> but
> right now the manual matches Stow's usual directory layout. The
> code in this state contradicts the documentation and does not
> take
> into account the additional "git" directory given dotfiles
> directory that looks like this:
>
> tree -a dotfiles/
> dotfiles/
> ??? git
> ??? .gitconfig
>
> 2 directories, 1 file
>
> this is [0] the layout that is documented in the manual, that
> Stow suggests and that I'm trying to implement.
I don't think stow suggests any layout. I wasn't able to find that
in the manual.

Toggle quote (3 lines)
> If you have something else in mind could you please share your
> layout?


Previously I've used `stow -d ~/.dotfiles zsh awesome git vim ...`
to create the symlinks. Just to emphasize - package list is a
mandatory parameter to `stow`. It should be supported by the
home-dotfiles-service if it is intended as a replacement for
`stow`.
G
G
Giacomo wrote on 29 Jan 17:09 +0100
(name . Sergey Trofimov)(address . sarg@sarg.org.ru)
C591BE6E-289B-48A7-A854-521EA4167F78@autistici.org
Hi Sergey ,

Whether the stow manual mandates/suggests a given layout was analyzed here [0].

The workflow you describe is not the only one possible and the app list is not mandatory. Only when -d is used, please look at my e-mail.

Anyway, if the current implementation works with your directory layout could you please share your home-dotfiles-configuration?

I don't seem to be able to make this implementation work with my layout.

Thank you,

giacomo

Attachment: file
L
L
Ludovic Courtès wrote on 29 Jan 17:10 +0100
(name . Sergey Trofimov)(address . sarg@sarg.org.ru)
87a5oonmsd.fsf@gnu.org
Hi,

Sergey Trofimov <sarg@sarg.org.ru> skribis:

Toggle quote (4 lines)
> Anyway, the reason I replied was that I am also a former Stow user and
> in my eyes we should've extended existing `home-files-service-type`
> instead of making a specialized new one.

‘home-dotfiles-service-type’ technically does extend
‘home-files-service-type’.

Toggle quote (11 lines)
> If you check `stow` manual
> (https://www.gnu.org/software/stow/manual/html_node/Invoking-Stow.html#Invoking-Stow),
> it should be invoked with the names of packages to be
> installed/removed. `home-dotfiles-service` doesn't have a parameter
> for the list of packages and assumes that everything in the specified
> directory should be installed, a limitation that prevents me to start
> using it. In my dotfiles I have optional packages which I install
> depending on OS or machine's purpose. Sure the service could be
> amended with the said parameter, but why adding a new service when a
> more generic one exists and is fitting the use case?

The way I see it, ‘home-dotfiles-service-type’ makes it easier to do
what one could have done with raw ‘home-files-service-type’. The
interface is nice IMO.

Now, we can still change the implementation as we see fit, and for
instance allow users to specify a predicate in the ‘excluded’ field, or
anything that would help address your use case.

WDYT?

Ludo’.
S
S
Sergey Trofimov wrote on 29 Jan 19:34 +0100
(name . Giacomo)(address . goodoldpaul@autistici.org)
87zfwo2d65.fsf@sarg.org.ru
Giacomo <goodoldpaul@autistici.org> writes:

Toggle quote (10 lines)
> Hi Sergey ,
>
> Whether the stow manual mandates/suggests a given layout was
> analyzed here [0].
>
> The workflow you describe is not the only one possible and the
> app list is not mandatory. Only when -d is used, please look at
> my
> e-mail.

I might be missing it, but how can I make stow do its job without
specifying which packages to install?

Toggle snippet (8 lines)
stow (GNU Stow) version 2.3.1

SYNOPSIS:

stow [OPTION ...] [-D|-S|-R] PACKAGE ... [-D|-S|-R] PACKAGE
...

When I omit the package list from the command it returns "stow: No
packages to stow or unstow"

Toggle quote (5 lines)
>
> Anyway, if the current implementation works with your directory
> layout could you please share your home-dotfiles-configuration?
>

Don't use it yet, because it only supports exlusions and I need
"inclusions".
This would work, but doesn't look pretty

Toggle snippet (6 lines)
(service home-dotfiles-service-type
(home-dotfiles-configuration
(directories (list ".."))
(excluded (list "\\.git" "README.md" "emacs" "xmonad" ...))))

This would be optimal:

Toggle snippet (4 lines)
(service home-dotfiles-service-type
(home-dotfiles-configuration
(packages (list "../backup" "../android" ...))))
G
G
Giacomo wrote on 31 Jan 13:31 +0100
Re: New home-dotfiles-service-type creates extra toplevel directories
D29097E8-217F-491E-8BD4-6FD15C1F162E@autistici.org
Hi Janneke, thank you for the report. I already pointed out this at https://issues.guix.gnu.org/60521. there was a fix that was removed by a misunderstanding on the requirements of the service since the code contradicts documentation as you pointed out . It should be pretty easy to apply the fix from 60521.

Thank you

Giacomo

Il 31 gennaio 2024 13:17:25 CET, Janneke Nieuwenhuizen <janneke@gnu.org> ha scritto:
Toggle quote (34 lines)
>Hi,
>
>When I follow the documentation, and have
>
> dotfiles/guix/.config/guix/channels.scm
>
>that shows suing tree -a ./dotfiles
>
> dotfiles
> ??? guix
> ??? .config
> ??? guix
> ??? channels.scm
>
>similar to the documentaion, and using
>
> (service home-dotfiles-service-type
> (home-dotfiles-configuration
> (directories (list "./dotfiles"))))
>
>creates
>
> ~/guix/.config/guix/channels.scm
>
>an extra toplevel `guix" directory!
>
>What gives?
>
>Greetings,
>Janneke
>
>--
>Janneke Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond https://LilyPond.org
>Freelance IT https://www.JoyOfSource.com | Avatar® https://AvatarAcademy.com
Attachment: file
L
L
Ludovic Courtès wrote on 7 Feb 23:17 +0100
Dot file layout for ‘home-dotfiles-service ’
(name . Giacomo)(address . goodoldpaul@autistici.org)
87le7v3oo1.fsf_-_@gnu.org
Hi!

Oops, my sincere apologies if I ended up “fixing” something that was in
fact intentional, effectively breaking it.

Giacomo <goodoldpaul@autistici.org> skribis:

Toggle quote (11 lines)
> The code that was reverted was an intentional fix I introduced after trying the latest revision and having my home break :) . I just believe we are not aligned on the requirements. Ludo': does a tree -a call to your dotfiles directory resemble what is documented in the manual?
>
> We either need to change the manual or the code, I don't have a clear preference . At this point I'm just happy this is in Guix but right now the manual matches Stow's usual directory layout. The code in this state contradicts the documentation and does not take into account the additional "git" directory given dotfiles directory that looks like this:
>
> tree -a dotfiles/
> dotfiles/
> ??? git
> ??? .gitconfig
>
> 2 directories, 1 file

Nope!

Toggle snippet (13 lines)
$ guix shell tree -- tree -a dot-files/
dot-files/
??? .dico
??? .gitconfig
??? .gnupg
?   ??? dirmngr.conf
?   ??? gpa.conf
?   ??? gpg.conf
?   ??? .gpg-v21-migrated
??? .Xdefaults
??? .xsession

So I guess I totally misunderstood the goal; sorry about that!

Where do we go from here? Should we just adjust the manual to match
this? Or the other way around, at the cost of breaking user config? Or
adding an option to choose between these two layouts?

Thanks,
Ludo’.
P
(name . Ludovic Courtès)(address . ludo@gnu.org)
440e04ac-2ab1-6dbe-6b3c-0ce5fcc43d9d@autistici.org
I said I would include Janneke but obviously I didn't :) . Sorry for the
noise

On 2/9/24 01:44, paul wrote:
Toggle quote (61 lines)
>
> Hi Ludo',
>
> On 2/7/24 23:17, Ludovic Courtès wrote:
>> Hi!
>>
>> Oops, my sincere apologies if I ended up “fixing” something that was in
>> fact intentional, effectively breaking it.
> Don't worry I think there's been a misunderstanding from the beginning
> and I was not able to explain myself . Sh*t happens :)
>> Should we just adjust the manual to match
>> this?
> I think that doing so would defeat the original purpose of supporting
> the de facto standard used by Stow users
>> Or the other way around, at the cost of breaking user config?
> This is really about what one means by breaking, we already received a
> bug report at https://issues.guix.gnu.org/68848 which in my opinion
> indicates that we give some expectations through the manual, which is
> not met by the code (I'm adding Janneke to this thread so that we are
> all aligned and can reach consensus).
>> Or adding an option to choose between these two layouts?
> This is the best option forward, in my opinion. It is flexible and
> allows for a both for the current simplified layout (without the
> per-application layer of directories typical of Stow) and the Stow
> default one.
>
> If there's consensus my next steps would be:
>
> 1. Apply Janneke's stylistic suggestion at
> https://issues.guix.gnu.org/68857 allowing us to close
> https://issues.guix.gnu.org/68848 and align the code with the manual
>
> 2. Add a layout field to home-dotfiles-configuration that allows for
> the simplified layout described by Ludo' in his last email, something
> like this
>
> $ guix shell tree -- tree -a dot-files/
> dot-files/
> ??? .dico
> ??? .gitconfig
> ??? .gnupg
> ?   ??? dirmngr.conf
> ?   ??? gpa.conf
> ?   ??? gpg.conf
> ?   ??? .gpg-v21-migrated
> ??? .Xdefaults
> ??? .xsession
>
> the default would be the current layout but this would allow for more
> flexibility in layouts in the future.
>
> 3. Possibly add an included-applications (the name is just a proposal)
> to support Sergey's use case of selecting a subset of application
> dotfiles to provision in the user's home
>
> what do you think about this plan?
>
> thank you all for your help and your time
>
> giacomo
>
Attachment: file
P
(name . Ludovic Courtès)(address . ludo@gnu.org)
dbc7cf88-9225-27bc-338a-d5e6cfaf6bf9@autistici.org
Hi Ludo',

On 2/7/24 23:17, Ludovic Courtès wrote:
Toggle quote (4 lines)
> Hi!
>
> Oops, my sincere apologies if I ended up “fixing” something that was in
> fact intentional, effectively breaking it.
Don't worry I think there's been a misunderstanding from the beginning
and I was not able to explain myself . Sh*t happens :)
Toggle quote (2 lines)
> Should we just adjust the manual to match
> this?
I think that doing so would defeat the original purpose of supporting
the de facto standard used by Stow users
Toggle quote (1 lines)
> Or the other way around, at the cost of breaking user config?
This is really about what one means by breaking, we already received a
bug report at https://issues.guix.gnu.org/68848which in my opinion
indicates that we give some expectations through the manual, which is
not met by the code (I'm adding Janneke to this thread so that we are
all aligned and can reach consensus).
Toggle quote (1 lines)
> Or adding an option to choose between these two layouts?
This is the best option forward, in my opinion. It is flexible and
allows for a both for the current simplified layout (without the
per-application layer of directories typical of Stow) and the Stow
default one.

If there's consensus my next steps would be:

1. Apply Janneke's stylistic suggestion at
https://issues.guix.gnu.org/68848and align the code with the manual

2. Add a layout field to home-dotfiles-configuration that allows for the
simplified layout described by Ludo' in his last email, something like this

$ guix shell tree -- tree -a dot-files/
dot-files/
??? .dico
??? .gitconfig
??? .gnupg
?   ??? dirmngr.conf
?   ??? gpa.conf
?   ??? gpg.conf
?   ??? .gpg-v21-migrated
??? .Xdefaults
??? .xsession

the default would be the current layout but this would allow for more
flexibility in layouts in the future.

3. Possibly add an included-applications (the name is just a proposal)
to support Sergey's use case of selecting a subset of application
dotfiles to provision in the user's home

what do you think about this plan?

thank you all for your help and your time

giacomo
Attachment: file
L
L
Ludovic Courtès wrote on 10 Feb 11:03 +0100
(name . paul)(address . goodoldpaul@autistici.org)
87a5o8k553.fsf@gnu.org
Hi,

paul <goodoldpaul@autistici.org> skribis:

Toggle quote (48 lines)
> On 2/7/24 23:17, Ludovic Courtès wrote:
>> Hi!
>>
>> Oops, my sincere apologies if I ended up “fixing” something that was in
>> fact intentional, effectively breaking it.
> Don't worry I think there's been a misunderstanding from the beginning
> and I was not able to explain myself . Sh*t happens :)
>> Should we just adjust the manual to match
>> this?
> I think that doing so would defeat the original purpose of supporting
> the de facto standard used by Stow users
>> Or the other way around, at the cost of breaking user config?
> This is really about what one means by breaking, we already received a
> bug report at https://issues.guix.gnu.org/68848 which in my opinion
> indicates that we give some expectations through the manual, which is
> not met by the code (I'm adding Janneke to this thread so that we are
> all aligned and can reach consensus).
>> Or adding an option to choose between these two layouts?
> This is the best option forward, in my opinion. It is flexible and
> allows for a both for the current simplified layout (without the
> per-application layer of directories typical of Stow) and the Stow
> default one.
>
> If there's consensus my next steps would be:
>
> 1. Apply Janneke's stylistic suggestion at
> https://issues.guix.gnu.org/68857 allowing us to close
> https://issues.guix.gnu.org/68848 and align the code with the manual
>
> 2. Add a layout field to home-dotfiles-configuration that allows for
> the simplified layout described by Ludo' in his last email, something
> like this
>
> $ guix shell tree -- tree -a dot-files/
> dot-files/
> ??? .dico
> ??? .gitconfig
> ??? .gnupg
> ?   ??? dirmngr.conf
> ?   ??? gpa.conf
> ?   ??? gpg.conf
> ?   ??? .gpg-v21-migrated
> ??? .Xdefaults
> ??? .xsession
>
> the default would be the current layout but this would allow for more
> flexibility in layouts in the future.

Thinking about it, either we add a ‘layout’ field (the default should
probably be the same as it is now, to user’s config will still work the
same).

Toggle quote (4 lines)
> 3. Possibly add an included-applications (the name is just a proposal)
> to support Sergey's use case of selecting a subset of application
> dotfiles to provision in the user's home

I’m not sure I understand but maybe this part can be addressed later.

Thanks,
Ludo’.
J
J
Janneke Nieuwenhuizen wrote on 10 Feb 11:47 +0100
(name . Ludovic Courtès)(address . ludo@gnu.org)
87il2w7g0p.fsf@gnu.org
Ludovic Courtès writes:

Hi,

Toggle quote (8 lines)
> paul <goodoldpaul@autistici.org> skribis:
>
>> On 2/7/24 23:17, Ludovic Courtès wrote:
>>> Hi!
>>>
>>> Oops, my sincere apologies if I ended up “fixing” something that was in
>>> fact intentional, effectively breaking it.

[..]

Toggle quote (19 lines)
>> $ guix shell tree -- tree -a dot-files/
>> dot-files/
>> ??? .dico
>> ??? .gitconfig
>> ??? .gnupg
>> ?   ??? dirmngr.conf
>> ?   ??? gpa.conf
>> ?   ??? gpg.conf
>> ?   ??? .gpg-v21-migrated
>> ??? .Xdefaults
>> ??? .xsession
>>
>> the default would be the current layout but this would allow for more
>> flexibility in layouts in the future.
>
> Thinking about it, either we add a ‘layout’ field (the default should
> probably be the same as it is now, to user’s config will still work the
> same).

+1

Having a layout 'default (or 'plain) vs 'stow makes sense to me.

I can understand how using this stow layout is nice for stow users, but
the extra "package-name" directory that I had to add makes little sense
to me. I added it because this is what the documentation prescribed,
but I would probably be removing those extra "pacage-name" directories.

Greetings,
Janneke

--
Janneke Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond https://LilyPond.org
Freelance IT https://www.JoyOfSource.com| Avatar® https://AvatarAcademy.com
?