maint: Use xgettext.scm wrapper to create .PO files reproducibly.

* build-aux/xgettext.scm: New script.
* po/guix/Makevars (XGETTEXT): Set it.
(XGETTEXT_OPTIONS): Add --xgettext option to `real' xgettext.
* po/packages/Makevars (XGETTEXT): Set it.
(XGETTEXT_OPTIONS): Add --xgettext option to `real' xgettext.

Change-Id: I71b6b843970090f765f46ac346b92a346560e3f0
This commit is contained in:
Janneke Nieuwenhuizen 2024-04-05 23:21:02 +02:00
parent b4d2838d51
commit 6c63c36677
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
3 changed files with 101 additions and 3 deletions

87
build-aux/xgettext.scm Executable file
View file

@ -0,0 +1,87 @@
#! /bin/sh
# -*-scheme-*-
build_aux=$(dirname $0)
srcdir=$build_aux/..
exec guile --no-auto-compile -L $srcdir -C $srcdir -e main -s "$0" "$@"
!#
;;; Copyright © 2024 Janneke Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This program 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.
;;;
;;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
;;;; Commentary:
;;;
;;; This script provides an xgettext wrapper to (re)set POT-Creation-Date from
;;; a Git timestamp. Test doing something like:
;;;
;;; build-aux/xgettext.scm --files-from=po/guix/POTFILES.in --default-domain=test
;;;
;;;; Code:
(use-modules (srfi srfi-1)
(srfi srfi-26)
(ice-9 curried-definitions)
(ice-9 match)
(ice-9 popen)
(ice-9 rdelim)
(guix build utils))
(define ((option? name) option)
(string-prefix? name option))
(define (get-option args name)
(let ((option (find (option? name) args)))
(and option
(substring option (string-length name)))))
(define (pipe-command command)
(let* ((port (apply open-pipe* OPEN_READ command))
(output (read-string port)))
(close-port port)
output))
;;;
;;; Entry point.
;;;
(define (main args)
;; Cater for being run in a container.
(setenv "LC_ALL" "en_US.UTF-8")
(setenv "TZ" "UTC0")
(fluid-set! %default-port-encoding #f)
(let* ((files-from (get-option args "--files-from="))
(default-domain (get-option args "--default-domain="))
(directory (or (get-option args "--directory=") "."))
(xgettext (or (get-option args "--xgettext=") "xgettext"))
(xgettext-args (filter (negate (option? "--xgettext=")) args))
(command (match xgettext-args
((xgettext.scm args ...)
`(,xgettext ,@args))))
(result (apply system* command))
(status (/ result 256)))
(if (or (not (zero? status))
(not files-from))
(exit status)
(let* ((text (with-input-from-file files-from read-string))
(lines (string-split text #\newline))
(files (filter (negate (cute string-prefix? "#" <>)) lines))
(files (map (cute string-append directory "/" <>) files))
(git-command `("git" "log" "--pretty=format:%ci" "-n1" ,@files))
(timestamp (pipe-command git-command))
(po-file (string-append default-domain ".po")))
(when (string-null? timestamp)
(exit 1))
(substitute* po-file
(("(\"POT-Creation-Date: )[^\\]*" all header)
(string-append header timestamp)))))))

View file

@ -5,6 +5,10 @@ DOMAIN = guix
subdir = po/guix
top_builddir = ../..
# We use our xgettext.scm wrapper to produce .PO files reproducibly using a
# timestamp from Git.
XGETTEXT:=$(top_srcdir)/build-aux/xgettext.scm
# These options get passed to xgettext. We want to catch standard
# gettext uses, and SRFI-35 error condition messages. In C++ code
# we use 'n_' instead of the more usual 'N_' for no-ops.
@ -14,7 +18,8 @@ XGETTEXT_OPTIONS = \
--keyword=message \
--keyword=description \
--keyword=synopsis \
--keyword=n_
--keyword=n_ \
--xgettext=$(XGETTEXT_)
COPYRIGHT_HOLDER = the authors of Guix (msgids)

View file

@ -6,12 +6,18 @@ DOMAIN = guix-packages
subdir = po/packages
top_builddir = ../..
# We use our xgettext.scm wrapper to produce .PO files reproducibly using a
# timestamp from Git. The `real' xgettext is passed as an option to
# xgettext.scm
XGETTEXT:=$(top_srcdir)/build-aux/xgettext.scm
# These options get passed to xgettext. We want to catch exclusively package
# synopses and descriptions.
XGETTEXT_OPTIONS = \
--language=Scheme --from-code=UTF-8 \
--keyword=synopsis --keyword=description \
--keyword=output-synopsis:2
--keyword=synopsis --keyword=description \
--keyword=output-synopsis:2 \
--xgettext=$(XGETTEXT_)
COPYRIGHT_HOLDER = the authors of Guix (msgids)