<commit_before>/// <reference path="./before-prepare.d.ts" />

import * as fs from "fs";
import * as mkdirp from "mkdirp";
import * as path from "path";
import { encodeKey, encodeValue } from "../sources/resource.ios";

export function createResourceFile(
  appResourcesDir: string,
  language: string,
  isDefaultLanguage: boolean,
  i18nContentIterator: Iterable<I18nEntry>
) {
  const lngResourcesDir = path.join(appResourcesDir, "iOS", `${language}.lproj`);
  fs.existsSync(lngResourcesDir) || mkdirp.sync(lngResourcesDir);
  const resourceFilePath = path.join(lngResourcesDir, "Localizable.strings");
	const stream = fs.createWriteStream(resourceFilePath);
	for (const { key, value } of i18nContentIterator) {
		const encodedKey = encodeKey(key);
		const encodedValue = encodeValue(value);
		stream.write(`"${encodedKey}" = "${encodedValue}";\n`);
		if (key === "app.name") {
      writeAppNameToInfoPlistStrings(lngResourcesDir, encodedValue);
		}
	}
	stream.end();
	if (isDefaultLanguage) {
    writeDefaultLanguageToInfoPlist(appResourcesDir, language);
	}
}

function writeAppNameToInfoPlistStrings(lngResourcesDir: string, encodedAppName: string) {
  const infoPlistStringsFilePath = path.join(lngResourcesDir, "InfoPlist.strings");
  let infoPlistStringsContent = readFileSync(infoPlistStringsFilePath);
  for (const key of ["CFBundleDisplayName", "CFBundleName"]) {
    const pattern = new RegExp(`^(\\s*?"?${key}"?\\s*?=)\\s*?"?.*?"?\\s*?;\\s*?$`, "gm");
    if (infoPlistStringsContent.match(pattern)) {
      infoPlistStringsContent = infoPlistStringsContent.replace(pattern, `$1 "${encodedAppName}";`);
    } else {
      infoPlistStringsContent += `\n"${key}" = "${encodedAppName}";\n`;
    }
  }
  fs.writeFileSync(infoPlistStringsFilePath, infoPlistStringsContent);
}

function writeDefaultLanguageToInfoPlist(appResourcesDir: string, defaultLanguage: string) {
  const infoPlistFilePath = path.join(appResourcesDir, "iOS", "Info.plist");
  let infoPlistContent = readFileSync(infoPlistFilePath);
  infoPlistContent = infoPlistContent.replace(
    /(<key>CFBundleDevelopmentRegion<\/key>\s*<string>).*?(<\/string>)/, `$1${defaultLanguage}$2`
  );
  fs.writeFileSync(infoPlistFilePath, infoPlistContent);
}

// TODO Write fallback language

function readFileSync(filePath: string): string {
  try {
    return fs.readFileSync(filePath, "utf8");
  } catch (error) {
    return "";
  }
}<commit_msg>Add fallback app name for iOS<commit_after>/// <reference path="./before-prepare.d.ts" />

import * as fs from "fs";
import * as mkdirp from "mkdirp";
import * as path from "path";
import { replace } from "../sources/resource.common";
import { encodeKey, encodeValue } from "../sources/resource.ios";

export function createResourceFile(
  appResourcesDir: string,
  language: string,
  isDefaultLanguage: boolean,
  i18nContentIterator: Iterable<I18nEntry>
) {
  const lngResourcesDir = path.join(appResourcesDir, "iOS", `${language}.lproj`);
  fs.existsSync(lngResourcesDir) || mkdirp.sync(lngResourcesDir);
  const resourceFilePath = path.join(lngResourcesDir, "Localizable.strings");
	const stream = fs.createWriteStream(resourceFilePath);
	for (const { key, value } of i18nContentIterator) {
		const encodedKey = encodeKey(key);
		const encodedValue = encodeValue(value);
		stream.write(`"${encodedKey}" = "${encodedValue}";\n`);
		if (key === "app.name") {
      writeAppNameToInfoPlistStrings(lngResourcesDir, encodedValue);
      if (isDefaultLanguage) {
        writeFallbackAppNameToInfoPlist(appResourcesDir, value);
      }
		}
	}
	stream.end();
	if (isDefaultLanguage) {
    writeDefaultLanguageToInfoPlist(appResourcesDir, language);
	}
}

function writeAppNameToInfoPlistStrings(lngResourcesDir: string, encodedAppName: string) {
  const infoPlistStringsFilePath = path.join(lngResourcesDir, "InfoPlist.strings");
  let infoPlistStringsContent = readFileSync(infoPlistStringsFilePath);
  for (const key of ["CFBundleDisplayName", "CFBundleName"]) {
    const pattern = new RegExp(`^(\\s*?"?${key}"?\\s*?=)\\s*?"?.*?"?\\s*?;\\s*?$`, "gm");
    if (infoPlistStringsContent.match(pattern)) {
      infoPlistStringsContent = infoPlistStringsContent.replace(pattern, `$1 "${encodedAppName}";`);
    } else {
      infoPlistStringsContent += `\n"${key}" = "${encodedAppName}";\n`;
    }
  }
  fs.writeFileSync(infoPlistStringsFilePath, infoPlistStringsContent);
}

function writeFallbackAppNameToInfoPlist(appResourcesDir: string, appName: string) {
  const encodedAppName = replace(["<", "&"], ["&lt;", "&amp;"], appName);
  const infoPlistFilePath = path.join(appResourcesDir, "iOS", "Info.plist");
  let infoPlistContent = readFileSync(infoPlistFilePath);
  infoPlistContent = infoPlistContent.replace(
    /(<key>CFBundleDisplayName<\/key>\s*<string>).*?(<\/string>)/, `$1${encodedAppName}$2`
  );
  infoPlistContent = infoPlistContent.replace(
    /(<key>CFBundleName<\/key>\s*<string>).*?(<\/string>)/, `$1${encodedAppName}$2`
  );
  fs.writeFileSync(infoPlistFilePath, infoPlistContent);
}

function writeDefaultLanguageToInfoPlist(appResourcesDir: string, defaultLanguage: string) {
  const infoPlistFilePath = path.join(appResourcesDir, "iOS", "Info.plist");
  let infoPlistContent = readFileSync(infoPlistFilePath);
  infoPlistContent = infoPlistContent.replace(
    /(<key>CFBundleDevelopmentRegion<\/key>\s*<string>).*?(<\/string>)/, `$1${defaultLanguage}$2`
  );
  fs.writeFileSync(infoPlistFilePath, infoPlistContent);
}

function readFileSync(filePath: string): string {
  try {
    return fs.readFileSync(filePath, "utf8");
  } catch (error) {
    return "";
  }
}
{'fraction_non_alphanumeric': 0.15631691648822268, 'fraction_numerical': 0.004282655246252677, 'mean_word_length': 5.625295508274232, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5143468', 'n_tokens_mistral': 1847, 'n_tokens_neox': 1815, 'n_words': 320}