Allow extensions to use new API and it get included in Language Packs (#163493)

* Allow extensions to use new API and it get included in Language Packs

This leverages the l10n-dev package to analyze ts files for `l10n.t` calls.

* delete console.logs
This commit is contained in:
Tyler James Leonhardt 2022-10-12 17:28:34 -07:00 committed by GitHub
parent 8a942246fb
commit a8108049ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 14 deletions

View file

@ -4,7 +4,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.prepareIslFiles = exports.prepareI18nPackFiles = exports.createXlfFilesForIsl = exports.createXlfFilesForExtensions = exports.createXlfFilesForCoreBundle = exports.getResource = exports.processNlsFiles = exports.XLF = exports.Line = exports.externalExtensionsWithTranslations = exports.extraLanguages = exports.defaultLanguages = void 0;
exports.prepareIslFiles = exports.prepareI18nPackFiles = exports.createXlfFilesForIsl = exports.createXlfFilesForExtensions = exports.createXlfFilesForCoreBundle = exports.getResource = exports.processNlsFiles = exports.XLF = exports.Line = exports.extraLanguages = exports.defaultLanguages = void 0;
const path = require("path");
const fs = require("fs");
const event_stream_1 = require("event-stream");
@ -37,7 +37,7 @@ exports.extraLanguages = [
{ id: 'tr', folderName: 'trk' }
];
// non built-in extensions also that are transifex and need to be part of the language packs
exports.externalExtensionsWithTranslations = {
const externalExtensionsWithTranslations = {
'vscode-chrome-debug': 'msjsdiag.debugger-for-chrome',
'vscode-node-debug': 'ms-vscode.node-debug',
'vscode-node-debug2': 'ms-vscode.node-debug2'
@ -508,6 +508,28 @@ function createXlfFilesForCoreBundle() {
});
}
exports.createXlfFilesForCoreBundle = createXlfFilesForCoreBundle;
function createL10nBundleForExtension(extensionName) {
const result = (0, event_stream_1.through)();
gulp.src([
`extensions/${extensionName}/src/**/*.ts`,
]).pipe((0, event_stream_1.writeArray)((err, files) => {
if (err) {
result.emit('error', err);
return;
}
const json = (0, l10n_dev_1.getL10nJson)(files.map(file => {
return file.contents.toString('utf8');
}));
if (Object.keys(json)) {
result.emit('data', new File({
path: `${extensionName}/bundle.l10n.json`,
contents: Buffer.from(JSON.stringify(json), 'utf8')
}));
}
result.emit('end');
}));
return result;
}
function createXlfFilesForExtensions() {
let counter = 0;
let folderStreamEnded = false;
@ -530,7 +552,7 @@ function createXlfFilesForExtensions() {
}
return _l10nMap;
}
gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe((0, event_stream_1.through)(function (file) {
(0, event_stream_1.merge)(gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }), createL10nBundleForExtension(extensionName)).pipe((0, event_stream_1.through)(function (file) {
if (file.isBuffer()) {
const buffer = file.contents;
const basename = path.basename(file.path);
@ -554,6 +576,10 @@ function createXlfFilesForExtensions() {
getL10nMap().set(`extensions/${extensionName}/${relPath}/${file}`, info);
}
}
else if (basename === 'bundle.l10n.json') {
const json = JSON.parse(buffer.toString('utf8'));
getL10nMap().set(`extensions/${extensionName}/bundle`, json);
}
else {
this.emit('error', new Error(`${file.path} is not a valid extension nls file`));
return;
@ -664,7 +690,7 @@ function getRecordFromL10nJsonFormat(l10nJsonFormat) {
}
return record;
}
function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths) {
function prepareI18nPackFiles(resultingTranslationPaths) {
const parsePromises = [];
const mainPack = { version: i18nPackVersion, contents: {} };
const extensionsPacks = {};
@ -685,7 +711,7 @@ function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths) {
if (!extPack) {
extPack = extensionsPacks[resource] = { version: i18nPackVersion, contents: {} };
}
const externalId = externalExtensions[resource];
const externalId = externalExtensionsWithTranslations[resource];
if (!externalId) { // internal extension: remove 'extensions/extensionId/' segnent
const secondSlash = path.indexOf('/', firstSlash + 1);
extPack.contents[path.substring(secondSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
@ -713,7 +739,7 @@ function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths) {
for (const extension in extensionsPacks) {
const translatedExtFile = createI18nFile(`extensions/${extension}`, extensionsPacks[extension]);
this.queue(translatedExtFile);
const externalExtensionId = externalExtensions[extension];
const externalExtensionId = externalExtensionsWithTranslations[extension];
if (externalExtensionId) {
resultingTranslationPaths.push({ id: externalExtensionId, resourceName: `extensions/${extension}.i18n.json` });
}

View file

@ -6,7 +6,7 @@
import * as path from 'path';
import * as fs from 'fs';
import { through, ThroughStream } from 'event-stream';
import { merge, through, ThroughStream, writeArray } from 'event-stream';
import * as File from 'vinyl';
import * as Is from 'is';
import * as xml2js from 'xml2js';
@ -14,7 +14,7 @@ import * as gulp from 'gulp';
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
import * as iconv from '@vscode/iconv-lite-umd';
import { l10nJsonFormat, getL10nXlf, l10nJsonDetails, getL10nFilesFromXlf } from '@vscode/l10n-dev';
import { l10nJsonFormat, getL10nXlf, l10nJsonDetails, getL10nFilesFromXlf, getL10nJson } from '@vscode/l10n-dev';
function log(message: any, ...rest: any[]): void {
fancyLog(ansiColors.green('[i18n]'), message, ...rest);
@ -50,7 +50,7 @@ export const extraLanguages: Language[] = [
];
// non built-in extensions also that are transifex and need to be part of the language packs
export const externalExtensionsWithTranslations = {
const externalExtensionsWithTranslations: Record<string, string> = {
'vscode-chrome-debug': 'msjsdiag.debugger-for-chrome',
'vscode-node-debug': 'ms-vscode.node-debug',
'vscode-node-debug2': 'ms-vscode.node-debug2'
@ -586,6 +586,32 @@ export function createXlfFilesForCoreBundle(): ThroughStream {
});
}
function createL10nBundleForExtension(extensionName: string): ThroughStream {
const result = through();
gulp.src([
`extensions/${extensionName}/src/**/*.ts`,
]).pipe(writeArray((err, files: File[]) => {
if (err) {
result.emit('error', err);
return;
}
const json = getL10nJson(files.map(file => {
return file.contents.toString('utf8');
}));
if (Object.keys(json)) {
result.emit('data', new File({
path: `${extensionName}/bundle.l10n.json`,
contents: Buffer.from(JSON.stringify(json), 'utf8')
}));
}
result.emit('end');
}));
return result;
}
export function createXlfFilesForExtensions(): ThroughStream {
let counter: number = 0;
let folderStreamEnded: boolean = false;
@ -608,7 +634,10 @@ export function createXlfFilesForExtensions(): ThroughStream {
}
return _l10nMap;
}
gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(through(function (file: File) {
merge(
gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }),
createL10nBundleForExtension(extensionName)
).pipe(through(function (file: File) {
if (file.isBuffer()) {
const buffer: Buffer = file.contents as Buffer;
const basename = path.basename(file.path);
@ -631,6 +660,9 @@ export function createXlfFilesForExtensions(): ThroughStream {
}
getL10nMap().set(`extensions/${extensionName}/${relPath}/${file}`, info);
}
} else if (basename === 'bundle.l10n.json') {
const json: l10nJsonFormat = JSON.parse(buffer.toString('utf8'));
getL10nMap().set(`extensions/${extensionName}/bundle`, json);
} else {
this.emit('error', new Error(`${file.path} is not a valid extension nls file`));
return;
@ -762,7 +794,7 @@ function getRecordFromL10nJsonFormat(l10nJsonFormat: l10nJsonFormat): Record<str
return record;
}
export function prepareI18nPackFiles(externalExtensions: Record<string, string>, resultingTranslationPaths: TranslationPath[]): NodeJS.ReadWriteStream {
export function prepareI18nPackFiles(resultingTranslationPaths: TranslationPath[]): NodeJS.ReadWriteStream {
const parsePromises: Promise<l10nJsonDetails[]>[] = [];
const mainPack: I18nPack = { version: i18nPackVersion, contents: {} };
const extensionsPacks: Record<string, I18nPack> = {};
@ -785,7 +817,7 @@ export function prepareI18nPackFiles(externalExtensions: Record<string, string>,
if (!extPack) {
extPack = extensionsPacks[resource] = { version: i18nPackVersion, contents: {} };
}
const externalId = externalExtensions[resource];
const externalId = externalExtensionsWithTranslations[resource];
if (!externalId) { // internal extension: remove 'extensions/extensionId/' segnent
const secondSlash = path.indexOf('/', firstSlash + 1);
extPack.contents[path.substring(secondSlash + 1)] = getRecordFromL10nJsonFormat(file.messages);
@ -814,7 +846,7 @@ export function prepareI18nPackFiles(externalExtensions: Record<string, string>,
const translatedExtFile = createI18nFile(`extensions/${extension}`, extensionsPacks[extension]);
this.queue(translatedExtFile);
const externalExtensionId = externalExtensions[extension];
const externalExtensionId = externalExtensionsWithTranslations[extension];
if (externalExtensionId) {
resultingTranslationPaths.push({ id: externalExtensionId, resourceName: `extensions/${extension}.i18n.json` });
} else {

View file

@ -68,7 +68,7 @@ function update(options) {
console.log(`Importing translations for ${languageId} form '${location}' to '${translationDataFolder}' ...`);
let translationPaths = [];
gulp.src(path.join(location, '**', languageId, '*.xlf'), { silent: false })
.pipe(i18n.prepareI18nPackFiles(i18n.externalExtensionsWithTranslations, translationPaths))
.pipe(i18n.prepareI18nPackFiles(translationPaths))
.on('error', (error) => {
console.log(`Error occurred while importing translations:`);
translationPaths = undefined;