Merge branch 'ab/dynamic-gettext-poison'
authorJunio C Hamano <gitster@pobox.com>
Mon, 19 Nov 2018 07:24:39 +0000 (16:24 +0900)
committerJunio C Hamano <gitster@pobox.com>
Mon, 19 Nov 2018 07:24:39 +0000 (16:24 +0900)
Our testing framework uses a special i18n "poisoned localization"
feature to find messages that ought to stay constant but are
incorrectly marked to be translated. This feature has been made
into a runtime option (it used to be a compile-time option).

* ab/dynamic-gettext-poison:
Makefile: ease dynamic-gettext-poison transition
i18n: make GETTEXT_POISON a runtime option

16 files changed:
.travis.yml
Makefile
ci/lib-travisci.sh
gettext.c
gettext.h
git-sh-i18n.sh
po/README
t/README
t/lib-gettext.sh
t/t0000-basic.sh
t/t0205-gettext-poison.sh
t/t3406-rebase-message.sh
t/t7201-co.sh
t/t9902-completion.sh
t/test-lib-functions.sh
t/test-lib.sh
index a5a82d6832563d48d8e7895e9a9656cea43b97b2..03c8e4c613015476fffe3f1e071c0c9d6609df0e 100644 (file)
@@ -14,7 +14,7 @@ compiler:
 
 matrix:
   include:
-    - env: jobname=GETTEXT_POISON
+    - env: jobname=GIT_TEST_GETTEXT_POISON
       os: linux
       compiler:
       addons:
index b8d5f1a27fcd661fcdcfd07b07b351de2c4dc65c..6579c01f9f119b25353cf883c973dffae45edbe0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -365,11 +365,6 @@ all::
 # Define HAVE_DEV_TTY if your system can open /dev/tty to interact with the
 # user.
 #
-# Define GETTEXT_POISON if you are debugging the choice of strings marked
-# for translation.  In a GETTEXT_POISON build, you can turn all strings marked
-# for translation into gibberish by setting the GIT_GETTEXT_POISON variable
-# (to any value) in your environment.
-#
 # Define JSMIN to point to JavaScript minifier that functions as
 # a filter to have gitweb.js minified.
 #
@@ -1454,7 +1449,7 @@ ifdef NO_SYMLINK_HEAD
        BASIC_CFLAGS += -DNO_SYMLINK_HEAD
 endif
 ifdef GETTEXT_POISON
-       BASIC_CFLAGS += -DGETTEXT_POISON
+$(warning The GETTEXT_POISON option has been removed in favor of runtime GIT_TEST_GETTEXT_POISON. See t/README!)
 endif
 ifdef NO_GETTEXT
        BASIC_CFLAGS += -DNO_GETTEXT
@@ -2604,7 +2599,6 @@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
        @echo GIT_TEST_CMP_USE_COPIED_CONTEXT=YesPlease >>$@+
 endif
        @echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@+
-       @echo GETTEXT_POISON=\''$(subst ','\'',$(subst ','\'',$(GETTEXT_POISON)))'\' >>$@+
 ifdef GIT_PERF_REPEAT_COUNT
        @echo GIT_PERF_REPEAT_COUNT=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_REPEAT_COUNT)))'\' >>$@+
 endif
index 06970f72134fae6f6fd6df9afd93a7c7f064f495..69dff4d1ecb4b21c32f8127d78a87a925e9390c5 100755 (executable)
@@ -123,7 +123,7 @@ osx-clang|osx-gcc)
        # Travis CI OS X
        export GIT_SKIP_TESTS="t9810 t9816"
        ;;
-GETTEXT_POISON)
-       export GETTEXT_POISON=YesPlease
+GIT_TEST_GETTEXT_POISON)
+       export GIT_TEST_GETTEXT_POISON=YesPlease
        ;;
 esac
index 7272771c8e445da194ea608443d8bc9c891b6b33..d4021d690c07237edefb0cf2869eb6795d227a54 100644 (file)
--- a/gettext.c
+++ b/gettext.c
@@ -7,6 +7,7 @@
 #include "gettext.h"
 #include "strbuf.h"
 #include "utf8.h"
