Subject: Re: [bug#77882] [PATCH] scripts: home: Support extracting home-environment from Guix System declaration.

From: Hilton Chain <[email-masked]>
Date: Sat, 03 May 2025 19:48:49 +0800

On Mon, 21 Apr 2025 09:33:12 +0800,
Maxim Cournoyer wrote:
>
> Hi,
>
> Hilton Chain <[email-masked]> writes:
>
> > * guix/scripts/home.scm (process-action): Handle operating-system declaration
> > and extract home environment for current user.
> > * doc/guix.texi (Guix Services)[Guix Home Service]: Document it.
>
> The use case is a bit unclear for me, despite reading...
>
> > Change-Id: I995f79c2549e6edc76322542d0422159e0b79996
> > ---
> >  doc/guix.texi         |  5 +++++
> >  guix/scripts/home.scm | 31 +++++++++++++++++++++++++++----
> >  2 files changed, 32 insertions(+), 4 deletions(-)
> >
> > diff --git a/doc/guix.texi b/doc/guix.texi
> > index 070528667f..a58326debf 100644
> > --- a/doc/guix.texi
> > +++ b/doc/guix.texi
> > @@ -42255,6 +42255,11 @@ Guix Services
> >  everything consistently at once, saving users the need to run
> >  @command{guix home reconfigure} independently.
> >
> > +@command{guix home} can operate on the home environment configured for
> > +current user via this service, but its effect won't last beyond the next
> > +system activation.  This can be used for quick testing and may avoid the
> > +need of keeping a separate home configuration.
>
> ... this.
>
> How do you declare a home environment in an `operating-system'
> declaration?  Is this already supported?
>
> Oh! 'guix-home-service-type'.  It seems I'm late in the news.  That's
> cool!
>
> >  @defvar guix-home-service-type
> >  Service type for the Guix Home service.  Its value must be a list of
> >  lists containing user and home environment pairs.  The key of each pair
> > diff --git a/guix/scripts/home.scm b/guix/scripts/home.scm
> > index b4c82d275f..6d0a68166e 100644
> > --- a/guix/scripts/home.scm
> > +++ b/guix/scripts/home.scm
> > @@ -35,6 +35,8 @@ (define-module (guix scripts home)
> >                                               shepherd-service-requirement)
> >    #:autoload   (guix modules) (source-module-closure)
> >    #:autoload   (gnu build linux-container) (call-with-container %namespaces)
> > +  #:use-module ((gnu system) #:select (operating-system?
> > +                                       operating-system-user-services))
> >    #:autoload   (gnu system linux-container) (eval/container)
> >    #:autoload   (gnu system file-systems) (file-system-mapping
> >                                            file-system-mapping-source
> > @@ -478,10 +480,31 @@ (define (process-action action args opts)
> >  declaration as an argument (a file name.)  OPTS is the raw alist of options
> >  resulting from command-line parsing."
> >    (define (ensure-home-environment file-or-exp obj)
> > -    (unless (home-environment? obj)
> > -      (leave (G_ "'~a' does not return a home environment~%")
> > -             file-or-exp))
> > -    obj)
> > +    (let* ((username
> > +            (or (getenv "LOGNAME")
> > +                (passwd:name (getpwuid (getuid)))))
>
> First time I've heard of LOGNAME :-).  Typically I see 'USER' used in
> its place; shouldn't that be consulted as well, or used instead?

OK, I have changed to use USER instead.

> As for the second clause of the above or, it can be simplified to just
> '(getpwnam (getuid))'.

Tried it in REPL, the result is the same as ‘(getpwuid (getuid))’.  So I left it
unchanged.

> > +           (os-home-env-config
> > +            (and (operating-system? obj)
> > +                 (and=> (find (lambda (%service)
> > +                                (eq? (service-type-name (service-kind %service))
> > +                                     'guix-home))
> > +                              (operating-system-user-services obj))
> > +                        service-value)))
> > +           (os-home-env
> > +            (and os-home-env-config
> > +                 (and=> (find (lambda (home-env-config)
> > +                                (string=? (first home-env-config) username))
> > +                              os-home-env-config)
> > +                        second)))
> > +           (home-env
> > +            (or os-home-env obj)))
> > +      (unless (home-environment? home-env)
> > +        (if (operating-system? obj)
> > +            (leave (G_ "'~a' does not contain a home environment for user '~a'~%")
> > +                   file-or-exp username)
> > +            (leave (G_ "'~a' does not return a home environment~%")
> > +                   file-or-exp)))
> > +      home-env))
>
> LGTM.
>
> Reviewed-by: Maxim Cournoyer <maxim.cournoyer@gmail>

Thanks for the review!  Applied as 415e3d98d6faf5fd3d1b7b3daa2f20636e4ff822.