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.
Crée un type d’enregistrement nommé nom
qui contient les champs
qui se trouvent dans les clauses.
Une clause peut avoir l’une des formes suivantes :
(nom-du-champ (type valeur-par-défaut) documentation) (nom-du-champ (type valeur-par-défaut) documentation sérialiseur) (nom-du-champ (type) documentation) (nom-du-champ (type) documentation sérialiseur)
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.
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 (titi-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.
Renvoie une G-expression qui contient les valeurs correspondant aux
champs de configuration, un enregistrement qui a été généré par
define-configuration
. La G-expression peut ensuite être sérialisée
vers le disque en utilisant par exemple 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.
Génère un fragment Texinfo à partir de docstrings dans documentation,
une liste de (étiquette champs sous-documentation
…)
. étiquette devrait être un symbole et devrait être le nom de
l’enregistrement de configuration. champs devrait être une liste de
tous les champs disponibles pour l’enregistrement de configuration.
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.
configuration-symbol
Prend configuration-symbol, le symbole correspondant au nom utilisé
pour définir un enregistrement de configuration avec
define-configuration
, et affiche la documentation Texinfo pour ses
champs. Cette procédure est utile s’il n’y a pas d’enregistrement de
configuration imbriqué car elle n’affiche que la documentation des champs de
plus haut niveau.
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]