From ead0ee9f657f30121cc95faa32e04ae9e356d36c Mon Sep 17 00:00:00 2001 From: Bamieh Date: Tue, 16 Apr 2019 22:28:32 +0300 Subject: [PATCH 01/18] scan node_modules/@kbn directory for i18n --- src/legacy/server/i18n/index.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/legacy/server/i18n/index.js b/src/legacy/server/i18n/index.js index 6377fc093dbca..cf955e0d01baf 100644 --- a/src/legacy/server/i18n/index.js +++ b/src/legacy/server/i18n/index.js @@ -27,10 +27,16 @@ export async function i18nMixin(kbnServer, server, config) { const locale = config.get('i18n.locale'); // eslint-disable-next-line max-len - const translationsDirs = [fromRoot('src/legacy/ui/translations'), fromRoot('src/legacy/server/translations'), fromRoot('src/core/translations')]; + const translationsDirs = [ + fromRoot('src/legacy/ui/translations'), + fromRoot('src/legacy/server/translations'), + fromRoot('src/core/translations'), + ]; + + const scanDirs = config.get('plugins.scanDirs').concat([fromRoot('node_modules/@kbn')]); const groupedEntries = await Promise.all([ - ...config.get('plugins.scanDirs').map(async path => { + ...scanDirs.map(async path => { const entries = await globby(`*/translations/${locale}.json`, { cwd: path, }); From b2b6cbc349d5460e7dd0ac49a7e0c59a608eff89 Mon Sep 17 00:00:00 2001 From: Bamieh Date: Tue, 16 Apr 2019 22:31:47 +0300 Subject: [PATCH 02/18] remove es-lint-disable-next line --- src/legacy/server/i18n/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/legacy/server/i18n/index.js b/src/legacy/server/i18n/index.js index cf955e0d01baf..65dcc8f25e40f 100644 --- a/src/legacy/server/i18n/index.js +++ b/src/legacy/server/i18n/index.js @@ -26,7 +26,6 @@ import { fromRoot } from '../../utils'; export async function i18nMixin(kbnServer, server, config) { const locale = config.get('i18n.locale'); - // eslint-disable-next-line max-len const translationsDirs = [ fromRoot('src/legacy/ui/translations'), fromRoot('src/legacy/server/translations'), From a29c6cf36a9e216d8c0ab67501d0bb485db1f2f5 Mon Sep 17 00:00:00 2001 From: Bamieh Date: Thu, 25 Apr 2019 14:42:01 +0300 Subject: [PATCH 03/18] update paths --- src/legacy/server/i18n/index.js | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/legacy/server/i18n/index.js b/src/legacy/server/i18n/index.js index 65dcc8f25e40f..85bffd90fb306 100644 --- a/src/legacy/server/i18n/index.js +++ b/src/legacy/server/i18n/index.js @@ -21,21 +21,11 @@ import { resolve } from 'path'; import globby from 'globby'; import { i18n, i18nLoader } from '@kbn/i18n'; -import { fromRoot } from '../../utils'; - export async function i18nMixin(kbnServer, server, config) { const locale = config.get('i18n.locale'); - const translationsDirs = [ - fromRoot('src/legacy/ui/translations'), - fromRoot('src/legacy/server/translations'), - fromRoot('src/core/translations'), - ]; - - const scanDirs = config.get('plugins.scanDirs').concat([fromRoot('node_modules/@kbn')]); - const groupedEntries = await Promise.all([ - ...scanDirs.map(async path => { + ...config.get('plugins.scanDirs').map(async path => { const entries = await globby(`*/translations/${locale}.json`, { cwd: path, }); @@ -51,13 +41,6 @@ export async function i18nMixin(kbnServer, server, config) { ); return entries.map(entry => resolve(path, entry)); }), - - ...translationsDirs.map(async path => { - const entries = await globby(`${locale}.json`, { - cwd: path, - }); - return entries.map(entry => resolve(path, entry)); - }), ]); const translationPaths = [].concat(...groupedEntries); From 2464a0369befd66dce3eb5d679fdb24297f29dde Mon Sep 17 00:00:00 2001 From: Bamieh Date: Wed, 26 Jun 2019 16:28:41 +0300 Subject: [PATCH 04/18] look inside .i18nrc.json instead of traversing files --- config/kibana.yml | 4 +- src/dev/build/tasks/copy_source_task.js | 1 + src/legacy/server/i18n/index.js | 56 +++++++++++++++++-------- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/config/kibana.yml b/config/kibana.yml index 218c32b8f680a..a40d3dff2e7c0 100644 --- a/config/kibana.yml +++ b/config/kibana.yml @@ -111,5 +111,5 @@ #ops.interval: 5000 # Specifies locale to be used for all localizable strings, dates and number formats. -# Supported languages are the following: English - en , by default , Chinese - zh-CN . -#i18n.locale: "en" +# Supported languages are the following: English - en , by default , Chinese - zh-CN . +i18n.locale: "ja-JP" diff --git a/src/dev/build/tasks/copy_source_task.js b/src/dev/build/tasks/copy_source_task.js index 472bf3143bbf9..e487ac0567f76 100644 --- a/src/dev/build/tasks/copy_source_task.js +++ b/src/dev/build/tasks/copy_source_task.js @@ -47,6 +47,7 @@ export const CopySourceTask = { 'webpackShims/**', 'config/kibana.yml', 'tsconfig*.json', + '.i18nrc.json', 'kibana.d.ts' ], }); diff --git a/src/legacy/server/i18n/index.js b/src/legacy/server/i18n/index.js index 85bffd90fb306..7ad2ce58c0ec6 100644 --- a/src/legacy/server/i18n/index.js +++ b/src/legacy/server/i18n/index.js @@ -20,31 +20,51 @@ import { resolve } from 'path'; import globby from 'globby'; import { i18n, i18nLoader } from '@kbn/i18n'; +import { readFile } from 'fs'; +import { fromRoot } from '../../utils'; +import { promisify } from 'util'; + +const readFileAsync = promisify(readFile); + +export async function getTranslationPaths({ cwd, glob }) { + const entries = await globby(glob, { cwd }); + + const configFiles = await Promise.all( + entries + .map(entry => resolve(cwd, entry)) + .map(configFilePath => readFileAsync(configFilePath, 'utf8')) + ); + + return configFiles + .map(configFile => JSON.parse(configFile)) + .reduce((acc, configFile) => acc.concat(...configFile.translations), []) + .map(translationPath => resolve(cwd, translationPath)); +} export async function i18nMixin(kbnServer, server, config) { const locale = config.get('i18n.locale'); + const localeRegExp = new RegExp(`${locale}.json$`); - const groupedEntries = await Promise.all([ - ...config.get('plugins.scanDirs').map(async path => { - const entries = await globby(`*/translations/${locale}.json`, { - cwd: path, - }); - return entries.map(entry => resolve(path, entry)); + const translationPaths = await Promise.all([ + getTranslationPaths({ + cwd: fromRoot('.'), + glob: `.i18nrc.json`, }), - - ...config.get('plugins.paths').map(async path => { - const entries = await globby( - [`translations/${locale}.json`, `plugins/*/translations/${locale}.json`], - { - cwd: path, - } - ); - return entries.map(entry => resolve(path, entry)); + getTranslationPaths({ + cwd: fromRoot('plugins'), + glob: `*/.i18nrc.json`, + }), + getTranslationPaths({ + cwd: fromRoot('../kibana-extra'), + glob: `*/.i18nrc.json`, }), ]); - const translationPaths = [].concat(...groupedEntries); - i18nLoader.registerTranslationFiles(translationPaths); + + const currentTranslationPaths = [].concat(...translationPaths) + .filter(translationPath => localeRegExp.test(translationPath)); + + i18nLoader.registerTranslationFiles(currentTranslationPaths); const translations = await i18nLoader.getTranslationsByLocale(locale); i18n.init(Object.freeze({ @@ -52,5 +72,5 @@ export async function i18nMixin(kbnServer, server, config) { ...translations, })); - server.decorate('server', 'getTranslationsFilePaths', () => translationPaths); + server.decorate('server', 'getTranslationsFilePaths', () => currentTranslationPaths); } From 7f371603c8c6f628a778728d6bcd774a2a6c6d8a Mon Sep 17 00:00:00 2001 From: Bamieh Date: Thu, 27 Jun 2019 11:16:48 +0300 Subject: [PATCH 05/18] split .i18nrc file and enhance i18n tooling --- .i18nrc.json | 41 +------------- src/dev/i18n/config.ts | 56 ++++++++++--------- src/dev/i18n/index.ts | 4 +- src/dev/i18n/tasks/check_configs.ts | 43 ++++++++++++++ .../tasks/extract_default_translations.ts | 9 +-- .../tasks/extract_untracked_translations.ts | 12 ++-- src/dev/i18n/tasks/index.ts | 2 + src/dev/i18n/tasks/merge_configs.ts | 43 ++++++++++++++ src/dev/i18n/utils.js | 5 ++ src/dev/run_i18n_check.ts | 35 ++++++++---- src/dev/run_i18n_extract.ts | 20 +++---- src/legacy/server/i18n/index.js | 17 ++++-- x-pack/.i18nrc.json | 43 ++++++++++++++ 13 files changed, 222 insertions(+), 108 deletions(-) create mode 100644 src/dev/i18n/tasks/check_configs.ts create mode 100644 src/dev/i18n/tasks/merge_configs.ts create mode 100644 x-pack/.i18nrc.json diff --git a/.i18nrc.json b/.i18nrc.json index 59d21a5894b4e..ba71d0071f1cf 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -23,45 +23,8 @@ "timelion": "src/legacy/core_plugins/timelion", "tagCloud": "src/legacy/core_plugins/tagcloud", "tsvb": "src/legacy/core_plugins/metrics", - "kbnESQuery": "packages/kbn-es-query", - "xpack.actions": "x-pack/legacy/plugins/actions", - "xpack.alerting": "x-pack/legacy/plugins/alerting", - "xpack.apm": "x-pack/legacy/plugins/apm", - "xpack.beatsManagement": "x-pack/legacy/plugins/beats_management", - "xpack.canvas": "x-pack/legacy/plugins/canvas", - "xpack.code": "x-pack/legacy/plugins/code", - "xpack.crossClusterReplication": "x-pack/legacy/plugins/cross_cluster_replication", - "xpack.dashboardMode": "x-pack/legacy/plugins/dashboard_mode", - "xpack.fileUpload": "x-pack/legacy/plugins/file_upload", - "xpack.graph": "x-pack/legacy/plugins/graph", - "xpack.grokDebugger": "x-pack/legacy/plugins/grokdebugger", - "xpack.idxMgmt": "x-pack/legacy/plugins/index_management", - "xpack.indexLifecycleMgmt": "x-pack/legacy/plugins/index_lifecycle_management", - "xpack.infra": "x-pack/legacy/plugins/infra", - "xpack.kueryAutocomplete": "x-pack/legacy/plugins/kuery_autocomplete", - "xpack.licenseMgmt": "x-pack/legacy/plugins/license_management", - "xpack.maps": "x-pack/legacy/plugins/maps", - "xpack.ml": "x-pack/legacy/plugins/ml", - "xpack.logstash": "x-pack/legacy/plugins/logstash", - "xpack.main": "x-pack/legacy/plugins/xpack_main", - "xpack.telemetry": "x-pack/legacy/plugins/telemetry", - "xpack.monitoring": "x-pack/legacy/plugins/monitoring", - "xpack.remoteClusters": "x-pack/legacy/plugins/remote_clusters", - "xpack.reporting": "x-pack/legacy/plugins/reporting", - "xpack.rollupJobs": "x-pack/legacy/plugins/rollup", - "xpack.searchProfiler": "x-pack/legacy/plugins/searchprofiler", - "xpack.siem": "x-pack/legacy/plugins/siem", - "xpack.security": "x-pack/legacy/plugins/security", - "xpack.server": "x-pack/legacy/server", - "xpack.snapshotRestore": "x-pack/legacy/plugins/snapshot_restore", - "xpack.spaces": "x-pack/legacy/plugins/spaces", - "xpack.upgradeAssistant": "x-pack/legacy/plugins/upgrade_assistant", - "xpack.uptime": "x-pack/legacy/plugins/uptime", - "xpack.watcher": "x-pack/legacy/plugins/watcher" + "kbnESQuery": "packages/kbn-es-query" }, "exclude": ["src/legacy/ui/ui_render/ui_render_mixin.js"], - "translations": [ - "x-pack/plugins/translations/translations/zh-CN.json", - "x-pack/plugins/translations/translations/ja-JP.json" - ] + "translations": [] } diff --git a/src/dev/i18n/config.ts b/src/dev/i18n/config.ts index 0327e2ea1b688..b2beb5c5bff99 100644 --- a/src/dev/i18n/config.ts +++ b/src/dev/i18n/config.ts @@ -20,46 +20,48 @@ import { resolve } from 'path'; // @ts-ignore -import { normalizePath, readFileAsync } from '.'; -// @ts-ignore -import rootConfig from '../../../.i18nrc.json'; +import { arrayify, normalizePath, readFileAsync } from '.'; export interface I18nConfig { paths: Record; exclude: string[]; translations: string[]; + prefix?: string; } -/** - * Merges root .i18nrc.json config with any other additional configs (e.g. from - * third-party plugins). - * @param configPaths List of config paths. - */ -export async function mergeConfigs(configPaths: string | string[] = []) { - const mergedConfig: I18nConfig = { exclude: [], translations: [], ...rootConfig }; +export async function checkConfigNamespacePrefix(configPath: string) { + const { prefix, paths } = JSON.parse(await readFileAsync(resolve(configPath))); + for (const [namespace] of Object.entries(paths)) { + if (prefix && prefix !== namespace.split('.')[0]) { + throw new Error(`namespace ${namespace} must be prefixed with ${prefix} in ${configPath}`); + } + } +} - for (const configPath of Array.isArray(configPaths) ? configPaths : [configPaths]) { - const additionalConfig: I18nConfig = { - paths: {}, - exclude: [], - translations: [], - ...JSON.parse(await readFileAsync(resolve(configPath))), - }; +export async function mergeConfig( + configPath: string, + config: I18nConfig = { exclude: [], translations: [], paths: {} } +) { + const additionalConfig: I18nConfig = { + paths: {}, + exclude: [], + translations: [], + ...JSON.parse(await readFileAsync(resolve(configPath))), + }; - for (const [namespace, path] of Object.entries(additionalConfig.paths)) { - mergedConfig.paths[namespace] = normalizePath(resolve(configPath, '..', path)); - } + for (const [namespace, path] of Object.entries(additionalConfig.paths)) { + config.paths[namespace] = normalizePath(resolve(configPath, '..', path)); + } - for (const exclude of additionalConfig.exclude) { - mergedConfig.exclude.push(normalizePath(resolve(configPath, '..', exclude))); - } + for (const exclude of additionalConfig.exclude) { + config.exclude.push(normalizePath(resolve(configPath, '..', exclude))); + } - for (const translations of additionalConfig.translations) { - mergedConfig.translations.push(normalizePath(resolve(configPath, '..', translations))); - } + for (const translations of additionalConfig.translations) { + config.translations.push(normalizePath(resolve(configPath, '..', translations))); } - return mergedConfig; + return config; } /** diff --git a/src/dev/i18n/index.ts b/src/dev/i18n/index.ts index 8f3e595509739..13355150b0490 100644 --- a/src/dev/i18n/index.ts +++ b/src/dev/i18n/index.ts @@ -22,7 +22,7 @@ export { extractMessagesFromPathToMap } from './extract_default_translations'; // @ts-ignore export { matchEntriesWithExctractors } from './extract_default_translations'; // @ts-ignore -export { writeFileAsync, readFileAsync, normalizePath, ErrorReporter } from './utils'; +export { arrayify, writeFileAsync, readFileAsync, normalizePath, ErrorReporter } from './utils'; export { serializeToJson, serializeToJson5 } from './serializers'; -export { I18nConfig, filterConfigPaths, mergeConfigs } from './config'; +export { I18nConfig, filterConfigPaths, mergeConfig, checkConfigNamespacePrefix } from './config'; export { integrateLocaleFiles } from './integrate_locale_files'; diff --git a/src/dev/i18n/tasks/check_configs.ts b/src/dev/i18n/tasks/check_configs.ts new file mode 100644 index 0000000000000..6f4a1a0dc8e97 --- /dev/null +++ b/src/dev/i18n/tasks/check_configs.ts @@ -0,0 +1,43 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { resolve, join } from 'path'; +import { ErrorReporter, checkConfigNamespacePrefix, arrayify } from '..'; + +export function checkConfigs(additionalConfigPaths: string | string[] = []) { + const root = join(__dirname, '../../../../'); + const kibanaRC = resolve(root, '.i18nrc.json'); + const xpackRC = resolve(root, 'x-pack/.i18nrc.json'); + + const configPaths = [kibanaRC, xpackRC, ...arrayify(additionalConfigPaths)]; + + return configPaths.map(configPath => ({ + task: async (context: { reporter: ErrorReporter }) => { + try { + await checkConfigNamespacePrefix(configPath); + } catch (err) { + const { reporter } = context; + const reporterWithContext = reporter.withContext({ name: configPath }); + reporterWithContext.report(err); + throw reporter; + } + }, + title: `Checking configs in ${configPath}`, + })); +} diff --git a/src/dev/i18n/tasks/extract_default_translations.ts b/src/dev/i18n/tasks/extract_default_translations.ts index 92bf9663e975e..208f0643684e9 100644 --- a/src/dev/i18n/tasks/extract_default_translations.ts +++ b/src/dev/i18n/tasks/extract_default_translations.ts @@ -21,14 +21,7 @@ import chalk from 'chalk'; import { ErrorReporter, extractMessagesFromPathToMap, filterConfigPaths, I18nConfig } from '..'; import { createFailError } from '../../run'; -export function extractDefaultMessages({ - path, - config, -}: { - path?: string | string[]; - config: I18nConfig; -}) { - const inputPaths = Array.isArray(path) ? path : [path || './']; +export function extractDefaultMessages(config: I18nConfig, inputPaths: string[]) { const filteredPaths = filterConfigPaths(inputPaths, config) as string[]; if (filteredPaths.length === 0) { throw createFailError( diff --git a/src/dev/i18n/tasks/extract_untracked_translations.ts b/src/dev/i18n/tasks/extract_untracked_translations.ts index cf83f02b76d82..9c595b5571372 100644 --- a/src/dev/i18n/tasks/extract_untracked_translations.ts +++ b/src/dev/i18n/tasks/extract_untracked_translations.ts @@ -92,13 +92,13 @@ export async function extractUntrackedMessagesTask({ } } -export function extractUntrackedMessages(srcPaths: string[], config: I18nConfig) { - return srcPaths.map(srcPath => ({ - title: `Checking untracked messages in ${srcPath}`, - task: async (context: { reporter: ErrorReporter }) => { - const { reporter } = context; +export function extractUntrackedMessages(inputPaths: string[]) { + return inputPaths.map(inputPath => ({ + title: `Checking untracked messages in ${inputPath}`, + task: async (context: { reporter: ErrorReporter; config: I18nConfig }) => { + const { reporter, config } = context; const initialErrorsNumber = reporter.errors.length; - const result = await extractUntrackedMessagesTask({ path: srcPath, config, reporter }); + const result = await extractUntrackedMessagesTask({ path: inputPath, config, reporter }); if (reporter.errors.length === initialErrorsNumber) { return result; } diff --git a/src/dev/i18n/tasks/index.ts b/src/dev/i18n/tasks/index.ts index bd33baa989e0f..a45cc81c236e7 100644 --- a/src/dev/i18n/tasks/index.ts +++ b/src/dev/i18n/tasks/index.ts @@ -20,3 +20,5 @@ export { extractDefaultMessages } from './extract_default_translations'; export { extractUntrackedMessages } from './extract_untracked_translations'; export { checkCompatibility } from './check_compatibility'; +export { mergeConfigs } from './merge_configs'; +export { checkConfigs } from './check_configs'; diff --git a/src/dev/i18n/tasks/merge_configs.ts b/src/dev/i18n/tasks/merge_configs.ts new file mode 100644 index 0000000000000..df2ae15a4c4c5 --- /dev/null +++ b/src/dev/i18n/tasks/merge_configs.ts @@ -0,0 +1,43 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { resolve, join } from 'path'; +import { ErrorReporter, I18nConfig, mergeConfig, arrayify } from '..'; + +export function mergeConfigs(additionalConfigPaths: string | string[] = []) { + const root = join(__dirname, '../../../../'); + const kibanaRC = resolve(root, '.i18nrc.json'); + const xpackRC = resolve(root, 'x-pack/.i18nrc.json'); + + const configPaths = [kibanaRC, xpackRC, ...arrayify(additionalConfigPaths)]; + + return configPaths.map(configPath => ({ + task: async (context: { reporter: ErrorReporter; config?: I18nConfig }) => { + try { + context.config = await mergeConfig(configPath, context.config); + } catch (err) { + const { reporter } = context; + const reporterWithContext = reporter.withContext({ name: configPath }); + reporterWithContext.report(err); + throw reporter; + } + }, + title: `Merging configs in ${configPath}`, + })); +} diff --git a/src/dev/i18n/utils.js b/src/dev/i18n/utils.js index 8ac2a1c98bc33..cbaab5152bb9e 100644 --- a/src/dev/i18n/utils.js +++ b/src/dev/i18n/utils.js @@ -324,3 +324,8 @@ export class ErrorReporter { ); } } + +// export function arrayify(subj: Subj | Subj[]): Subj[] { +export function arrayify(subj) { + return Array.isArray(subj) ? subj : [subj]; +} diff --git a/src/dev/run_i18n_check.ts b/src/dev/run_i18n_check.ts index 89f890f726350..9f2b9946b2445 100644 --- a/src/dev/run_i18n_check.ts +++ b/src/dev/run_i18n_check.ts @@ -20,8 +20,14 @@ import chalk from 'chalk'; import Listr from 'listr'; -import { ErrorReporter, mergeConfigs } from './i18n'; -import { extractDefaultMessages, extractUntrackedMessages, checkCompatibility } from './i18n/tasks'; +import { ErrorReporter } from './i18n'; +import { + extractDefaultMessages, + extractUntrackedMessages, + checkCompatibility, + checkConfigs, + mergeConfigs, +} from './i18n/tasks'; import { createFailError, run } from './run'; run( @@ -59,27 +65,34 @@ run( throw createFailError(`${chalk.white.bgRed(' I18N ERROR ')} --fix can't have a value`); } - const config = await mergeConfigs(includeConfig); const srcPaths = Array().concat(path || ['./src', './packages', './x-pack']); - if (config.translations.length === 0) { - return; - } - const list = new Listr( [ + { + title: 'Checking .i18nrc.json files', + task: () => new Listr(checkConfigs(includeConfig), { exitOnError: true }), + }, + { + title: 'Merging .i18nrc.json files', + task: () => new Listr(mergeConfigs(includeConfig), { exitOnError: true }), + }, { title: 'Checking For Untracked Messages based on .i18nrc.json', - task: () => new Listr(extractUntrackedMessages(srcPaths, config), { exitOnError: true }), + skip: ({ config }) => !config.translations.length, + task: ({ config }) => + new Listr(extractUntrackedMessages(srcPaths), { exitOnError: true }), }, { title: 'Validating Default Messages', - task: () => - new Listr(extractDefaultMessages({ path: srcPaths, config }), { exitOnError: true }), + skip: ({ config }) => !config.translations.length, + task: ({ config }) => + new Listr(extractDefaultMessages(config, srcPaths), { exitOnError: true }), }, { title: 'Compatibility Checks', - task: () => + skip: ({ config }) => !config.translations.length, + task: ({ config }) => new Listr( checkCompatibility( config, diff --git a/src/dev/run_i18n_extract.ts b/src/dev/run_i18n_extract.ts index 63f7429ec420e..7026d9e14ebba 100644 --- a/src/dev/run_i18n_extract.ts +++ b/src/dev/run_i18n_extract.ts @@ -21,14 +21,8 @@ import chalk from 'chalk'; import Listr from 'listr'; import { resolve } from 'path'; -import { - ErrorReporter, - mergeConfigs, - serializeToJson, - serializeToJson5, - writeFileAsync, -} from './i18n'; -import { extractDefaultMessages } from './i18n/tasks'; +import { ErrorReporter, serializeToJson, serializeToJson5, writeFileAsync } from './i18n'; +import { extractDefaultMessages, mergeConfigs } from './i18n/tasks'; import { createFailError, run } from './run'; run( @@ -52,13 +46,17 @@ run( `${chalk.white.bgRed(' I18N ERROR ')} --path and --include-config require a value` ); } - - const config = await mergeConfigs(includeConfig); + const srcPaths = Array().concat(path || ['./src', './packages', './x-pack']); const list = new Listr([ + { + title: 'Merging .i18nrc.json files', + task: () => new Listr(mergeConfigs(includeConfig), { exitOnError: true }), + }, { title: 'Extracting Default Messages', - task: () => new Listr(extractDefaultMessages({ path, config }), { exitOnError: true }), + task: ({ config }) => + new Listr(extractDefaultMessages(config, srcPaths), { exitOnError: true }), }, { title: 'Writing to file', diff --git a/src/legacy/server/i18n/index.js b/src/legacy/server/i18n/index.js index 7ad2ce58c0ec6..94b1e3e723076 100644 --- a/src/legacy/server/i18n/index.js +++ b/src/legacy/server/i18n/index.js @@ -32,11 +32,20 @@ export async function getTranslationPaths({ cwd, glob }) { const configFiles = await Promise.all( entries .map(entry => resolve(cwd, entry)) - .map(configFilePath => readFileAsync(configFilePath, 'utf8')) + .map(async configFilePath => ({ + path: configFilePath, + content: await readFileAsync(configFilePath, 'utf8') + })) ); return configFiles - .map(configFile => JSON.parse(configFile)) + .map(({ content, path }) => { + try { + return JSON.parse(content); + } catch (err) { + throw new Error(`Failed to parse .i18nrc.json file at ${path}`); + } + }) .reduce((acc, configFile) => acc.concat(...configFile.translations), []) .map(translationPath => resolve(cwd, translationPath)); } @@ -44,12 +53,14 @@ export async function getTranslationPaths({ cwd, glob }) { export async function i18nMixin(kbnServer, server, config) { const locale = config.get('i18n.locale'); const localeRegExp = new RegExp(`${locale}.json$`); + const pluginPaths = config.get('plugins.paths'); const translationPaths = await Promise.all([ getTranslationPaths({ cwd: fromRoot('.'), glob: `.i18nrc.json`, }), + ...pluginPaths.map(cwd => getTranslationPaths({ glob: `.i18nrc.json`, cwd })), getTranslationPaths({ cwd: fromRoot('plugins'), glob: `*/.i18nrc.json`, @@ -60,12 +71,10 @@ export async function i18nMixin(kbnServer, server, config) { }), ]); - const currentTranslationPaths = [].concat(...translationPaths) .filter(translationPath => localeRegExp.test(translationPath)); i18nLoader.registerTranslationFiles(currentTranslationPaths); - const translations = await i18nLoader.getTranslationsByLocale(locale); i18n.init(Object.freeze({ locale, diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json new file mode 100644 index 0000000000000..f8c37c792d51c --- /dev/null +++ b/x-pack/.i18nrc.json @@ -0,0 +1,43 @@ +{ + "prefix": "xpack", + "paths": { + "xpack.actions": "legacy/plugins/actions", + "xpack.alerting": "legacy/plugins/alerting", + "xpack.apm": "legacy/plugins/apm", + "xpack.beatsManagement": "legacy/plugins/beats_management", + "xpack.canvas": "legacy/plugins/canvas", + "xpack.code": "legacy/plugins/code", + "xpack.crossClusterReplication": "legacy/plugins/cross_cluster_replication", + "xpack.dashboardMode": "legacy/plugins/dashboard_mode", + "xpack.fileUpload": "legacy/plugins/file_upload", + "xpack.graph": "legacy/plugins/graph", + "xpack.grokDebugger": "legacy/plugins/grokdebugger", + "xpack.idxMgmt": "legacy/plugins/index_management", + "xpack.indexLifecycleMgmt": "legacy/plugins/index_lifecycle_management", + "xpack.infra": "legacy/plugins/infra", + "xpack.kueryAutocomplete": "legacy/plugins/kuery_autocomplete", + "xpack.licenseMgmt": "legacy/plugins/license_management", + "xpack.maps": "legacy/plugins/maps", + "xpack.ml": "legacy/plugins/ml", + "xpack.logstash": "legacy/plugins/logstash", + "xpack.main": "legacy/plugins/xpack_main", + "xpack.telemetry": "legacy/plugins/telemetry", + "xpack.monitoring": "legacy/plugins/monitoring", + "xpack.remoteClusters": "legacy/plugins/remote_clusters", + "xpack.reporting": "legacy/plugins/reporting", + "xpack.rollupJobs": "legacy/plugins/rollup", + "xpack.searchProfiler": "legacy/plugins/searchprofiler", + "xpack.siem": "legacy/plugins/siem", + "xpack.security": "legacy/plugins/security", + "xpack.server": "legacy/server", + "xpack.snapshotRestore": "legacy/plugins/snapshot_restore", + "xpack.spaces": "legacy/plugins/spaces", + "xpack.upgradeAssistant": "legacy/plugins/upgrade_assistant", + "xpack.uptime": "legacy/plugins/uptime", + "xpack.watcher": "legacy/plugins/watcher" + }, + "translations": [ + "plugins/translations/translations/zh-CN.json", + "plugins/translations/translations/ja-JP.json" + ] +} From 904d8a8688e0e3b5cc40fd67cc913b27852169c4 Mon Sep 17 00:00:00 2001 From: Bamieh Date: Thu, 27 Jun 2019 12:01:19 +0300 Subject: [PATCH 06/18] checkout master kibana config --- config/kibana.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/kibana.yml b/config/kibana.yml index a40d3dff2e7c0..218c32b8f680a 100644 --- a/config/kibana.yml +++ b/config/kibana.yml @@ -111,5 +111,5 @@ #ops.interval: 5000 # Specifies locale to be used for all localizable strings, dates and number formats. -# Supported languages are the following: English - en , by default , Chinese - zh-CN . -i18n.locale: "ja-JP" +# Supported languages are the following: English - en , by default , Chinese - zh-CN . +#i18n.locale: "en" From 8963fd74d662cc5c850007472b1ecbf349586a24 Mon Sep 17 00:00:00 2001 From: Bamieh Date: Thu, 27 Jun 2019 12:03:40 +0300 Subject: [PATCH 07/18] include x-pack/.i18nrc.json file --- x-pack/.kibana-plugin-helpers.json | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/.kibana-plugin-helpers.json b/x-pack/.kibana-plugin-helpers.json index b9e7d32af9ef1..b4f0915a27b9d 100644 --- a/x-pack/.kibana-plugin-helpers.json +++ b/x-pack/.kibana-plugin-helpers.json @@ -11,6 +11,7 @@ "yarn.lock", "tsconfig.json", "index.js", + ".i18nrc.json", "plugins/**/*", "legacy/plugins/reporting/.phantom/*", "legacy/plugins/reporting/.chromium/*", From 658f56548f23602de0fda46e7cddb71ae1468e5e Mon Sep 17 00:00:00 2001 From: Bamieh Date: Thu, 27 Jun 2019 12:05:01 +0300 Subject: [PATCH 08/18] remove unused import --- src/dev/i18n/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dev/i18n/config.ts b/src/dev/i18n/config.ts index b2beb5c5bff99..6b7d937721b70 100644 --- a/src/dev/i18n/config.ts +++ b/src/dev/i18n/config.ts @@ -20,7 +20,7 @@ import { resolve } from 'path'; // @ts-ignore -import { arrayify, normalizePath, readFileAsync } from '.'; +import { normalizePath, readFileAsync } from '.'; export interface I18nConfig { paths: Record; From b1978ecb2ae35ed9e4ac53059f39949e3626181f Mon Sep 17 00:00:00 2001 From: Bamieh Date: Thu, 27 Jun 2019 13:02:43 +0300 Subject: [PATCH 09/18] fix i18n_integrate --- src/dev/run_i18n_integrate.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/dev/run_i18n_integrate.ts b/src/dev/run_i18n_integrate.ts index b80dd8deac274..c950b0fef57bd 100644 --- a/src/dev/run_i18n_integrate.ts +++ b/src/dev/run_i18n_integrate.ts @@ -20,8 +20,8 @@ import chalk from 'chalk'; import Listr from 'listr'; -import { ErrorReporter, integrateLocaleFiles, mergeConfigs } from './i18n'; -import { extractDefaultMessages } from './i18n/tasks'; +import { ErrorReporter, integrateLocaleFiles } from './i18n'; +import { extractDefaultMessages, mergeConfigs } from './i18n/tasks'; import { createFailError, run } from './run'; run( @@ -75,11 +75,15 @@ run( ); } - const config = await mergeConfigs(includeConfig); const list = new Listr([ + { + title: 'Merging .i18nrc.json files', + task: () => new Listr(mergeConfigs(includeConfig), { exitOnError: true }), + }, { title: 'Extracting Default Messages', - task: () => new Listr(extractDefaultMessages({ path, config }), { exitOnError: true }), + task: ({ config }) => + new Listr(extractDefaultMessages(config, path), { exitOnError: true }), }, { title: 'Intregrating Locale File', From da94bf1a0566b3c35716abeca3da589d0d7ffac8 Mon Sep 17 00:00:00 2001 From: Bamieh Date: Thu, 27 Jun 2019 13:34:20 +0300 Subject: [PATCH 10/18] fix i18n_integrate --- src/dev/run_i18n_integrate.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dev/run_i18n_integrate.ts b/src/dev/run_i18n_integrate.ts index c950b0fef57bd..9b006fd9b3972 100644 --- a/src/dev/run_i18n_integrate.ts +++ b/src/dev/run_i18n_integrate.ts @@ -75,6 +75,8 @@ run( ); } + const srcPaths = Array().concat(path || ['./src', './packages', './x-pack']); + const list = new Listr([ { title: 'Merging .i18nrc.json files', @@ -83,11 +85,11 @@ run( { title: 'Extracting Default Messages', task: ({ config }) => - new Listr(extractDefaultMessages(config, path), { exitOnError: true }), + new Listr(extractDefaultMessages(config, srcPaths), { exitOnError: true }), }, { title: 'Intregrating Locale File', - task: async ({ messages }) => { + task: async ({ messages, config }) => { await integrateLocaleFiles(messages, { sourceFileName: source, targetFileName: target, From 2eba298304fde533ea71971f10390b9a782ebf43 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Wed, 3 Jul 2019 15:31:35 +0300 Subject: [PATCH 11/18] code review changes --- src/dev/i18n/constants.ts | 1 + src/dev/i18n/tasks/check_configs.ts | 5 +- src/dev/run_i18n_check.ts | 8 ++-- src/legacy/server/i18n/constants.js | 20 ++++++++ .../server/i18n/get_translations_path.js | 46 +++++++++++++++++++ src/legacy/server/i18n/index.js | 45 ++++-------------- 6 files changed, 83 insertions(+), 42 deletions(-) create mode 100644 src/legacy/server/i18n/constants.js create mode 100644 src/legacy/server/i18n/get_translations_path.js diff --git a/src/dev/i18n/constants.ts b/src/dev/i18n/constants.ts index b6f8ab8be1c9b..7fd48b7eeaf84 100644 --- a/src/dev/i18n/constants.ts +++ b/src/dev/i18n/constants.ts @@ -20,3 +20,4 @@ export const DEFAULT_MESSAGE_KEY = 'defaultMessage'; export const DESCRIPTION_KEY = 'description'; export const VALUES_KEY = 'values'; +export const I18N_RC = '.i18nrc.json'; diff --git a/src/dev/i18n/tasks/check_configs.ts b/src/dev/i18n/tasks/check_configs.ts index 6f4a1a0dc8e97..9cbffcca581e8 100644 --- a/src/dev/i18n/tasks/check_configs.ts +++ b/src/dev/i18n/tasks/check_configs.ts @@ -18,12 +18,13 @@ */ import { resolve, join } from 'path'; +import { I18N_RC } from '../constants'; import { ErrorReporter, checkConfigNamespacePrefix, arrayify } from '..'; export function checkConfigs(additionalConfigPaths: string | string[] = []) { const root = join(__dirname, '../../../../'); - const kibanaRC = resolve(root, '.i18nrc.json'); - const xpackRC = resolve(root, 'x-pack/.i18nrc.json'); + const kibanaRC = resolve(root, I18N_RC); + const xpackRC = resolve(root, `x-pack/${I18N_RC}`); const configPaths = [kibanaRC, xpackRC, ...arrayify(additionalConfigPaths)]; diff --git a/src/dev/run_i18n_check.ts b/src/dev/run_i18n_check.ts index 9f2b9946b2445..f160061b0fae0 100644 --- a/src/dev/run_i18n_check.ts +++ b/src/dev/run_i18n_check.ts @@ -30,6 +30,8 @@ import { } from './i18n/tasks'; import { createFailError, run } from './run'; +const skipNoTranslations = ({ config }) => !config.translations.length; + run( async ({ flags: { @@ -79,19 +81,19 @@ run( }, { title: 'Checking For Untracked Messages based on .i18nrc.json', - skip: ({ config }) => !config.translations.length, + skip: skipNoTranslations, task: ({ config }) => new Listr(extractUntrackedMessages(srcPaths), { exitOnError: true }), }, { title: 'Validating Default Messages', - skip: ({ config }) => !config.translations.length, + skip: skipNoTranslations, task: ({ config }) => new Listr(extractDefaultMessages(config, srcPaths), { exitOnError: true }), }, { title: 'Compatibility Checks', - skip: ({ config }) => !config.translations.length, + skip: skipNoTranslations, task: ({ config }) => new Listr( checkCompatibility( diff --git a/src/legacy/server/i18n/constants.js b/src/legacy/server/i18n/constants.js new file mode 100644 index 0000000000000..a7a410dbcb5b3 --- /dev/null +++ b/src/legacy/server/i18n/constants.js @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const I18N_RC = '.i18nrc.json'; diff --git a/src/legacy/server/i18n/get_translations_path.js b/src/legacy/server/i18n/get_translations_path.js new file mode 100644 index 0000000000000..868cb189f066f --- /dev/null +++ b/src/legacy/server/i18n/get_translations_path.js @@ -0,0 +1,46 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { promisify } from 'util'; +import { readFile } from 'fs'; +import { resolve } from 'path'; +import globby from 'globby'; + +const readFileAsync = promisify(readFile); + +export async function getTranslationPaths({ cwd, glob }) { + const entries = await globby(glob, { cwd }); + const translationPaths = []; + + for (const entry of entries) { + const entyFullPath = resolve(cwd, entry); + const content = await readFileAsync(entyFullPath, 'utf8'); + try { + const { translations } = JSON.parse(content); + translations.forEach(translation => { + const translationFullPath = resolve(cwd, translation); + translationPaths.push(translationFullPath); + }); + } catch (err) { + throw new Error(`Failed to parse .i18nrc.json file at ${entyFullPath}`); + } + } + + return translationPaths; +} diff --git a/src/legacy/server/i18n/index.js b/src/legacy/server/i18n/index.js index 94b1e3e723076..3c2cb12a1d874 100644 --- a/src/legacy/server/i18n/index.js +++ b/src/legacy/server/i18n/index.js @@ -17,62 +17,33 @@ * under the License. */ -import { resolve } from 'path'; -import globby from 'globby'; import { i18n, i18nLoader } from '@kbn/i18n'; -import { readFile } from 'fs'; +import { basename } from 'path'; import { fromRoot } from '../../utils'; -import { promisify } from 'util'; - -const readFileAsync = promisify(readFile); - -export async function getTranslationPaths({ cwd, glob }) { - const entries = await globby(glob, { cwd }); - - const configFiles = await Promise.all( - entries - .map(entry => resolve(cwd, entry)) - .map(async configFilePath => ({ - path: configFilePath, - content: await readFileAsync(configFilePath, 'utf8') - })) - ); - - return configFiles - .map(({ content, path }) => { - try { - return JSON.parse(content); - } catch (err) { - throw new Error(`Failed to parse .i18nrc.json file at ${path}`); - } - }) - .reduce((acc, configFile) => acc.concat(...configFile.translations), []) - .map(translationPath => resolve(cwd, translationPath)); -} +import { getTranslationPaths } from './get_translations_path'; +import { I18N_RC } from './constants'; export async function i18nMixin(kbnServer, server, config) { const locale = config.get('i18n.locale'); - const localeRegExp = new RegExp(`${locale}.json$`); const pluginPaths = config.get('plugins.paths'); const translationPaths = await Promise.all([ getTranslationPaths({ cwd: fromRoot('.'), - glob: `.i18nrc.json`, + glob: I18N_RC, }), - ...pluginPaths.map(cwd => getTranslationPaths({ glob: `.i18nrc.json`, cwd })), + ...pluginPaths.map(cwd => getTranslationPaths({ glob: I18N_RC, cwd })), getTranslationPaths({ cwd: fromRoot('plugins'), - glob: `*/.i18nrc.json`, + glob: `*/${I18N_RC}`, }), getTranslationPaths({ cwd: fromRoot('../kibana-extra'), - glob: `*/.i18nrc.json`, + glob: `*/${I18N_RC}`, }), ]); - const currentTranslationPaths = [].concat(...translationPaths) - .filter(translationPath => localeRegExp.test(translationPath)); + const currentTranslationPaths = translationPaths.filter(translationPath => basename(translationPath, '.json') === locale); i18nLoader.registerTranslationFiles(currentTranslationPaths); const translations = await i18nLoader.getTranslationsByLocale(locale); From 84cadf261077efb1471c1ee086d1467dabb81457 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Wed, 3 Jul 2019 15:31:52 +0300 Subject: [PATCH 12/18] code review changes --- src/legacy/server/i18n/get_translations_path.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/legacy/server/i18n/get_translations_path.js b/src/legacy/server/i18n/get_translations_path.js index 868cb189f066f..c4d23d28b7f7b 100644 --- a/src/legacy/server/i18n/get_translations_path.js +++ b/src/legacy/server/i18n/get_translations_path.js @@ -30,8 +30,8 @@ export async function getTranslationPaths({ cwd, glob }) { for (const entry of entries) { const entyFullPath = resolve(cwd, entry); - const content = await readFileAsync(entyFullPath, 'utf8'); try { + const content = await readFileAsync(entyFullPath, 'utf8'); const { translations } = JSON.parse(content); translations.forEach(translation => { const translationFullPath = resolve(cwd, translation); From b6b9db920ef4f429a7b1aa78aaa1acfbb80ae37b Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Wed, 3 Jul 2019 16:03:13 +0300 Subject: [PATCH 13/18] try using scanDir --- src/legacy/server/i18n/index.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/legacy/server/i18n/index.js b/src/legacy/server/i18n/index.js index 3c2cb12a1d874..8b6bea3bc4459 100644 --- a/src/legacy/server/i18n/index.js +++ b/src/legacy/server/i18n/index.js @@ -25,18 +25,14 @@ import { I18N_RC } from './constants'; export async function i18nMixin(kbnServer, server, config) { const locale = config.get('i18n.locale'); - const pluginPaths = config.get('plugins.paths'); const translationPaths = await Promise.all([ getTranslationPaths({ cwd: fromRoot('.'), glob: I18N_RC, }), - ...pluginPaths.map(cwd => getTranslationPaths({ glob: I18N_RC, cwd })), - getTranslationPaths({ - cwd: fromRoot('plugins'), - glob: `*/${I18N_RC}`, - }), + ...config.get('plugins.paths').map(cwd => getTranslationPaths({ cwd, glob: I18N_RC })), + ...config.get('plugins.scanDirs').map(cwd => getTranslationPaths({ cwd, glob: `*/${I18N_RC}` })), getTranslationPaths({ cwd: fromRoot('../kibana-extra'), glob: `*/${I18N_RC}`, From a8cfcbd93c7ba700c4b9ded720e6e3d4f6bb151c Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Wed, 3 Jul 2019 16:36:18 +0300 Subject: [PATCH 14/18] revert to using concat --- src/legacy/server/i18n/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/legacy/server/i18n/index.js b/src/legacy/server/i18n/index.js index 8b6bea3bc4459..ce01d07576f28 100644 --- a/src/legacy/server/i18n/index.js +++ b/src/legacy/server/i18n/index.js @@ -39,9 +39,9 @@ export async function i18nMixin(kbnServer, server, config) { }), ]); - const currentTranslationPaths = translationPaths.filter(translationPath => basename(translationPath, '.json') === locale); - + const currentTranslationPaths = [].concat(...translationPaths).filter(translationPath => basename(translationPath, '.json') === locale); i18nLoader.registerTranslationFiles(currentTranslationPaths); + const translations = await i18nLoader.getTranslationsByLocale(locale); i18n.init(Object.freeze({ locale, From 19c1f5215ed3965ed41f3478144935e8605b6755 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Wed, 3 Jul 2019 17:11:54 +0300 Subject: [PATCH 15/18] add config type --- src/dev/run_i18n_check.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dev/run_i18n_check.ts b/src/dev/run_i18n_check.ts index f160061b0fae0..d3c98a02edfe1 100644 --- a/src/dev/run_i18n_check.ts +++ b/src/dev/run_i18n_check.ts @@ -20,7 +20,7 @@ import chalk from 'chalk'; import Listr from 'listr'; -import { ErrorReporter } from './i18n'; +import { ErrorReporter, I18nConfig } from './i18n'; import { extractDefaultMessages, extractUntrackedMessages, @@ -30,7 +30,7 @@ import { } from './i18n/tasks'; import { createFailError, run } from './run'; -const skipNoTranslations = ({ config }) => !config.translations.length; +const skipNoTranslations = ({ config }: { config: I18nConfig }) => !config.translations.length; run( async ({ From 619aa1a7e2aba21a0e7d41d6f1ef8cbb24a14ef1 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Sun, 21 Jul 2019 07:48:58 +0300 Subject: [PATCH 16/18] code review fixes --- src/dev/i18n/config.ts | 8 +++----- src/dev/i18n/index.ts | 7 ++++++- src/dev/i18n/tasks/check_configs.ts | 2 +- src/dev/i18n/tasks/merge_configs.ts | 4 ++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/dev/i18n/config.ts b/src/dev/i18n/config.ts index 6b7d937721b70..572ec0d26ff6c 100644 --- a/src/dev/i18n/config.ts +++ b/src/dev/i18n/config.ts @@ -38,9 +38,9 @@ export async function checkConfigNamespacePrefix(configPath: string) { } } -export async function mergeConfig( - configPath: string, - config: I18nConfig = { exclude: [], translations: [], paths: {} } +export async function assignConfigFromPath( + config: I18nConfig = { exclude: [], translations: [], paths: {} }, + configPath: string ) { const additionalConfig: I18nConfig = { paths: {}, @@ -60,8 +60,6 @@ export async function mergeConfig( for (const translations of additionalConfig.translations) { config.translations.push(normalizePath(resolve(configPath, '..', translations))); } - - return config; } /** diff --git a/src/dev/i18n/index.ts b/src/dev/i18n/index.ts index 13355150b0490..cfc03f1c08b3c 100644 --- a/src/dev/i18n/index.ts +++ b/src/dev/i18n/index.ts @@ -24,5 +24,10 @@ export { matchEntriesWithExctractors } from './extract_default_translations'; // @ts-ignore export { arrayify, writeFileAsync, readFileAsync, normalizePath, ErrorReporter } from './utils'; export { serializeToJson, serializeToJson5 } from './serializers'; -export { I18nConfig, filterConfigPaths, mergeConfig, checkConfigNamespacePrefix } from './config'; +export { + I18nConfig, + filterConfigPaths, + assignConfigFromPath, + checkConfigNamespacePrefix, +} from './config'; export { integrateLocaleFiles } from './integrate_locale_files'; diff --git a/src/dev/i18n/tasks/check_configs.ts b/src/dev/i18n/tasks/check_configs.ts index 9cbffcca581e8..ffb9a499fbb43 100644 --- a/src/dev/i18n/tasks/check_configs.ts +++ b/src/dev/i18n/tasks/check_configs.ts @@ -24,7 +24,7 @@ import { ErrorReporter, checkConfigNamespacePrefix, arrayify } from '..'; export function checkConfigs(additionalConfigPaths: string | string[] = []) { const root = join(__dirname, '../../../../'); const kibanaRC = resolve(root, I18N_RC); - const xpackRC = resolve(root, `x-pack/${I18N_RC}`); + const xpackRC = resolve(root, 'x-pack', I18N_RC); const configPaths = [kibanaRC, xpackRC, ...arrayify(additionalConfigPaths)]; diff --git a/src/dev/i18n/tasks/merge_configs.ts b/src/dev/i18n/tasks/merge_configs.ts index df2ae15a4c4c5..bed002dd4956e 100644 --- a/src/dev/i18n/tasks/merge_configs.ts +++ b/src/dev/i18n/tasks/merge_configs.ts @@ -18,7 +18,7 @@ */ import { resolve, join } from 'path'; -import { ErrorReporter, I18nConfig, mergeConfig, arrayify } from '..'; +import { ErrorReporter, I18nConfig, assignConfigFromPath, arrayify } from '..'; export function mergeConfigs(additionalConfigPaths: string | string[] = []) { const root = join(__dirname, '../../../../'); @@ -30,7 +30,7 @@ export function mergeConfigs(additionalConfigPaths: string | string[] = []) { return configPaths.map(configPath => ({ task: async (context: { reporter: ErrorReporter; config?: I18nConfig }) => { try { - context.config = await mergeConfig(configPath, context.config); + await assignConfigFromPath(context.config, configPath); } catch (err) { const { reporter } = context; const reporterWithContext = reporter.withContext({ name: configPath }); From 0ca5dc63731a29cda94ee5b1b6fbb3f19b91624d Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Sun, 21 Jul 2019 09:14:05 +0300 Subject: [PATCH 17/18] finalize PR --- config/kibana.yml | 4 ++-- src/dev/i18n/config.ts | 2 ++ src/dev/i18n/tasks/extract_default_translations.ts | 1 - src/dev/i18n/tasks/merge_configs.ts | 2 +- src/legacy/server/i18n/get_translations_path.js | 11 ++++++----- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/config/kibana.yml b/config/kibana.yml index 218c32b8f680a..ea2f4cdeda21d 100644 --- a/config/kibana.yml +++ b/config/kibana.yml @@ -111,5 +111,5 @@ #ops.interval: 5000 # Specifies locale to be used for all localizable strings, dates and number formats. -# Supported languages are the following: English - en , by default , Chinese - zh-CN . -#i18n.locale: "en" +# Supported languages are the following: English - en , by default , Chinese - zh-CN . +i18n.locale: "zh-CN" diff --git a/src/dev/i18n/config.ts b/src/dev/i18n/config.ts index 572ec0d26ff6c..b877ae473acca 100644 --- a/src/dev/i18n/config.ts +++ b/src/dev/i18n/config.ts @@ -60,6 +60,8 @@ export async function assignConfigFromPath( for (const translations of additionalConfig.translations) { config.translations.push(normalizePath(resolve(configPath, '..', translations))); } + + return config; } /** diff --git a/src/dev/i18n/tasks/extract_default_translations.ts b/src/dev/i18n/tasks/extract_default_translations.ts index c9eefd1355d77..3384e3c515822 100644 --- a/src/dev/i18n/tasks/extract_default_translations.ts +++ b/src/dev/i18n/tasks/extract_default_translations.ts @@ -30,7 +30,6 @@ export function extractDefaultMessages(config: I18nConfig, inputPaths: string[]) )} None of input paths is covered by the mappings in .i18nrc.json.` ); } - return filteredPaths.map(filteredPath => ({ task: async (context: { messages: Map; diff --git a/src/dev/i18n/tasks/merge_configs.ts b/src/dev/i18n/tasks/merge_configs.ts index bed002dd4956e..ec005f0ce9367 100644 --- a/src/dev/i18n/tasks/merge_configs.ts +++ b/src/dev/i18n/tasks/merge_configs.ts @@ -30,7 +30,7 @@ export function mergeConfigs(additionalConfigPaths: string | string[] = []) { return configPaths.map(configPath => ({ task: async (context: { reporter: ErrorReporter; config?: I18nConfig }) => { try { - await assignConfigFromPath(context.config, configPath); + context.config = await assignConfigFromPath(context.config, configPath); } catch (err) { const { reporter } = context; const reporterWithContext = reporter.withContext({ name: configPath }); diff --git a/src/legacy/server/i18n/get_translations_path.js b/src/legacy/server/i18n/get_translations_path.js index c4d23d28b7f7b..95de6c7560660 100644 --- a/src/legacy/server/i18n/get_translations_path.js +++ b/src/legacy/server/i18n/get_translations_path.js @@ -19,7 +19,7 @@ import { promisify } from 'util'; import { readFile } from 'fs'; -import { resolve } from 'path'; +import { resolve, dirname } from 'path'; import globby from 'globby'; const readFileAsync = promisify(readFile); @@ -29,16 +29,17 @@ export async function getTranslationPaths({ cwd, glob }) { const translationPaths = []; for (const entry of entries) { - const entyFullPath = resolve(cwd, entry); + const entryFullPath = resolve(cwd, entry); + const pluginBasePath = dirname(entryFullPath); try { - const content = await readFileAsync(entyFullPath, 'utf8'); + const content = await readFileAsync(entryFullPath, 'utf8'); const { translations } = JSON.parse(content); translations.forEach(translation => { - const translationFullPath = resolve(cwd, translation); + const translationFullPath = resolve(pluginBasePath, translation); translationPaths.push(translationFullPath); }); } catch (err) { - throw new Error(`Failed to parse .i18nrc.json file at ${entyFullPath}`); + throw new Error(`Failed to parse .i18nrc.json file at ${entryFullPath}`); } } From bbd62fa9946975ecd3325ce1a371fe939ec5a6c6 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Sun, 21 Jul 2019 09:14:41 +0300 Subject: [PATCH 18/18] revert kibana.yml --- config/kibana.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/kibana.yml b/config/kibana.yml index ea2f4cdeda21d..7d49fb37e0320 100644 --- a/config/kibana.yml +++ b/config/kibana.yml @@ -112,4 +112,4 @@ # Specifies locale to be used for all localizable strings, dates and number formats. # Supported languages are the following: English - en , by default , Chinese - zh-CN . -i18n.locale: "zh-CN" +#i18n.locale: "en"