From 322815f14beb99f0a24e9ec97689deac71aa29a1 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 18 Oct 2017 14:19:37 -0700 Subject: [PATCH 1/5] Fix https://github.com/Microsoft/TypeScript/issues/19270: ensure output name is a valid locale name --- Gulpfile.ts | 9 ++-- Jakefile.js | 7 +++- .../generateLocalizedDiagnosticMessages.ts | 42 ++++++++++++++++++- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 24ff1f3f3c9fe..c57505e53ce9c 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -180,6 +180,11 @@ const libraryTargets = librarySourceMap.map(function(f) { return path.join(builtLocalDirectory, f.target); }); +const generatedLCGFile = path.join(builtLocalDirectory, "enu", "diagnosticMessages.generated.json.lcg"); +var localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map(function (f) { + return path.join(builtLocalDirectory, f, "diagnosticMessages.generated.json"); +}).concat(generatedLCGFile); + for (const i in libraryTargets) { const entry = librarySourceMap[i]; const target = libraryTargets[i]; @@ -398,7 +403,6 @@ gulp.task(generateLocalizedDiagnosticMessagesJs, /*help*/ false, [], () => { }); // Localize diagnostics -const generatedLCGFile = path.join(builtLocalDirectory, "enu", "diagnosticMessages.generated.json.lcg"); gulp.task(generatedLCGFile, [generateLocalizedDiagnosticMessagesJs, diagnosticInfoMapTs], (done) => { if (fs.existsSync(builtLocalDirectory) && needsUpdate(generatedDiagnosticMessagesJSON, generatedLCGFile)) { exec(host, [generateLocalizedDiagnosticMessagesJs, lclDirectory, builtLocalDirectory, generatedDiagnosticMessagesJSON], done, done); @@ -576,8 +580,7 @@ gulp.task("dontUseDebugMode", /*help*/ false, [], (done) => { useDebugMode = fal gulp.task("VerifyLKG", /*help*/ false, [], () => { const expectedFiles = [builtLocalCompiler, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, typingsInstallerJs, cancellationTokenJs].concat(libraryTargets); const missingFiles = expectedFiles. - concat(fs.readdirSync(lclDirectory).map(function (d) { return path.join(builtLocalDirectory, d, "diagnosticMessages.generated.json"); })). - concat(generatedLCGFile). + concat(localizationTargets). filter(f => !fs.existsSync(f)); if (missingFiles.length > 0) { throw new Error("Cannot replace the LKG unless all built targets are present in directory " + builtLocalDirectory + diff --git a/Jakefile.js b/Jakefile.js index ba6943d30153d..05f43c178f460 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -239,6 +239,10 @@ var libraryTargets = librarySourceMap.map(function (f) { return path.join(builtLocalDirectory, f.target); }); +var localizationTargets = ["cs", "de", "enu", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map(function (f) { + return path.join(builtLocalDirectory, f); +}); + // Prepends the contents of prefixFile to destinationFile function prependFile(prefixFile, destinationFile) { if (!fs.existsSync(prefixFile)) { @@ -736,8 +740,7 @@ desc("Makes a new LKG out of the built js files"); task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () { var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts, watchGuardFile]. concat(libraryTargets). - concat(fs.readdirSync(lclDirectory).map(function (d) { return path.join(builtLocalDirectory, d) })). - concat(path.dirname(generatedLCGFile)); + concat(localizationTargets); var missingFiles = expectedFiles.filter(function (f) { return !fs.existsSync(f); }); diff --git a/scripts/generateLocalizedDiagnosticMessages.ts b/scripts/generateLocalizedDiagnosticMessages.ts index edfe957515516..d7d5f5c0e7969 100644 --- a/scripts/generateLocalizedDiagnosticMessages.ts +++ b/scripts/generateLocalizedDiagnosticMessages.ts @@ -27,16 +27,54 @@ function main(): void { function visitDirectory(name: string) { const inputFilePath = path.join(inputPath, name, "diagnosticMessages", "diagnosticMessages.generated.json.lcl"); - const outputFilePath = path.join(outputPath, name, "diagnosticMessages.generated.json"); + fs.readFile(inputFilePath, (err, data) => { handleError(err); xml2js.parseString(data.toString(), (err, result) => { handleError(err); - writeFile(outputFilePath, xmlObjectToString(result)); + if (!result || !result.LCX || !result.LCX.$ || !result.LCX.$.TgtCul) { + console.error("Unexpected XML file structure. Expected to find result.LCX.$.TgtCul."); + process.exit(1); + } + const outputDirectoryName = getPreferedLocaleName(result.LCX.$.TgtCul); + if (!outputDirectoryName) { + console.error(`Invalid output locale name for '${result.LCX.$.TgtCul}'.`); + process.exit(1); + } + writeFile(path.join(outputPath, outputDirectoryName, "diagnosticMessages.generated.json"), xmlObjectToString(result)); }); }); } + /** + * A locale name is based on the language tagging conventions of RFC 4646 (Windows Vista + * and later), and is represented by LOCALE_SNAME. + * Generally, the pattern - is used. Here, language is a lowercase ISO 639 + * language code. The codes from ISO 639-1 are used when available. Otherwise, codes from + * ISO 639-2/T are used. REGION specifies an uppercase ISO 3166-1 country/region identifier. + * For example, the locale name for English (United States) is "en-US" and the locale name + * for Divehi (Maldives) is "dv-MV". + * + * If the locale is a neutral locale (no region), the LOCALE_SNAME value follows the + * pattern . If it is a neutral locale for which the script is significant, the + * pattern is -