Exporting translations to a Bazaar branch

There used to be only one way of exporting translations from Launchpad—by requesting your files in the Launchpad UI and waiting for an email with the download URL.  It works, but it’s not very convenient if you’re trying to automate things.  It’s not that easy to make the request automatically, and then right in the middle of your script you also have to wait for the email, catch it, and parse it to get the file.

Now there’s another option: automatic exports to a Bazaar branch.  If you set up this option, Launchpad will regularly produce a snapshot of your translations and commit it to a Launchpad-hosted branch of your choice.  Now you can always find a reasonably fresh export of your translations in the same place, and download it automatically, without any asynchronous requests.

It also means that large numbers of developers or translators can get regular, fresh updates of the translation files.

How to use it

Let’s say you have a project called bzamqi. It’s set up for translation in Launchpad, and you want regular translation exports of the 1.0 release series.

The first thing you need is a branch.  It doesn’t have to be a branch for the bzamqi project, but you do have to be the owner.  (The branch can belong to a team, but then you do need to be a direct or indirect member of that team.)  The Launchpad help wiki describes various ways to create a branch:

  • https://help.launchpad.net/Code/UploadingABranch
  • https://help.launchpad.net/Code/TeamBranches
  • https://help.launchpad.net/Code/PersonalBranches

Just remember that the branch must be Hosted, i.e. the master branch must be stored on Launchpad where we can commit to it.

Update: at the moment, team-owned branches don’t work. To work around this, make yourself the owner of the branch; set it as the translations branch; and then make the team the owner of the branch again.

Now, go to the page for bzamqi’s 1.0 release series.  You’ll be wanting the Translations tab.  Once there, pick the Settings option.

On the page that takes you to, near the bottom, there’s a section “Export translations to branch.”  You can set a branch there, and translations for the series will be exported to that branch.

If you want to disable the exports, go back (use the “pencil” icon next to the branch name to select a different branch) and select no branch at all.  Just clear the input field.  The settings page will go back to how it was before you selected a branch.

How it works

The main thing to grok is that this is not Launchpad “editing” text files for you.  The export brutally overwrites any previous versions of the files in your branch.  In the file that Launchpad writes, translations may have changed—but messages may also appear in a different order, or with different comments, and so on.

So do not expect files that you can merge back into the originals without any further work!  The Launchpad database and bzr have completely different views of this data.  There is a trick though; see the “Advanced” bit below.  Also, it will help to keep the messages in translation files in the same order in which they appear in the template.

Directory layout

In the branch, each translation file will have a normalized name (de.po for a German translation, zh_CN.po for Simplified Chinese, eo.po for Esperanto, and so on).  Each translation sits in the same directory where its template was on import.

If you have multiple templates, make sure that they have different directory paths, or the translation files for one will overwrite those for the other!  It was already recommended practice to give each template its own directory.

Templates are not exported.

Advanced: going two-way

It is possible to import translations from and export translations to the same branch.  If you push changes to a translation file into the branch, the export will not overwrite the changed file unless your updated file has already been copied onto the translations import queue.

Of course it’s still possible for the import to fail for whatever reason, and in that case your file will be overwritten.  This hopefully won’t hurt; the file that’s being exported is “better” in the sense that it shouldn’t cause any import errors.  But it may not always be what you want, so be careful if you do choose this setup.

(Your templates will not be touched, since the export doesn’t write them.)

Don’t use this “two-way” setup lightly, since it complicates things.  Complications are where accidents happen.  Either wait until there’s more practical experience with this, or make sure in some way that you won’t lose data if something goes horribly wrong.

A bit less adventurous but still useful is to have only your templates imported from a branch, and have your translations committed to the same branch.


How often do the exports happen?

For now, once a day.  We may tweak that later depending on how much this feature is used and how heavily it loads the servers.

If the export runs at a moment when you’ve pushed changes into the branch that Launchpad hasn’t processed yet, the export will not happen.  This is a deliberate protection against conflicting updates.  Unless you update your branch all the time or just at the wrong time of day, the next day’s export should catch up with the latest changes.

Why do I need to own the branch?

Otherwise you would be making Launchpad write data into someone else’s branch.  Not a nice thing to do to someone who isn’t expecting it!

If you want someone else to own the branch, you can change who owns it later, using the normal branch settings UI.  You only need to be the owner when you set it as the translations export branch.

What happens if I leave the project?

The exports keep happening to the same branch.  If that is not what you want, it’s up to the remaining project owners to choose a different branch or disable the exports.

4 Responses to “Exporting translations to a Bazaar branch”

  1. Mike Rooney Says:

    This is quite excellent and I’ve blogged about it at http://mrooney.blogspot.com/2009/07/launchpad-is-now-automatic-magical.html . I do have a question though: would it be possible to have an option just like in the manual export for choosing between po and mo format?

    As a developer of a project native to Launchpad, I don’t ever care about .po[t] files, I just run xgettext, commit, and want Launchpad to take care of the rest. If gettext requires .mo files, I just want Launchpad to commit them to the right place so I don’t have to manually compile them each time.

    Also, it would be super excellent in the future to allow Launchpad to create the template automatically from the code, as I’m only running a command to generate the .pot file and giving it to LP, but I don’t actually do anything with it, so it would be slick if Rosetta could generate the template itself! Basically I think to make things easier for developers, once the framework is set up, all they should have to do is wrap new strings appropriately and Launchpad should handle everything else.

    Does this make sense or am I doing it wrong?

  2. Jeroen Vermeulen Says:

    Mike: I’m so glad you like it! The MO files are a great idea. I just filed it here: https://bugs.launchpad.net/rosetta/+bug/407581

    We have discussed creating the templates automatically. There’s enough room for customization and scripting there that we couldn’t do it for the general case. We could probably cover the usual case though.

    It looks like the bzr integration opened the door to a whole laundry list of new feature ideas: linking from the translation page to the source code, automatic template generation, and even managing Ubuntu’s translations through bzr branches.

    Now that our source code is public, maybe some people out there could even help us implement some of these. It’s never as simple as it looks—pre-implementation discussion, UI design, testing, reviews—but that’s why we need this all the more.

  3. Dylan McCall Says:

    So, what is the best plan for a separate branch that Launchpad pushes translations to? I’m thinking this from the perspective of getting those translations back to the main branch. I would love to use bzr merge from it, but that wouldn’t work if I just create an empty branch with the init command.

  4. Jeroen Vermeulen Says:

    Dylan: yes, if you want to merge between branches the two branches have to be related. So if you want to merge translations back into your development branch, export to a branch that you create by branching off the development branch.

    The first merges will be a bit harder, since the export may change the ordering of messages and such.

Leave a Reply