Skip to content

Commit 6cdccfc

Browse files
avargitster
authored andcommitted
i18n: make GETTEXT_POISON a runtime option
Change the GETTEXT_POISON compile-time + runtime GIT_GETTEXT_POISON test parameter to only be a GIT_TEST_GETTEXT_POISON=<non-empty?> runtime parameter, to be consistent with other parameters documented in "Running tests with special setups" in t/README. When I added GETTEXT_POISON in bb946bb ("i18n: add GETTEXT_POISON to simulate unfriendly translator", 2011-02-22) I was concerned with ensuring that the _() function would get constant folded if NO_GETTEXT was defined, and likewise that GETTEXT_POISON would be compiled out unless it was defined. But as the benchmark in my [1] shows doing a one-off runtime getenv("GIT_TEST_[...]") is trivial, and since GETTEXT_POISON was originally added the GIT_TEST_* env variables have become the common idiom for turning on special test setups. So change GETTEXT_POISON to work the same way. Now the GETTEXT_POISON=YesPlease compile-time option is gone, and running the tests with GIT_TEST_GETTEXT_POISON=[YesPlease|] can be toggled on/off without recompiling. This allows for conditionally amending tests to test with/without poison, similar to what 859fdc0 ("commit-graph: define GIT_TEST_COMMIT_GRAPH", 2018-08-29) did for GIT_TEST_COMMIT_GRAPH. Do some of that, now we e.g. always run the t0205-gettext-poison.sh test. I did enough there to remove the GETTEXT_POISON prerequisite, but its inverse C_LOCALE_OUTPUT is still around, and surely some tests using it can be converted to e.g. always set GIT_TEST_GETTEXT_POISON=. Notes on the implementation: * We still compile a dedicated GETTEXT_POISON build in Travis CI. Perhaps this should be revisited and integrated into the "linux-gcc" build, see ae59a4e ("travis: run tests with GIT_TEST_SPLIT_INDEX", 2018-01-07) for prior art in that area. Then again maybe not, see [2]. * We now skip a test in t0000-basic.sh under GIT_TEST_GETTEXT_POISON=YesPlease that wasn't skipped before. This test relies on C locale output, but due to an edge case in how the previous implementation of GETTEXT_POISON worked (reading it from GIT-BUILD-OPTIONS) wasn't enabling poison correctly. Now it does, and needs to be skipped. * The getenv() function is not reentrant, so out of paranoia about code of the form: printf(_("%s"), getenv("some-env")); call use_gettext_poison() in our early setup in git_setup_gettext() so we populate the "poison_requested" variable in a codepath that's won't suffer from that race condition. * We error out in the Makefile if you're still saying GETTEXT_POISON=YesPlease to prompt users to change their invocation. * We should not print out poisoned messages during the test initialization itself to keep it more readable, so the test library hides the variable if set in $GIT_TEST_GETTEXT_POISON_ORIG during setup. See [3]. See also [4] for more on the motivation behind this patch, and the history of the GETTEXT_POISON facility. 1. https://public-inbox.org/git/[email protected]/ 2. https://public-inbox.org/git/[email protected]/ 3. https://public-inbox.org/git/[email protected]/ 4. https://public-inbox.org/git/[email protected]/ Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d582ea2 commit 6cdccfc

16 files changed

+59
-49
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ addons:
2626

2727
matrix:
2828
include:
29-
- env: jobname=GETTEXT_POISON
29+
- env: jobname=GIT_TEST_GETTEXT_POISON
3030
os: linux
3131
compiler:
3232
addons:

