107 lines
3.5 KiB
Swift
107 lines
3.5 KiB
Swift
//
|
|
// Copyright 2022 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import Foundation
|
|
|
|
// Maps Smartling language codes to App Store Connect language codes.
|
|
private let languageMap: [String: [String]] = [
|
|
// These languages are returned from Smartling and need to be moved to their correct final destination.
|
|
"ar": ["ar-SA"],
|
|
"ca": ["ca"],
|
|
"cs": ["cs"],
|
|
"da": ["da"],
|
|
"de": ["de-DE"],
|
|
"el": ["el"],
|
|
"es": ["es-ES", "es-MX"],
|
|
"fi": ["fi"],
|
|
"fr": ["fr-CA", "fr-FR"],
|
|
"he": ["he"],
|
|
"hi-IN": ["hi"],
|
|
"hr-HR": ["hr"],
|
|
"hu": ["hu"],
|
|
"id": ["id"],
|
|
"it": ["it"],
|
|
"ja": ["ja"],
|
|
"ko": ["ko"],
|
|
"ms": ["ms"],
|
|
"nb": ["no"],
|
|
"nl": ["nl-NL"],
|
|
"pl": ["pl"],
|
|
"pt-BR": ["pt-BR"],
|
|
"pt-PT": ["pt-PT"],
|
|
"ro-RO": ["ro"],
|
|
"ru": ["ru"],
|
|
"sk-SK": ["sk"],
|
|
"sv": ["sv"],
|
|
"th": ["th"],
|
|
"tr": ["tr"],
|
|
"uk-UA": ["uk"],
|
|
"vi": ["vi"],
|
|
"zh-CN": ["zh-Hans"],
|
|
"zh-HK": ["zh-Hant"]
|
|
|
|
// These don't exist in App Store Connect, so there's no need to fetch them from Smartling.
|
|
// "bn-BD": [],
|
|
// "fa-IR": [],
|
|
// "ga-IE": [],
|
|
// "gu-IN": [],
|
|
// "mr-IN": [],
|
|
// "sr-YR": [],
|
|
// "ug": [],
|
|
// "ur": [],
|
|
// "yue": [],
|
|
// "zh-TW": [],
|
|
]
|
|
|
|
private let extraEnglishLanguages: [String] = ["en-AU", "en-CA", "en-GB"]
|
|
|
|
struct MetadataFile: TranslatableFile {
|
|
var filename: String
|
|
|
|
var relativeSourcePath: String { relativePath(for: "en-US") }
|
|
|
|
private static let relativeDirectoryPath = "fastlane/metadata"
|
|
|
|
private func relativePath(for languageCode: String) -> String {
|
|
return "\(Self.relativeDirectoryPath)/\(languageCode)/\(filename)"
|
|
}
|
|
|
|
func downloadAllTranslations(to repositoryURL: URL, using client: Smartling) async throws {
|
|
try await withLimitedThrowingTaskGroup(limit: Constant.concurrentRequestLimit) { taskGroup in
|
|
try await taskGroup.addTask {
|
|
// English is special. Instead of downloading a file, we copy the file we
|
|
// uploaded to other English languages.
|
|
let fileURL = repositoryURL.appendingPathComponent(relativeSourcePath)
|
|
try processDownloadedFile(at: fileURL, repositoryURL: repositoryURL, localIdentifiers: extraEnglishLanguages)
|
|
}
|
|
for (remoteIdentifier, localIdentifiers) in languageMap {
|
|
try await taskGroup.addTask {
|
|
let fileURL = try await client.downloadTranslatedFile(for: filename, in: remoteIdentifier)
|
|
try processDownloadedFile(at: fileURL, repositoryURL: repositoryURL, localIdentifiers: localIdentifiers)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func processDownloadedFile(at fileURL: URL, repositoryURL: URL, localIdentifiers: [String]) throws {
|
|
for localIdentifier in localIdentifiers {
|
|
let localRelativePath = relativePath(for: localIdentifier)
|
|
try FileManager.default.copyItem(
|
|
at: fileURL,
|
|
replacingItemAt: repositoryURL.appendingPathComponent(localRelativePath)
|
|
)
|
|
print("Saved \(localRelativePath)")
|
|
}
|
|
}
|
|
|
|
static func checkForUnusedLocalizations(in repositoryURL: URL) throws {
|
|
try checkForUnusedLocalizations(
|
|
in: repositoryURL.appendingPathComponent(Self.relativeDirectoryPath),
|
|
suffix: "",
|
|
expectedLocalizations: languageMap.flatMap { $1 } + extraEnglishLanguages + ["en-US"]
|
|
)
|
|
}
|
|
}
|