mirror of
https://git.savannah.gnu.org/git/guix.git
synced 2025-01-18 13:36:36 +01:00
50927338dd
Support for non-ASCII characters was mixed. Some gexp forms did support them, while others did not. Combined with current value for %default-port-conversion-strategy, that sometimes led to unpleasant surprises. For example: (scheme-file "utf8" #~(with-output-to-file #$output (λ _ (display "猫")))) Was written to the store as: ((? _ (display "\u732b"))) No, that is not font issue on your part, that is an actual #\? instead of the lambda character. Which, surprisingly, does not do what it should when executed. The solution is to switch to C.UTF-8 locale where possible, since it is now always available. Or to explicitly set the port encoding. No tests are provided, since majority of tests/gexp.scm use guile in version 2, and it tends to work under it. The issues occur mostly with guile 3. I did test it locally using: #!/bin/sh set -eu set -x [ -f guix.scm ] || { echo >&2 Run from root of Guix repo.; exit 1; } [ -f gnu.scm ] || { echo >&2 Run from root of Guix repo.; exit 1; } cat >猫.scm <<'EOF' (define-module (猫) #:export (say)) (define (say) "nyaaaa~~~~!") EOF mkdir -p dir-with-utf8-file cp 猫.scm dir-with-utf8-file/ cat >repro.scm <<'EOF' (use-modules (guix build utils) (guix derivations) (guix gexp) (guix store) (ice-9 ftw) (ice-9 textual-ports)) (define cat "猫") (define (drv-content drv) (call-with-input-file (derivation->output-path drv) get-string-all)) (define (out-content out) (call-with-input-file out get-string-all)) (define (drv-listing drv) (scandir (derivation->output-path drv))) (define (dir-listing dir) (scandir dir)) (define-macro (test exp lower? report) (let ((type (car exp))) `(false-if-exception (let ((drv (with-store %store (run-with-store %store (,(if lower? lower-object identity) ,exp))))) (format #t "~%~a:~%" ',type) (when (with-store %store (build-derivations %store (list drv))) (format #t "~a~%" (,report drv))))))) (test (computed-file "utf8" #~(with-output-to-file #$output (λ _ (display #$cat)))) #t drv-content) (test (program-file "utf8" #~((λ _ (display #$cat)))) #t drv-content) (test (scheme-file "utf8" #~((λ _ (display #$cat)))) #t drv-content) (test (text-file* "utf8" cat cat cat) #f drv-content) (test (compiled-modules '((猫))) #f drv-listing) (test (file-union "utf8" `((,cat ,(plain-file "utf8" cat)))) #t drv-listing) ;;; No fix needed: (test (imported-modules '((猫))) #f dir-listing) (test (local-file "dir-with-utf8-file" #:recursive? #t) #t dir-listing) (test (plain-file "utf8" cat) #t out-content) (test (mixed-text-file "utf8" cat cat cat) #t drv-content) (test (directory-union "utf8" (list (local-file "dir-with-utf8-file" #:recursive? #t))) #t dir-listing) EOF guix shell -CWN -D guix glibc-locales -- \ env LANG=C.UTF-8 ./pre-inst-env guix repl -- ./repro.scm Before this commit, the output is: + '[' -f guix.scm ']' + '[' -f gnu.scm ']' + cat + mkdir -p dir-with-utf8-file + cp 猫.scm dir-with-utf8-file/ + cat + guix shell -CWN -D guix glibc-locales -- env LANG=C.UTF-8 ./pre-inst-env guix repl -- ./repro.scm computed-file: ? program-file: #!/gnu/store/mfkz7fvlfpv3ppwbkv0imb19nrf95akf-guile-3.0.9/bin/guile --no-auto-compile !# ((? _ (display "\u732b"))) scheme-file: ((? _ (display "\u732b"))) text-file*: ??? compiled-modules: building path(s) `/gnu/store/ay3jifyvliigfgnz67jf0kgngzpya5a5-module-import-compiled' Backtrace: 5 (primitive-load "/gnu/store/rn7b0dq6iqfmmqyqzamix2mjmfy?") In ice-9/eval.scm: 619:8 4 (_ #f) In srfi/srfi-1.scm: 460:18 3 (fold #<procedure 7ffff79245e0 at ice-9/eval.scm:336:1?> ?) In ice-9/eval.scm: 245:16 2 (_ #(#(#<directory (guix build utils) 7ffff779f320>) # ?)) In ice-9/boot-9.scm: 1982:24 1 (_ _) In unknown file: 0 (stat "./???.scm" #<undefined>) ERROR: In procedure stat: In procedure stat: No such file or directory: "./???.scm" builder for `/gnu/store/dxg87135zcd6a1c92dlrkyvxlbhfwfld-module-import-compiled.drv' failed with exit code 1 file-union: (. .. ?) imported-modules: (. .. 猫.scm) local-file: (. .. 猫.scm) plain-file: 猫 mixed-text-file: 猫猫猫 directory-union: (. .. 猫.scm) Which I think you will agree is far from optimal. After my fix the output changes to: + '[' -f guix.scm ']' + '[' -f gnu.scm ']' + cat + mkdir -p dir-with-utf8-file + cp 猫.scm dir-with-utf8-file/ + cat + guix shell -CWN -D guix glibc-locales -- env LANG=C.UTF-8 ./pre-inst-env guix repl -- ./repro.scm computed-file: 猫 program-file: #!/gnu/store/8kbmn359jqkgsbqgqxnmiryvd9ynz8w7-guile-3.0.9/bin/guile --no-auto-compile !# ((λ _ (display "猫"))) scheme-file: ((λ _ (display "猫"))) text-file*: 猫猫猫 compiled-modules: (. .. 猫.go) file-union: (. .. 猫) imported-modules: (. .. 猫.scm) local-file: (. .. 猫.scm) plain-file: 猫 mixed-text-file: 猫猫猫 directory-union: (. .. 猫.scm) Which is actually what the user would expect. I also added missing arguments to the documentation. * guix/gexp.scm (computed-file): Set LANG to C.UTF-8 by default. (compiled-modules): Try to `setlocale'. (gexp->script), (gexp->file): New `locale' argument defaulting to C.UTF-8. (text-file*): Set output port encoding to UTF-8. * doc/guix.texi (G-Expressions)[computed-file]: Document the changes. Use @var. Document #:guile. [gexp->script]: Document #:locale. Fix default value for #:target. [gexp->file]: Document #:locale, #:system and #:target. Change-Id: Ib323b51af88a588b780ff48ddd04db8be7c729fb |
||
---|---|---|
.. | ||
build | ||
build-system | ||
import | ||
platforms | ||
scripts | ||
store | ||
tests | ||
android-repo-download.scm | ||
avahi.scm | ||
base16.scm | ||
base32.scm | ||
base64.scm | ||
build-system.scm | ||
bzr-download.scm | ||
cache.scm | ||
channels.scm | ||
ci.scm | ||
colors.scm | ||
combinators.scm | ||
config.scm.in | ||
cpio.scm | ||
cpu.scm | ||
cve.scm | ||
cvs-download.scm | ||
d3.v3.js | ||
deprecation.scm | ||
derivations.scm | ||
describe.scm | ||
diagnostics.scm | ||
discovery.scm | ||
docker.scm | ||
download.scm | ||
elf.scm | ||
ftp-client.scm | ||
gexp.scm | ||
git-authenticate.scm | ||
git-download.scm | ||
git.scm | ||
glob.scm | ||
gnu-maintenance.scm | ||
gnupg.scm | ||
grafts.scm | ||
graph.js | ||
graph.scm | ||
hash.scm | ||
hg-download.scm | ||
http-client.scm | ||
i18n.scm | ||
inferior.scm | ||
ipfs.scm | ||
least-authority.scm | ||
licenses.scm | ||
lint.scm | ||
man-db.scm | ||
memoization.scm | ||
modules.scm | ||
monad-repl.scm | ||
monads.scm | ||
nar.scm | ||
narinfo.scm | ||
openpgp.scm | ||
packages.scm | ||
pki.scm | ||
platform.scm | ||
profiles.scm | ||
profiling.scm | ||
progress.scm | ||
quirks.scm | ||
read-print.scm | ||
records.scm | ||
remote.scm | ||
repl.scm | ||
rpm.scm | ||
scripts.scm | ||
search-paths.scm | ||
self.scm | ||
serialization.scm | ||
sets.scm | ||
ssh.scm | ||
status.scm | ||
store.scm | ||
substitutes.scm | ||
svn-download.scm | ||
swh.scm | ||
tests.scm | ||
transformations.scm | ||
ui.scm | ||
upstream.scm | ||
utils.scm | ||
workers.scm |