+#include "config.h"
 
 #ifndef NO_GETTEXT
 #      include <locale.h>
@@ -46,15 +47,15 @@ const char *get_preferred_languages(void)
        return NULL;
 }
 
-#ifdef GETTEXT_POISON
 int use_gettext_poison(void)
 {
        static int poison_requested = -1;
-       if (poison_requested == -1)
-               poison_requested = getenv("GIT_GETTEXT_POISON") ? 1 : 0;
+       if (poison_requested == -1) {
+               const char *v = getenv("GIT_TEST_GETTEXT_POISON");
+               poison_requested = v && strlen(v) ? 1 : 0;
+       }
        return poison_requested;
 }
-#endif
 
 #ifndef NO_GETTEXT
 static int test_vsnprintf(const char *fmt, ...)
@@ -164,6 +165,8 @@ void git_setup_gettext(void)
        if (!podir)
                podir = p = system_path(GIT_LOCALE_PATH);
 
+       use_gettext_poison(); /* getenv() reentrancy paranoia */
+
        if (!is_directory(podir)) {
                free(p);
                return;
index 7eee64a34fa0a5e922606e6351b29d08cb26fe6b..71255e503eeb70e691e03ac1be0e2a249244a096 100644 (file)
--- a/gettext.h
+++ b/gettext.h
 
 #define FORMAT_PRESERVING(n) __attribute__((format_arg(n)))
 
+extern int use_gettext_poison(void);
+
 #ifndef NO_GETTEXT
 extern void git_setup_gettext(void);
 extern int gettext_width(const char *s);
 #else
 static inline void git_setup_gettext(void)
 {
+       use_gettext_poison(); /* getenv() reentrancy paranoia */
 }
 static inline int gettext_width(const char *s)
 {
@@ -41,12 +44,6 @@ static inline int gettext_width(const char *s)
 }
 #endif
 
-#ifdef GETTEXT_POISON
-extern int use_gettext_poison(void);
-#else
-#define use_gettext_poison() 0
-#endif
-
 static inline FORMAT_PRESERVING(1) const char *_(const char *msgid)
 {
        if (!*msgid)
index 9d065fb4bf9a308e64fa2d4aa5dff294b116f1a9..e1d917fd2796d1f2d952c509cb79d8cafe0cf89e 100644 (file)
@@ -17,7 +17,7 @@ export TEXTDOMAINDIR
 
 # First decide what scheme to use...
 GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough
-if test -n "$GIT_GETTEXT_POISON"
+if test -n "$GIT_TEST_GETTEXT_POISON"
 then
        GIT_INTERNAL_GETTEXT_SH_SCHEME=poison
 elif test -n "@@USE_GETTEXT_SCHEME@@"
index fef4c0f0b5ae15e98b8a5913afe60783a701f40a..aa704ffcb7f70af2c42494a2f26eeef17c5eed67 100644 (file)
--- a/po/README
+++ b/po/README
@@ -289,16 +289,11 @@ something in the test suite might still depend on the US English
 version of the strings, e.g. to grep some error message or other
 output.
 
-To smoke out issues like these Git can be compiled with gettext poison
-support, at the top-level:
+To smoke out issues like these, Git tested with a translation mode that
+emits gibberish on every call to gettext. To use it run the test suite
+with it, e.g.:
 
-    make GETTEXT_POISON=YesPlease
-
-That'll give you a git which emits gibberish on every call to
-gettext. It's obviously not meant to be installed, but you should run
-the test suite with it:
-
-    cd t && prove -j 9 ./t[0-9]*.sh
+    cd t && GIT_TEST_GETTEXT_POISON=YesPlease prove -j 9 ./t[0-9]*.sh
 
 If tests break with it you should inspect them manually and see if
 what you're translating is sane, i.e. that you're not translating
index 3df5d12e46ff994a18f5adf97a93c1f5aa766ec8..28711cc508f9e5dfb2f2ef238be14926d56f9a12 100644 (file)
--- a/t/README
+++ b/t/README
@@ -302,6 +302,12 @@ that cannot be easily covered by a few specific test cases. These
 could be enabled by running the test suite with correct GIT_TEST_
 environment set.
 
+GIT_TEST_GETTEXT_POISON=<non-empty?> turns all strings marked for
+translation into gibberish if non-empty (think "test -n"). Used for
+spotting those tests that need to be marked with a C_LOCALE_OUTPUT
+prerequisite when adding more strings for translation. See "Testing
+marked strings" in po/README for details.
+
 GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
 test suite. Accept any boolean values that are accepted by git-config.
 
index eec757f104708df3a00935cef89dd7dad537afb9..755f4214319fb931870b701d4177a32f38849565 100644 (file)
@@ -12,7 +12,7 @@ export GIT_TEXTDOMAINDIR GIT_PO_PATH
 
 . "$GIT_BUILD_DIR"/git-sh-i18n
 
-if test_have_prereq GETTEXT && ! test_have_prereq GETTEXT_POISON
+if test_have_prereq GETTEXT && test_have_prereq C_LOCALE_OUTPUT
 then
        # is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian
        is_IS_locale=$(locale -a 2>/dev/null |
index 4d23373526945eea7bc4e875beac5fdc4451cac8..b6566003dd8704503305314767f84d516c170f7a 100755 (executable)
@@ -274,7 +274,7 @@ test_expect_success 'pretend we have a mix of all possible results' "
        EOF
 "
 
-test_expect_success 'test --verbose' '
+test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
        test_must_fail run_sub_test_lib_test \
                test-verbose "test verbose" --verbose <<-\EOF &&
        test_expect_success "passing test" true
index 438e778d6afa086e8823b2ac3d38c2a26f171dbd..a06269f38ae555f952b83b6fbc38374a725293d1 100755 (executable)
@@ -5,13 +5,15 @@
 
 test_description='Gettext Shell poison'
 
+GIT_TEST_GETTEXT_POISON=YesPlease
+export GIT_TEST_GETTEXT_POISON
 . ./lib-gettext.sh
 
-test_expect_success GETTEXT_POISON 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is poison' '
+test_expect_success 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is poison' '
     test "$GIT_INTERNAL_GETTEXT_SH_SCHEME" = "poison"
 '
 
-test_expect_success GETTEXT_POISON 'gettext: our gettext() fallback has poison semantics' '
+test_expect_success 'gettext: our gettext() fallback has poison semantics' '
     printf "# GETTEXT POISON #" >expect &&
     gettext "test" >actual &&
     test_cmp expect actual &&
@@ -20,7 +22,7 @@ test_expect_success GETTEXT_POISON 'gettext: our gettext() fallback has poison s
     test_cmp expect actual
 '
 
-test_expect_success GETTEXT_POISON 'eval_gettext: our eval_gettext() fallback has poison semantics' '
+test_expect_success 'eval_gettext: our eval_gettext() fallback has poison semantics' '
     printf "# GETTEXT POISON #" >expect &&
     eval_gettext "test" >actual &&
     test_cmp expect actual &&
index 2c79eed4febda6977dde4d530d73a184cfa92d80..38bd876cabf9757cce439be90c0f1e094225cac3 100755 (executable)
@@ -77,7 +77,7 @@ test_expect_success 'rebase -n overrides config rebase.stat config' '
 #     "Does not point to a valid commit: invalid-ref"
 #
 # NEEDSWORK: This "grep" is fine in real non-C locales, but
-# GETTEXT_POISON poisons the refname along with the enclosing
+# GIT_TEST_GETTEXT_POISON poisons the refname along with the enclosing
 # error message.
 test_expect_success 'rebase --onto outputs the invalid ref' '
        test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&
index 826987ca804fbd74bc06467446c99b7b4a27ea3e..72b9b375baa6b26d0bca91c0c2d214cd4a9b8a42 100755 (executable)
@@ -254,9 +254,9 @@ test_expect_success 'checkout to detach HEAD (with advice declined)' '
 test_expect_success 'checkout to detach HEAD' '
        git config advice.detachedHead true &&
        git checkout -f renamer && git clean -f &&
-       git checkout renamer^ 2>messages &&
-       test_i18ngrep "HEAD is now at 7329388" messages &&
-       (test_line_count -gt 1 messages || test -n "$GETTEXT_POISON") &&
+       GIT_TEST_GETTEXT_POISON= git checkout renamer^ 2>messages &&
+       grep "HEAD is now at 7329388" messages &&
+       test_line_count -gt 1 messages &&
        H=$(git rev-parse --verify HEAD) &&
        M=$(git show-ref -s --verify refs/heads/master) &&
        test "z$H" = "z$M" &&
index 175f83d7042a0fb9f093bc6f25e1d0b25ce548af..3c6b185b60891c164f56a638071873051420fdac 100755 (executable)
@@ -1697,7 +1697,8 @@ test_expect_success 'sourcing the completion script clears cached commands' '
        verbose test -z "$__git_all_commands"
 '
 
-test_expect_success !GETTEXT_POISON 'sourcing the completion script clears cached merge strategies' '
+test_expect_success 'sourcing the completion script clears cached merge strategies' '
+       GIT_TEST_GETTEXT_POISON= &&
        __git_compute_merge_strategies &&
        verbose test -n "$__git_merge_strategies" &&
        . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
index d158c8d0bf704646b2ce764fe96a849fb0303c2f..4397c01be03b376b7eb942c0e89032190ad82313 100644 (file)
@@ -778,16 +778,16 @@ test_cmp_bin() {
 
 # Use this instead of test_cmp to compare files that contain expected and
 # actual output from git commands that can be translated.  When running
-# under GETTEXT_POISON this pretends that the command produced expected
+# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
 # results.
 test_i18ncmp () {
-       test -n "$GETTEXT_POISON" || test_cmp "$@"
+       ! test_have_prereq C_LOCALE_OUTPUT || test_cmp "$@"
 }
 
 # Use this instead of "grep expected-string actual" to see if the
 # output from a git command that can be translated either contains an
 # expected string, or does not contain an unwanted one.  When running
-# under GETTEXT_POISON this pretends that the command produced expected
+# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
 # results.
 test_i18ngrep () {
        eval "last_arg=\${$#}"
@@ -802,7 +802,7 @@ test_i18ngrep () {
                error "bug in the test script: too few parameters to test_i18ngrep"
        fi
 
-       if test -n "$GETTEXT_POISON"
+       if test_have_prereq !C_LOCALE_OUTPUT
        then
                # pretend success
                return 0
index aba66cafa207765cb74d78e86c13faa619788c16..219ca1d520e3b343685b47bd7940be6778ae152d 100644 (file)
@@ -95,6 +95,16 @@ PAGER=cat
 TZ=UTC
 export LANG LC_ALL PAGER TZ
 EDITOR=:
+
+# GIT_TEST_GETTEXT_POISON should not influence git commands executed
+# during initialization of test-lib and the test repo. Back it up,
+# unset and then restore after initialization is finished.
+if test -n "$GIT_TEST_GETTEXT_POISON"
+then
+       GIT_TEST_GETTEXT_POISON_ORIG=$GIT_TEST_GETTEXT_POISON
+       unset GIT_TEST_GETTEXT_POISON
+fi
+
 # A call to "unset" with no arguments causes at least Solaris 10
 # /usr/xpg4/bin/sh and /bin/ksh to bail out.  So keep the unsets
 # deriving from the command substitution clustered with the other
@@ -1104,13 +1114,15 @@ test -n "$USE_LIBPCRE1" && test_set_prereq LIBPCRE1
 test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2
 test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
 
+if test -n "$GIT_TEST_GETTEXT_POISON_ORIG"
+then
+       GIT_TEST_GETTEXT_POISON=$GIT_TEST_GETTEXT_POISON_ORIG
+       unset GIT_TEST_GETTEXT_POISON_ORIG
+fi
+
 # Can we rely on git's output in the C locale?
-if test -n "$GETTEXT_POISON"
+if test -z "$GIT_TEST_GETTEXT_POISON"
 then
-       GIT_GETTEXT_POISON=YesPlease
-       export GIT_GETTEXT_POISON
-       test_set_prereq GETTEXT_POISON
-else
        test_set_prereq C_LOCALE_OUTPUT
 fi