GNU bug report logs - #62969
[PATCH] home: Add msmtp service.

Previous Next

Package: guix-patches;

Reported by: Tanguy Le Carrour <tanguy <at> bioneland.org>

Date: Thu, 20 Apr 2023 14:44:02 UTC

Severity: normal

Tags: patch

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 62969 in the body.
You can then email your comments to 62969 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to guix-patches <at> gnu.org:
bug#62969; Package guix-patches. (Thu, 20 Apr 2023 14:44:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Tanguy Le Carrour <tanguy <at> bioneland.org>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Thu, 20 Apr 2023 14:44:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Tanguy Le Carrour <tanguy <at> bioneland.org>
To: guix-patches <at> gnu.org
Cc: Tanguy Le Carrour <tanguy <at> bioneland.org>
Subject: [PATCH] home: Add msmtp service.
Date: Thu, 20 Apr 2023 16:42:30 +0200
Hi Guix,

It's my first time 1) submitting a patch for a home service and
2) editing a `.texi` file, so please be understanding and…
pay special attention! :-)

Be aware that the code contains two FIXMEs:

- one that I don't know how to solve
```
+  ;; FIXME `In procedure every: Wrong type argument: #<syntax-transformer msmtp-account?>`
+  ;(every msmtp-account? lst))
```

- one that is a cosmetic change, and probabliy doesn't need fixing
```
+  ; FIXME Begin each line inside an account section with a space.
+  #~(string-append #$(serialize-configuration value msmtp-configuration-fields)))
```

And the documentation could probably be more detailed!

This being said… thanks for reading!


* gnu/home/services/mail.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
* doc/guix.texi (Mailing): New node.
---
 doc/guix.texi              |  95 ++++++++++++++++++
 gnu/home/services/mail.scm | 196 +++++++++++++++++++++++++++++++++++++
 gnu/local.mk               |   1 +
 3 files changed, 292 insertions(+)
 create mode 100644 gnu/home/services/mail.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index adb1975935..5a1e215d17 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -114,6 +114,7 @@ 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 Tanguy Le Carrour
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -41880,6 +41881,7 @@ services)}.
 * Guix: Guix Home Services.     Services for Guix.
 * Fonts: Fonts Home Services.   Services for managing User's fonts.
 * Sound: Sound Home Services.   Dealing with audio.
+* Mail: Mail Home Services.  Services for managing mail.
 * Messaging: Messaging Home Services.  Services for managing messaging.
 * Media: Media Home Services.   Services for managing media.
 @end menu
@@ -43082,6 +43084,99 @@ Stopping the Shepherd service turns off broadcasting.
 This is the multicast address used by default by the two services above.
 @end defvar
 
+@node Mail Home Services
+@subsection Mail Home Services
+
+@cindex msmtp
+@uref{https://marlam.de/msmtp, MSMTP} is an SMTP client.
+
+@deftp {Data Type} home-msmtp-configuration
+Available @code{home-msmtp-configuration} fields are:
+
+@table @asis
+@item @code{defaults} (type: msmtp-configuration)
+The configuration that will be set as default for all accounts.
+
+@item @code{accounts} (default: @code{()}) (type: list-of-msmtp-accounts)
+A list of @code{msmtp-account} records which contain information about
+all your accounts.
+
+@item @code{default-account} (type: maybe-string)
+Set the default account.
+
+@item @code{extra-content} (default: @code{""}) (type: raw-configuration-string)
+Extra content appended as-is to the configuration file.  Run
+@command{man msmtp} for more information about the configuration file
+format.
+
+@end table
+
+@end deftp
+
+@deftp {Data Type} msmtp-account
+Available @code{msmtp-account} fields are:
+
+@table @asis
+@item @code{name} (type: string)
+The unique name of the account.
+
+@item @code{configuration} (type: msmtp-configuration)
+The configuration for this given account.
+
+@end table
+
+@end deftp
+
+@deftp {Data Type} msmtp-configuration
+Available @code{msmtp-configuration} fields are:
+
+@table @asis
+@item @code{auth?} (type: maybe-boolean)
+Enable or disable authentication.
+
+@item @code{tls?} (type: maybe-boolean)
+Enable or disable TLS (also known as SSL) for secured connections.
+
+@item @code{tls-starttls} (type: maybe-boolean)
+Choose the TLS variant: start TLS from within the session (‘on’,
+default), or tunnel the session through TLS (‘off’).
+
+@item @code{tls-trust-file} (type: maybe-string)
+Activate server certificate verification using a list of trusted
+Certification Authorities (CAs).
+
+@item @code{logfile} (type: maybe-string)
+Enable logging to the specified file.  An empty argument disables
+logging.  The file name ‘-’ directs the log information to standard
+output.
+
+@item @code{host} (type: maybe-string)
+The SMTP server to send the mail to.
+
+@item @code{port} (type: maybe-integer)
+The port that the SMTP server listens on.  The default is 25 ("smtp"),
+unless TLS without STARTTLS is used, in which case it is 465 ("smtps").
+
+@item @code{user} (type: maybe-string)
+Set the user name for authentication.
+
+@item @code{from} (type: maybe-string)
+Set the envelope-from address.
+
+@item @code{passwordeval} (type: maybe-string)
+Set the password for authentication to the output (stdout) of the
+command cmd.
+
+@item @code{extra-content} (default: @code{""}) (type: raw-configuration-string)
+Extra content appended as-is to the configuration block.  Run
+@command{man msmtp} for more information about the configuration file
+format.
+
+@end table
+
+@end deftp
+
+
 @node Messaging Home Services
 @subsection Messaging Home Services
 
diff --git a/gnu/home/services/mail.scm b/gnu/home/services/mail.scm
new file mode 100644
index 0000000000..b31f68d2ca
--- /dev/null
+++ b/gnu/home/services/mail.scm
@@ -0,0 +1,196 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Tanguy Le Carrour <tanguy <at> bioneland.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 mail)
+  #:use-module (guix gexp)
+  #:use-module (gnu packages)
+  #:use-module (gnu services)
+  #:use-module (gnu services configuration)
+  #:use-module (gnu home services)
+  #:use-module (gnu home services shepherd)
+  #:use-module (ice-9 string-fun)
+  #:use-module (srfi srfi-26)
+  #:export (home-msmtp-configuration
+            home-msmtp-configuration?
+            home-msmtp-service-type
+            msmtp-account
+            msmtp-configuration))
+
+(define raw-configuration-string? string?)
+
+(define-maybe string)
+(define-maybe boolean)
+(define-maybe integer)
+
+;; Serialization of 'msmtp'.
+(define (uglify-symbol field-name)
+  (let* ((name (symbol->string field-name))
+         (ugly-name (string-replace-substring name "-" "_")))
+    (if (string-suffix? "?" ugly-name)
+      (string-drop-right ugly-name 1)
+      ugly-name)))
+
+(define (configuration-serialize-maybe-string field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " #$value "\n")
+      ""))
+
+(define (configuration-serialize-maybe-integer field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " (number->string #$value) "\n")
+      ""))
+
+(define (configuration-serialize-maybe-boolean field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " (if #$value "on" "off") "\n")
+      ""))
+
+(define (configuration-serialize-raw-configuration-string field-name value)
+  #~(if #$(string=? value "") "" (string-append #$value "\n")))
+
+(define (account-serialize-name field-name value)
+  #~(string-append "\naccount " #$value "\n"))
+
+(define (account-serialize-string field-name value)
+  #~(string-append " " #$(uglify-symbol field-name) " " #$value "\n"))
+
+(define (account-serialize-string field-name value)
+  #~(string-append " " #$(uglify-symbol field-name) " " #$value "\n"))
+
+(define (account-serialize-msmtp-configuration field-name value)
+  ; FIXME Begin each line inside an account section with a space.
+  #~(string-append #$(serialize-configuration value msmtp-configuration-fields)))
+
+(define (home-configuration-serialize-list-of-msmtp-accounts field-name value)
+  #~(string-append #$@(map (cut serialize-configuration <> msmtp-account-fields)
+                           value)))
+
+(define (home-configuration-serialize-msmtp-configuration field-name value)
+  #~(string-append "defaults\n"
+                   #$(serialize-configuration value msmtp-configuration-fields)))
+
+(define (home-configuration-serialize-string field-name value)
+  #~(string-append #$(uglify-symbol field-name) " " #$value "\n"))
+
+(define (home-configuration-serialize-default-account field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append "\naccount default : " #$value "\n")
+      ""))
+
+(define (home-configuration-serialize-raw-configuration-string field-name value)
+  #~(if #$(string=? value "") "" (string-append #$value "\n")))
+
+;; Configuration of 'msmtp'.
+(define (list-of-msmtp-accounts? lst)
+  ;; FIXME `In procedure every: Wrong type argument: #<syntax-transformer msmtp-account?>`
+  ;(every msmtp-account? lst))
+  #t)
+
+;; Source <https://marlam.de/msmtp/msmtp.html#Configuration-files>.
+(define-configuration msmtp-configuration
+  (auth?
+   maybe-boolean
+   "Enable or disable authentication.")
+  (tls?
+   maybe-boolean
+   "Enable or disable TLS (also known as SSL) for secured connections.")
+  (tls-starttls
+   maybe-boolean
+   "Choose the TLS variant: start TLS from within the session (‘on’, default),
+or tunnel the session through TLS (‘off’).")
+  (tls-trust-file
+   maybe-string
+   "Activate server certificate verification using a list of
+trusted Certification Authorities (CAs).")
+  (logfile
+   maybe-string
+   "Enable logging to the specified file. An empty argument disables logging.
+The file name ‘-’ directs the log information to standard output.")
+  (host
+    maybe-string
+    "The SMTP server to send the mail to.")
+  (port
+    maybe-integer
+    "The port that the SMTP server listens on. The default is 25 (\"smtp\"),
+unless TLS without STARTTLS is used, in which case it is 465 (\"smtps\").")
+  (user
+    maybe-string
+    "Set the user name for authentication.")
+  (from
+    maybe-string
+    "Set the envelope-from address.")
+  (passwordeval
+    maybe-string
+    "Set the password for authentication to the output (stdout) of the command cmd.")
+  (extra-content
+   (raw-configuration-string "")
+   "Extra content appended as-is to the configuration block.  Run
+@command{man msmtp} for more information about the configuration file
+format.")
+  (prefix configuration-))
+
+(define-configuration msmtp-account
+  (name
+   (string)
+   "The unique name of the account."
+   (serializer account-serialize-name))
+  (configuration
+   (msmtp-configuration)
+   "The configuration for this given account.")
+  (prefix account-))
+
+(define-configuration home-msmtp-configuration
+  (defaults
+   (msmtp-configuration (msmtp-configuration))
+   "The configuration that will be set as default for all accounts.")
+  (accounts
+   (list-of-msmtp-accounts '())
+   "A list of @code{msmtp-account} records which contain
+information about all your accounts.")
+  (default-account
+   maybe-string
+   "Set the default account."
+   (serializer home-configuration-serialize-default-account))
+  (extra-content
+   (raw-configuration-string "")
+   "Extra content appended as-is to the configuration file.  Run
+@command{man msmtp} for more information about the configuration file
+format.")
+  (prefix home-configuration-))
+
+(define (home-msmtp-files-service config)
+  (list
+   `(".config/msmtp/config"
+     ,(mixed-text-file "config"
+                       (serialize-configuration config home-msmtp-configuration-fields)))))
+
+(define (home-msmtp-profile-service config)
+  (specifications->packages (list "msmtp")))
+
+(define home-msmtp-service-type
+  (service-type (name 'home-msmtp)
+                (extensions
+                  (list
+                    (service-extension
+                      home-profile-service-type
+                      home-msmtp-profile-service)
+                    (service-extension
+                      home-files-service-type
+                      home-msmtp-files-service)))
+                (default-value (home-msmtp-configuration))
+                (description "Configures msmtp.")))
diff --git a/gnu/local.mk b/gnu/local.mk
index 01ffe3fdb6..3f57ca3c98 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -93,6 +93,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/home/services/fontutils.scm		\
   %D%/home/services/gnupg.scm			\
   %D%/home/services/guix.scm			\
+  %D%/home/services/mail.scm			\
   %D%/home/services/media.scm			\
   %D%/home/services/messaging.scm		\
   %D%/home/services/pm.scm			\
-- 
2.39.2





Information forwarded to guix-patches <at> gnu.org:
bug#62969; Package guix-patches. (Thu, 20 Apr 2023 16:38:02 GMT) Full text and rfc822 format available.

Message #8 received at 62969 <at> debbugs.gnu.org (full text, mbox):

From: Bruno Victal <mirai <at> makinata.eu>
To: Tanguy Le Carrour <tanguy <at> bioneland.org>
Cc: 62969 <at> debbugs.gnu.org
Subject: Re: [bug#62969] [PATCH] home: Add msmtp service.
Date: Thu, 20 Apr 2023 17:36:59 +0100
Hi Tanguy,

On 2023-04-20 15:42, Tanguy Le Carrour wrote:
> - one that I don't know how to solve
> ```
> +  ;; FIXME `In procedure every: Wrong type argument: #<syntax-transformer msmtp-account?>`
> +  ;(every msmtp-account? lst))
> ```

Place this after '(define-configuration mstmp-account ...)'. You might want to place this block
before '(define-configuration msmtp-configuration ...)'.

> +@deftp {Data Type} home-msmtp-configuration
> +Available @code{home-msmtp-configuration} fields are:
> +
> +@table @asis
> +@item @code{defaults} (type: msmtp-configuration)
> +The configuration that will be set as default for all accounts.
> +
> +@item @code{accounts} (default: @code{()}) (type: list-of-msmtp-accounts)
> +A list of @code{msmtp-account} records which contain information about
> +all your accounts.
> +
> +@item @code{default-account} (type: maybe-string)
> +Set the default account.
> +
> +@item @code{extra-content} (default: @code{""}) (type: raw-configuration-string)
> +Extra content appended as-is to the configuration file.  Run
> +@command{man msmtp} for more information about the configuration file
> +format.
> +
> +@end table
> +
> +@end deftp

You should preserve the @c lines from configuration->documentation to make it clear that
the block of text was generated.

> +
> +(define-module (gnu home services mail)
> +  #:use-module (guix gexp)
> +  #:use-module (gnu packages)
> +  #:use-module (gnu services)
> +  #:use-module (gnu services configuration)
> +  #:use-module (gnu home services)
> +  #:use-module (gnu home services shepherd)
> +  #:use-module (ice-9 string-fun)
> +  #:use-module (srfi srfi-26)
> +  #:export (home-msmtp-configuration
> +            home-msmtp-configuration?
> +            home-msmtp-service-type
> +            msmtp-account
> +            msmtp-configuration))

You should export the accessors for the fields.
You can use this snippet within 'guix repl' to automate the typing for you:

--8<---------------cut here---------------start------------->8---
(define (helper-configuration-exports fields)
  (map
   (lambda (s)
     (let* ((f (compose object->string configuration-field-getter))
           (g (compose cadr string-tokenize))
           (s* ((compose g f) s)))
       (string->symbol (substring s* 1 (string-contains s* "-procedure")))))
   fields))

(define (helper-formatted-exports fields)
  (format #t "~{~a~%~}" (helper-configuration-exports fields)))
--8<---------------cut here---------------end--------------->8---

Example usage:

--8<---------------cut here---------------start------------->8---
;; paste snippet above into repl

scheme@(guix-user)> ,m (gnu services audio)
scheme@(gnu services audio)> (helper-formatted-exports mpd-configuration-fields)
mpd-configuration-user
mpd-configuration-group
mpd-configuration-shepherd-requirement
mpd-configuration-environment-variables
mpd-configuration-log-file
mpd-configuration-log-level
mpd-configuration-music-directory
mpd-configuration-music-dir
mpd-configuration-playlist-directory
mpd-configuration-playlist-dir
mpd-configuration-db-file
mpd-configuration-state-file
mpd-configuration-sticker-file
mpd-configuration-default-port
mpd-configuration-endpoints
mpd-configuration-address
mpd-configuration-database
mpd-configuration-partitions
mpd-configuration-neighbors
mpd-configuration-inputs
mpd-configuration-archive-plugins
mpd-configuration-input-cache-size
mpd-configuration-decoders
mpd-configuration-resampler
mpd-configuration-filters
mpd-configuration-outputs
mpd-configuration-playlist-plugins
mpd-configuration-extra-options
$1 = #t
--8<---------------cut here---------------end--------------->8---

> +
> +(define raw-configuration-string? string?)

This isn't necessary, continued below. [1]

> +
> +(define (configuration-serialize-maybe-string field-name value)
> +  #~(if #$(maybe-value-set? value)
> +      (string-append #$(uglify-symbol field-name) " " #$value "\n")
> +      ""))> +
> +(define (configuration-serialize-maybe-integer field-name value)
> +  #~(if #$(maybe-value-set? value)
> +      (string-append #$(uglify-symbol field-name) " " (number->string #$value) "\n")
> +      ""))
> +
> +(define (configuration-serialize-maybe-boolean field-name value)
> +  #~(if #$(maybe-value-set? value)
> +      (string-append #$(uglify-symbol field-name) " " (if #$value "on" "off") "\n")
> +      ""))
You don't have to perform the maybe-value-set? checks, it is automatically done for you.
The only cases where this isn't true is if you explicitly override the serializer in
define-configuration. [2]


> +(define (account-serialize-string field-name value)
> +  #~(string-append " " #$(uglify-symbol field-name) " " #$value "\n"))
> +
> +(define (account-serialize-string field-name value)
> +  #~(string-append " " #$(uglify-symbol field-name) " " #$value "\n"))

Duplicated?

> +
> +(define (account-serialize-msmtp-configuration field-name value)
> +  ; FIXME Begin each line inside an account section with a space.
> +  #~(string-append #$(serialize-configuration value msmtp-configuration-fields)))

This doesn't do anything and since it's a cosmetic change I'd just ignore it, since
the file is managed with guix anyways.

> +(define (home-configuration-serialize-default-account field-name value)
> +  #~(if #$(maybe-value-set? value)
> +      (string-append "\naccount default : " #$value "\n")
> +      ""))

See [2] above.

> +;; Source <https://marlam.de/msmtp/msmtp.html#Configuration-files>.
> +(define-configuration msmtp-configuration
> +  (auth?
> +   maybe-boolean
> +   "Enable or disable authentication.")
> +  (tls?
> +   maybe-boolean
> +   "Enable or disable TLS (also known as SSL) for secured connections.")
> +  (tls-starttls
> +   maybe-boolean
> +   "Choose the TLS variant: start TLS from within the session (‘on’, default),
> +or tunnel the session through TLS (‘off’).")
> +  (tls-trust-file
> +   maybe-string
> +   "Activate server certificate verification using a list of
> +trusted Certification Authorities (CAs).")
> +  (logfile
> +   maybe-string
> +   "Enable logging to the specified file. An empty argument disables logging.
> +The file name ‘-’ directs the log information to standard output.")
> +  (host
> +    maybe-string
> +    "The SMTP server to send the mail to.")
> +  (port
> +    maybe-integer
> +    "The port that the SMTP server listens on. The default is 25 (\"smtp\"),
> +unless TLS without STARTTLS is used, in which case it is 465 (\"smtps\").")
> +  (user
> +    maybe-string
> +    "Set the user name for authentication.")
> +  (from
> +    maybe-string
> +    "Set the envelope-from address.")
> +  (passwordeval
> +    maybe-string
> +    "Set the password for authentication to the output (stdout) of the command cmd.")
> +  (extra-content
> +   (raw-configuration-string "")
> +   "Extra content appended as-is to the configuration block.  Run
> +@command{man msmtp} for more information about the configuration file
> +format.")

Instead of defining a raw-configuration-string? predicate, simply use string?
and set the serializer to '(serializer my-custom-string-serializer)' or '(serializer (lambda ...))'. [1]

> +  (prefix configuration-))

These are poor prefix choices for a module named (gnu home services mail).
If it were (gnu home services msmtp) or (gnu home services mail msmtp) it would be acceptable
but a module named (gnu home services mail) is expected to eventually contain multiple services that
have to co-exist. These prefixes are too non-specific and confusion prone for such circumstances.

I'd set this to (prefix msmtp-configuration-). (the same logic applies to the remaining (prefix ...) lines)

> +
> +(define-configuration msmtp-account
> +  (name
> +   (string)
> +   "The unique name of the account."
> +   (serializer account-serialize-name))
> +  (configuration
> +   (msmtp-configuration)
> +   "The configuration for this given account.")
> +  (prefix account-))
> +
> +(define-configuration home-msmtp-configuration
> +  (defaults
> +   (msmtp-configuration (msmtp-configuration))
> +   "The configuration that will be set as default for all accounts.")
> +  (accounts
> +   (list-of-msmtp-accounts '())
> +   "A list of @code{msmtp-account} records which contain
> +information about all your accounts.")
> +  (default-account
> +   maybe-string
> +   "Set the default account."
> +   (serializer home-configuration-serialize-default-account))
> +  (extra-content
> +   (raw-configuration-string "")
> +   "Extra content appended as-is to the configuration file.  Run
> +@command{man msmtp} for more information about the configuration file
> +format.")
> +  (prefix home-configuration-))

You might want to separate each field with a space to make things easier to read but this is optional.


Cheers,
Bruno





Information forwarded to guix-patches <at> gnu.org:
bug#62969; Package guix-patches. (Sun, 23 Apr 2023 17:11:02 GMT) Full text and rfc822 format available.

Message #11 received at 62969 <at> debbugs.gnu.org (full text, mbox):

From: Tanguy LE CARROUR <tanguy <at> bioneland.org>
To: Bruno Victal <mirai <at> makinata.eu>
Cc: 62969 <at> debbugs.gnu.org
Subject: Re: [bug#62969] [PATCH] home: Add msmtp service.
Date: Sun, 23 Apr 2023 19:10:15 +0200
Hi Bruno,

Thank you so much for you comments!
I've applied (almost, see below) all of your suggestions and I will send a v2.


Quoting Bruno Victal (2023-04-20 18:36:59)
> On 2023-04-20 15:42, Tanguy Le Carrour wrote:
> > +(define (configuration-serialize-maybe-string field-name value)
> > +  #~(if #$(maybe-value-set? value)
> > +      (string-append #$(uglify-symbol field-name) " " #$value "\n")
> > +      ""))> +
> > +(define (configuration-serialize-maybe-integer field-name value)
> > +  #~(if #$(maybe-value-set? value)
> > +      (string-append #$(uglify-symbol field-name) " " (number->string #$value) "\n")
> > +      ""))
> > +
> > +(define (configuration-serialize-maybe-boolean field-name value)
> > +  #~(if #$(maybe-value-set? value)
> > +      (string-append #$(uglify-symbol field-name) " " (if #$value "on" "off") "\n")
> > +      ""))
> You don't have to perform the maybe-value-set? checks, it is automatically done for you.
> The only cases where this isn't true is if you explicitly override the serializer in
> define-configuration. [2]

This is the only thing I can't figure out how to make work?!
When I remove the `(if #$(maybe-value-set? value) …)` I get the
following error:

```
Backtrace:
          10 (primitive-load "/gnu/store/ajcf46q8yr9sb9n90psa5ay96jw?")
In ice-9/ports.scm:
   433:17  9 (call-with-output-file _ _ #:binary _ #:encoding _)
In ice-9/eval.scm:
    159:9  8 (_ #(#(#<directory (guile-user) 7ffff3fd7c80>) #<outp?>))
    155:9  7 (_ #(#(#<directory (guile-user) 7ffff3fd7c80>) #<outp?>))
   173:39  6 (_ #(#(#<directory (guile-user) 7ffff3fd7c80>) #<outp?>))
    159:9  5 (_ #(#(#<directory (guile-user) 7ffff3fd7c80>) #<outp?>))
   173:55  4 (_ #(#(#<directory (guile-user) 7ffff3fd7c80>) #<outp?>))
   173:55  3 (_ #(#(#<directory (guile-user) 7ffff3fd7c80>) #<outp?>))
   279:15  2 (_ #(#(#<directory (guile-user) 7ffff3fd7c80>) #<outp?>))
   223:20  1 (proc #(#(#<directory (guile-user) 7ffff3fd7c80>) #<o?>))
In unknown file:
           0 (%resolve-variable (7 . %unset-marker%) #<directory (gu?>)

ERROR: In procedure %resolve-variable:
Unbound variable: %unset-marker%
```


> > +  (prefix configuration-))
> These are poor prefix choices for a module named (gnu home services mail).
> If it were (gnu home services msmtp) or (gnu home services mail msmtp) it would be acceptable
> but a module named (gnu home services mail) is expected to eventually contain multiple services that
> have to co-exist. These prefixes are too non-specific and confusion prone for such circumstances.
> 
> I'd set this to (prefix msmtp-configuration-). (the same logic applies to the remaining (prefix ...) lines)

I totally agree! You guessed correctly, this home service was living
inside `(bioneland home services msmtp)`, so the naming seemed to make
sense at the time, but not any more!

Thanks again for your time and help!

-- 
Tanguy




Information forwarded to guix-patches <at> gnu.org:
bug#62969; Package guix-patches. (Sun, 23 Apr 2023 17:13:02 GMT) Full text and rfc822 format available.

Message #14 received at 62969 <at> debbugs.gnu.org (full text, mbox):

From: Tanguy Le Carrour <tanguy <at> bioneland.org>
To: 62969 <at> debbugs.gnu.org
Cc: mirai <at> makinata.eu, Tanguy Le Carrour <tanguy <at> bioneland.org>
Subject: [PATCH v2] home: Add msmtp service.
Date: Sun, 23 Apr 2023 19:12:17 +0200
* gnu/home/services/mail.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
* doc/guix.texi (Mailing): New node.
---
 doc/guix.texi              | 106 ++++++++++++++++++
 gnu/home/services/mail.scm | 219 +++++++++++++++++++++++++++++++++++++
 gnu/local.mk               |   1 +
 3 files changed, 326 insertions(+)
 create mode 100644 gnu/home/services/mail.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index adb1975935..78efa822f9 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -114,6 +114,7 @@ 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 Tanguy Le Carrour
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -41880,6 +41881,7 @@ services)}.
 * Guix: Guix Home Services.     Services for Guix.
 * Fonts: Fonts Home Services.   Services for managing User's fonts.
 * Sound: Sound Home Services.   Dealing with audio.
+* Mail: Mail Home Services.  Services for managing mail.
 * Messaging: Messaging Home Services.  Services for managing messaging.
 * Media: Media Home Services.   Services for managing media.
 @end menu
@@ -43082,6 +43084,110 @@ Stopping the Shepherd service turns off broadcasting.
 This is the multicast address used by default by the two services above.
 @end defvar
 
+@node Mail Home Services
+@subsection Mail Home Services
+
+@cindex msmtp
+@uref{https://marlam.de/msmtp, MSMTP} is an SMTP client.
+
+@c %start of fragment
+
+@deftp {Data Type} home-msmtp-configuration
+Available @code{home-msmtp-configuration} fields are:
+
+@table @asis
+@item @code{defaults} (type: msmtp-configuration)
+The configuration that will be set as default for all accounts.
+
+@item @code{accounts} (default: @code{()}) (type: list-of-msmtp-accounts)
+A list of @code{msmtp-account} records which contain information about
+all your accounts.
+
+@item @code{default-account} (type: maybe-string)
+Set the default account.
+
+@item @code{extra-content} (default: @code{""}) (type: string)
+Extra content appended as-is to the configuration file.  Run
+@command{man msmtp} for more information about the configuration file
+format.
+
+@end table
+
+@end deftp
+
+@c %end of fragment
+
+@c %start of fragment
+
+@deftp {Data Type} msmtp-account
+Available @code{msmtp-account} fields are:
+
+@table @asis
+@item @code{name} (type: string)
+The unique name of the account.
+
+@item @code{configuration} (type: msmtp-configuration)
+The configuration for this given account.
+
+@end table
+
+@end deftp
+
+@c %end of fragment
+
+@c %start of fragment
+
+@deftp {Data Type} msmtp-configuration
+Available @code{msmtp-configuration} fields are:
+
+@table @asis
+@item @code{auth?} (type: maybe-boolean)
+Enable or disable authentication.
+
+@item @code{tls?} (type: maybe-boolean)
+Enable or disable TLS (also known as SSL) for secured connections.
+
+@item @code{tls-starttls?} (type: maybe-boolean)
+Choose the TLS variant: start TLS from within the session (‘on’,
+default), or tunnel the session through TLS (‘off’).
+
+@item @code{tls-trust-file} (type: maybe-string)
+Activate server certificate verification using a list of trusted
+Certification Authorities (CAs).
+
+@item @code{logfile} (type: maybe-string)
+Enable logging to the specified file.  An empty argument disables
+logging.  The file name ‘-’ directs the log information to standard
+output.
+
+@item @code{host} (type: maybe-string)
+The SMTP server to send the mail to.
+
+@item @code{port} (type: maybe-integer)
+The port that the SMTP server listens on.  The default is 25 ("smtp"),
+unless TLS without STARTTLS is used, in which case it is 465 ("smtps").
+
+@item @code{user} (type: maybe-string)
+Set the user name for authentication.
+
+@item @code{from} (type: maybe-string)
+Set the envelope-from address.
+
+@item @code{passwordeval} (type: maybe-string)
+Set the password for authentication to the output (stdout) of the
+command cmd.
+
+@item @code{extra-content} (default: @code{""}) (type: string)
+Extra content appended as-is to the configuration block.  Run
+@command{man msmtp} for more information about the configuration file
+format.
+
+@end table
+
+@end deftp
+
+@c %end of fragment
+
 @node Messaging Home Services
 @subsection Messaging Home Services
 
diff --git a/gnu/home/services/mail.scm b/gnu/home/services/mail.scm
new file mode 100644
index 0000000000..e151cf8607
--- /dev/null
+++ b/gnu/home/services/mail.scm
@@ -0,0 +1,219 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Tanguy Le Carrour <tanguy <at> bioneland.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 mail)
+  #:use-module (guix gexp)
+  #:use-module (gnu packages)
+  #:use-module (gnu services)
+  #:use-module (gnu services configuration)
+  #:use-module (gnu home services)
+  #:use-module (gnu home services shepherd)
+  #:use-module (ice-9 string-fun)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:export (home-msmtp-configuration
+            home-msmtp-configuration?
+            home-msmtp-configuration-defaults
+            home-msmtp-configuration-accounts
+            home-msmtp-configuration-default-account
+            home-msmtp-configuration-extra-content
+            home-msmtp-service-type
+            msmtp-configuration
+            msmtp-configuration-auth?
+            msmtp-configuration-tls?
+            msmtp-configuration-tls-starttls?
+            msmtp-configuration-tls-trust-file
+            msmtp-configuration-logfile
+            msmtp-configuration-host
+            msmtp-configuration-port
+            msmtp-configuration-user
+            msmtp-configuration-from
+            msmtp-configuration-passwordeval
+            msmtp-configuration-extra-content
+            msmtp-account
+            msmtp-account-name
+            msmtp-account-configuration))
+
+(define-maybe string)
+(define-maybe boolean)
+(define-maybe integer)
+
+;; Serialization of 'msmtp'.
+(define (uglify-symbol field-name)
+  (let* ((name (symbol->string field-name))
+         (ugly-name (string-replace-substring name "-" "_")))
+    (if (string-suffix? "?" ugly-name)
+      (string-drop-right ugly-name 1)
+      ugly-name)))
+
+(define (msmtp-configuration-serialize-maybe-boolean field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " (if #$value "on" "off") "\n")
+      ""))
+
+(define (msmtp-configuration-serialize-maybe-string field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " #$value "\n")
+      ""))
+
+(define (msmtp-configuration-serialize-maybe-integer field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " (number->string #$value) "\n")
+      ""))
+
+(define (msmtp-configuration-serialize-extra-content field-name value)
+  #~(if (string=? #$value "") "" (string-append #$value "\n")))
+
+(define (msmtp-account-serialize-name field-name value)
+  #~(string-append "\naccount " #$value "\n"))
+
+(define (msmtp-account-serialize-msmtp-configuration field-name value)
+  #~(string-append #$(serialize-configuration value msmtp-configuration-fields)))
+
+(define (home-msmtp-configuration-serialize-list-of-msmtp-accounts field-name value)
+  #~(string-append #$@(map (cut serialize-configuration <> msmtp-account-fields)
+                           value)))
+
+(define (home-msmtp-configuration-serialize-msmtp-configuration field-name value)
+  #~(string-append "defaults\n"
+                   #$(serialize-configuration value msmtp-configuration-fields)))
+
+(define (home-msmtp-configuration-serialize-default-account field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append "\naccount default : " #$value "\n")
+      ""))
+
+(define (home-msmtp-configuration-serialize-extra-content field-name value)
+  #~(if (string=? #$value "") "" (string-append #$value "\n")))
+
+;; Configuration of 'msmtp'.
+;; Source <https://marlam.de/msmtp/msmtp.html#Configuration-files>.
+(define-configuration msmtp-configuration
+  (auth?
+   maybe-boolean
+   "Enable or disable authentication.")
+
+  (tls?
+   maybe-boolean
+   "Enable or disable TLS (also known as SSL) for secured connections.")
+
+  (tls-starttls?
+   maybe-boolean
+   "Choose the TLS variant: start TLS from within the session (‘on’, default),
+or tunnel the session through TLS (‘off’).")
+
+  (tls-trust-file
+   maybe-string
+   "Activate server certificate verification using a list of
+trusted Certification Authorities (CAs).")
+
+  (logfile
+   maybe-string
+   "Enable logging to the specified file. An empty argument disables logging.
+The file name ‘-’ directs the log information to standard output.")
+
+  (host
+    maybe-string
+    "The SMTP server to send the mail to.")
+
+  (port
+    maybe-integer
+    "The port that the SMTP server listens on. The default is 25 (\"smtp\"),
+unless TLS without STARTTLS is used, in which case it is 465 (\"smtps\").")
+
+  (user
+    maybe-string
+    "Set the user name for authentication.")
+
+  (from
+    maybe-string
+    "Set the envelope-from address.")
+
+  (passwordeval
+    maybe-string
+    "Set the password for authentication to the output (stdout) of the command cmd.")
+
+  (extra-content
+   (string "")
+   "Extra content appended as-is to the configuration block.  Run
+@command{man msmtp} for more information about the configuration file
+format."
+   (serializer msmtp-configuration-serialize-extra-content))
+
+  (prefix msmtp-configuration-))
+
+(define-configuration msmtp-account
+  (name
+   (string)
+   "The unique name of the account."
+   (serializer msmtp-account-serialize-name))
+
+  (configuration
+   (msmtp-configuration)
+   "The configuration for this given account.")
+
+  (prefix msmtp-account-))
+
+(define (list-of-msmtp-accounts? lst)
+  (every msmtp-account? lst))
+
+(define-configuration home-msmtp-configuration
+  (defaults
+   (msmtp-configuration (msmtp-configuration))
+   "The configuration that will be set as default for all accounts.")
+
+  (accounts
+   (list-of-msmtp-accounts '())
+   "A list of @code{msmtp-account} records which contain
+information about all your accounts.")
+
+  (default-account
+   maybe-string
+   "Set the default account."
+   (serializer home-msmtp-configuration-serialize-default-account))
+
+  (extra-content
+   (string "")
+   "Extra content appended as-is to the configuration file.  Run
+@command{man msmtp} for more information about the configuration file
+format."
+   (serializer home-msmtp-configuration-serialize-extra-content))
+
+  (prefix home-msmtp-configuration-))
+
+(define (home-msmtp-files-service config)
+  (list
+   `(".config/msmtp/config"
+     ,(mixed-text-file "config"
+                       (serialize-configuration config home-msmtp-configuration-fields)))))
+
+(define (home-msmtp-profile-service config)
+  (specifications->packages (list "msmtp")))
+
+(define home-msmtp-service-type
+  (service-type (name 'home-msmtp)
+                (extensions
+                  (list
+                    (service-extension
+                      home-profile-service-type
+                      home-msmtp-profile-service)
+                    (service-extension
+                      home-files-service-type
+                      home-msmtp-files-service)))
+                (default-value (home-msmtp-configuration))
+                (description "Configures msmtp.")))
diff --git a/gnu/local.mk b/gnu/local.mk
index 01ffe3fdb6..3f57ca3c98 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -93,6 +93,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/home/services/fontutils.scm		\
   %D%/home/services/gnupg.scm			\
   %D%/home/services/guix.scm			\
+  %D%/home/services/mail.scm			\
   %D%/home/services/media.scm			\
   %D%/home/services/messaging.scm		\
   %D%/home/services/pm.scm			\
-- 
2.39.2





Information forwarded to guix-patches <at> gnu.org:
bug#62969; Package guix-patches. (Sun, 30 Apr 2023 21:31:01 GMT) Full text and rfc822 format available.

Message #17 received at 62969 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Tanguy Le Carrour <tanguy <at> bioneland.org>
Cc: 62969 <at> debbugs.gnu.org, mirai <at> makinata.eu
Subject: Re: bug#62969: [PATCH] home: Add msmtp service.
Date: Sun, 30 Apr 2023 23:30:10 +0200
Hi Tanguy! :-)

Tanguy Le Carrour <tanguy <at> bioneland.org> skribis:

> * gnu/home/services/mail.scm: New file.
> * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
> * doc/guix.texi (Mailing): New node.

I get:

--8<---------------cut here---------------start------------->8---
[ 94%] GUILEC   gnu/home/services/mail.go
gnu/home/services/mail.scm:52:0: warning: possibly unbound variable `serialize-string'
gnu/home/services/mail.scm:53:0: warning: possibly unbound variable `serialize-boolean'
gnu/home/services/mail.scm:54:0: warning: possibly unbound variable `serialize-integer'
--8<---------------cut here---------------end--------------->8---

I guess these procedures should be provided as well?

> +@node Mail Home Services
> +@subsection Mail Home Services
> +
> +@cindex msmtp
> +@uref{https://marlam.de/msmtp, MSMTP} is an SMTP client.

Could you give a bit more context, including @acronym for SMTP?  It
would also be nice to provide one commented example that readers might
copy/paste as a starting point.

You can take inspiration form the “Mcron Home Services”, “Secure Shell”,
or “Messaging Home Services” nodes, for example.

[...]

> +                (default-value (home-msmtp-configuration))
> +                (description "Configures msmtp.")))

Likewise, something like “Configure msmtp, a simple @acronym{SMTP, …}
client that can relay email to SMTP servers.”

Otherwise this looks great to me, thank you!

Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#62969; Package guix-patches. (Wed, 03 May 2023 10:03:02 GMT) Full text and rfc822 format available.

Message #20 received at 62969 <at> debbugs.gnu.org (full text, mbox):

From: Tanguy LE CARROUR <tanguy <at> bioneland.org>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 62969 <at> debbugs.gnu.org, mirai <at> makinata.eu
Subject: [PATCH v3] home: Add msmtp service.
Date: Wed, 03 May 2023 12:01:48 +0200
Hi Ludo’,

Quoting Ludovic Courtès (2023-04-30 23:30:10)
> Tanguy Le Carrour <tanguy <at> bioneland.org> skribis:
> 
> > * gnu/home/services/mail.scm: New file.
> > * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
> > * doc/guix.texi (Mailing): New node.
> 
> I get:
> 
> --8<---------------cut here---------------start------------->8---
> [ 94%] GUILEC   gnu/home/services/mail.go
> gnu/home/services/mail.scm:52:0: warning: possibly unbound variable `serialize-string'
> gnu/home/services/mail.scm:53:0: warning: possibly unbound variable `serialize-boolean'
> gnu/home/services/mail.scm:54:0: warning: possibly unbound variable `serialize-integer'
> --8<---------------cut here---------------end--------------->8---
>
> I guess these procedures should be provided as well?

I also get them when making `gnu/home/services/mail.go`. But aren't
those "just" warnings. Everything seems to work as expected and when I
`guix home container test.home.scm` I get the expected
`.config/msmtp/config` file.


> > +@node Mail Home Services
> > +@subsection Mail Home Services
> > +
> > +@cindex msmtp
> > +@uref{https://marlam.de/msmtp, MSMTP} is an SMTP client.
> 
> Could you give a bit more context, including @acronym for SMTP?  It
> would also be nice to provide one commented example that readers might
> copy/paste as a starting point.
> 
> You can take inspiration form the “Mcron Home Services”, “Secure Shell”,
> or “Messaging Home Services” nodes, for example.
> 
> [...]
> 
> > +                (default-value (home-msmtp-configuration))
> > +                (description "Configures msmtp.")))
> 
> Likewise, something like “Configure msmtp, a simple @acronym{SMTP, …}
> client that can relay email to SMTP servers.”

I tried to improve it based on your suggestions. No yet perfect, though.

Cheers,
Tanguy


* gnu/home/services/mail.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
* doc/guix.texi (Mailing): New node.
---
 doc/guix.texi              | 137 +++++++++++++++++++++++
 gnu/home/services/mail.scm | 221 +++++++++++++++++++++++++++++++++++++
 gnu/local.mk               |   1 +
 3 files changed, 359 insertions(+)
 create mode 100644 gnu/home/services/mail.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index 7af2a85499..2ae815475b 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -114,6 +114,7 @@
 Copyright @copyright{} 2023 Giacomo Leidi@*
 Copyright @copyright{} 2022 Antero Mejr@*
 Copyright @copyright{} 2023 Karl Hallsby
+Copyright @copyright{} 2023 Tanguy Le Carrour

 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -41887,6 +41888,7 @@ Home Services
 * Guix: Guix Home Services.     Services for Guix.
 * Fonts: Fonts Home Services.   Services for managing User's fonts.
 * Sound: Sound Home Services.   Dealing with audio.
+* Mail: Mail Home Services.  Services for managing mail.
 * Messaging: Messaging Home Services.  Services for managing messaging.
 * Media: Media Home Services.   Services for managing media.
 @end menu
@@ -43110,6 +43112,141 @@ Sound Home Services
 This is the multicast address used by default by the two services above.
 @end defvar

+@node Mail Home Services
+@subsection Mail Home Services
+
+The @code{(gnu home services mail)} modules provides services that help
+you set up the tools to work with emails in your home environment.
+
+@cindex msmtp
+@uref{https://marlam.de/msmtp, MSMTP} is a @acronym{SMTP, Simple Mail
+Transfer Protocol} client.  It sends mails to a predefined SMTP server
+that takes care of proper delivery.
+
+The service reference is given below.
+
+@defvar home-msmtp-service-type
+This is the service type for @command{msmtp}.  Its value must be a
+@code{home-msmtp-configuration}, as shown below.  It provides the
+@code{~/.config/msmtp/config} file.
+
+As an example, here is how you would configure @code{msmtp} for a single
+account:
+
+@lisp
+(service home-msmtp-service-type
+         (home-msmtp-configuration
+          (accounts
+           (list
+            (msmtp-account
+             (name "alice")
+             (configuration
+              (msmtp-configuration
+               (host "mail.example.org")
+               (port 587)
+               (user "alice")
+               (passwordeval "pass Mail/alice"))))))))
+@end lisp
+@end defvar
+
+@c %start of fragment
+
+@deftp {Data Type} home-msmtp-configuration
+Available @code{home-msmtp-configuration} fields are:
+
+@table @asis
+@item @code{defaults} (type: msmtp-configuration)
+The configuration that will be set as default for all accounts.
+
+@item @code{accounts} (default: @code{()}) (type: list-of-msmtp-accounts)
+A list of @code{msmtp-account} records which contain information about
+all your accounts.
+
+@item @code{default-account} (type: maybe-string)
+Set the default account.
+
+@item @code{extra-content} (default: @code{""}) (type: string)
+Extra content appended as-is to the configuration file.  Run
+@command{man msmtp} for more information about the configuration file
+format.
+
+@end table
+
+@end deftp
+
+@c %end of fragment
+
+@c %start of fragment
+
+@deftp {Data Type} msmtp-account
+Available @code{msmtp-account} fields are:
+
+@table @asis
+@item @code{name} (type: string)
+The unique name of the account.
+
+@item @code{configuration} (type: msmtp-configuration)
+The configuration for this given account.
+
+@end table
+
+@end deftp
+
+@c %end of fragment
+
+@c %start of fragment
+
+@deftp {Data Type} msmtp-configuration
+Available @code{msmtp-configuration} fields are:
+
+@table @asis
+@item @code{auth?} (type: maybe-boolean)
+Enable or disable authentication.
+
+@item @code{tls?} (type: maybe-boolean)
+Enable or disable TLS (also known as SSL) for secured connections.
+
+@item @code{tls-starttls?} (type: maybe-boolean)
+Choose the TLS variant: start TLS from within the session (‘on’,
+default), or tunnel the session through TLS (‘off’).
+
+@item @code{tls-trust-file} (type: maybe-string)
+Activate server certificate verification using a list of trusted
+Certification Authorities (CAs).
+
+@item @code{logfile} (type: maybe-string)
+Enable logging to the specified file.  An empty argument disables
+logging.  The file name ‘-’ directs the log information to standard
+output.
+
+@item @code{host} (type: maybe-string)
+The SMTP server to send the mail to.
+
+@item @code{port} (type: maybe-integer)
+The port that the SMTP server listens on.  The default is 25 ("smtp"),
+unless TLS without STARTTLS is used, in which case it is 465 ("smtps").
+
+@item @code{user} (type: maybe-string)
+Set the user name for authentication.
+
+@item @code{from} (type: maybe-string)
+Set the envelope-from address.
+
+@item @code{passwordeval} (type: maybe-string)
+Set the password for authentication to the output (stdout) of the
+command cmd.
+
+@item @code{extra-content} (default: @code{""}) (type: string)
+Extra content appended as-is to the configuration block.  Run
+@command{man msmtp} for more information about the configuration file
+format.
+
+@end table
+
+@end deftp
+
+@c %end of fragment
+
 @node Messaging Home Services
 @subsection Messaging Home Services

diff --git a/gnu/home/services/mail.scm b/gnu/home/services/mail.scm
new file mode 100644
index 0000000000..ec5f869c87
--- /dev/null
+++ b/gnu/home/services/mail.scm
@@ -0,0 +1,221 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Tanguy Le Carrour <tanguy <at> bioneland.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 mail)
+  #:use-module (guix gexp)
+  #:use-module (gnu packages)
+  #:use-module (gnu services)
+  #:use-module (gnu services configuration)
+  #:use-module (gnu home services)
+  #:use-module (gnu home services shepherd)
+  #:use-module (ice-9 string-fun)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:export (home-msmtp-configuration
+            home-msmtp-configuration?
+            home-msmtp-configuration-defaults
+            home-msmtp-configuration-accounts
+            home-msmtp-configuration-default-account
+            home-msmtp-configuration-extra-content
+            home-msmtp-service-type
+            msmtp-configuration
+            msmtp-configuration-auth?
+            msmtp-configuration-tls?
+            msmtp-configuration-tls-starttls?
+            msmtp-configuration-tls-trust-file
+            msmtp-configuration-logfile
+            msmtp-configuration-host
+            msmtp-configuration-port
+            msmtp-configuration-user
+            msmtp-configuration-from
+            msmtp-configuration-passwordeval
+            msmtp-configuration-extra-content
+            msmtp-account
+            msmtp-account-name
+            msmtp-account-configuration))
+
+(define-maybe string)
+(define-maybe boolean)
+(define-maybe integer)
+
+;; Serialization of 'msmtp'.
+(define (uglify-symbol field-name)
+  (let* ((name (symbol->string field-name))
+         (ugly-name (string-replace-substring name "-" "_")))
+    (if (string-suffix? "?" ugly-name)
+      (string-drop-right ugly-name 1)
+      ugly-name)))
+
+(define (msmtp-configuration-serialize-maybe-boolean field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " (if #$value "on" "off") "\n")
+      ""))
+
+(define (msmtp-configuration-serialize-maybe-string field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " #$value "\n")
+      ""))
+
+(define (msmtp-configuration-serialize-maybe-integer field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " (number->string #$value) "\n")
+      ""))
+
+(define (msmtp-configuration-serialize-extra-content field-name value)
+  #~(if (string=? #$value "") "" (string-append #$value "\n")))
+
+(define (msmtp-account-serialize-name field-name value)
+  #~(string-append "\naccount " #$value "\n"))
+
+(define (msmtp-account-serialize-msmtp-configuration field-name value)
+  #~(string-append #$(serialize-configuration value msmtp-configuration-fields)))
+
+(define (home-msmtp-configuration-serialize-list-of-msmtp-accounts field-name value)
+  #~(string-append #$@(map (cut serialize-configuration <> msmtp-account-fields)
+                           value)))
+
+(define (home-msmtp-configuration-serialize-msmtp-configuration field-name value)
+  #~(string-append "defaults\n"
+                   #$(serialize-configuration value msmtp-configuration-fields)))
+
+(define (home-msmtp-configuration-serialize-default-account field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append "\naccount default : " #$value "\n")
+      ""))
+
+(define (home-msmtp-configuration-serialize-extra-content field-name value)
+  #~(if (string=? #$value "") "" (string-append #$value "\n")))
+
+;; Configuration of 'msmtp'.
+;; Source <https://marlam.de/msmtp/msmtp.html#Configuration-files>.
+(define-configuration msmtp-configuration
+  (auth?
+   maybe-boolean
+   "Enable or disable authentication.")
+
+  (tls?
+   maybe-boolean
+   "Enable or disable TLS (also known as SSL) for secured connections.")
+
+  (tls-starttls?
+   maybe-boolean
+   "Choose the TLS variant: start TLS from within the session (‘on’, default),
+or tunnel the session through TLS (‘off’).")
+
+  (tls-trust-file
+   maybe-string
+   "Activate server certificate verification using a list of
+trusted Certification Authorities (CAs).")
+
+  (logfile
+   maybe-string
+   "Enable logging to the specified file. An empty argument disables logging.
+The file name ‘-’ directs the log information to standard output.")
+
+  (host
+    maybe-string
+    "The SMTP server to send the mail to.")
+
+  (port
+    maybe-integer
+    "The port that the SMTP server listens on. The default is 25 (\"smtp\"),
+unless TLS without STARTTLS is used, in which case it is 465 (\"smtps\").")
+
+  (user
+    maybe-string
+    "Set the user name for authentication.")
+
+  (from
+    maybe-string
+    "Set the envelope-from address.")
+
+  (passwordeval
+    maybe-string
+    "Set the password for authentication to the output (stdout) of the command cmd.")
+
+  (extra-content
+   (string "")
+   "Extra content appended as-is to the configuration block.  Run
+@command{man msmtp} for more information about the configuration file
+format."
+   (serializer msmtp-configuration-serialize-extra-content))
+
+  (prefix msmtp-configuration-))
+
+(define-configuration msmtp-account
+  (name
+   (string)
+   "The unique name of the account."
+   (serializer msmtp-account-serialize-name))
+
+  (configuration
+   (msmtp-configuration)
+   "The configuration for this given account.")
+
+  (prefix msmtp-account-))
+
+(define (list-of-msmtp-accounts? lst)
+  (every msmtp-account? lst))
+
+(define-configuration home-msmtp-configuration
+  (defaults
+   (msmtp-configuration (msmtp-configuration))
+   "The configuration that will be set as default for all accounts.")
+
+  (accounts
+   (list-of-msmtp-accounts '())
+   "A list of @code{msmtp-account} records which contain
+information about all your accounts.")
+
+  (default-account
+   maybe-string
+   "Set the default account."
+   (serializer home-msmtp-configuration-serialize-default-account))
+
+  (extra-content
+   (string "")
+   "Extra content appended as-is to the configuration file.  Run
+@command{man msmtp} for more information about the configuration file
+format."
+   (serializer home-msmtp-configuration-serialize-extra-content))
+
+  (prefix home-msmtp-configuration-))
+
+(define (home-msmtp-files-service config)
+  (list
+   `(".config/msmtp/config"
+     ,(mixed-text-file "config"
+                       (serialize-configuration config home-msmtp-configuration-fields)))))
+
+(define (home-msmtp-profile-service config)
+  (specifications->packages (list "msmtp")))
+
+(define home-msmtp-service-type
+  (service-type (name 'home-msmtp)
+                (extensions
+                  (list
+                    (service-extension
+                      home-profile-service-type
+                      home-msmtp-profile-service)
+                    (service-extension
+                      home-files-service-type
+                      home-msmtp-files-service)))
+                (default-value (home-msmtp-configuration))
+                (description "Configure msmtp, a simple
+@acronym{SMTP, Simple Mail Transfer Protocol} client that can relay email
+to SMTP servers.")))
diff --git a/gnu/local.mk b/gnu/local.mk
index 4305bee89c..94ea3a4e8d 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -93,6 +93,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/home/services/fontutils.scm		\
   %D%/home/services/gnupg.scm			\
   %D%/home/services/guix.scm			\
+  %D%/home/services/mail.scm			\
   %D%/home/services/media.scm			\
   %D%/home/services/messaging.scm		\
   %D%/home/services/pm.scm			\

base-commit: 94e2e3553440a2a5ac4a312e80b8ea21ddebafeb
-- 
2.39.2




Information forwarded to guix-patches <at> gnu.org:
bug#62969; Package guix-patches. (Wed, 03 May 2023 20:28:01 GMT) Full text and rfc822 format available.

Message #23 received at 62969 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Tanguy LE CARROUR <tanguy <at> bioneland.org>
Cc: 62969 <at> debbugs.gnu.org, mirai <at> makinata.eu
Subject: Re: [PATCH v3] home: Add msmtp service.
Date: Wed, 03 May 2023 22:27:03 +0200
Hello!

Tanguy LE CARROUR <tanguy <at> bioneland.org> skribis:

> Quoting Ludovic Courtès (2023-04-30 23:30:10)
>> Tanguy Le Carrour <tanguy <at> bioneland.org> skribis:
>> 
>> > * gnu/home/services/mail.scm: New file.
>> > * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
>> > * doc/guix.texi (Mailing): New node.
>> 
>> I get:
>> 
>> --8<---------------cut here---------------start------------->8---
>> [ 94%] GUILEC   gnu/home/services/mail.go
>> gnu/home/services/mail.scm:52:0: warning: possibly unbound variable `serialize-string'
>> gnu/home/services/mail.scm:53:0: warning: possibly unbound variable `serialize-boolean'
>> gnu/home/services/mail.scm:54:0: warning: possibly unbound variable `serialize-integer'
>> --8<---------------cut here---------------end--------------->8---
>>
>> I guess these procedures should be provided as well?
>
> I also get them when making `gnu/home/services/mail.go`. But aren't
> those "just" warnings.

It means that there’s code referring to these procedures, and that they
don’t exist.  It’s worth investigating anyway.

> Everything seems to work as expected and when I `guix home container
> test.home.scm` I get the expected `.config/msmtp/config` file.

Perhaps that doesn’t exercise those bits, maybe because you’re not using
string-valued or boolean-valued fields or something?

A couple of minor things:

> * gnu/home/services/mail.scm: New file.
> * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
> * doc/guix.texi (Mailing): New node.
> +@subsection Mail Home Services
> +
> +The @code{(gnu home services mail)} modules provides services that help

“module” (singular)

> +@uref{https://marlam.de/msmtp, MSMTP} is a @acronym{SMTP, Simple Mail
> +Transfer Protocol} client.  It sends mails to a predefined SMTP server

“mail” (singular)

> +@code{~/.config/msmtp/config} file.

“@file”

This new intro + example look nice to me!

> +@item @code{logfile} (type: maybe-string)

[...]

> +@item @code{passwordeval} (type: maybe-string)
> +Set the password for authentication to the output (stdout) of the
> +command cmd.

Sorry for not noticing earlier but I’d suggest ‘log-file’ and
‘password-evaluation’ (?) to stick with the established naming
convention.

So I think beyond this the main issue is figuring out the missing
serialization procedures, and then we’re done!

Thanks,
Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#62969; Package guix-patches. (Wed, 17 May 2023 08:53:01 GMT) Full text and rfc822 format available.

Message #26 received at 62969 <at> debbugs.gnu.org (full text, mbox):

From: Tanguy LE CARROUR <tanguy <at> bioneland.org>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 62969 <at> debbugs.gnu.org, mirai <at> makinata.eu
Subject: Re: [PATCH v3] home: Add msmtp service.
Date: Wed, 17 May 2023 10:52:05 +0200
Hi,


Quoting Ludovic Courtès (2023-05-03 22:27:03)
> Tanguy LE CARROUR <tanguy <at> bioneland.org> skribis:
> 
> > Quoting Ludovic Courtès (2023-04-30 23:30:10)
> >> Tanguy Le Carrour <tanguy <at> bioneland.org> skribis:
> >> 
> >> > * gnu/home/services/mail.scm: New file.
> >> > * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
> >> > * doc/guix.texi (Mailing): New node.
> >> 
> >> I get:
> >> 
> >> --8<---------------cut here---------------start------------->8---
> >> [ 94%] GUILEC   gnu/home/services/mail.go
> >> gnu/home/services/mail.scm:52:0: warning: possibly unbound variable `serialize-string'
> >> gnu/home/services/mail.scm:53:0: warning: possibly unbound variable `serialize-boolean'
> >> gnu/home/services/mail.scm:54:0: warning: possibly unbound variable `serialize-integer'
> >> --8<---------------cut here---------------end--------------->8---
> >>
> >> I guess these procedures should be provided as well?
> >
> > I also get them when making `gnu/home/services/mail.go`. But aren't
> > those "just" warnings.
> 
> It means that there’s code referring to these procedures, and that they
> don’t exist.  It’s worth investigating anyway.

I have noooo clue where to start! #noob’ 😅


> A couple of minor things:
> […]
> > +The @code{(gnu home services mail)} modules provides services that help
> 
> “module” (singular)

Done!


> > +@uref{https://marlam.de/msmtp, MSMTP} is a @acronym{SMTP, Simple Mail
> > +Transfer Protocol} client.  It sends mails to a predefined SMTP server
> 
> “mail” (singular)

Done!


> > +@code{~/.config/msmtp/config} file.
> 
> “@file”

Done!


> This new intro + example look nice to me!
> 
> > +@item @code{logfile} (type: maybe-string)
> 
> [...]
> 
> > +@item @code{passwordeval} (type: maybe-string)
> > +Set the password for authentication to the output (stdout) of the
> > +command cmd.
> 
> Sorry for not noticing earlier but I’d suggest ‘log-file’ and
> ‘password-evaluation’ (?) to stick with the established naming
> convention.

Done!


> So I think beyond this the main issue is figuring out the missing
> serialization procedures, and then we’re done!

I'm sending a v4!

Cheers,


-- 
Tanguy




Information forwarded to ludo <at> gnu.org, guix-patches <at> gnu.org:
bug#62969; Package guix-patches. (Wed, 17 May 2023 08:53:02 GMT) Full text and rfc822 format available.

Message #29 received at 62969 <at> debbugs.gnu.org (full text, mbox):

From: Tanguy Le Carrour <tanguy <at> bioneland.org>
To: 62969 <at> debbugs.gnu.org
Cc: ludo <at> gnu.org, mirai <at> makinata.eu, Tanguy Le Carrour <tanguy <at> bioneland.org>
Subject: [PATCH v4] home: Add msmtp service.
Date: Wed, 17 May 2023 10:51:44 +0200
* gnu/home/services/mail.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
* doc/guix.texi (Mailing): New node.
---
 doc/guix.texi              | 137 ++++++++++++++++++++++
 gnu/home/services/mail.scm | 229 +++++++++++++++++++++++++++++++++++++
 gnu/local.mk               |   3 +-
 3 files changed, 368 insertions(+), 1 deletion(-)
 create mode 100644 gnu/home/services/mail.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index 60972f408d..e61d7f81ed 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -115,6 +115,7 @@
 Copyright @copyright{} 2022 Antero Mejr@*
 Copyright @copyright{} 2023 Karl Hallsby
 Copyright @copyright{} 2023 Nathaniel Nicandro
+Copyright @copyright{} 2023 Tanguy Le Carrour
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -42223,6 +42224,7 @@ Home Services
 * Guix: Guix Home Services.     Services for Guix.
 * Fonts: Fonts Home Services.   Services for managing User's fonts.
 * Sound: Sound Home Services.   Dealing with audio.
+* Mail: Mail Home Services.  Services for managing mail.
 * Messaging: Messaging Home Services.  Services for managing messaging.
 * Media: Media Home Services.   Services for managing media.
 @end menu
@@ -43452,6 +43454,141 @@ Sound Home Services
 This is the multicast address used by default by the two services above.
 @end defvar
 
+@node Mail Home Services
+@subsection Mail Home Services
+ 
+The @code{(gnu home services mail)} module provides services that help
+you set up the tools to work with emails in your home environment.
+ 
+@cindex msmtp
+@uref{https://marlam.de/msmtp, MSMTP} is a @acronym{SMTP, Simple Mail
+Transfer Protocol} client.  It sends mail to a predefined SMTP server
+that takes care of proper delivery.
+ 
+The service reference is given below.
+ 
+@defvar home-msmtp-service-type
+This is the service type for @command{msmtp}.  Its value must be a
+@code{home-msmtp-configuration}, as shown below.  It provides the
+@file{~/.config/msmtp/config} file.
+ 
+As an example, here is how you would configure @code{msmtp} for a single
+account:
+ 
+@lisp
+(service home-msmtp-service-type
+         (home-msmtp-configuration
+          (accounts
+           (list
+            (msmtp-account
+             (name "alice")
+             (configuration
+              (msmtp-configuration
+               (host "mail.example.org")
+               (port 587)
+               (user "alice")
+               (password-eval "pass Mail/alice"))))))))
+@end lisp
+@end defvar
+
+@c %start of fragment
+ 
+@deftp {Data Type} home-msmtp-configuration
+Available @code{home-msmtp-configuration} fields are:
+ 
+@table @asis
+@item @code{defaults} (type: msmtp-configuration)
+The configuration that will be set as default for all accounts.
+ 
+@item @code{accounts} (default: @code{()}) (type: list-of-msmtp-accounts)
+A list of @code{msmtp-account} records which contain information about
+all your accounts.
+ 
+@item @code{default-account} (type: maybe-string)
+Set the default account.
+ 
+@item @code{extra-content} (default: @code{""}) (type: string)
+Extra content appended as-is to the configuration file.  Run
+@command{man msmtp} for more information about the configuration file
+format.
+ 
+@end table
+ 
+@end deftp
+ 
+@c %end of fragment
+ 
+@c %start of fragment
+ 
+@deftp {Data Type} msmtp-account
+Available @code{msmtp-account} fields are:
+ 
+@table @asis
+@item @code{name} (type: string)
+The unique name of the account.
+ 
+@item @code{configuration} (type: msmtp-configuration)
+The configuration for this given account.
+ 
+@end table
+ 
+@end deftp
+ 
+@c %end of fragment
+
+@c %start of fragment
+ 
+@deftp {Data Type} msmtp-configuration
+Available @code{msmtp-configuration} fields are:
+ 
+@table @asis
+@item @code{auth?} (type: maybe-boolean)
+Enable or disable authentication.
+ 
+@item @code{tls?} (type: maybe-boolean)
+Enable or disable TLS (also known as SSL) for secured connections.
+ 
+@item @code{tls-starttls?} (type: maybe-boolean)
+Choose the TLS variant: start TLS from within the session (‘on’,
+default), or tunnel the session through TLS (‘off’).
+ 
+@item @code{tls-trust-file} (type: maybe-string)
+Activate server certificate verification using a list of trusted
+Certification Authorities (CAs).
+ 
+@item @code{log-file} (type: maybe-string)
+Enable logging to the specified file.  An empty argument disables
+logging.  The file name ‘-’ directs the log information to standard
+output.
+ 
+@item @code{host} (type: maybe-string)
+The SMTP server to send the mail to.
+ 
+@item @code{port} (type: maybe-integer)
+The port that the SMTP server listens on.  The default is 25 ("smtp"),
+unless TLS without STARTTLS is used, in which case it is 465 ("smtps").
+ 
+@item @code{user} (type: maybe-string)
+Set the user name for authentication.
+ 
+@item @code{from} (type: maybe-string)
+Set the envelope-from address.
+ 
+@item @code{password-eval} (type: maybe-string)
+Set the password for authentication to the output (stdout) of the
+command cmd.
+ 
+@item @code{extra-content} (default: @code{""}) (type: string)
+Extra content appended as-is to the configuration block.  Run
+@command{man msmtp} for more information about the configuration file
+format.
+ 
+@end table
+ 
+@end deftp
+ 
+@c %end of fragment
+
 @node Messaging Home Services
 @subsection Messaging Home Services
 
diff --git a/gnu/home/services/mail.scm b/gnu/home/services/mail.scm
new file mode 100644
index 0000000000..c3d34240f1
--- /dev/null
+++ b/gnu/home/services/mail.scm
@@ -0,0 +1,229 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Tanguy Le Carrour <tanguy <at> bioneland.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 mail)
+  #:use-module (guix gexp)
+  #:use-module (gnu packages)
+  #:use-module (gnu services)
+  #:use-module (gnu services configuration)
+  #:use-module (gnu home services)
+  #:use-module (gnu home services shepherd)
+  #:use-module (ice-9 string-fun)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
+  #:export (home-msmtp-configuration
+            home-msmtp-configuration?
+            home-msmtp-configuration-defaults
+            home-msmtp-configuration-accounts
+            home-msmtp-configuration-default-account
+            home-msmtp-configuration-extra-content
+            home-msmtp-service-type
+            msmtp-configuration
+            msmtp-configuration-auth?
+            msmtp-configuration-tls?
+            msmtp-configuration-tls-starttls?
+            msmtp-configuration-tls-trust-file
+            msmtp-configuration-log-file
+            msmtp-configuration-host
+            msmtp-configuration-port
+            msmtp-configuration-user
+            msmtp-configuration-from
+            msmtp-configuration-password-eval
+            msmtp-configuration-extra-content
+            msmtp-account
+            msmtp-account-name
+            msmtp-account-configuration))
+
+(define-maybe string)
+(define-maybe boolean)
+(define-maybe integer)
+
+;; Serialization of 'msmtp'.
+(define (uglify-symbol field-name)
+  (let* ((name (symbol->string field-name))
+         (ugly-name (string-replace-substring name "-" "_")))
+    (if (string-suffix? "?" ugly-name)
+      (string-drop-right ugly-name 1)
+      ugly-name)))
+
+(define (msmtp-configuration-serialize-maybe-boolean field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " (if #$value "on" "off") "\n")
+      ""))
+
+(define (msmtp-configuration-serialize-maybe-string field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " #$value "\n")
+      ""))
+
+(define (msmtp-configuration-serialize-maybe-string-no-underscore field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append
+        #$(string-replace-substring (uglify-symbol field-name) "_" "") " " #$value "\n")
+      ""))
+
+(define (msmtp-configuration-serialize-maybe-integer field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append #$(uglify-symbol field-name) " " (number->string #$value) "\n")
+      ""))
+
+(define (msmtp-configuration-serialize-extra-content field-name value)
+  #~(if (string=? #$value "") "" (string-append #$value "\n")))
+
+(define (msmtp-account-serialize-name field-name value)
+  #~(string-append "\naccount " #$value "\n"))
+
+(define (msmtp-account-serialize-msmtp-configuration field-name value)
+  #~(string-append #$(serialize-configuration value msmtp-configuration-fields)))
+
+(define (home-msmtp-configuration-serialize-list-of-msmtp-accounts field-name value)
+  #~(string-append #$@(map (cut serialize-configuration <> msmtp-account-fields)
+                           value)))
+
+(define (home-msmtp-configuration-serialize-msmtp-configuration field-name value)
+  #~(string-append "defaults\n"
+                   #$(serialize-configuration value msmtp-configuration-fields)))
+
+(define (home-msmtp-configuration-serialize-default-account field-name value)
+  #~(if #$(maybe-value-set? value)
+      (string-append "\naccount default : " #$value "\n")
+      ""))
+
+(define (home-msmtp-configuration-serialize-extra-content field-name value)
+  #~(if (string=? #$value "") "" (string-append #$value "\n")))
+
+;; Configuration of 'msmtp'.
+;; Source <https://marlam.de/msmtp/msmtp.html#Configuration-files>.
+(define-configuration msmtp-configuration
+  (auth?
+   maybe-boolean
+   "Enable or disable authentication.")
+
+  (tls?
+   maybe-boolean
+   "Enable or disable TLS (also known as SSL) for secured connections.")
+
+  (tls-starttls?
+   maybe-boolean
+   "Choose the TLS variant: start TLS from within the session (‘on’, default),
+or tunnel the session through TLS (‘off’).")
+
+  (tls-trust-file
+   maybe-string
+   "Activate server certificate verification using a list of
+trusted Certification Authorities (CAs).")
+
+  (log-file
+   maybe-string
+   "Enable logging to the specified file. An empty argument disables logging.
+The file name ‘-’ directs the log information to standard output."
+   (serializer msmtp-configuration-serialize-maybe-string-no-underscore))
+
+  (host
+    maybe-string
+    "The SMTP server to send the mail to.")
+
+  (port
+    maybe-integer
+    "The port that the SMTP server listens on. The default is 25 (\"smtp\"),
+unless TLS without STARTTLS is used, in which case it is 465 (\"smtps\").")
+
+  (user
+    maybe-string
+    "Set the user name for authentication.")
+
+  (from
+    maybe-string
+    "Set the envelope-from address.")
+
+  (password-eval
+    maybe-string
+    "Set the password for authentication to the output (stdout) of the command cmd."
+    (serializer msmtp-configuration-serialize-maybe-string-no-underscore))
+
+  (extra-content
+   (string "")
+   "Extra content appended as-is to the configuration block.  Run
+@command{man msmtp} for more information about the configuration file
+format."
+   (serializer msmtp-configuration-serialize-extra-content))
+
+  (prefix msmtp-configuration-))
+
+(define-configuration msmtp-account
+  (name
+   (string)
+   "The unique name of the account."
+   (serializer msmtp-account-serialize-name))
+
+  (configuration
+   (msmtp-configuration)
+   "The configuration for this given account.")
+
+  (prefix msmtp-account-))
+
+(define (list-of-msmtp-accounts? lst)
+  (every msmtp-account? lst))
+
+(define-configuration home-msmtp-configuration
+  (defaults
+   (msmtp-configuration (msmtp-configuration))
+   "The configuration that will be set as default for all accounts.")
+
+  (accounts
+   (list-of-msmtp-accounts '())
+   "A list of @code{msmtp-account} records which contain
+information about all your accounts.")
+
+  (default-account
+   maybe-string
+   "Set the default account."
+   (serializer home-msmtp-configuration-serialize-default-account))
+
+  (extra-content
+   (string "")
+   "Extra content appended as-is to the configuration file.  Run
+@command{man msmtp} for more information about the configuration file
+format."
+   (serializer home-msmtp-configuration-serialize-extra-content))
+
+  (prefix home-msmtp-configuration-))
+
+(define (home-msmtp-files-service config)
+  (list
+   `(".config/msmtp/config"
+     ,(mixed-text-file "config"
+                       (serialize-configuration config home-msmtp-configuration-fields)))))
+
+(define (home-msmtp-profile-service config)
+  (specifications->packages (list "msmtp")))
+
+(define home-msmtp-service-type
+  (service-type (name 'home-msmtp)
+                (extensions
+                  (list
+                    (service-extension
+                      home-profile-service-type
+                      home-msmtp-profile-service)
+                    (service-extension
+                      home-files-service-type
+                      home-msmtp-files-service)))
+                (default-value (home-msmtp-configuration))
+                (description "Configure msmtp, a simple
+@acronym{SMTP, Simple Mail Transfer Protocol} client that can relay email
+to SMTP servers.")))
diff --git a/gnu/local.mk b/gnu/local.mk
index 42514ded8e..930e69e289 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -35,7 +35,7 @@
 # Copyright © 2020 Ryan Prior <rprior <at> protonmail.com>
 # Copyright © 2020 Jan Wielkiewicz <tona_kosmicznego_smiecia <at> interia.pl>
 # Copyright © 2020, 2021 Brice Waegeneire <brice <at> waegenei.re>
-# Copyright © 2020 Tanguy Le Carrour <tanguy <at> bioneland.org>
+# Copyright © 2020, 2023 Tanguy Le Carrour <tanguy <at> bioneland.org>
 # Copyright © 2020 Martin Becze <mjbecze <at> riseup.net>
 # Copyright © 2020 Malte Frank Gerdes <mate.f.gerdes <at> gmail.com>
 # Copyright © 2020, 2023 Vinicius Monego <monego <at> posteo.net>
@@ -94,6 +94,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/home/services/fontutils.scm		\
   %D%/home/services/gnupg.scm			\
   %D%/home/services/guix.scm			\
+  %D%/home/services/mail.scm			\
   %D%/home/services/media.scm			\
   %D%/home/services/messaging.scm		\
   %D%/home/services/pm.scm			\

base-commit: c8e599b9391f789a8a3e2183fc8f0c2a5061ceb0
-- 
2.40.1





Reply sent to Ludovic Courtès <ludo <at> gnu.org>:
You have taken responsibility. (Mon, 29 May 2023 21:44:01 GMT) Full text and rfc822 format available.

Notification sent to Tanguy Le Carrour <tanguy <at> bioneland.org>:
bug acknowledged by developer. (Mon, 29 May 2023 21:44:02 GMT) Full text and rfc822 format available.

Message #34 received at 62969-done <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Tanguy Le Carrour <tanguy <at> bioneland.org>
Cc: 62969-done <at> debbugs.gnu.org, mirai <at> makinata.eu
Subject: Re: bug#62969: [PATCH] home: Add msmtp service.
Date: Mon, 29 May 2023 23:43:14 +0200
[Message part 1 (text/plain, inline)]
Hi,

Tanguy Le Carrour <tanguy <at> bioneland.org> skribis:

> * gnu/home/services/mail.scm: New file.
> * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
> * doc/guix.texi (Mailing): New node.

Sorry for the delay!

I applied it with the changes below.  The ‘define-maybe’ change fixes
the unbound-variable warnings that we were seeing, and it lets us remove
a bit of boilerplate.

In a subsequent patch, we should make the msmtp package configurable, as
is done for other services (see redshift, unclutter, dbus, etc.).
I was going to do it but ran out of time; could you take a look?

Thanks!

Ludo’.

[Message part 2 (text/x-patch, inline)]
diff --git a/gnu/home/services/mail.scm b/gnu/home/services/mail.scm
index c3d34240f1..5445c82c67 100644
--- a/gnu/home/services/mail.scm
+++ b/gnu/home/services/mail.scm
@@ -18,11 +18,11 @@
 
 (define-module (gnu home services mail)
   #:use-module (guix gexp)
-  #:use-module (gnu packages)
   #:use-module (gnu services)
   #:use-module (gnu services configuration)
   #:use-module (gnu home services)
   #:use-module (gnu home services shepherd)
+  #:use-module (gnu packages mail)
   #:use-module (ice-9 string-fun)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-26)
@@ -49,9 +49,9 @@ (define-module (gnu home services mail)
             msmtp-account-name
             msmtp-account-configuration))
 
-(define-maybe string)
-(define-maybe boolean)
-(define-maybe integer)
+(define-maybe string (prefix msmtp-configuration-))
+(define-maybe boolean (prefix msmtp-configuration-))
+(define-maybe integer (prefix msmtp-configuration-))
 
 ;; Serialization of 'msmtp'.
 (define (uglify-symbol field-name)




















@@ -61,15 +61,12 @@ (define (uglify-symbol field-name)
       (string-drop-right ugly-name 1)
       ugly-name)))
 
-(define (msmtp-configuration-serialize-maybe-boolean field-name value)
-  #~(if #$(maybe-value-set? value)
-      (string-append #$(uglify-symbol field-name) " " (if #$value "on" "off") "\n")
-      ""))
+(define (msmtp-configuration-serialize-boolean field-name value)
+  #~(string-append #$(uglify-symbol field-name) " "
+                   (if #$value "on" "off") "\n"))
 
-(define (msmtp-configuration-serialize-maybe-string field-name value)
-  #~(if #$(maybe-value-set? value)
-      (string-append #$(uglify-symbol field-name) " " #$value "\n")
-      ""))
+(define (msmtp-configuration-serialize-string field-name value)
+  #~(string-append #$(uglify-symbol field-name) " " #$value "\n"))
 
 (define (msmtp-configuration-serialize-maybe-string-no-underscore field-name value)
   #~(if #$(maybe-value-set? value)
@@ -77,10 +74,9 @@ (define (msmtp-configuration-serialize-maybe-string-no-underscore field-name val
         #$(string-replace-substring (uglify-symbol field-name) "_" "") " " #$value "\n")
       ""))
 
-(define (msmtp-configuration-serialize-maybe-integer field-name value)
-  #~(if #$(maybe-value-set? value)
-      (string-append #$(uglify-symbol field-name) " " (number->string #$value) "\n")
-      ""))
+(define (msmtp-configuration-serialize-integer field-name value)
+  #~(string-append #$(uglify-symbol field-name) " "
+                   (number->string #$value) "\n"))
 
 (define (msmtp-configuration-serialize-extra-content field-name value)
   #~(if (string=? #$value "") "" (string-append #$value "\n")))
@@ -204,25 +200,22 @@ (define-configuration home-msmtp-configuration
 
   (prefix home-msmtp-configuration-))
 
-(define (home-msmtp-files-service config)
+(define (home-msmtp-files config)
   (list
    `(".config/msmtp/config"
-     ,(mixed-text-file "config"
+     ,(mixed-text-file "msmtp-config"
                        (serialize-configuration config home-msmtp-configuration-fields)))))
 
-(define (home-msmtp-profile-service config)
-  (specifications->packages (list "msmtp")))
+(define (home-msmtp-profile-entries config)
+  (list msmtp))
 
 (define home-msmtp-service-type
   (service-type (name 'home-msmtp)
                 (extensions
-                  (list
-                    (service-extension
-                      home-profile-service-type
-                      home-msmtp-profile-service)
-                    (service-extension
-                      home-files-service-type
-                      home-msmtp-files-service)))
+                 (list (service-extension home-profile-service-type
+                                          home-msmtp-profile-entries)
+                       (service-extension home-files-service-type
+                                          home-msmtp-files)))
                 (default-value (home-msmtp-configuration))
                 (description "Configure msmtp, a simple
 @acronym{SMTP, Simple Mail Transfer Protocol} client that can relay email

Information forwarded to guix-patches <at> gnu.org:
bug#62969; Package guix-patches. (Tue, 30 May 2023 06:55:02 GMT) Full text and rfc822 format available.

Message #37 received at 62969-done <at> debbugs.gnu.org (full text, mbox):

From: Tanguy LE CARROUR <tanguy <at> bioneland.org>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 62969-done <at> debbugs.gnu.org, mirai <at> makinata.eu
Subject: Re: bug#62969: [PATCH] home: Add msmtp service.
Date: Tue, 30 May 2023 08:54:12 +0200
Hi Ludo’


Quoting Ludovic Courtès (2023-05-29 23:43:14)
> Tanguy Le Carrour <tanguy <at> bioneland.org> skribis:
> 
> > * gnu/home/services/mail.scm: New file.
> > * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
> > * doc/guix.texi (Mailing): New node.
> 
> Sorry for the delay!
> 
> I applied it with the changes below.  The ‘define-maybe’ change fixes
> the unbound-variable warnings that we were seeing, and it lets us remove
> a bit of boilerplate.

Thaaaanks!


> In a subsequent patch, we should make the msmtp package configurable, as
> is done for other services (see redshift, unclutter, dbus, etc.).
> I was going to do it but ran out of time; could you take a look?

Absolutely! I submitted a simple one in order to have something
to improve upon! 😁

Cheers,

-- 
Tanguy




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 27 Jun 2023 11:24:10 GMT) Full text and rfc822 format available.

This bug report was last modified 297 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.