Précédent: Services Shepherd, Monter: Définir des services [Table des matières][Index]
Certains programmes peuvent avoir des fichiers ou des formats de
configuration complexes, et pour rendre plus simple la création de liaisons
Scheme pour ces fichiers de configuration, vous pouvez utiliser les fonction
auxiliaires définies dans le modules (gnu services configuration)
.
L’utilitaire principal est la macro define-configuration
, que vous
utiliserez pour définir un type d’enregistrement Scheme (voir Record
Overview dans GNU Guile Reference Manual). L’enregistrement Scheme
sera sérialisé en un fichier de configuration par des sérialiseurs,
qui sont des procédures qui prennent une valeur Scheme et renvoient une
G-expression (voir G-Expressions), ce qui devrait, une fois sérialisé sur
le disque, renvoyer une chaine. Plus de détails se trouvent plus bas.
Create a record type named name
that contains the fields found
in the clauses.
Une clause peut avoir l’une des formes suivantes :
(field-name (type default-value) documentation) (field-name (type default-value) documentation (serializer serializer)) (nom-du-champ (type) documentation) (field-name (type) documentation (serializer serializer)) (field-name (type) documentation (sanitizer sanitizer) (field-name (type) documentation (sanitizer sanitizer) (serializer serializer))
nom-du-champ est un identifiant qui dénote le nom du champ dans l’enregistrement généré.
type est le type de valeur correspondant à nom-du-champ ; comme
Guile n’est pas typé, une procédure de prédicat — type?
—
sera appelée avec la valeur correspondant au champ pour s’assurer que la
valeur est du type correct. Cela signifie que si type est
package
, alors une procédure nommée package?
sera appliquée
sur la valeur pour s’assurer que c’est bien un objet <package>
.
valeur-par-défaut est la valeur par défaut correspondant au champ ; si aucune n’est spécifiée, l’utilisateur ou l’utilisatrice doit fournir une valeur à la création d’un objet de ce type d’enregistrement.
documentation est une chaine formatée avec la syntaxe de Texinfo qui fournit une description de ce que ce champ de configuration signifie.
sanitizer is a procedure which takes one argument, a user-supplied value, and returns a “sanitized” value for the field. If no sanitizer is specified, a default sanitizer is used, which raises an error if the value is not of type type.
An example of a sanitizer for a field that accepts both strings and symbols looks like this:
(define (sanitize-foo value)
(cond ((string? value) value)
((symbol? value) (symbol->string value))
(else (error "bad value"))))
sérialiseur est le nom d’une procédure qui prend deux arguments, le
premier est le nom du champ, et le second est la valeur correspondant au
champ. La procédure devrait renvoyer une chaine ou une G-expression
(voir G-Expressions) qui représente le contenu qui sera sérialisé dans le
fichier de configuration. Si aucun n’est spécifié, une procédure nommée
serialize-type
sera utilisée.
Une simple procédure de sérialisation pourrait ressembler à ceci :
(define (serialize-boolean field-name value)
(let ((value (if value "true" "false")))
#~(string-append #$field-name #$value)))
Dans certains cas plusieurs enregistrements de configuration différents
peuvent être définis dans le même fichier, mais leurs sérialiseurs pour le
même type peuvent devoir être différents, à cause de formats de
configuration différents. Par exemple, la procédure serialize-boolean
pour le service Getmail doit être différente de celle pour le service
Transmission. Pour faciliter cette situation, on peut spécifier un préfixe
pour sérialiseur en utilisant le littéral prefix
dans la forme
define-configuration
. Cela signifie qu’on n’a pas à spécifier
manuellement un sérialiseur personnalisé pour chaque champ.
(define (toto-serialize-string field-name value) …) (define (bar-serialize-string field-name value) …) (define-configuration toto-configuration (label (string) "Le nom de l'étiquette.") (prefix toto-)) (define-configuration titi-configuration (ip-address (string) "L'adresse IPv4 de cet appareil.") (prefix titi-))
Cependant, dans certains cas vous ne voudrez pas sérialiser les valeurs de
l’enregistrement. Pour cela, vous pouvez utiliser le littéral
no-serialization
. Il y a aussi la macro
define-configuration/no-serialization
qui est un raccourci.
Parfois un champ ne devrait pas être sérialisé si l’utilisateur ou
l’utilisatrice de spécifie par de valeur. Pour cela, vous pouvez utiliser la
macro define-maybe
pour définir un « type peut-être » ; si la valeur
d’un type peut-être n’est pas spécifiée, ou est indiquée à
%unset-value
, elle n’est pas sérialisée.
Lorsque vous définissez un « type peut-être », le sérialiseur correspondant
au type normal sera utilisé par défaut. Par exemple, un champ de type
maybe-string
sera sérialisé avec la procédure serialize-string
par défaut, vous pouvez évidemment changer cela en spécifiant une procédure
de sérialisation personnalisée. De la même manière, le type de la valeur
doit être une chaine, ou la valeur doit rester non spécifiée.
(define-maybe string) (define (serialize-string field-name value) …) (define-configuration tata-configuration (name ;; Si c'est une chaine, la procédure « serialize-string » sera utilisée ;; pour sérialiser la chaine. Sinon ce champ n'est pas sérialisé maybe-string "Le nom de ce module."))
Comme avec define-configuration
, on peut indiquer un préfixe pour le
nom de sérialiseur en utilisant le littéral prefix
.
(define-maybe integer (prefix tata-)) (define (tata-serialize-integer field-name value) …)
Il y a aussi le littéral no-serialization
, qui s’il est utilisé
indique qu’aucun sérialiseur ne sera défini pour le « type peut-être »,
indépendamment de si la valeur est indiquée ou
non. define-maybe/no-serialization
est un raccourci pour spécifier le
littéral no-serialization
.
(define-maybe/no-serialization symbol) (define-configuration/no-serialization test-configuration (mode maybe-symbol "Docstring."))
Prédicat pour vérifier si l’utilisateur ou l’utilisatrice a spécifié la valeur d’un champ peut-être.
Return a G-expression that contains the values corresponding to the
fields of configuration, a record that has been generated by
define-configuration
. The G-expression can then be serialized to
disk by using something like mixed-text-file
.
Un sérialiseur qui renvoie juste une chaine vide. La procédure
serialize-package
est un alias pour cette procédure.
Une fois que vous avez défini un enregistrement de configuration, vous voudrez aussi sans doute le documenter pour que d’autres personnes sachent comment l’utiliser. Pour vous aider, il y a deux procédure qui sont documentées plus bas.
Generate a Texinfo fragment from the docstrings in documentation, a
list of (label fields sub-documentation ...)
.
label should be a symbol and should be the name of the configuration
record. fields should be a list of all the fields available for the
configuration record.
sous-documentation est un tuple (nom-de-champ
nom-de-configuration)
. nom-de-champ est le nom du champ qui
prend un autre enregistrement de configuration comme valeur, et
nom-de-configuration est le nom de cet enregistrement de
configuration.
sous-documentation n’est requis que s’il y a des enregistrements de
configuration imbriqués. Par exemple, l’enregistrement
getmail-configuration
(voir Services de courriels) accepte un
enregistrement getmail-configuration-file
dans l’un de ses champs
rcfile
, donc la documentation de getmail-configuration-file
est imbriquée dans getmail-configuration
.
(generate-documentation
`((getmail-configuration ,getmail-configuration-fields
(rcfile getmail-configuration-file))
…)
'getmail-configuration)
nom-de-documentation devrait être un symbole et devrait être le nom de l’enregistrement de configuration.
Take configuration-symbol, the symbol corresponding to the name used
when defining a configuration record with define-configuration
, and
print the Texinfo documentation of its fields. This is useful if there
aren’t any nested configuration records since it only prints the
documentation for the top-level fields.
Actuellement, il n’y a pas de manière automatique de générer la
documentation pour les enregistrements de configuration et les ajouter au
manuel. Au lieu de cela, chaque fois que vous faites un changement dans les
docstrings d’un enregistrement de configuration, vous devez appeler
manuellement generate-documentation
ou
configuration->documentation
et coller la sortie dans le fichier
doc/guix.texi.
Ci-dessous se trouve un exemple d’un type d’enregistrement créé avec
define-configuration
et compagnie.
(use-modules (gnu services) (guix gexp) (gnu services configuration) (srfi srfi-26) (srfi srfi-1)) ;; Transforme les noms de champs, qui sont des symboles Scheme, en chaines (define (uglify-field-name field-name) (let ((str (symbol->string field-name))) ;; field? -> is-field (if (string-suffix? "?" str) (string-append "is-" (string-drop-right str 1)) str))) (define (serialize-string field-name value) #~(string-append #$(uglify-field-name field-name) " = " #$value "\n")) (define (serialize-integer field-name value) (serialize-string field-name (number->string value))) (define (serialize-boolean field-name value) (serialize-string field-name (if value "true" "false"))) (define (serialize-contact-name field-name value) #~(string-append "\n[" #$value "]\n")) (define (list-of-contact-configurations? lst) (every contact-configuration? lst)) (define (serialize-list-of-contact-configurations field-name value) #~(string-append #$@(map (cut serialize-configuration <> contact-configuration-fields) value))) (define (serialize-contacts-list-configuration configuration) (mixed-text-file "contactrc" #~(string-append "[Owner]\n" #$(serialize-configuration configuration contacts-list-configuration-fields)))) (define-maybe integer) (define-maybe string) (define-configuration contact-configuration (name (string) "Le nom du contact." serialize-contact-name) (phone-number maybe-integer "Le numéro de téléphone de la personne.") (email maybe-string "L'adresse de courriel de la personne.") (married? (boolean) "Indique si la personne est mariée.")) (define-configuration contacts-list-configuration (name (string) "Le nom du propriétaire de cette liste de contacts.") (email (string) "L'adresse de courriel du propriétaire.") (contacts (list-of-contact-configurations '()) "Une liste d'enregistrements @code{contact-configuation} qui contiennent des informations sur tous vos contacts."))
Une configuration de liste de contacts pourrait alors être créée de cette manière :
(define my-contacts
(contacts-list-configuration
(name "Alice")
(email "alice@example.org")
(contacts
(list (contact-configuration
(name "Bob")
(phone-number 1234)
(email "bob@gnu.org")
(married? #f))
(contact-configuration
(name "Charlie")
(phone-number 0000)
(married? #t))))))
Après la sérialisation de la configuration sur le disque, le fichier qui en résulte ressemble à ceci :
[owner] name = Alice email = alice@example.org [Bob] phone-number = 1234 email = bob@gnu.org is-married = false [Charlie] phone-number = 0 is-married = true
Précédent: Services Shepherd, Monter: Définir des services [Table des matières][Index]