Hi Ian, Thank you very much for your reply and your help. I wrote my replies after the quotes.
Ian Eure <[email protected]> writes: > Sébastien Gendre <[email protected]> writes: >> ;; Define serializer functions >> (define (serialize-luanti-admin-name field-name value) >> "Serialize the Luanti admin name field for the config >> file." >> (let ((field-real-name "name")) >> #~(string-append #$field-real-name " = " #$value))) > > Since you’re only building strings, you don’t need a gexp, nor do you > need the let binding. Here’s a simplified version: > > (define (serialize-luanti-admin-name _ value) > "Serialize the Luanti admin name field for the config file." > (string-append "name = " #$value)) Thank you very much. I'm still very new with gexp. The `define-configuration' documentation was saying that the serializer procedure should return a gexp. But if it can be done without gexp, that make it easy. >> ;; Define the Luanti Game configuration >> (define-configuration luanti-game-configuration >> (admin-name >> maybe-string >> "Username of the administrator." >> (serializer serialize-luanti-admin-name))) > > This is mixing an optional predicate with a required serializer, which > won’t work right. While it’s boilerplatey, I find that the best > approach is to make one type per field: > > (define admin-name? string?) > (define (serialize-admin-name field-name value) "do the right > thing here") > > Then use `define-maybe' and the predicate & serializer it expands to: > > (define-maybe admin-name) > > (define-configuration luanti-game-configuration > (admin-name maybe-admin-name "Username of the > administrator.")) > > Within the configuration system, "type" covers both the value *and* > how it’s handled, which can cause problems when you have two fields > which take string, but need different serialize-string handling -- > like one needing to be quoted, or one representing an INI-style > [section] and another a key = value pair. Starting here gives you > clean separation you can merge later, if you like. I thought that I could use an existing type (string) and only specify a specific serializer for this parameter. An then, define a generic string serializer for the simple string parameters. When I define a maybe and a serializer procedure for a type, the serializer procedure didn't have to adapt its behavior based on the "maybe" part ? Like returning something only if the value is not empty ? >> ;; Define Luanti game configuration file generator >> (define (minetest.conf config) >> "Return the Luanti config file." >> (plain-file "minetest.conf" >> (with-output-to-string >> (lambda () >> (serialize-configuration >> config >> luanti-game-configuration-fields))))) > > This is the crux of your problem. The `with-output-to-string' > procedure captures any value *printed* and returns it as a string. > Your lambda doesn’t print anything, because `serialize-configuration' > doesn’t print anything, it returns a value. Since there’s no output, > `with-output-to-string' returns an empty string, and `plain-file' puts > that in your minetest.conf. Whoops. I took inspiration of `libvirt-conf-file' (in file gnu/services/virtualization.scm:486). How is it working in the case of `libvirt-conf-file' ? Is it only working in the context of a system service activation ? > The procedure should be: > > ;; Define Luanti game configuration file generator > (define (minetest.conf config) > "Return the Luanti config file." > (mixed-text-file > "minetest.conf" > (serialize-configuration config > luanti-game-configuration-fields))) > > Note that if your serializers use gexps, you will need to build the > mixed-text-file to see anything. If you’ve used the (guix) module in > your Guile REPL, you can do this with: > > ,build (minetest.conf ...) A great thank you for this part. I was trying to use `mixed-text-file' at the beginning, but didn't know how to generate the content of the obtained `computed-file'. > On a closing note, I’ll share that I’ve also struggled a lot with the > configuration system in Guix, both in its documentation and > implementation. Implementation-wise, the system feels both barebones > and verbose. I’ve run into some stuff with unsatisfying expressions, > like fields whose names aren’t needed, config subsections, and > configurations spanning multiple files. These all require workarounds > which feel more like subverting the system than using it as intended. I have the same problem. I have more experience with Ansible and it's template module. I thought that `define-configuration' would serve the same goal but using Scheme programming instead of template. I bit like the HTML export backend of Org-mode is, compared to usual template system of static and dynamic web pages generators. > On the documentation side, the Guix manual is an invaluable reference, > but a lot of it feels like just that -- a reference. It has great > "what" and "how" information, but in my opinion, sorely lacks the > contextual "why" and "when" to effectively apply it. Yes, I get what you mean about the manual. I think the contextual "why" and "when" is more in the cookbook. But, for now, there is no section about writing a system service step by step. Or a home service. I would love to help, but my actual understanding of it is not a the required level to write a good tutorial. And, about the manual, I noticed that as a new Guix and Guix system user, I have some difficulties to understand some parts. It's like I miss an information, or a details, in the manual. But I didn't note it somewhere, so now it would be difficult to notice it again. At least, for parts I understand now.
signature.asc
Description: PGP signature
