Skip to content

Commit 911d49b

Browse files
committed
Added CLI argument --fallback-to-default
1 parent 31ebc40 commit 911d49b

File tree

5 files changed

+87
-3
lines changed

5 files changed

+87
-3
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[[Main]]
2+
3+
[value_with_local_lang_codes]
4+
en = Bar
5+
es = Bar
6+
es-MX = Bar
7+
pt = Bar
8+
pt-BR = Bar
9+
10+
[value_with_duplicated]
11+
en = NULL
12+
de = NULL
13+
fr = Avant
14+

python_twine/tests/test_twine_file.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def test_write_file(self):
203203
Path(temp_path).unlink()
204204

205205

206-
class TestWriter:
206+
class TestTwineFileReader:
207207
@pytest.fixture
208208
def fixtures_dir(self):
209209
"""Get fixtures directory path."""
@@ -219,5 +219,42 @@ def test_accent_symbol(self, fixtures_dir):
219219
assert twine_file.definitions_by_key["value_wrapped_by_spaces"].translations["en"] == ' value '
220220
assert twine_file.definitions_by_key["value_wrapped_by_accents"].translations["en"] == '`value`'
221221

222+
class TestTwineFileOptimizations:
223+
@pytest.fixture
224+
def fixture_twine_file(self) -> TwineFile:
225+
twine_file = TwineFile()
226+
fixtures_dir = Path(__file__).parent / "fixtures"
227+
twine_file.read(str(fixtures_dir / "twine_preoptimized.txt"))
228+
return twine_file
229+
230+
def test_deduplication_local_langs(self, fixture_twine_file: TwineFile):
231+
definitionA = fixture_twine_file.definitions_by_key['value_with_local_lang_codes']
232+
assert definitionA.translations['pt'] == definitionA.translations['pt-BR']
233+
assert definitionA.translations['es'] == definitionA.translations['es-MX']
234+
235+
fixture_twine_file.fallback_to_default = False
236+
fixture_twine_file.optimize_duplicates()
237+
238+
# Check that 'pt-BR' and 'es-MX' are removed from the TwineFile
239+
definitionA = fixture_twine_file.definitions_by_key['value_with_local_lang_codes']
240+
assert 'pt-BR' not in definitionA.translations
241+
assert 'pt' in definitionA.translations
242+
assert 'es-MX' not in definitionA.translations
243+
assert 'es' in definitionA.translations
244+
assert definitionA.translations['es'] == definitionA.translations['en']
245+
246+
def test_deduplication_default_lang(self, fixture_twine_file: TwineFile):
247+
definitionB = fixture_twine_file.definitions_by_key['value_with_duplicated']
248+
assert definitionB.translations['en'] == definitionB.translations['de']
249+
250+
fixture_twine_file.fallback_to_default = True
251+
fixture_twine_file.optimize_duplicates()
252+
253+
# Check that 'de' lang is removed from the TwineFile because it matches 'en'
254+
definitionB = fixture_twine_file.definitions_by_key['value_with_duplicated']
255+
assert 'de' not in definitionB.translations
256+
assert 'fr' in definitionB.translations
257+
258+
222259
if __name__ == "__main__":
223260
pytest.main([__file__, "-v"])

python_twine/twine/cli.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ def create_parser() -> argparse.ArgumentParser:
6363
)
6464
consume_file.add_argument("twine_file", help="Path to Twine data file")
6565
consume_file.add_argument("input_path", help="Input file path")
66+
consume_file.add_argument(
67+
"--fallback-to-default",
68+
action="store_true",
69+
help="Remove translations matching default language",
70+
)
6671
CLI._add_common_arguments(consume_file)
6772
CLI._add_language_argument(consume_file)
6873
CLI._add_consume_arguments(consume_file)
@@ -74,6 +79,11 @@ def create_parser() -> argparse.ArgumentParser:
7479
)
7580
consume_all.add_argument("twine_file", help="Path to Twine data file")
7681
consume_all.add_argument("input_path", help="Input directory path")
82+
consume_all.add_argument(
83+
"--fallback-to-default",
84+
action="store_true",
85+
help="Remove translations matching default language",
86+
)
7787
consume_all.add_argument(
7888
"-n", "--file-name", help="Input file name (default: format-specific)"
7989
)

python_twine/twine/runner.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ def consume_localization_file(self):
172172
if self.options.get("languages"):
173173
lang = self.options["languages"][0]
174174

175+
if bool(self.options.get("fallback_to_default")):
176+
self.twine_file.fallback_to_default = True
177+
175178
formatter, lang = self._prepare_read_write(self.options["input_path"], lang)
176179

177180
with open(self.options["input_path"], "r", encoding="UTF-8") as f:
@@ -191,6 +194,9 @@ def consume_all_localization_files(self):
191194
if not input_path.is_dir():
192195
raise TwineError(f"Directory does not exist: {input_path}")
193196

197+
if bool(self.options.get("fallback_to_default")):
198+
self.twine_file.fallback_to_default = True
199+
194200
formatter = self._get_formatter()
195201

196202
files_consumed = 0

python_twine/twine/twine_file.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,27 @@ def __init__(self, name: str):
170170
class TwineFile:
171171
"""Main Twine data file containing sections and definitions."""
172172

173-
def __init__(self):
173+
def __init__(self, fallback_to_default:bool = False):
174+
"""
175+
:param fallback_to_default: indicates if TwineFile optimization should deduplicate
176+
languages matching default (English) value.
177+
178+
For example in next strings 'es' should not be removed (fallback_to_default = False)
179+
[bar]
180+
en = Bar
181+
es = Bar
182+
uk = Bar
183+
184+
While in next sample all languages except 'en' should be removed (fallback_to_default = True)
185+
[take_exit_number_street_verb]
186+
en = NULL
187+
de = NULL
188+
nl = NULL
189+
"""
174190
self.sections: List[TwineSection] = []
175191
self.definitions_by_key: Dict[str, TwineDefinition] = {}
176192
self.language_codes: List[str] = []
193+
self.fallback_to_default = fallback_to_default
177194

178195
def add_language_code(self, code: str):
179196
"""Add a language code, maintaining developer language at position 0."""
@@ -218,7 +235,7 @@ def optimize_duplicates(self):
218235

219236
def match_fallback_lang(self, translations: dict, lang:str, key:str, value: Any) -> bool:
220237
# TODO: this method is invoked for each key and lang. Optimize: cache all fallback languages in a dict
221-
for fallback_lang in self.fallback_languages(lang):
238+
for fallback_lang in self.fallback_languages(lang, self.fallback_to_default):
222239
if translations.get(fallback_lang) == value:
223240
print(f"Warning: key '{key}' in lang '{lang}' matches value from fallback language '{fallback_lang}'")
224241
return True

0 commit comments

Comments
 (0)