github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/packaging/debian-sid/patches/0007-i18n-use-dummy-localizations-to-avoid-dependencies.patch (about) 1 From b12169ea4f913574821ceeb19db52b4f679e88d7 Mon Sep 17 00:00:00 2001 2 From: Zygmunt Krynicki <me@zygoon.pl> 3 Date: Thu, 17 Jan 2019 16:42:35 +0200 4 Subject: [PATCH 7/9] i18n: use dummy localizations to avoid dependencies 5 6 Upstream snapd uses the github.com/ojii/gettext.go package for access to 7 translation catalogs. This package is currently not available in Debian 8 and prevents building the package. As such, replace the real 9 implementation with a simple dummy one that always uses the English 10 input strings. 11 12 Signed-off-by: Zygmunt Krynicki <me@zygoon.pl> 13 Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com> 14 --- 15 i18n/i18n.go | 87 +++----------------------------- 16 i18n/i18n_test.go | 125 ++-------------------------------------------- 17 2 files changed, 11 insertions(+), 201 deletions(-) 18 19 diff --git a/i18n/i18n.go b/i18n/i18n.go 20 index 352e9a65d3c9ff802c18c8dbac613668aa23064d..12885f7149ff005e189762ae93f7eb9897e20db3 100644 21 --- a/i18n/i18n.go 22 +++ b/i18n/i18n.go 23 @@ -19,76 +19,11 @@ 24 25 package i18n 26 27 -//go:generate update-pot 28 - 29 import ( 30 - "fmt" 31 "os" 32 - "path/filepath" 33 "strings" 34 - 35 - "github.com/snapcore/go-gettext" 36 - 37 - "github.com/snapcore/snapd/dirs" 38 - "github.com/snapcore/snapd/osutil" 39 ) 40 41 -// TEXTDOMAIN is the message domain used by snappy; see dgettext(3) 42 -// for more information. 43 -var ( 44 - TEXTDOMAIN = "snappy" 45 - locale gettext.Catalog 46 - translations gettext.Translations 47 -) 48 - 49 -func init() { 50 - bindTextDomain(TEXTDOMAIN, "/usr/share/locale") 51 - setLocale("") 52 -} 53 - 54 -func langpackResolver(baseRoot string, locale string, domain string) string { 55 - // first check for the real locale (e.g. de_DE) 56 - // then try to simplify the locale (e.g. de_DE -> de) 57 - locales := []string{locale, strings.SplitN(locale, "_", 2)[0]} 58 - for _, locale := range locales { 59 - r := filepath.Join(locale, "LC_MESSAGES", fmt.Sprintf("%s.mo", domain)) 60 - 61 - // look into the core snaps first for translations, 62 - // then the main system 63 - candidateDirs := []string{ 64 - filepath.Join(dirs.SnapMountDir, "/core/current/", baseRoot), 65 - baseRoot, 66 - } 67 - for _, root := range candidateDirs { 68 - // ubuntu uses /usr/lib/locale-langpack and patches the glibc gettext 69 - // implementation 70 - langpack := filepath.Join(root, "..", "locale-langpack", r) 71 - if osutil.FileExists(langpack) { 72 - return langpack 73 - } 74 - 75 - regular := filepath.Join(root, r) 76 - if osutil.FileExists(regular) { 77 - return regular 78 - } 79 - } 80 - } 81 - 82 - return "" 83 -} 84 - 85 -func bindTextDomain(domain, dir string) { 86 - translations = gettext.NewTranslations(dir, domain, langpackResolver) 87 -} 88 - 89 -func setLocale(loc string) { 90 - if loc == "" { 91 - loc = localeFromEnv() 92 - } 93 - 94 - locale = translations.Locale(simplifyLocale(loc)) 95 -} 96 - 97 func simplifyLocale(loc string) string { 98 // de_DE.UTF-8, de_DE@euro all need to get simplified 99 loc = strings.Split(loc, "@")[0] 100 @@ -106,30 +41,20 @@ func localeFromEnv() string { 101 return loc 102 } 103 104 -// CurrentLocale returns the current locale without encoding or variants. 105 func CurrentLocale() string { 106 return simplifyLocale(localeFromEnv()) 107 } 108 109 // G is the shorthand for Gettext 110 func G(msgid string) string { 111 - return locale.Gettext(msgid) 112 -} 113 - 114 -// https://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html 115 -// (search for 1000) 116 -func ngn(d int) uint32 { 117 - const max = 1000000 118 - if d < 0 { 119 - d = -d 120 - } 121 - if d > max { 122 - return uint32((d % max) + max) 123 - } 124 - return uint32(d) 125 + return msgid 126 } 127 128 // NG is the shorthand for NGettext 129 func NG(msgid string, msgidPlural string, n int) string { 130 - return locale.NGettext(msgid, msgidPlural, ngn(n)) 131 + if n == 1 { 132 + return msgid 133 + } else { 134 + return msgidPlural 135 + } 136 } 137 diff --git a/i18n/i18n_test.go b/i18n/i18n_test.go 138 index 81cb050a76b824d1b83e97e02c08628520329d96..86b59f3b439e9c27d37cfb35e21d84724c4cd52f 100644 139 --- a/i18n/i18n_test.go 140 +++ b/i18n/i18n_test.go 141 @@ -20,143 +20,28 @@ 142 package i18n 143 144 import ( 145 - "io/ioutil" 146 - "os" 147 - "os/exec" 148 - "path/filepath" 149 "testing" 150 151 . "gopkg.in/check.v1" 152 - 153 - "github.com/snapcore/snapd/dirs" 154 ) 155 156 // Hook up check.v1 into the "go test" runner 157 func Test(t *testing.T) { TestingT(t) } 158 159 -var mockLocalePo = []byte(` 160 -msgid "" 161 -msgstr "" 162 -"Project-Id-Version: snappy-test\n" 163 -"Report-Msgid-Bugs-To: snappy-devel@lists.ubuntu.com\n" 164 -"POT-Creation-Date: 2015-06-16 09:08+0200\n" 165 -"Language: en_DK\n" 166 -"MIME-Version: 1.0\n" 167 -"Content-Type: text/plain; charset=UTF-8\n" 168 -"Content-Transfer-Encoding: 8bit\n" 169 -"Plural-Forms: nplurals=2; plural=n != 1;>\n" 170 - 171 -msgid "plural_1" 172 -msgid_plural "plural_2" 173 -msgstr[0] "translated plural_1" 174 -msgstr[1] "translated plural_2" 175 - 176 -msgid "singular" 177 -msgstr "translated singular" 178 -`) 179 - 180 -func makeMockTranslations(c *C, localeDir string) { 181 - fullLocaleDir := filepath.Join(localeDir, "en_DK", "LC_MESSAGES") 182 - err := os.MkdirAll(fullLocaleDir, 0755) 183 - c.Assert(err, IsNil) 184 - 185 - po := filepath.Join(fullLocaleDir, "snappy-test.po") 186 - mo := filepath.Join(fullLocaleDir, "snappy-test.mo") 187 - err = ioutil.WriteFile(po, mockLocalePo, 0644) 188 - c.Assert(err, IsNil) 189 - 190 - cmd := exec.Command("msgfmt", po, "--output-file", mo) 191 - cmd.Stdout = os.Stdout 192 - cmd.Stderr = os.Stderr 193 - err = cmd.Run() 194 - c.Assert(err, IsNil) 195 -} 196 - 197 -type i18nTestSuite struct { 198 - origLang string 199 - origLcMessages string 200 -} 201 +type i18nTestSuite struct{} 202 203 var _ = Suite(&i18nTestSuite{}) 204 205 -func (s *i18nTestSuite) SetUpTest(c *C) { 206 - // this dir contains a special hand-crafted en_DK/snappy-test.mo 207 - // file 208 - localeDir := c.MkDir() 209 - makeMockTranslations(c, localeDir) 210 - 211 - // we use a custom test mo file 212 - TEXTDOMAIN = "snappy-test" 213 - 214 - s.origLang = os.Getenv("LANG") 215 - s.origLcMessages = os.Getenv("LC_MESSAGES") 216 - 217 - bindTextDomain("snappy-test", localeDir) 218 - os.Setenv("LANG", "en_DK.UTF-8") 219 - setLocale("") 220 -} 221 - 222 -func (s *i18nTestSuite) TearDownTest(c *C) { 223 - os.Setenv("LANG", s.origLang) 224 - os.Setenv("LC_MESSAGES", s.origLcMessages) 225 -} 226 - 227 func (s *i18nTestSuite) TestTranslatedSingular(c *C) { 228 // no G() to avoid adding the test string to snappy-pot 229 var Gtest = G 230 - c.Assert(Gtest("singular"), Equals, "translated singular") 231 + c.Assert(Gtest("singular"), Equals, "singular") 232 } 233 234 func (s *i18nTestSuite) TestTranslatesPlural(c *C) { 235 // no NG() to avoid adding the test string to snappy-pot 236 var NGtest = NG 237 - c.Assert(NGtest("plural_1", "plural_2", 1), Equals, "translated plural_1") 238 -} 239 - 240 -func (s *i18nTestSuite) TestTranslatedMissingLangNoCrash(c *C) { 241 - setLocale("invalid") 242 - 243 - // no G() to avoid adding the test string to snappy-pot 244 - var Gtest = G 245 - c.Assert(Gtest("singular"), Equals, "singular") 246 -} 247 - 248 -func (s *i18nTestSuite) TestInvalidTextDomainDir(c *C) { 249 - bindTextDomain("snappy-test", "/random/not/existing/dir") 250 - setLocale("invalid") 251 - 252 - // no G() to avoid adding the test string to snappy-pot 253 - var Gtest = G 254 - c.Assert(Gtest("singular"), Equals, "singular") 255 -} 256 - 257 -func (s *i18nTestSuite) TestLangpackResolverFromLangpack(c *C) { 258 - root := c.MkDir() 259 - localeDir := filepath.Join(root, "/usr/share/locale") 260 - err := os.MkdirAll(localeDir, 0755) 261 - c.Assert(err, IsNil) 262 - 263 - d := filepath.Join(root, "/usr/share/locale-langpack") 264 - makeMockTranslations(c, d) 265 - bindTextDomain("snappy-test", localeDir) 266 - setLocale("") 267 - 268 - // no G() to avoid adding the test string to snappy-pot 269 - var Gtest = G 270 - c.Assert(Gtest("singular"), Equals, "translated singular", Commentf("test with %q failed", d)) 271 -} 272 - 273 -func (s *i18nTestSuite) TestLangpackResolverFromCore(c *C) { 274 - origSnapMountDir := dirs.SnapMountDir 275 - defer func() { dirs.SnapMountDir = origSnapMountDir }() 276 - dirs.SnapMountDir = c.MkDir() 277 - 278 - d := filepath.Join(dirs.SnapMountDir, "/core/current/usr/share/locale") 279 - makeMockTranslations(c, d) 280 - bindTextDomain("snappy-test", "/usr/share/locale") 281 - setLocale("") 282 - 283 - // no G() to avoid adding the test string to snappy-pot 284 - var Gtest = G 285 - c.Assert(Gtest("singular"), Equals, "translated singular", Commentf("test with %q failed", d)) 286 + c.Assert(NGtest("plural_1", "plural_2", 0), Equals, "plural_2") 287 + c.Assert(NGtest("plural_1", "plural_2", 1), Equals, "plural_1") 288 + c.Assert(NGtest("plural_1", "plural_2", 2), Equals, "plural_2") 289 } 290 -- 291 2.31.1 292