summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-24 17:13:20 +0000
committerjamiewalch@google.com <jamiewalch@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-24 17:13:20 +0000
commit99d88771a76f5355e4cc271f501880ddd8cc64b4 (patch)
tree010041ea0b52d0b6d4234aba6ec2c508ed0e290a
parentac239a8025e5d779f9372a0fe559e8c1ce1e42f7 (diff)
downloadchromium_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.cc22
-rw-r--r--remoting/remoting.gyp25
-rw-r--r--remoting/webapp/me2mom/remoting.js12
-rwxr-xr-xremoting/webapp/verify-webapp.py107
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()