diff options
author | jamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-24 17:13:20 +0000 |
---|---|---|
committer | jamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-24 17:13:20 +0000 |
commit | 99d88771a76f5355e4cc271f501880ddd8cc64b4 (patch) | |
tree | 010041ea0b52d0b6d4234aba6ec2c508ed0e290a | |
parent | ac239a8025e5d779f9372a0fe559e8c1ce1e42f7 (diff) | |
download | chromium_src-99d88771a76f5355e4cc271f501880ddd8cc64b4.zip chromium_src-99d88771a76f5355e4cc271f501880ddd8cc64b4.tar.gz chromium_src-99d88771a76f5355e4cc271f501880ddd8cc64b4.tar.bz2 |
Add build step to verify the l10n strings are not out of sync.
BUG=None
TEST=Manual
Review URL: http://codereview.chromium.org/7631055
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98064 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | remoting/host/plugin/host_script_object.cc | 22 | ||||
-rw-r--r-- | remoting/remoting.gyp | 25 | ||||
-rw-r--r-- | remoting/webapp/me2mom/remoting.js | 12 | ||||
-rwxr-xr-x | remoting/webapp/verify-webapp.py | 107 |
4 files changed, 151 insertions, 15 deletions
diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc index b02135d..d1f65af 100644 --- a/remoting/host/plugin/host_script_object.cc +++ b/remoting/host/plugin/host_script_object.cc @@ -651,22 +651,26 @@ void HostNPScriptObject::LocalizeStrings() { LocalizeString("@@bidi_dir", &direction); ui_strings.direction = UTF16ToUTF8(direction) == "rtl" ? remoting::UiStrings::RTL : remoting::UiStrings::LTR; - LocalizeString("PRODUCT_NAME", &ui_strings.product_name); - LocalizeString("DISCONNECT_BUTTON", &ui_strings.disconnect_button_text); + LocalizeString(/*i18n-content*/"PRODUCT_NAME", &ui_strings.product_name); + LocalizeString(/*i18n-content*/"DISCONNECT_BUTTON", + &ui_strings.disconnect_button_text); LocalizeString( #if defined(OS_WIN) - "DISCONNECT_BUTTON_PLUS_SHORTCUT_WINDOWS", + /*i18n-content*/"DISCONNECT_BUTTON_PLUS_SHORTCUT_WINDOWS", #elif defined(OS_MAC) - "DISCONNECT_BUTTON_PLUS_SHORTCUT_MAC_OS_X", + /*i18n-content*/"DISCONNECT_BUTTON_PLUS_SHORTCUT_MAC_OS_X", #else - "DISCONNECT_BUTTON_PLUS_SHORTCUT_LINUX", + /*i18n-content*/"DISCONNECT_BUTTON_PLUS_SHORTCUT_LINUX", #endif &ui_strings.disconnect_button_text_plus_shortcut); - LocalizeString("CONTINUE_PROMPT", &ui_strings.continue_prompt); - LocalizeString("CONTINUE_BUTTON", &ui_strings.continue_button_text); - LocalizeString("STOP_SHARING_BUTTON", + LocalizeString(/*i18n-content*/"CONTINUE_PROMPT", + &ui_strings.continue_prompt); + LocalizeString(/*i18n-content*/"CONTINUE_BUTTON", + &ui_strings.continue_button_text); + LocalizeString(/*i18n-content*/"STOP_SHARING_BUTTON", &ui_strings.stop_sharing_button_text); - LocalizeString("MESSAGE_SHARED", &ui_strings.disconnect_message); + LocalizeString(/*i18n-content*/"MESSAGE_SHARED", + &ui_strings.disconnect_message); host_->SetUiStrings(ui_strings); } diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 91eed9a..8a16164 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -235,6 +235,7 @@ ], 'sources': [ 'webapp/build-webapp.py', + 'webapp/verify-webapp.py', '<@(remoting_it2me_files)', '<@(remoting_it2me_os_files)', '<@(remoting_it2me_locale_files)', @@ -247,6 +248,30 @@ # when the actual project is generated. 'actions': [ { + 'action_name': 'Verify It2Me WebApp i18n', + 'inputs': [ + 'webapp/verify-webapp.py', + 'webapp/me2mom/_locales/en/messages.json', + 'webapp/me2mom/choice.html', + 'webapp/me2mom/manifest.json', + 'webapp/me2mom/remoting.js', + 'host/plugin/host_script_object.cc', + ], + 'outputs': [ + '<(PRODUCT_DIR)/remoting/it2me_verified.stamp', + ], + 'action': [ + 'python', + 'webapp/verify-webapp.py', + '<(PRODUCT_DIR)/remoting/it2me_verified.stamp', + 'webapp/me2mom/_locales/en/messages.json', + 'webapp/me2mom/choice.html', + 'webapp/me2mom/manifest.json', + 'webapp/me2mom/remoting.js', + 'host/plugin/host_script_object.cc', + ], + }, + { 'action_name': 'Build It2Me WebApp', 'output_dir': '<(PRODUCT_DIR)/remoting/it2me.webapp', 'plugin_path': '<(PRODUCT_DIR)/<(plugin_prefix)remoting_host_plugin.<(plugin_extension)', diff --git a/remoting/webapp/me2mom/remoting.js b/remoting/webapp/me2mom/remoting.js index c1736e6..3165fe5 100644 --- a/remoting/webapp/me2mom/remoting.js +++ b/remoting/webapp/me2mom/remoting.js @@ -40,11 +40,11 @@ remoting.HOST_PLUGIN_ID = 'host-plugin-id'; /** @enum {string} */ remoting.ClientError = { - NO_RESPONSE: 'ERROR_NO_RESPONSE', - INVALID_ACCESS_CODE: 'ERROR_INVALID_ACCESS_CODE', - MISSING_PLUGIN: 'ERROR_MISSING_PLUGIN', - OAUTH_FETCH_FAILED: 'ERROR_AUTHENTICATION_FAILED', - OTHER_ERROR: 'ERROR_GENERIC' + NO_RESPONSE: /*i18n-content*/'ERROR_NO_RESPONSE', + INVALID_ACCESS_CODE: /*i18n-content*/'ERROR_INVALID_ACCESS_CODE', + MISSING_PLUGIN: /*i18n-content*/'ERROR_MISSING_PLUGIN', + OAUTH_FETCH_FAILED: /*i18n-content*/'ERROR_AUTHENTICATION_FAILED', + OTHER_ERROR: /*i18n-content*/'ERROR_GENERIC' }; /** @@ -626,7 +626,7 @@ remoting.promptClose = function() { case remoting.AppMode.HOST_WAITING_FOR_CONNECTION: case remoting.AppMode.HOST_SHARED: case remoting.AppMode.IN_SESSION: - var result = chrome.i18n.getMessage('CLOSE_PROMPT'); + var result = chrome.i18n.getMessage(/*i18n-content*/'CLOSE_PROMPT'); return result; default: return NULL; diff --git a/remoting/webapp/verify-webapp.py b/remoting/webapp/verify-webapp.py new file mode 100755 index 0000000..2defa94 --- /dev/null +++ b/remoting/webapp/verify-webapp.py @@ -0,0 +1,107 @@ +#!/usr/bin/python +# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Verifies that a given messages.json file defines all the strings used by the +a given set of files. For file formats where it is not possible to infer which +strings represent message identifiers, localized strings should be explicitly +annotated with the string "i18n-content", for example: + + LocalizeString(/*i18n-content*/"PRODUCT_NAME"); + +This script also recognises localized strings in HTML and manifest.json files: + + HTML: <span i18n-content="PRODUCT_NAME"></span> + manifest.json: __MSG_PRODUCT_NAME__ + +Note that these forms must be exact; extra spaces are not permitted, though +either single or double quotes are recognized. + +In addition, the script checks that all the messages are still in use; if +this is not the case then a warning is issued, but the script still succeeds. +""" + +import json +import os +import re +import sys + +all_tags = set([]) + +WARNING_MESSAGE = """ +To remove this warning, either remove the unused tags from +messages.json, add the files that use the tags listed above to +remoting.gyp, or annotate existing uses of those tags with the +prefix /*i18n-content*/ +""" + + +def ExtractTagFromLine(line): + """Extract a tag from a line of HTML, C++, JS or JSON.""" + # HTML-style + m = re.search('i18n-content=[\'"]([^\'"]*)[\'"]', line) + if m: return m.group(1) + # C++/Javascript style + m = re.search('/\*i18n-content\*/[\'"]([^\`"]*)[\'"]', line) + if m: return m.group(1) + # Manifest style + m = re.search('__MSG_(.*)__', line) + if m: return m.group(1) + return None + + +def CheckFileForUnknownTag(filename, messages): + """Parse |filename|, looking for tags and report any that are not included in + |messages|. Return True if all tags are present and correct, or False if + any are missing. If no tags are found, print a warning message and return + True.""" + result = True + matches = False + f = open(filename, 'r') + lines = f.readlines() + for i in xrange(0, len(lines)): + tag = ExtractTagFromLine(lines[i]) + if tag: + all_tags.add(tag) + matches = True + if not tag in messages: + result = False + print 'remoting/%s:%d: Error: Undefined tag: %s' % (filename, i + 1, + tag) + if not matches: + print 'remoting/%s: Warning: No tags found' % filename + f.close() + return result + + +def main(): + if len(sys.argv) < 4: + print 'Usage: verify-webapp.py <touch> <messages> <message_users...>' + sys.exit(1) + + touch_file = sys.argv[1] + messages = json.load(open(sys.argv[2], 'r')) + exit_code = 0 + for f in sys.argv[3:]: + if not CheckFileForUnknownTag(f, messages): + exit_code = 1 + + warnings = False + for tag in messages: + if tag not in all_tags: + print 'Warning: ' + tag + ' is defined but not used' + warnings = True + if warnings: + print WARNING_MESSAGE + + if exit_code == 0: + f = open(touch_file, 'a') + f.close() + os.utime(touch_file, None) + + sys.exit(exit_code) + + +if __name__ == '__main__': + main() |