[PATCH] home: Add msmtp service.

  • Done
  • quality assurance status badge
Details
3 participants
  • Ludovic Courtès
  • Bruno Victal
  • Tanguy Le Carrour
Owner
unassigned
Submitted by
Tanguy Le Carrour
Severity
normal
T
T
Tanguy Le Carrour wrote on 20 Apr 2023 16:42
(address . guix-patches@gnu.org)(name . Tanguy Le Carrour)(address . tanguy@bioneland.org)
20230420144230.9392-1-tanguy@bioneland.org
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

Toggle diff (336 lines)
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@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
B
B
Bruno Victal wrote on 20 Apr 2023 18:36
(name . Tanguy Le Carrour)(address . tanguy@bioneland.org)(address . 62969@debbugs.gnu.org)
4f8624a0-31fe-1ea5-733a-b2e1917291b4@makinata.eu
Hi Tanguy,

On 2023-04-20 15:42, Tanguy Le Carrour wrote:
Toggle quote (6 lines)
> - 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 ...)'.

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

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

Toggle snippet (13 lines)
(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)))

Example usage:

Toggle snippet (35 lines)
;; 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

Toggle quote (3 lines)
> +
> +(define raw-configuration-string? string?)

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

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


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

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

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

See [2] above.

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

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

Toggle quote (30 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
T
T
Tanguy LE CARROUR wrote on 23 Apr 2023 19:10
(name . Bruno Victal)(address . mirai@makinata.eu)(address . 62969@debbugs.gnu.org)
168226981597.13515.12105199384744750840@localhost
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)
Toggle quote (18 lines)
> 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%
```


Toggle quote (8 lines)
> > + (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
T
T
Tanguy Le Carrour wrote on 23 Apr 2023 19:12
[PATCH v2] home: Add msmtp service.
(address . 62969@debbugs.gnu.org)
20230423171217.14894-1-tanguy@bioneland.org
* 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

Toggle diff (370 lines)
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@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
L
L
Ludovic Courtès wrote on 30 Apr 2023 23:30
Re: bug#62969: [PATCH] home: Add msmtp service.
(name . Tanguy Le Carrour)(address . tanguy@bioneland.org)
87ilddnjml.fsf_-_@gnu.org
Hi Tanguy! :-)

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

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

I get:

Toggle snippet (6 lines)
[ 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'

I guess these procedures should be provided as well?

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

[...]

Toggle quote (3 lines)
> + (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’.
T
T
Tanguy LE CARROUR wrote on 3 May 2023 12:01
[PATCH v3] home: Add msmtp service.
(name . Ludovic Courtès)(address . ludo@gnu.org)
168310810854.1650.852938763274164245@localhost
Hi Ludo’,

Quoting Ludovic Courtès (2023-04-30 23:30:10)
Toggle quote (17 lines)
> Tanguy Le Carrour <tanguy@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.


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

Toggle diff (405 lines)
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@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
L
L
Ludovic Courtès wrote on 3 May 2023 22:27
(name . Tanguy LE CARROUR)(address . tanguy@bioneland.org)
87ednxyxd4.fsf@gnu.org
Hello!

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

Toggle quote (21 lines)
> Quoting Ludovic Courtès (2023-04-30 23:30:10)
>> Tanguy Le Carrour <tanguy@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.

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

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

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

Toggle quote (2 lines)
> +@code{~/.config/msmtp/config} file.

“@file”

This new intro + example look nice to me!

Toggle quote (2 lines)
> +@item @code{logfile} (type: maybe-string)

[...]

Toggle quote (4 lines)
> +@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’.
T
T
Tanguy LE CARROUR wrote on 17 May 2023 10:52
(name . Ludovic Courtès)(address . ludo@gnu.org)
168431352507.9673.2828328652177284378@localhost
Hi,


Quoting Ludovic Courtès (2023-05-03 22:27:03)
Toggle quote (26 lines)
> Tanguy LE CARROUR <tanguy@bioneland.org> skribis:
>
> > Quoting Ludovic Courtès (2023-04-30 23:30:10)
> >> Tanguy Le Carrour <tanguy@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’ ?


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

Done!


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


Toggle quote (4 lines)
> > +@code{~/.config/msmtp/config} file.
>
> “@file”

Done!


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


Toggle quote (3 lines)
> 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
T
T
Tanguy Le Carrour wrote on 17 May 2023 10:51
[PATCH v4] home: Add msmtp service.
(address . 62969@debbugs.gnu.org)
b2cd3fe9db8d8c4ddb0678dbd36937e83a09511d.1684313128.git.tanguy@bioneland.org
* 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

Toggle diff (422 lines)
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@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@protonmail.com>
# Copyright © 2020 Jan Wielkiewicz <tona_kosmicznego_smiecia@interia.pl>
# Copyright © 2020, 2021 Brice Waegeneire <brice@waegenei.re>
-# Copyright © 2020 Tanguy Le Carrour <tanguy@bioneland.org>
+# Copyright © 2020, 2023 Tanguy Le Carrour <tanguy@bioneland.org>
# Copyright © 2020 Martin Becze <mjbecze@riseup.net>
# Copyright © 2020 Malte Frank Gerdes <mate.f.gerdes@gmail.com>
# Copyright © 2020, 2023 Vinicius Monego <monego@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
L
L
Ludovic Courtès wrote on 29 May 2023 23:43
Re: bug#62969: [PATCH] home: Add msmtp service.
(name . Tanguy Le Carrour)(address . tanguy@bioneland.org)
87ttvuerv1.fsf_-_@gnu.org
Hi,

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

Toggle quote (4 lines)
> * 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’.
Toggle diff (119 lines)
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
Closed
T
T
Tanguy LE CARROUR wrote on 30 May 2023 08:54
(name . Ludovic Courtès)(address . ludo@gnu.org)
168542965253.3863.1458539807352226508@localhost
Hi Ludo’


Quoting Ludovic Courtès (2023-05-29 23:43:14)
Toggle quote (12 lines)
> Tanguy Le Carrour <tanguy@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!


Toggle quote (4 lines)
> 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
Closed
?
Your comment

This issue is archived.

To comment on this conversation send an email to 62969@debbugs.gnu.org

To respond to this issue using the mumi CLI, first switch to it
mumi current 62969
Then, you may apply the latest patchset in this issue (with sign off)
mumi am -- -s
Or, compose a reply to this issue
mumi compose
Or, send patches to this issue
mumi send-email *.patch