Makefile

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -362,11 +362,6 @@ all::
362362
# Define HAVE_DEV_TTY if your system can open /dev/tty to interact with the
363363
# user.
364364
#
365-
# Define GETTEXT_POISON if you are debugging the choice of strings marked
366-
# for translation. In a GETTEXT_POISON build, you can turn all strings marked
367-
# for translation into gibberish by setting the GIT_GETTEXT_POISON variable
368-
# (to any value) in your environment.
369-
#
370365
# Define JSMIN to point to JavaScript minifier that functions as
371366
# a filter to have gitweb.js minified.
372367
#
@@ -1452,7 +1447,7 @@ ifdef NO_SYMLINK_HEAD
14521447
BASIC_CFLAGS += -DNO_SYMLINK_HEAD
14531448
endif
14541449
ifdef GETTEXT_POISON
1455-
BASIC_CFLAGS += -DGETTEXT_POISON
1450+
$(error The GETTEXT_POISON option has been removed in favor of runtime GIT_TEST_GETTEXT_POISON. See t/README!)
14561451
endif
14571452
ifdef NO_GETTEXT
14581453
BASIC_CFLAGS += -DNO_GETTEXT
@@ -2603,7 +2598,6 @@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
26032598
@echo GIT_TEST_CMP_USE_COPIED_CONTEXT=YesPlease >>$@+
26042599
endif
26052600
@echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@+
2606-
@echo GETTEXT_POISON=\''$(subst ','\'',$(subst ','\'',$(GETTEXT_POISON)))'\' >>$@+
26072601
ifdef GIT_PERF_REPEAT_COUNT
26082602
@echo GIT_PERF_REPEAT_COUNT=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_REPEAT_COUNT)))'\' >>$@+
26092603
endif

ci/lib-travisci.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ osx-clang|osx-gcc)
123123
# Travis CI OS X
124124
export GIT_SKIP_TESTS="t9810 t9816"
125125
;;
126-
GETTEXT_POISON)
127-
export GETTEXT_POISON=YesPlease
126+
GIT_TEST_GETTEXT_POISON)
127+
export GIT_TEST_GETTEXT_POISON=YesPlease
128128
;;
129129
esac

gettext.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "gettext.h"
88
#include "strbuf.h"
99
#include "utf8.h"
10+
#include "config.h"
1011

1112
#ifndef NO_GETTEXT
1213
# include <locale.h>
@@ -46,15 +47,15 @@ const char *get_preferred_languages(void)
4647
return NULL;
4748
}
4849

49-
#ifdef GETTEXT_POISON
5050
int use_gettext_poison(void)
5151
{
5252
static int poison_requested = -1;
53-
if (poison_requested == -1)
54-
poison_requested = getenv("GIT_GETTEXT_POISON") ? 1 : 0;
53+
if (poison_requested == -1) {
54+
const char *v = getenv("GIT_TEST_GETTEXT_POISON");
55+
poison_requested = v && strlen(v) ? 1 : 0;
56+
}
5557
return poison_requested;
5658
}
57-
#endif
5859

5960
#ifndef NO_GETTEXT
6061
static int test_vsnprintf(const char *fmt, ...)
@@ -164,6 +165,8 @@ void git_setup_gettext(void)
164165
if (!podir)
165166
podir = p = system_path(GIT_LOCALE_PATH);
166167

