Liu Song’s Projects


~/Projects/chrome-devtools-frontend

git clone https://code.lsong.org/chrome-devtools-frontend

Commit

Commit
855d0d2613ed99fdd22db0821c64da3fcbf4ac8d
Author
Simon Zünd <[email protected]>
Date
2022-11-21 11:15:47 +0100 +0100
Diffstat
 config/gni/i18n.gni | 8 ++
 front_end/core/i18n/BUILD.gn | 20 +++++++
 front_end/core/i18n/collect-ui-strings.js | 65 +++++++++++++++++++++++++

[l10n] Turn en-US.json and en-XL.json into build output

This CL introduces a variant of `collect-strings.js` that can be
invoked from GN and allows more options to be configured via command
line arguments. Also the new variant skips writing the *.ctc.json files
as they are only required for translation but not during runtime.

We can't modify the existing `collect-strings.js` as it's still used
by PRESUBMIT.py and some other l10n infra scripts.

Note that we don't use the generated files just yet. Replacing the
in-tree en-US.json/en-XL.json with these generated ones will happen
later, once we also have implemented minification of the generated
en-US/en-XL.json.

Verified locally that:
  * The output matches exactly the in-tree version (via sha256sum)
  * The build works in a standalone and Chromium integrated build

[email protected], [email protected]

Bug: 1185727
Change-Id: I66c8ca2b7d8f97d554921daa1141ea4b1ce11580
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4040927
Commit-Queue: Simon Zünd <[email protected]>
Reviewed-by: Jack Franklin <[email protected]>
Reviewed-by: Kim-Anh Tran <[email protected]>


diff --git a/config/gni/i18n.gni b/config/gni/i18n.gni
index a80f33e0a143c60d06effc00686f220fa6688b31..c3526fa8225ceedbbd814a3f8b3ad98219a7f0e2 100644
--- a/config/gni/i18n.gni
+++ b/config/gni/i18n.gni
@@ -2,6 +2,8 @@ # Copyright 2022 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.
 
+import("//build/config/devtools.gni")
+
 remote_devtools_locales = [
   "af",
   "am",
@@ -90,7 +92,9 @@   "en-US",
   "zh",
 ]
 
-  "as",
+include_en_xl = is_debug
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
   bundled_devtools_locales += [ "en-XL" ]
 }
 
@@ -103,3 +107,5 @@ # Path relative to i18nImpl.ts. This is because we can't make assumptions
 # wether DevTools is in hosted mode (e.g web tests/e2e tests) or non-hosted
 # mode (devtools://devtools/bundled).
 local_fetch_pattern = "./locales/@[email protected]"
+
+devtools_collection_directories = [ "//$devtools_location/front_end" ]




diff --git a/front_end/core/i18n/BUILD.gn b/front_end/core/i18n/BUILD.gn
index 793b29f512c92ba38d6c8cb41aa759127d10ad20..103548f9ed9beac7ce87cd8f41869d6a25186085 100644
--- a/front_end/core/i18n/BUILD.gn
+++ b/front_end/core/i18n/BUILD.gn
@@ -27,6 +27,7 @@     "../../third_party/intl-messageformat:bundle",
   ]
 
   public_deps = [
+    ":collect_strings",
     ":i18n_bundled_locales",
     ":i18n_locales",
   ]
@@ -74,6 +75,25 @@   if (is_debug) {
     metadata = {
       grd_files = outputs
     }
+  }
+}
+
+node_action("collect_strings") {
+  script = "front_end/core/i18n/collect-ui-strings.js"
+
+  args = [ "--input-directories" ]
+  foreach(dir, devtools_collection_directories) {
+    args += [ rebase_path(dir, root_build_dir) ]
+  }
+  args += [
+    "--output-directory",
+    rebase_path("$target_gen_dir/locales/generated"),
+  ]
+
+  outputs = [ "$target_gen_dir/locales/generated/en-US.json" ]
+  if (include_en_xl) {
+    args += [ "--include-en-xl" ]
+    outputs += [ "$target_gen_dir/locales/generated/en-XL.json" ]
   }
 }
 




diff --git a/front_end/core/i18n/collect-ui-strings.js b/front_end/core/i18n/collect-ui-strings.js
new file mode 100644
index 0000000000000000000000000000000000000000..edd1196be31caf9a970a48901d8e5e6cd4bb3f01
--- /dev/null
+++ b/front_end/core/i18n/collect-ui-strings.js
@@ -0,0 +1,65 @@
+// Copyright 2022 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.
+
+const path = require('path');
+
+const {collectAllStringsInDir, createPsuedoLocaleStrings} = require('../../../third_party/i18n/collect-strings.js');
+const {bakePlaceholders} = require('../../../third_party/i18n/bake-ctc-to-lhl.js');
+const {writeIfChanged} = require('../../../scripts/build/ninja/write-if-changed.js');
+
+/** @typedef {import('../../../third_party/i18n/bake-ctc-to-lhl.js').CtcMessage} CtcMessage */
+
+const yargsObject = require('yargs')
+                        .option('input-directories', {
+                          type: 'array',
+                          demandOption: true,
+                        })
+                        .option('output-directory', {
+                          type: 'string',
+                          demandOption: true,
+                        })
+                        .option('include-en-xl', {
+                          type: 'boolean',
+                        })
+                        .strict()
+                        .argv;
+
+/**
+ * @param {string} outputDirectory
+ * @param {string} locale
+ * @param {Record<string, CtcMessage>} strings
+ */
+function convertCtcToLhLAndSave(outputDirectory, locale, strings) {
+  const outputPath = path.join(outputDirectory, `${locale}.json`);
+
+  /** @type {Record<string, CtcMessage>} */
+  const sortedCtcStrings = {};
+  const sortedEntries = Object.entries(strings).sort(([keyA], [keyB]) => keyA.localeCompare(keyB));
+  for (const [key, defn] of sortedEntries) {
+    sortedCtcStrings[key] = defn;
+  }
+
+  const convertedStrings = bakePlaceholders(sortedCtcStrings);
+  writeIfChanged(outputPath, JSON.stringify(convertedStrings, null, 2) + '\n');
+}
+
+const inputDirectories = yargsObject['input-directories'];
+if (inputDirectories.length === 0) {
+  throw new Error('Provide at least one directory!');
+}
+
+/** @type {Record<string, CtcMessage} */
+let collectedStrings = {};
+for (const directory of inputDirectories) {
+  collectedStrings = {
+    ...collectedStrings,
+    ...collectAllStringsInDir(directory),
+  };
+}
+
+const outputDirectory = yargsObject['output-directory'];
+convertCtcToLhLAndSave(outputDirectory, 'en-US', collectedStrings);
+if (yargsObject['include-en-xl']) {
+  convertCtcToLhLAndSave(outputDirectory, 'en-XL', createPsuedoLocaleStrings(collectedStrings));
+}