[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
?