зеркало из https://github.com/microsoft/git.git
Merge branch 'ab/dynamic-gettext-poison'
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
This commit is contained in:
Коммит
954932667d
|
@ -14,7 +14,7 @@ compiler:
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- env: jobname=GETTEXT_POISON
|
- env: jobname=GIT_TEST_GETTEXT_POISON
|
||||||
os: linux
|
os: linux
|
||||||
compiler:
|
compiler:
|
||||||
addons:
|
addons:
|
||||||
|
|
8
Makefile
8
Makefile
|
@ -365,11 +365,6 @@ all::
|
||||||
# Define HAVE_DEV_TTY if your system can open /dev/tty to interact with the
|
# Define HAVE_DEV_TTY if your system can open /dev/tty to interact with the
|
||||||
# user.
|
# 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
|
# Define JSMIN to point to JavaScript minifier that functions as
|
||||||
# a filter to have gitweb.js minified.
|
# a filter to have gitweb.js minified.
|
||||||
#
|
#
|
||||||
|
@ -1454,7 +1449,7 @@ ifdef NO_SYMLINK_HEAD
|
||||||
BASIC_CFLAGS += -DNO_SYMLINK_HEAD
|
BASIC_CFLAGS += -DNO_SYMLINK_HEAD
|
||||||
endif
|
endif
|
||||||
ifdef GETTEXT_POISON
|
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
|
endif
|
||||||
ifdef NO_GETTEXT
|
ifdef NO_GETTEXT
|
||||||
BASIC_CFLAGS += -DNO_GETTEXT
|
BASIC_CFLAGS += -DNO_GETTEXT
|
||||||
|
@ -2604,7 +2599,6 @@ ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
|
||||||
@echo GIT_TEST_CMP_USE_COPIED_CONTEXT=YesPlease >>$@+
|
@echo GIT_TEST_CMP_USE_COPIED_CONTEXT=YesPlease >>$@+
|
||||||
endif
|
endif
|
||||||
@echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@+
|
@echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@+
|
||||||
@echo GETTEXT_POISON=\''$(subst ','\'',$(subst ','\'',$(GETTEXT_POISON)))'\' >>$@+
|
|
||||||
ifdef GIT_PERF_REPEAT_COUNT
|
ifdef GIT_PERF_REPEAT_COUNT
|
||||||
@echo GIT_PERF_REPEAT_COUNT=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_REPEAT_COUNT)))'\' >>$@+
|
@echo GIT_PERF_REPEAT_COUNT=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_REPEAT_COUNT)))'\' >>$@+
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -123,7 +123,7 @@ osx-clang|osx-gcc)
|
||||||
# Travis CI OS X
|
# Travis CI OS X
|
||||||
export GIT_SKIP_TESTS="t9810 t9816"
|
export GIT_SKIP_TESTS="t9810 t9816"
|
||||||
;;
|
;;
|
||||||
GETTEXT_POISON)
|
GIT_TEST_GETTEXT_POISON)
|
||||||
export GETTEXT_POISON=YesPlease
|
export GIT_TEST_GETTEXT_POISON=YesPlease
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
11
gettext.c
11
gettext.c
|
@ -7,6 +7,7 @@
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#ifndef NO_GETTEXT
|
#ifndef NO_GETTEXT
|
||||||
# include <locale.h>
|
# include <locale.h>
|
||||||
|
@ -46,15 +47,15 @@ const char *get_preferred_languages(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GETTEXT_POISON
|
|
||||||
int use_gettext_poison(void)
|
int use_gettext_poison(void)
|
||||||
{
|
{
|
||||||
static int poison_requested = -1;
|
static int poison_requested = -1;
|
||||||
if (poison_requested == -1)
|
if (poison_requested == -1) {
|
||||||
poison_requested = getenv("GIT_GETTEXT_POISON") ? 1 : 0;
|
const char *v = getenv("GIT_TEST_GETTEXT_POISON");
|
||||||
|
poison_requested = v && strlen(v) ? 1 : 0;
|
||||||
|
}
|
||||||
return poison_requested;
|
return poison_requested;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NO_GETTEXT
|
#ifndef NO_GETTEXT
|
||||||
static int test_vsnprintf(const char *fmt, ...)
|
static int test_vsnprintf(const char *fmt, ...)
|
||||||
|
@ -164,6 +165,8 @@ void git_setup_gettext(void)
|
||||||
if (!podir)
|
if (!podir)
|
||||||
podir = p = system_path(GIT_LOCALE_PATH);
|
podir = p = system_path(GIT_LOCALE_PATH);
|
||||||
|
|
||||||
|
use_gettext_poison(); /* getenv() reentrancy paranoia */
|
||||||
|
|
||||||
if (!is_directory(podir)) {
|
if (!is_directory(podir)) {
|
||||||
free(p);
|
free(p);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -28,12 +28,15 @@
|
||||||
|
|
||||||
#define FORMAT_PRESERVING(n) __attribute__((format_arg(n)))
|
#define FORMAT_PRESERVING(n) __attribute__((format_arg(n)))
|
||||||
|
|
||||||
|
extern int use_gettext_poison(void);
|
||||||
|
|
||||||
#ifndef NO_GETTEXT
|
#ifndef NO_GETTEXT
|
||||||
extern void git_setup_gettext(void);
|
extern void git_setup_gettext(void);
|
||||||
extern int gettext_width(const char *s);
|
extern int gettext_width(const char *s);
|
||||||
#else
|
#else
|
||||||
static inline void git_setup_gettext(void)
|
static inline void git_setup_gettext(void)
|
||||||
{
|
{
|
||||||
|
use_gettext_poison(); /* getenv() reentrancy paranoia */
|
||||||
}
|
}
|
||||||
static inline int gettext_width(const char *s)
|
static inline int gettext_width(const char *s)
|
||||||
{
|
{
|
||||||
|
@ -41,12 +44,6 @@ static inline int gettext_width(const char *s)
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
static inline FORMAT_PRESERVING(1) const char *_(const char *msgid)
|
||||||
{
|
{
|
||||||
if (!*msgid)
|
if (!*msgid)
|
||||||
|
|
|
@ -17,7 +17,7 @@ export TEXTDOMAINDIR
|
||||||
|
|
||||||
# First decide what scheme to use...
|
# First decide what scheme to use...
|
||||||
GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough
|
GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough
|
||||||
if test -n "$GIT_GETTEXT_POISON"
|
if test -n "$GIT_TEST_GETTEXT_POISON"
|
||||||
then
|
then
|
||||||
GIT_INTERNAL_GETTEXT_SH_SCHEME=poison
|
GIT_INTERNAL_GETTEXT_SH_SCHEME=poison
|
||||||
elif test -n "@@USE_GETTEXT_SCHEME@@"
|
elif test -n "@@USE_GETTEXT_SCHEME@@"
|
||||||
|
|
13
po/README
13
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
|
version of the strings, e.g. to grep some error message or other
|
||||||
output.
|
output.
|
||||||
|
|
||||||
To smoke out issues like these Git can be compiled with gettext poison
|
To smoke out issues like these, Git tested with a translation mode that
|
||||||
support, at the top-level:
|
emits gibberish on every call to gettext. To use it run the test suite
|
||||||
|
with it, e.g.:
|
||||||
|
|
||||||
make GETTEXT_POISON=YesPlease
|
cd t && GIT_TEST_GETTEXT_POISON=YesPlease prove -j 9 ./t[0-9]*.sh
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
If tests break with it you should inspect them manually and see if
|
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
|
what you're translating is sane, i.e. that you're not translating
|
||||||
|
|
6
t/README
6
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_
|
could be enabled by running the test suite with correct GIT_TEST_
|
||||||
environment set.
|
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
|
GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
|
||||||
test suite. Accept any boolean values that are accepted by git-config.
|
test suite. Accept any boolean values that are accepted by git-config.
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ export GIT_TEXTDOMAINDIR GIT_PO_PATH
|
||||||
|
|
||||||
. "$GIT_BUILD_DIR"/git-sh-i18n
|
. "$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
|
then
|
||||||
# is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian
|
# is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian
|
||||||
is_IS_locale=$(locale -a 2>/dev/null |
|
is_IS_locale=$(locale -a 2>/dev/null |
|
||||||
|
|
|
@ -274,7 +274,7 @@ test_expect_success 'pretend we have a mix of all possible results' "
|
||||||
EOF
|
EOF
|
||||||
"
|
"
|
||||||
|
|
||||||
test_expect_success 'test --verbose' '
|
test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
|
||||||
test_must_fail run_sub_test_lib_test \
|
test_must_fail run_sub_test_lib_test \
|
||||||
test-verbose "test verbose" --verbose <<-\EOF &&
|
test-verbose "test verbose" --verbose <<-\EOF &&
|
||||||
test_expect_success "passing test" true
|
test_expect_success "passing test" true
|
||||||
|
|
|
@ -5,13 +5,15 @@
|
||||||
|
|
||||||
test_description='Gettext Shell poison'
|
test_description='Gettext Shell poison'
|
||||||
|
|
||||||
|
GIT_TEST_GETTEXT_POISON=YesPlease
|
||||||
|
export GIT_TEST_GETTEXT_POISON
|
||||||
. ./lib-gettext.sh
|
. ./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 "$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 &&
|
printf "# GETTEXT POISON #" >expect &&
|
||||||
gettext "test" >actual &&
|
gettext "test" >actual &&
|
||||||
test_cmp expect 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_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 &&
|
printf "# GETTEXT POISON #" >expect &&
|
||||||
eval_gettext "test" >actual &&
|
eval_gettext "test" >actual &&
|
||||||
test_cmp expect actual &&
|
test_cmp expect actual &&
|
||||||
|
|
|
@ -77,7 +77,7 @@ test_expect_success 'rebase -n overrides config rebase.stat config' '
|
||||||
# "Does not point to a valid commit: invalid-ref"
|
# "Does not point to a valid commit: invalid-ref"
|
||||||
#
|
#
|
||||||
# NEEDSWORK: This "grep" is fine in real non-C locales, but
|
# 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.
|
# error message.
|
||||||
test_expect_success 'rebase --onto outputs the invalid ref' '
|
test_expect_success 'rebase --onto outputs the invalid ref' '
|
||||||
test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&
|
test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&
|
||||||
|
|
|
@ -254,9 +254,9 @@ test_expect_success 'checkout to detach HEAD (with advice declined)' '
|
||||||
test_expect_success 'checkout to detach HEAD' '
|
test_expect_success 'checkout to detach HEAD' '
|
||||||
git config advice.detachedHead true &&
|
git config advice.detachedHead true &&
|
||||||
git checkout -f renamer && git clean -f &&
|
git checkout -f renamer && git clean -f &&
|
||||||
git checkout renamer^ 2>messages &&
|
GIT_TEST_GETTEXT_POISON= git checkout renamer^ 2>messages &&
|
||||||
test_i18ngrep "HEAD is now at 7329388" messages &&
|
grep "HEAD is now at 7329388" messages &&
|
||||||
(test_line_count -gt 1 messages || test -n "$GETTEXT_POISON") &&
|
test_line_count -gt 1 messages &&
|
||||||
H=$(git rev-parse --verify HEAD) &&
|
H=$(git rev-parse --verify HEAD) &&
|
||||||
M=$(git show-ref -s --verify refs/heads/master) &&
|
M=$(git show-ref -s --verify refs/heads/master) &&
|
||||||
test "z$H" = "z$M" &&
|
test "z$H" = "z$M" &&
|
||||||
|
|
|
@ -1697,7 +1697,8 @@ test_expect_success 'sourcing the completion script clears cached commands' '
|
||||||
verbose test -z "$__git_all_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 &&
|
__git_compute_merge_strategies &&
|
||||||
verbose test -n "$__git_merge_strategies" &&
|
verbose test -n "$__git_merge_strategies" &&
|
||||||
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
|
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
|
||||||
|
|
|
@ -778,16 +778,16 @@ test_cmp_bin() {
|
||||||
|
|
||||||
# Use this instead of test_cmp to compare files that contain expected and
|
# Use this instead of test_cmp to compare files that contain expected and
|
||||||
# actual output from git commands that can be translated. When running
|
# 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.
|
# results.
|
||||||
test_i18ncmp () {
|
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
|
# Use this instead of "grep expected-string actual" to see if the
|
||||||
# output from a git command that can be translated either contains an
|
# output from a git command that can be translated either contains an
|
||||||
# expected string, or does not contain an unwanted one. When running
|
# 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.
|
# results.
|
||||||
test_i18ngrep () {
|
test_i18ngrep () {
|
||||||
eval "last_arg=\${$#}"
|
eval "last_arg=\${$#}"
|
||||||
|
@ -802,7 +802,7 @@ test_i18ngrep () {
|
||||||
error "bug in the test script: too few parameters to test_i18ngrep"
|
error "bug in the test script: too few parameters to test_i18ngrep"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -n "$GETTEXT_POISON"
|
if test_have_prereq !C_LOCALE_OUTPUT
|
||||||
then
|
then
|
||||||
# pretend success
|
# pretend success
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -95,6 +95,16 @@ PAGER=cat
|
||||||
TZ=UTC
|
TZ=UTC
|
||||||
export LANG LC_ALL PAGER TZ
|
export LANG LC_ALL PAGER TZ
|
||||||
EDITOR=:
|
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
|
# 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
|
# /usr/xpg4/bin/sh and /bin/ksh to bail out. So keep the unsets
|
||||||
# deriving from the command substitution clustered with the other
|
# 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 -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2
|
||||||
test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
|
test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
|
||||||
|
|
||||||
# Can we rely on git's output in the C locale?
|
if test -n "$GIT_TEST_GETTEXT_POISON_ORIG"
|
||||||
if test -n "$GETTEXT_POISON"
|
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 -z "$GIT_TEST_GETTEXT_POISON"
|
||||||
then
|
then
|
||||||
GIT_GETTEXT_POISON=YesPlease
|
|
||||||
export GIT_GETTEXT_POISON
|
|
||||||
test_set_prereq GETTEXT_POISON
|
|
||||||
else
|
|
||||||
test_set_prereq C_LOCALE_OUTPUT
|
test_set_prereq C_LOCALE_OUTPUT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче