unofficial mirror of help-guix@gnu.org 
 help / color / mirror / Atom feed
* Home service that serializes into an executable file
@ 2023-03-28 20:53 Mario Forzanini
  2023-05-04  6:56 ` Tom Willemse
  0 siblings, 1 reply; 2+ messages in thread
From: Mario Forzanini @ 2023-03-28 20:53 UTC (permalink / raw)
  To: help-guix

Hello everyone!

I've recently tried to write a simple home service that serializes into
an ~/.xsession file. As someone pointed out in an older message on this
list, this file has to be executable; I used to achieve this including
an external file like: (local-file "xsession" #recursive? #t). Is there
a procedure that allows changing permission bits while generating a file
in the store?

This is still in a rough state, but here is the definition of the
service:

<snip>
    (define (serialize-string field-name val) val)

    (define (string-join strings delimiter)
      (if (null? strings)
          ""
          (fold (lambda (s so-far) (string-append so-far delimiter s))
                (car strings)
                (cdr strings))))

    (define (xsession-serialize-program program args)
      (if (pair? program)
          (string-append
           (string-join (cons* "try" (cdr program) args) " ")
           "\n")
          (string-append
           (string-join (cons* "try" (package-name program) args) " ")
           "\n")))

    (define (serialize-xsession-programs field-name alist)
      (generic-serialize-alist string-append
                               xsession-serialize-program
                               alist))

    (define (serialize-xsession-window-manager field-name window-manager)
      (string-append "exec " (cdr window-manager) "\n"))

    (define-configuration home-xsession-configuration
      (window-manager
       (pair `(,dwm . "dwm"))
       "Cons pair of window manager package and executable name."
       serialize-xsession-window-manager)
      (programs
       (alist '())
       "Alist of programs to start and arguments to such programs."
       serialize-xsession-programs)
      (log-file
       (string "$HOME/.local/share/xsession.log")
       "Log file to store errors and info."))

    (define (xsession-filter-fields field)
      (filter-configuration-fields home-xsession-configuration-fields (list field)))

    (define (xsession-serialize-field config field)
      (serialize-configuration config (xsession-filter-fields field)))

    (define (xsession-file config)
      (define dot-xsession
        (mixed-text-file "xsession"
         "#!/bin/sh
    try() {
    pgrep -q $1 || $@ 2>> "
         (xsession-serialize-field config 'log-file)
         "\n}\n"
         (xsession-serialize-field config 'programs)
         (xsession-serialize-field config 'window-manager)))
      `((".xsession" ,dot-xsession)))

    (define (add-xsession-packages config)
      (cons*
       (car (home-xsession-configuration-window-manager config))
       (map (lambda (association)
              (if (pair? (car association))
                  (caar association)
                  (car association)))
            (home-xsession-configuration-programs config))))

    (define home-xsession-service-type
      (service-type (name 'xsession)
                    (extensions
                     (list (service-extension
                            home-files-service-type
                            xsession-file)
                           (service-extension
                            home-profile-service-type
                            add-xsession-packages)))
                    (compose identity)
                    (default-value (home-xsession-configuration))
                    (description "Configure the X session via ~/.xsession.")))
<snap>

This serializes a configuration such as this:

<snip>
    (service home-xsession-service-type
                (home-xsession-configuration
                 (window-manager `(,mf-dwm . "dwm"))
                 (programs
                  `((,picom . ())
                    (,dunst . ())
                    ((,blueman . "blueman-applet") . ())
                    (,pasystray . ())
                    ((,network-manager-applet . "nm-applet") . ())
                    (,mpd . ())
                    (,cbatticon . ("BAT0"))
                    (,cbatticon . ("BAT1"))
                    (,xsettingsd . ())
                    (,tmux . ("new-session" "-d"))
                    (,hsetroot . ("-cover" "$HOME/Pictures/forest.jpg"))
                    (,setxkbmap . ("-layout" "us" "-option" "compose:ralt"))
                    ((,emacs-next . "emacs") . ("--daemon"))))
                 (log-file "~/.local/share/xsession.log")))
<snap>

into:

<snip>
    #!/bin/sh
    try() {
    pgrep -q $1 || $@ 2>> ~/.local/share/xsession.log
    }
    try picom
    try dunst
    try blueman-applet
    try pasystray
    try nm-applet
    try mpd
    try cbatticon BAT0
    try cbatticon BAT1
    try xsettingsd
    try tmux new-session -d
    try hsetroot -cover $HOME/Pictures/forest.jpg
    try setxkbmap -layout us -option compose:ralt
    try emacs --daemon
    exec dwm
<snap>

But the permissions are wrong:

<snip>
    ┌(22:49:18) 
    └(~) % ls -l ~/.xsession                                         
    lrwxrwxrwx 1 mario users 52 Mar 28 22:23 /home/mario/.xsession -> /gnu/store/p213clvznwrrrasr3mygb6iqqnqsg2ra-xsession
    ┌(22:49:21) 
    └(~) % ls -l /gnu/store/p213clvznwrrrasr3mygb6iqqnqsg2ra-xsession 
    -r--r--r-- 1 root root 342 Jan  1  1970 /gnu/store/p213clvznwrrrasr3mygb6iqqnqsg2ra-xsession
<snap>

If you spot something wrong, let me know.

Thank you in advance :)
-- 
Mario


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Home service that serializes into an executable file
  2023-03-28 20:53 Home service that serializes into an executable file Mario Forzanini
@ 2023-05-04  6:56 ` Tom Willemse
  0 siblings, 0 replies; 2+ messages in thread
From: Tom Willemse @ 2023-05-04  6:56 UTC (permalink / raw)
  To: Mario Forzanini, help-guix

Hey Mario!

Mario Forzanini <mf@marioforzanini.com> writes:

> Hello everyone!
>
> I've recently tried to write a simple home service that serializes into
> an ~/.xsession file. As someone pointed out in an older message on this
> list, this file has to be executable; I used to achieve this including
> an external file like: (local-file "xsession" #recursive? #t). Is there
> a procedure that allows changing permission bits while generating a file
> in the store?
>
> This is still in a rough state, but here is the definition of the
> service:

That looks nice :) much more interesting than my xsession home service,
which just joins a few strings together into an .xsession file.

I ran into this issue as well, and what I ended up doing was copying (I
think it was) mixed-text-file and modifying it for my own configuration.

I have:

    (define* (mixed-executable-file name #:key guile #:rest text)
      "Return an object representing store file NAME containing TEXT and having the
    executable bit set. TEXT is a sequence of strings and file-like objects, as in:
    
      (mixed-executable-file \"profile\"
                             \"export PATH=\" coreutils \"/bin:\" grep \"/bin\")"
      (define build
        (let ((text (if guile (drop text 2) text)))
          (gexp (call-with-output-file (ungexp output "out")
                  (lambda (port)
                    (set-port-encoding! port "UTF-8")
                    (display (string-append (ungexp-splicing text)) port)
                    (chmod port #o555))))))
    
      (computed-file name build #:guile guile))

Which really should be just like `mixed-text-file' except the call to
`chmod' has been added. And then I would use it just to replace the
`mixed-text-file'.

> <snip>
>     (define (xsession-file config)
>       (define dot-xsession
>         (mixed-executable-file "xsession"
>          "#!/bin/sh
>     try() {
>     pgrep -q $1 || $@ 2>> "
>          (xsession-serialize-field config 'log-file)
>          "\n}\n"
>          (xsession-serialize-field config 'programs)
>          (xsession-serialize-field config 'window-manager)))
>       `((".xsession" ,dot-xsession)))
> <snap>

I don't know if this is the best solution, but this worked for me.

Hopefully this helps!


Cheers,

Tom


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-05-04  7:18 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-28 20:53 Home service that serializes into an executable file Mario Forzanini
2023-05-04  6:56 ` Tom Willemse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).