git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3 3/9] Makefile: have "make pot" not "reset --hard"

From
Jiang Xin <worldhello.net@gmail.com>
Date
May 23, 2022, 15:00 UTC
Message-ID
<CANYiYbEKkz=_GX+KQPjF1Bi-9bNYSYw2Y2eTMaXgTy8KnKF=-A@mail.gmail.com>
In-Reply-To
<220523.86mtf8zn7t.gmgdl@evledraar.gmail.com>

On Mon, May 23, 2022 at 4:07 PM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:

Show 242 quoted lines
>
>
> On Mon, May 23 2022, Jiang Xin wrote:
>
> > From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> >
> > Before commit fc0fd5b23b (Makefile: help gettext tools to cope with our
> > custom PRItime format, 2017-07-20) we'd consider source files as-is
> > with gettext, but because we need to understand PRItime in the same way
> > that gettext itself understands PRIuMAX we'd first check if we had a
> > clean checkout, then munge all of the processed files in-place with
> > "sed", generate "po/git.pot", and then finally "reset --hard" to undo
> > our changes.
> >
> > By generating "pot" snippets in ".build/pot/po" for each source file
> > and rewriting certain source files with PRItime macros to temporary
> > files in ".build/pot/po", we can avoid running "make pot" by altering
> > files in place and doing a "reset --hard" afterwards.
> >
> > This speed of "make pot" is slower than before on an initial run,
> > because we run "xgettext" many times (once per source file), but it
> > can be boosted by parallelization. It is *much* faster for incremental
> > runs, and will allow us to implement related targets in subsequent
> > commits.
> >
> > When the "pot" target was originally added in cd5513a7168 (i18n:
> > Makefile: "pot" target to extract messages marked for translation,
> > 2011-02-22) it behaved like a "normal" target. I.e. we'd skip the
> > re-generation of the po/git.pot if nothing had to be done.
> >
> > Then after po/git.pot was checked in in dce37b66fb0 (l10n: initial
> > git.pot for 1.7.10 upcoming release, 2012-02-13) the target was broken
> > until 1f31963e921 (i18n: treat "make pot" as an explicitly-invoked
> > target, 2014-08-22) when it was made to depend on "FORCE". I.e. the
> > Makefile's dependency resolution inherently can't handle incremental
> > building when the target file may be updated by git (or something else
> > external to "make"). But this case no longer applies, so FORCE is no
> > longer needed.
> >
> > That out of the way, the main logic change here is getting rid of the
> > "reset --hard":
> >
> > We'll generate intermediate ".build/pot/po/%.po" files from "%", which
> > is handy to see at a glance what strings (if any) in a given file are
> > marked for translation:
> >
> >       $ make .build/pot/po/pretty.c.po
> >       [...]
> >       $ cat .build/pot/po/pretty.c.po
> >       #: pretty.c:1051
> >       msgid "unable to parse --pretty format"
> >       msgstr ""
> >       $
> >
> > For these C source files which contain the PRItime macros, we will
> > create temporary munged "*.c" files in a tree in ".build/pot/po"
> > corresponding to our source tree, and have "xgettext" consider those.
> > The rule needs to be careful to "(cd .build/pot/po && ...)", because
> > otherwise the comments in the po/git.pot file wouldn't refer to the
> > correct source locations (they'd be prefixed with ".build/pot/po").
> > These temporary munged "*.c” files will be removed immediately after
> > the corresponding po files are generated, because some development tools
> > cannot ignore the duplicate source files in the ".build" directory
> > according to the ".gitignore" file, and that may cause trouble.
> >
> > The output of the generated po/git.pot file is changed in one minor
> > way: Because we're using msgcat(1) instead of xgettext(1) to
> > concatenate the output we'll now disambiguate where "TRANSLATORS"
> > comments come from, in cases where a message is the same in N files,
> > and either only one has a "TRANSLATORS" comment, or they're
> > different. E.g. for the "Your edited hunk[...]" message we'll now
> > apply this change (comment content elided):
> >
> >       +#. #-#-#-#-#  add-patch.c.po  #-#-#-#-#
> >        #. TRANSLATORS: do not translate [y/n]
> >       [...]
> >       +#. #-#-#-#-#  git-add--interactive.perl.po  #-#-#-#-#
> >        #. TRANSLATORS: do not translate [y/n]
> >       [...]
> >        #: add-patch.c:1253 git-add--interactive.perl:1244
> >        msgid ""
> >        "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
> >        msgstr ""
> >
> > There are six such changes, and they all make the context more
> > understandable, as msgcat(1) is better at handling these edge cases
> > than xgettext(1)'s previously used "--join-existing" flag.
> >
> > But filenames in the above disambiguation lines of extracted-comments
> > have an extra ".po" extension compared to the filenames at the file
> > locations. While we could rename the intermediate ".build/pot/po/%.po"
> > files without the ".po" extension to use more intuitive filenames in
> > the disambiguation lines of extracted-comments, but that will confuse
> > developer tools with lots of invalid C or other source files in
> > ".build/pot/po" directory.
> >
> > The addition of "--omit-header" option for xgettext makes the "pot"
> > snippets in ".build/pot/po/*.po" smaller. But as we'll see in a
> > subsequent commit this header behavior has been hiding an
> > encoding-related bug from us, so let's carry it forward instead of
> > re-generating it with xgettext(1).
> >
> > The "po/git.pot" file should have a header entry, because a proper
> > header entry will increase the speed of creating a new po file using
> > msginit and set a proper "POT-Creation-Date:" field in the header
> > entry of a "po/XX.po" file. We use xgettext to generate a separate
> > header file at ".build/pot/git.header" from "/dev/null", and use this
> > header to assemble "po/git.pot".
> >
> > Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> > Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
> > Signed-off-by: Junio C Hamano <gitster@pobox.com>
> > ---
> >  .gitignore |  1 +
> >  Makefile   | 80 ++++++++++++++++++++++++++++++++++++++++--------------
> >  2 files changed, 60 insertions(+), 21 deletions(-)
> >
> > diff --git a/.gitignore b/.gitignore
> > index e81de1063a..a452215764 100644
> > --- a/.gitignore
> > +++ b/.gitignore
> > @@ -200,6 +200,7 @@
> >  *.[aos]
> >  *.o.json
> >  *.py[co]
> > +.build/
> >  .depend/
> >  *.gcda
> >  *.gcno
> > diff --git a/Makefile b/Makefile
> > index 46914dcd80..1962999c18 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -569,6 +569,7 @@ INSTALL = install
> >  TCL_PATH = tclsh
> >  TCLTK_PATH = wish
> >  XGETTEXT = xgettext
> > +MSGCAT = msgcat
> >  MSGFMT = msgfmt
> >  CURL_CONFIG = curl-config
> >  GCOV = gcov
> > @@ -2706,6 +2707,7 @@ XGETTEXT_FLAGS = \
> >       --force-po \
> >       --add-comments=TRANSLATORS: \
> >       --msgid-bugs-address="Git Mailing List <git@vger.kernel.org>" \
> > +     --package-name=Git \
> >       --sort-by-file \
> >       --from-code=UTF-8
> >  XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \
> > @@ -2714,6 +2716,7 @@ XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \
> >       --keyword=gettextln --keyword=eval_gettextln
> >  XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \
> >       --keyword=__ --keyword=N__ --keyword="__n:1,2"
> > +MSGCAT_FLAGS = --sort-by-file
> >  LOCALIZED_C = $(FOUND_C_SOURCES) $(FOUND_H_SOURCES) $(SCALAR_SOURCES) \
> >             $(GENERATED_H)
> >  LOCALIZED_SH = $(SCRIPT_SH)
> > @@ -2726,34 +2729,68 @@ LOCALIZED_SH += t/t0200/test.sh
> >  LOCALIZED_PERL += t/t0200/test.perl
> >  endif
> >
> > -## Note that this is meant to be run only by the localization coordinator
> > -## under a very controlled condition, i.e. (1) it is to be run in a
> > -## Git repository (not a tarball extract), (2) any local modifications
> > -## will be lost.
> > +## We generate intermediate .build/pot/po/%.po files containing a
> > +## extract of the translations we find in each file in the source
> > +## tree. We will assemble them using msgcat to create the final
> > +## "po/git.pot" file.
> > +LOCALIZED_ALL_GEN_PO =
> > +
> > +LOCALIZED_C_GEN_PO = $(LOCALIZED_C:%=.build/pot/po/%.po)
> > +LOCALIZED_ALL_GEN_PO += $(LOCALIZED_C_GEN_PO)
> > +
> > +LOCALIZED_SH_GEN_PO = $(LOCALIZED_SH:%=.build/pot/po/%.po)
> > +LOCALIZED_ALL_GEN_PO += $(LOCALIZED_SH_GEN_PO)
> > +
> > +LOCALIZED_PERL_GEN_PO = $(LOCALIZED_PERL:%=.build/pot/po/%.po)
> > +LOCALIZED_ALL_GEN_PO += $(LOCALIZED_PERL_GEN_PO)
> > +
> >  ## Gettext tools cannot work with our own custom PRItime type, so
> >  ## we replace PRItime with PRIuMAX.  We need to update this to
> >  ## PRIdMAX if we switch to a signed type later.
> > +$(LOCALIZED_C_GEN_PO): .build/pot/po/%.po: %
> > +     $(call mkdir_p_parent_template)
> > +     $(QUIET_XGETTEXT) \
> > +         if grep -q PRItime $<; then \
> > +             (\
> > +                     sed -e 's|PRItime|PRIuMAX|g' <$< \
> > +                             >.build/pot/po/$< && \
> > +                     cd .build/pot/po && \
> > +                     $(XGETTEXT) --omit-header \
> > +                             -o $(@:.build/pot/po/%=%) \
> > +                             $(XGETTEXT_FLAGS_C) $< && \
> > +                     rm $<; \
> > +             ); \
> > +         else \
> > +             $(XGETTEXT) --omit-header \
> > +                     -o $@ $(XGETTEXT_FLAGS_C) $<; \
> > +         fi
> >
> > -po/git.pot: $(GENERATED_H) FORCE
> > -     # All modifications will be reverted at the end, so we do not
> > -     # want to have any local change.
> > -     git diff --quiet HEAD && git diff --quiet --cached
> > +$(LOCALIZED_SH_GEN_PO): .build/pot/po/%.po: %
> > +     $(call mkdir_p_parent_template)
> > +     $(QUIET_XGETTEXT)$(XGETTEXT) --omit-header \
> > +             -o$@ $(XGETTEXT_FLAGS_SH) $<
> >
> > -     @for s in $(LOCALIZED_C) $(LOCALIZED_SH) $(LOCALIZED_PERL); \
> > -     do \
> > -             sed -e 's|PRItime|PRIuMAX|g' <"$$s" >"$$s+" && \
> > -             cat "$$s+" >"$$s" && rm "$$s+"; \
> > -     done
> > +$(LOCALIZED_PERL_GEN_PO): .build/pot/po/%.po: %
> > +     $(call mkdir_p_parent_template)
> > +     $(QUIET_XGETTEXT)$(XGETTEXT) --omit-header \
> > +             -o$@ $(XGETTEXT_FLAGS_PERL) $<
> > +q
> > +define gen_pot_header
> > +$(XGETTEXT) $(XGETTEXT_FLAGS_C) \
> > +     -o - /dev/null | \
> > +sed -e 's|charset=CHARSET|charset=UTF-8|' \
> > +    -e 's|\(Last-Translator: \)FULL NAME <.*>|\1make by the Makefile|' \
> > +    -e 's|\(Language-Team: \)LANGUAGE <.*>|\1Git Mailing List <git@vger.kernel.org>|' \
> > +    >$@ && \
> > +echo '"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n"' >>$@
> > +endef
> >
> > -     $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C)
> > -     $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_SH) \
> > -             $(LOCALIZED_SH)
> > -     $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_PERL) \
> > -             $(LOCALIZED_PERL)
> > +.build/pot/git.header: $(LOCALIZED_ALL_GEN_PO)
> > +     $(call mkdir_p_parent_template)
> > +     $(QUIET_GEN)$(gen_pot_header)
>
> So re a previous round I think the addition of a header to po/git.pot
> doesn't make sense, i.e. it's not needed, so we can just drop this
> entirely.
You missed a note about this in commit log in this reroll:
    The "po/git.pot" file should have a header entry, because a proper
    header entry will increase the speed of creating a new po file using
    msginit and set a proper "POT-Creation-Date:" field in the header
    entry of a "po/XX.po" file. We use xgettext to generate a separate
    header file at ".build/pot/git.header" from "/dev/null", and use this
    header to assemble "po/git.pot".
