On 2022-01-09 12:19, Liliana Marie Prikler wrote: > Hi Andrew, > > Am Sonntag, dem 09.01.2022 um 12:12 +0300 schrieb Andrew Tropin: >> Before fee0bc serialization for text-config worked this way: >> --8<---------------cut here---------------start------------->8--- >> `("string here" >>   ,#~"string valued gexp" >>   "source \" >>   ,(local-file "blabla.sh")) >> --8<---------------cut here---------------end--------------->8--- >> >> would yield something like: >> >> --8<---------------cut here---------------start------------->8--- >> string here >> string valued gexp >> source \ >> /gnu/store/00fl96dj2aak4i1vqvdqzlhbmmskc7fx-blabla.sh >> --8<---------------cut here---------------end--------------->8--- >> >> [...] >> >> The new text-config serialization implementation (after fee0bc >> commit) doesn't support gexps and tries to insert the literal content >> of the file in place where file-like object was used[.] > I agree that the old one looks nicer in this context, but wasn't the > new one introduced to solve the issue of (slurp-file-gexp) in the > importer? Meaning whichever way we go, we need something that allows > us to insert literal file contents of another file at more or less G- > exp compile time. > From my experience the usage of slurp-file-gexp is somewhat really rare, so I didn't upstream it originally, keeping in mind that it is possible to use the gexp mentioned below directly and that later we can add slurp-file-gexp or alternative if necessary. Just missed that importer already uses it. We could just do something like that instead of slurp-file-gexp: --8<---------------cut here---------------start------------->8--- #~(call-with-input-file #$(local-file "./files/bashrc") (@ (ice-9 textual-ports) get-string-all)) --8<---------------cut here---------------end--------------->8--- Or just take the implementation https://git.sr.ht/~abcdw/rde/tree/47f6c65c82a4f6761fa1ff5b9405b363cfda6482/gnu/home-services-utils.scm#L90 and rename it to read-file-content-gexp or somewhat more apropriate and use it. > > Perhaps that issue could be solved, if instead the importer just reads > the file contents and declares it as a variable as in (define %bashrc > " ;; Original contents of bashrc ") (define bashrc (plain-file > %bashrc)). > > WDYT? > Another possible solution, but I would prefer to stick with the direct usage of gexp with the code for reading a file, because importer is intended for creation of an example configuration and user will need to continue the work on it and copying the content of bashrc and other configs to scheme files, escaping string can be a little tedious. >> If we want to insert the file path to file-like object for new-style >> text-config internally we do something like >> >> (mixed-text-file ... >>  "source \" "\n" >>  #~(read-everything-from-file >>     #$(computed-file "unecessary-file-name" >>        #~#$(local-file "blabla.sh")))) >> >> when originally it was >> (mixed-text-file >>  "source \" "\n" >>  (local-file "blabla.sh")) > Is unnecessary-file-name ever created in this instance? I think we > have something similar in other locations as well, where G-expressions > are merged -- public keys for substitutes spring to mind. Perhaps all > it'd need to make use of new-style text configs is a better way of > quoting such things, e.g. a procedure which takes a file-like object > and produces a plain file with its name. > > For the record, the use of (read-everything-from-file) in your example > -- a procedure which I'm unable to find in my local Guix checkout -- > makes it somewhat difficult to come up with concrete solutions here, so > pardon me for being abstract. read-everything-from-file is just a shorthand for --8<---------------cut here---------------start------------->8--- #~(begin (use-modules (ice-9 rdelim)) (with-fluids ((%default-port-encoding "UTF-8")) (with-input-from-file #$COMPUTED_FILE_CALL_HERE read-string))) --8<---------------cut here---------------end--------------->8--- a gexp used in https://git.savannah.gnu.org/cgit/guix.git/tree/gnu/services/configuration.scm?h=2c451db39aabc69bdbf186f412ee6e0b4e180ccb#n386 The example was already verbose, so I decided to simplify it a little bit. Actually, it's very similar to what slurp-file-gexp does, but it's moved inside serializer and hidden from user. Why not to give it to the user and eleminate two more layers of wrapping in gexps and file-likes. To demonstrate the idea of those additional layers, I'll "rephrase" the previous example in slightly different form. Originally it was: --8<---------------cut here---------------start------------->8--- (mixed-text-file ... ;; evaluated to path to the store file-like ;; evaluated to the string value ; 1 gexp ; can be the result of slurp-file-gexp function if we ; need the file content ;; evaluated to itself "string") --8<---------------cut here---------------end--------------->8--- It became: --8<---------------cut here---------------start------------->8--- (mixed-text-file ... ;; evaluated to path to the store ; 2 (read-everything-from-file (mixed-text-file "intermediate-name" file-like)) ;; evaluated to the string value ; 3 (read-everything-from-file (computed-file "intermediate-name" gexp)) ;; evaluated to itself "string") --8<---------------cut here---------------end--------------->8--- New style is not that bad, especially having some helper functions (get-file-path file-like) and (get-value-of-gexp gexp) for 2 and 3, but why? Especially, if we can have only one slurp-file-gexp like helper for 1, which is rarely used and maybe not even really needed. -- Best regards, Andrew Tropin