168+
use_gettext_poison(); /* getenv() reentrancy paranoia */
169+
167170
if (!is_directory(podir)) {
168171
free(p);
169172
return;

gettext.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,22 @@
2828

2929
#define FORMAT_PRESERVING(n) __attribute__((format_arg(n)))
3030

31+
extern int use_gettext_poison(void);
32+
3133
#ifndef NO_GETTEXT
3234
extern void git_setup_gettext(void);
3335
extern int gettext_width(const char *s);
3436
#else
3537
static inline void git_setup_gettext(void)
3638
{
39+
use_gettext_poison(); /* getenv() reentrancy paranoia */
3740
}
3841
static inline int gettext_width(const char *s)
3942
{
4043
return strlen(s);
4144
}
4245
#endif
4346

44-
#ifdef GETTEXT_POISON
45-
extern int use_gettext_poison(void);
46-
#else
47-
#define use_gettext_poison() 0
48-
#endif
49-
5047
static inline FORMAT_PRESERVING(1) const char *_(const char *msgid)
5148
{
5249
if (!*msgid)

git-sh-i18n.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export TEXTDOMAINDIR
1717

1818
# First decide what scheme to use...
1919
GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough
20-
if test -n "$GIT_GETTEXT_POISON"
20+
if test -n "$GIT_TEST_GETTEXT_POISON"
2121
then
2222
GIT_INTERNAL_GETTEXT_SH_SCHEME=poison
2323
elif test -n "@@USE_GETTEXT_SCHEME@@"

po/README

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -289,16 +289,11 @@ something in the test suite might still depend on the US English
289289
version of the strings, e.g. to grep some error message or other
290290
output.
291291

292-
To smoke out issues like these Git can be compiled with gettext poison
293-
support, at the top-level:
292+
To smoke out issues like these, Git tested with a translation mode that
293+
emits gibberish on every call to gettext. To use it run the test suite
294+
with it, e.g.:
294295

295-
make GETTEXT_POISON=YesPlease
296-
297-
That'll give you a git which emits gibberish on every call to
298-
gettext. It's obviously not meant to be installed, but you should run
299-
the test suite with it:
300-
301-
cd t && prove -j 9 ./t[0-9]*.sh
296+
cd t && GIT_TEST_GETTEXT_POISON=YesPlease prove -j 9 ./t[0-9]*.sh
302297

303298
If tests break with it you should inspect them manually and see if
304299
what you're translating is sane, i.e. that you're not translating

t/README

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,12 @@ that cannot be easily covered by a few specific test cases. These
301301
could be enabled by running the test suite with correct GIT_TEST_
302302
environment set.
303303

304+
GIT_TEST_GETTEXT_POISON=<non-empty?> turns all strings marked for
305+
translation into gibberish if non-empty (think "test -n"). Used for
306+
spotting those tests that need to be marked with a C_LOCALE_OUTPUT
307+
prerequisite when adding more strings for translation. See "Testing
308+
marked strings" in po/README for details.
309+
304310
GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
305311
test suite. Accept any boolean values that are accepted by git-config.
306312

t/lib-gettext.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export GIT_TEXTDOMAINDIR GIT_PO_PATH
1212

1313
. "$GIT_BUILD_DIR"/git-sh-i18n
1414

15-
if test_have_prereq GETTEXT && ! test_have_prereq GETTEXT_POISON
15+
if test_have_prereq GETTEXT && test_have_prereq C_LOCALE_OUTPUT
1616
then
1717
# is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian
1818
is_IS_locale=$(locale -a 2>/dev/null |

t/t0000-basic.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ test_expect_success 'pretend we have a mix of all possible results' "
274274
EOF
275275
"
276276

277-
test_expect_success 'test --verbose' '
277+
test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
278278
test_must_fail run_sub_test_lib_test \
279279
test-verbose "test verbose" --verbose <<-\EOF &&
280280
test_expect_success "passing test" true

t/t0205-gettext-poison.sh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55

66
test_description='Gettext Shell poison'
77

8+
GIT_TEST_GETTEXT_POISON=YesPlease
9+
export GIT_TEST_GETTEXT_POISON
810
. ./lib-gettext.sh
911

10-
test_expect_success GETTEXT_POISON 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is poison' '
12+
test_expect_success 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is poison' '
1113
test "$GIT_INTERNAL_GETTEXT_SH_SCHEME" = "poison"
1214
'
1315

14-
test_expect_success GETTEXT_POISON 'gettext: our gettext() fallback has poison semantics' '
16+
test_expect_success 'gettext: our gettext() fallback has poison semantics' '
1517
printf "# GETTEXT POISON #" >expect &&
1618
gettext "test" >actual &&
1719
test_cmp expect actual &&
@@ -20,7 +22,7 @@ test_expect_success GETTEXT_POISON 'gettext: our gettext() fallback has poison s
2022
test_cmp expect actual
2123
'
2224

23-
test_expect_success GETTEXT_POISON 'eval_gettext: our eval_gettext() fallback has poison semantics' '
25+
test_expect_success 'eval_gettext: our eval_gettext() fallback has poison semantics' '
2426
printf "# GETTEXT POISON #" >expect &&
2527
eval_gettext "test" >actual &&
2628
test_cmp expect actual &&

t/t3406-rebase-message.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ test_expect_success 'rebase -n overrides config rebase.stat config' '
7777
# "Does not point to a valid commit: invalid-ref"
7878
#
7979
# NEEDSWORK: This "grep" is fine in real non-C locales, but
80-
# GETTEXT_POISON poisons the refname along with the enclosing
80+
# GIT_TEST_GETTEXT_POISON poisons the refname along with the enclosing
8181
# error message.
8282
test_expect_success 'rebase --onto outputs the invalid ref' '
8383
test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&

t/t7201-co.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,9 @@ test_expect_success 'checkout to detach HEAD (with advice declined)' '
254254
test_expect_success 'checkout to detach HEAD' '
255255
git config advice.detachedHead true &&
256256
git checkout -f renamer && git clean -f &&
257-
git checkout renamer^ 2>messages &&
258-
test_i18ngrep "HEAD is now at 7329388" messages &&
259-
(test_line_count -gt 1 messages || test -n "$GETTEXT_POISON") &&
257+
GIT_TEST_GETTEXT_POISON= git checkout renamer^ 2>messages &&
258+
grep "HEAD is now at 7329388" messages &&
259+
test_line_count -gt 1 messages &&
260260
H=$(git rev-parse --verify HEAD) &&
261261
M=$(git show-ref -s --verify refs/heads/master) &&
262262
test "z$H" = "z$M" &&

t/t9902-completion.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1697,7 +1697,8 @@ test_expect_success 'sourcing the completion script clears cached commands' '
16971697
verbose test -z "$__git_all_commands"
16981698
'
16991699

1700-
test_expect_success !GETTEXT_POISON 'sourcing the completion script clears cached merge strategies' '
1700+
test_expect_success 'sourcing the completion script clears cached merge strategies' '
1701+
GIT_TEST_GETTEXT_POISON= &&
17011702
__git_compute_merge_strategies &&
17021703
verbose test -n "$__git_merge_strategies" &&
17031704
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&

t/test-lib-functions.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -755,16 +755,16 @@ test_cmp_bin() {
755755

756756
# Use this instead of test_cmp to compare files that contain expected and
757757
# actual output from git commands that can be translated. When running
758-
# under GETTEXT_POISON this pretends that the command produced expected
758+
# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
759759
# results.
760760
test_i18ncmp () {
761-
test -n "$GETTEXT_POISON" || test_cmp "$@"
761+
! test_have_prereq C_LOCALE_OUTPUT || test_cmp "$@"
762762
}
763763

764764
# Use this instead of "grep expected-string actual" to see if the
765765
# output from a git command that can be translated either contains an
766766
# expected string, or does not contain an unwanted one. When running
767-
# under GETTEXT_POISON this pretends that the command produced expected
767+
# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
768768
# results.
769769
test_i18ngrep () {
770770
eval "last_arg=\${$#}"
@@ -779,7 +779,7 @@ test_i18ngrep () {
779779
error "bug in the test script: too few parameters to test_i18ngrep"
780780
fi
781781

782-
if test -n "$GETTEXT_POISON"
782+
if test_have_prereq !C_LOCALE_OUTPUT
783783
then
784784
# pretend success
785785
return 0

t/test-lib.sh

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@ PAGER=cat
9595
TZ=UTC
9696
export LANG LC_ALL PAGER TZ
9797
EDITOR=:
98+
99+
# GIT_TEST_GETTEXT_POISON should not influence git commands executed
100+
# during initialization of test-lib and the test repo. Back it up,
101+
# unset and then restore after initialization is finished.
102+
if test -n "$GIT_TEST_GETTEXT_POISON"
103+
then
104+
GIT_TEST_GETTEXT_POISON_ORIG=$GIT_TEST_GETTEXT_POISON
105+
unset GIT_TEST_GETTEXT_POISON
106+
fi
107+
98108
# A call to "unset" with no arguments causes at least Solaris 10
99109
# /usr/xpg4/bin/sh and /bin/ksh to bail out. So keep the unsets
100110
# deriving from the command substitution clustered with the other
@@ -1104,13 +1114,15 @@ test -n "$USE_LIBPCRE1" && test_set_prereq LIBPCRE1
11041114
test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2
11051115
test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
11061116

1117+
if test -n "$GIT_TEST_GETTEXT_POISON_ORIG"
1118+
then
1119+
GIT_TEST_GETTEXT_POISON=$GIT_TEST_GETTEXT_POISON_ORIG
1120+
unset GIT_TEST_GETTEXT_POISON_ORIG
1121+
fi
1122+
11071123
# Can we rely on git's output in the C locale?
1108-
if test -n "$GETTEXT_POISON"
1124+
if test -z "$GIT_TEST_GETTEXT_POISON"
11091125
then
1110-
GIT_GETTEXT_POISON=YesPlease
1111-
export GIT_GETTEXT_POISON
1112-
test_set_prereq GETTEXT_POISON
1113-
else
11141126
test_set_prereq C_LOCALE_OUTPUT
11151127
fi
11161128

0 commit comments

Comments
 (0)