> But if you really want to include it anyway then this dependency is
> broken, the header just depends on this gen_pot_header you've defined,
> we don't need to re-generate it every time any single source file
> changes.

The header file ".build/pot/git.header" should have the same prerequisites as the file "po/git.pot". This is because we need to refresh the timestamp of the "POT-Creation-Date:" field.

> Or is the intent to have its timestamp bumped if any of the source files
> change?

Right. Just like using xgettext to create a "po/git.pot" with a fresh header entry, we should recreate the header file for msgcat to create "po/git.pot".

We want to switch to a new l10n workflow, and we want everything works as usual. When l10n contributors update their "po/XX.po" file, it should contain the latest "POT-Creation-Date" timestamp instead of sticking to a fixed and outdated timestamp.

Show 5 quoted lines
> If so I think that to the extent we need headers at all (for the *.po
> files) it might be worthwhile to just have the timestamp be the same
> epoch we use for the tests in t/, i.e. never update it and avoid the
> needless churn. If people need to check when things were last changed,
> or initially added, they can use this little thing called "git" :)
I stick to my option, see above.
Previous: Ævar Arnfjörð BjarmasonNext: Jiang Xin
Message 82 of 110 in “Incremental po/git.pot update and new l10n workflow”
  1. 0/9 Incremental po/git.pot update and new l10n workflowJiang Xin, May 3, 2022
  2. 1/9 Makefile: sort "po/git.pot" by file locationJiang Xin, May 3, 2022
  3. 2/9 Makefile: generate "po/git.pot" from stable LOCALIZED_CJiang Xin, May 3, 2022
  4. 5/9 po/git.pot: don't check in result of "make pot"Jiang Xin, May 3, 2022
  5. 3/9 Makefile: have "make pot" not "reset --hard"Jiang Xin, May 3, 2022
  6. 7/9 Makefile: add "po-update" rule to update po/XX.poJiang Xin, May 3, 2022
  7. 9/9 l10n: Document the new l10n workflowJiang Xin, May 3, 2022
  8. 8/9 Makefile: add "po-init" rule to initialize po/XX.poJiang Xin, May 3, 2022
  9. 4/9 i18n CI: stop allowing non-ASCII source messages in po/git.potJiang Xin, May 3, 2022
  10. 6/9 po/git.pot: remove this now generated file, see preceding commitJiang Xin, May 3, 2022
  11. Peter KreftingMay 3, 2022
  12. Jiang XinMay 4, 2022
  13. Junio C HamanoMay 4, 2022
  14. Daniel SantosMay 4, 2022
  15. Jiang XinMay 5, 2022
  16. Daniel SantosMay 5, 2022
  17. Junio C HamanoMay 5, 2022
  18. Jiang XinMay 6, 2022
  19. Jiang XinMay 5, 2022
  20. Junio C HamanoMay 4, 2022
  21. 1/9 Makefile: sort "po/git.pot" by file locationJiang Xin, May 19, 2022
  22. Ævar Arnfjörð BjarmasonMay 19, 2022
  23. Jiang XinMay 19, 2022
  24. 0/9 Incremental po/git.pot update and new l10n workflowJiang Xin, May 19, 2022
  25. Ævar Arnfjörð BjarmasonMay 19, 2022
  26. Jiang XinMay 19, 2022
  27. Ævar Arnfjörð BjarmasonMay 19, 2022
  28. 0/9 Incremental po/git.pot update and new l10n workflowJiang Xin, May 23, 2022
  29. Ævar Arnfjörð BjarmasonMay 23, 2022
  30. Ævar Arnfjörð BjarmasonMay 23, 2022
  31. Jiang XinMay 23, 2022
  32. Ævar Arnfjörð BjarmasonMay 23, 2022
  33. Jiang XinMay 23, 2022
  34. Jiang XinMay 23, 2022
  35. 0/9 Incremental po/git.pot update and new l10n workflowJiang Xin, May 23, 2022
  36. Junio C HamanoMay 23, 2022
  37. 01/10 Makefile: sort source files before feeding to xgettextJiang Xin, May 26, 2022
  38. 00/10 Incremental po/git.pot update and new l10n workflowJiang Xin, May 26, 2022
  39. 02/10 Makefile: generate "po/git.pot" from stable LOCALIZED_CJiang Xin, May 26, 2022
  40. 10/10 l10n: Document the new l10n workflowJiang Xin, May 26, 2022
  41. 06/10 po/git.pot: this is now a generated fileJiang Xin, May 26, 2022
  42. Junio C HamanoMay 26, 2022
  43. 04/10 i18n CI: stop allowing non-ASCII source messages in po/git.potJiang Xin, May 26, 2022
  44. 05/10 Makefile: remove duplicate and unwanted files in FOUND_SOURCE_FILESJiang Xin, May 26, 2022
  45. 08/10 Makefile: add "po-update" rule to update po/XX.poJiang Xin, May 26, 2022
  46. 07/10 po/git.pot: don't check in result of "make pot"Jiang Xin, May 26, 2022
  47. 09/10 Makefile: add "po-init" rule to initialize po/XX.poJiang Xin, May 26, 2022
  48. 03/10 Makefile: have "make pot" not "reset --hard"Jiang Xin, May 26, 2022
  49. 2/9 Makefile: generate "po/git.pot" from stable LOCALIZED_CJiang Xin, May 23, 2022
  50. 7/9 Makefile: add "po-update" rule to update po/XX.poJiang Xin, May 23, 2022
  51. 1/9 Makefile: sort "po/git.pot" by file locationJiang Xin, May 23, 2022
  52. 4/9 i18n CI: stop allowing non-ASCII source messages in po/git.potJiang Xin, May 23, 2022
  53. 3/9 Makefile: have "make pot" not "reset --hard"Jiang Xin, May 23, 2022
  54. Junio C HamanoMay 25, 2022
  55. Junio C HamanoMay 25, 2022
  56. Jiang XinMay 26, 2022
  57. Makefile: dedup git-ls-files output to prevent duplicate targetsJiang Xin, May 26, 2022
  58. Junio C HamanoMay 26, 2022
  59. Jiang XinMay 26, 2022
  60. Junio C HamanoMay 26, 2022
  61. Jiang XinMay 26, 2022
  62. Ævar Arnfjörð BjarmasonMay 26, 2022
  63. Jiang XinMay 26, 2022
  64. Junio C HamanoMay 26, 2022
  65. Ævar Arnfjörð BjarmasonMay 26, 2022
  66. Junio C HamanoMay 26, 2022
  67. Ævar Arnfjörð BjarmasonMay 26, 2022
  68. 6/9 po/git.pot: don't check in result of "make pot"Jiang Xin, May 23, 2022
  69. 5/9 po/git.pot: this is now a generated fileJiang Xin, May 23, 2022
  70. 9/9 l10n: Document the new l10n workflowJiang Xin, May 23, 2022
  71. 8/9 Makefile: add "po-init" rule to initialize po/XX.poJiang Xin, May 23, 2022
  72. 1/9 Makefile: sort "po/git.pot" by file locationJiang Xin, May 23, 2022
  73. Junio C HamanoMay 23, 2022
  74. Jiang XinMay 23, 2022
  75. 2/9 Makefile: generate "po/git.pot" from stable LOCALIZED_CJiang Xin, May 23, 2022
  76. Junio C HamanoMay 23, 2022
  77. 9/9 l10n: Document the new l10n workflowJiang Xin, May 23, 2022
  78. 7/9 Makefile: add "po-update" rule to update po/XX.poJiang Xin, May 23, 2022
  79. 8/9 Makefile: add "po-init" rule to initialize po/XX.poJiang Xin, May 23, 2022
  80. 3/9 Makefile: have "make pot" not "reset --hard"Jiang Xin, May 23, 2022
  81. Ævar Arnfjörð BjarmasonMay 23, 2022
  82. Jiang XinMay 23, 2022
  83. Jiang XinMay 24, 2022
  84. Junio C HamanoMay 23, 2022
  85. Jiang XinMay 23, 2022
  86. 4/9 i18n CI: stop allowing non-ASCII source messages in po/git.potJiang Xin, May 23, 2022
  87. 6/9 po/git.pot: don't check in result of "make pot"Jiang Xin, May 23, 2022
  88. Ævar Arnfjörð BjarmasonMay 23, 2022
  89. Jiang XinMay 23, 2022
  90. Jiang XinMay 23, 2022
  91. Ævar Arnfjörð BjarmasonMay 23, 2022
  92. 5/9 po/git.pot: this is now a generated fileJiang Xin, May 23, 2022
  93. 2/9 Makefile: generate "po/git.pot" from stable LOCALIZED_CJiang Xin, May 19, 2022
  94. Ævar Arnfjörð BjarmasonMay 19, 2022
  95. Jiang XinMay 19, 2022
  96. 3/9 Makefile: have "make pot" not "reset --hard"Jiang Xin, May 19, 2022
  97. Ævar Arnfjörð BjarmasonMay 19, 2022
  98. Jiang XinMay 19, 2022
  99. Ævar Arnfjörð BjarmasonMay 19, 2022
  100. 5/9 po/git.pot: this is now a generated fileJiang Xin, May 19, 2022
  101. 7/9 Makefile: add "po-update" rule to update po/XX.poJiang Xin, May 19, 2022
  102. Ævar Arnfjörð BjarmasonMay 19, 2022
  103. 6/9 po/git.pot: don't check in result of "make pot"Jiang Xin, May 19, 2022
  104. 8/9 Makefile: add "po-init" rule to initialize po/XX.poJiang Xin, May 19, 2022
  105. Ævar Arnfjörð BjarmasonMay 19, 2022
  106. 9/9 l10n: Document the new l10n workflowJiang Xin, May 19, 2022
  107. Junio C HamanoMay 19, 2022
  108. Jiang XinMay 21, 2022
  109. 4/9 i18n CI: stop allowing non-ASCII source messages in po/git.potJiang Xin, May 19, 2022
  110. Ævar Arnfjörð BjarmasonMay 19, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.