guix_mirror_bot pushed a commit to branch master
in repository guix.

commit b5054a85c1bff91ca8a55b2ca218fb5f2b9518cd
Author: Florian Pelz <[email protected]>
AuthorDate: Mon Sep 1 13:51:04 2025 +0200

    nls: Minify translation PO files.
    
    To save a lot of disk space, keep only actually translated messages in
    Gettext PO files.  Ignore the guix domain, which is more complicated
    and is tiny.
    
    * build-aux/keep-only-translated.scm: New file.
    * Makefile.am (download-po): Run it.
    
    Change-Id: I6442ce0ef8d62f7e48e667c766b86d0ebf9c5415
---
 Makefile.am                        | 17 +++++++--
 build-aux/keep-only-translated.scm | 78 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+), 4 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 19aad0042e..b29f2dfa84 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1299,8 +1299,10 @@ WEBLATE_REPO = https://codeberg.org/guix/translations
 # Shallow clone the Git repository behind Weblate and copy files from it if
 # they contain at least one translation, and they are well-formed (Scheme
 # format only), warn otherwise.  Copied files are converted to a canonical
-# form.
-download-po:
+# form.  Note: The files will be minified to reduce file size, except the
+# guix domain, because they are comparatively small and it would need more
+# comprehensive PO file parsing abilities for plural forms.
+download-po: guix/build/po.go
        dir=$$(mktemp -d); \
        git clone --depth 1 "$(WEBLATE_REPO)" "$$dir/translations" && \
        for domain in po/doc po/guix po/packages; do \
@@ -1313,8 +1315,15 @@ download-po:
                target="$$domain/$$target"; \
                msgfmt -c "$$po"; \
                if msgfmt -c "$$po" && [ "$$translated" != "0" ] && ([ 
"$$domain" != "po/doc" ] || [ "$$translated" -gt $$(($$total/10)) ] || [ -f 
$$target ]); then \
-                   msgconv --no-wrap -o "$$po".tmp "$$po"; \
-                   mv "$$po".tmp "$$target"; \
+                   if [ "$$domain" != "po/guix" ]; then \
+                     $(GUILE) -L "$(top_builddir)" -L "$(top_srcdir)" \
+                       --no-auto-compile \
+                       -s "$(top_srcdir)"/build-aux/keep-only-translated.scm \
+                       "$$po" > "$$po".tmp; \
+                   else ln -s "$$po" "$$po".tmp; fi; \
+                   msgconv --no-wrap -o "$$po".tmp2 "$$po".tmp; \
+                   rm "$$po".tmp; \
+                   mv "$$po".tmp2 "$$target"; \
                    echo "copied $$target."; \
                else \
                    echo "WARN: $$target ($$translated translated messages 
($$((translated/total*100))%)) was not added/updated."; \
diff --git a/build-aux/keep-only-translated.scm 
b/build-aux/keep-only-translated.scm
new file mode 100644
index 0000000000..c6b0905c4b
--- /dev/null
+++ b/build-aux/keep-only-translated.scm
@@ -0,0 +1,78 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2025 Florian Pelz <[email protected]>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+;; Minify Gettext PO files when synced from
+;; <https://codeberg.org/guix/translations/>,
+;; keeping only actually translated messages.
+
+;; Note: This does not work for PO files of the guix domain, which needed
+;; support for plural forms in (@ (guix build po) read-po-file).  The guix
+;; domain's files are comparatively small and the read-po-file API would
+;; have to be expanded to use records or such; it is not worth it.
+
+(use-modules (guix build po)
+             (ice-9 match)
+             (ice-9 textual-ports))
+
+(define (escape str)
+  "Escape msgid or msgstr.  Replace by C-style escape sequences."
+  (let* ((in (open-input-string str))
+         (text (get-string-all in))
+         (escaped-text-as-list
+          (string-fold-right
+           (lambda (char result)
+             (cons (case char
+                     ((#\") "\\\"")
+                     ((#\\) "\\\\")
+                     ((#\linefeed) "\\n")
+                     ((#\return) "\\r")
+                     ((#\tab) "\\t")
+                     (else (string char)))
+                   result))
+           '()
+           text))
+         (escaped-text (apply string-append escaped-text-as-list)))
+    (display escaped-text)))
+
+(match (command-line)
+  ((program pofile)
+   (let ((input (open-input-file pofile)))
+     ;; Just copy until an empty line.
+     (letrec ((copy
+               (lambda ()
+                 (let ((next-line (get-line input)))
+                   (display next-line)
+                   (newline)
+                   (when (> (string-length next-line) 0)
+                     (copy))))))
+       (copy))
+     ;; Then print only translated messages.
+     (for-each
+      (lambda (msg)
+        (match msg
+          ((msgid . msgstr)
+           (display "msgid \"")
+           (escape msgid)
+           (display "\"")
+           (newline)
+           (display "msgstr \"")
+           (escape msgstr)
+           (display "\"")
+           (newline)
+           (newline))))
+      (read-po-file input)))))

Reply via email to