L20n/Toolchain
L20n provides a basic command-line tool set for localizers, developers, and localization maintainers (aka release drivers).
The toolchain enables all three parties to:
- start a new localization project
- learn about the status of one or more localizations
- learn about what has to be done for the localization to be completed
- aid in updating localizations to a given version of product string set
- manage complete localizations for release purposes
Basic concepts
The toolchain is written in python and is made of library code and command line scripts. Command line scripts are meant to be used directly by end users, while the library code behind them constitutes an API for tool developers to build on top of.
Second design decision is to leave the process details open to particular project preference. The way the project structures the localization directories, what files are part of localization pack etc. are just stored within the project cfg file that l20n toolchain reads from. It also executes particular code for each project for things like bootstrapping new locale or updating an existing one.
In particular it works like this:
- a project has to have a single l10n.cfg file in /config directory
- the file has to point to particular API code that will be executed as part of toolchain commands
- and any additional settings for the given project (like, which locale is a source one)
Commands
We probably will use some sort of activate code to shake the path and prompt line to improve the l10n operations experience.
Initially we offer three scripts:
l10n-bootstrap
gandalf@peacesaw> mkdir ./fr gandalf@peacesaw> cd ./fr gandalf@peacesaw> activate-l10n gandalf@peacesaw [l10n]> bootstrap-locale mozilla/gaia fr gandalf@peacesaw [l10n:mozilla/gaia:fr:0%]>
The result is a new directory "fr" that contains the whole structure of files that have to be localized.
l10n-status
gandalf@peacesaw> activate-l10n gandalf@peacesaw [l10n]> cd ./fr gandalf@peacesaw [l10n:mozilla/gaia:fr:6%]> status Project: mozilla/gaia Locale: fr Branch: nightly Translated: 5.6% (59/1050) Untranslated: 90.5 (950/1050) Obsolete: 3.6% (38/1050) Missing: 0.3 (3/1050)
gandalf@peacesaw [l10n:mozilla/gaia:fr:5%]> status --show-tree Project: mozilla/gaia Locale: fr Branch: nightly Translated: 5.6% (59/1050) Untranslated: 90.5 (950/1050) Obsolete: 3.6% (38/1050) Missing: 0.3 (3/1050) fr homescreen homescreen.lol: ~welcomeMsg +title +noSimCard +missing -oldEntity
l10n-update
gandalf@peacesaw> activate-l10n gandalf@peacesaw [l10n]> cd ./fr gandalf@peacesaw [l10n:mozilla/gaia:fr:6%]> update-locale --test Project: mozilla/gaia Locale: fr Branch: nightly before the update, the status is: Translated: 5.6% (59/1050) Untranslated: 90.5 (950/1050) Obsolete: 3.6% (38/1050) Missing: 0.3 (3/1050) the update will: Bring new entities: 25 Make entities obsolete: 10 Update the content of entities: 1
gandalf@peacesaw [l10n:mozilla/gaia:fr:6%]> update-locale --test --show-tree Project: mozilla/gaia Locale: fr Branch: nightly before the update, the status is: Translated: 5.6% (59/1050) Untranslated: 90.5 (950/1050) Obsolete: 3.6% (38/1050) Missing: 0.3 (3/1050) the update will: Bring new entities: 3 Make entities obsolete: 2 Update the content of entities: 1 tree: homescreen homescreen.lol: +clickMe +windowTitle +phisingProtection -oldEntity -welcomeMsg ~helloWorld value: "Hello World" -> "Welcome World"
gandalf@peacesaw [l10n:mozilla/gaia:fr:6%]> update-locale homescreen: homescreen.lol | 6 ++++++ 1 file changed, 3 entities added, 2 marked as obsolete, 1 updated
gandalf@peacesaw [l10n:mozilla/gaia:fr:6%]> update-locale -path homescreen/homescreen.lol --all homescreen: homescreen.lol fr | 6 ++++++ de | 5 +++++ it | 6 ++++++ pt-BR | 6 ++++++
validate
gandalf@peacesaw> activate-l10n gandalf@peacesaw [l10n]> cd ./fr gandalf@peacesaw [l10n:mozilla/gaia:fr:5%]> validate homescreen/homescreen.lol Test of homescreen/homescreen.lol OK
gandalf@peacesaw [l10n:mozilla/gaia:fr:5%]> validate --show-ast homescreen/homescreen.lol [LOL] .body [Entity] .id[Identifier] .name[str="noSimCard"] .value[String] .content[str="No SIM card"] .attrs [KeyValuePair] .key[Identifier] .name[str="foo"] .value[String] .content[str="test"]