forked from slang-i18n/slang
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnormalize.dart
More file actions
112 lines (96 loc) · 3.36 KB
/
normalize.dart
File metadata and controls
112 lines (96 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import 'package:collection/collection.dart';
import 'package:slang/src/builder/builder/translation_map_builder.dart';
import 'package:slang/src/builder/model/enums.dart';
import 'package:slang/src/builder/model/i18n_locale.dart';
import 'package:slang/src/builder/model/slang_file_collection.dart';
import 'package:slang/src/builder/utils/file_utils.dart';
import 'package:slang/src/builder/utils/path_utils.dart';
import 'package:slang/src/runner/apply.dart';
import 'package:slang/src/utils/log.dart' as log;
const _supportedFiles = [FileType.json, FileType.yaml];
/// Normalizes the translation files according to the base locale.
///
/// As a side effect, this command also reformats the translation file/files.
Future<void> runNormalize({
required SlangFileCollection fileCollection,
required List<String> arguments,
}) async {
I18nLocale? targetLocale; // only this locale will be considered
for (final a in arguments) {
if (a.startsWith('--locale=')) {
targetLocale = I18nLocale.fromString(a.substring(9));
}
}
final translationMap = await TranslationMapBuilder.build(
fileCollection: fileCollection,
);
final baseTranslationMap = translationMap[fileCollection.config.baseLocale]!;
if (targetLocale != null) {
log.info('Target: <${targetLocale.languageTag}>');
await _normalizeLocale(
fileCollection: fileCollection,
locale: targetLocale,
baseTranslations: baseTranslationMap,
);
} else {
log.info('Target: all locales');
for (final locale in translationMap.getLocales()) {
await _normalizeLocale(
fileCollection: fileCollection,
locale: locale,
baseTranslations: baseTranslationMap,
);
}
}
log.info('Normalization finished!');
}
/// Normalizes all files for the given [locale].
Future<void> _normalizeLocale({
required SlangFileCollection fileCollection,
required I18nLocale locale,
required Map<String, Map<String, dynamic>> baseTranslations,
}) async {
final fileMap = <String, TranslationFile>{}; // namespace -> file
for (final file in fileCollection.files) {
if (file.locale == locale) {
fileMap[file.namespace] = file;
}
}
if (fileMap.isEmpty) {
throw 'Could not find a file for locale <${locale.languageTag}>';
}
for (final entry in fileMap.entries) {
await _normalizeFile(
baseTranslations: baseTranslations[entry.key] ?? {},
destinationFile: entry.value,
);
}
}
/// Reads the [destinationFile]
/// and normalizes the order according to [baseTranslations].
///
/// In namespace mode, this function represents ONE namespace.
/// [baseTranslations] should also only contain the selected namespace.
Future<void> _normalizeFile({
required Map<String, dynamic> baseTranslations,
required TranslationFile destinationFile,
}) async {
final existingFile = destinationFile;
final fileType = _supportedFiles.firstWhereOrNull(
(type) => type.name == PathUtils.getFileExtension(existingFile.path));
if (fileType == null) {
throw FileTypeNotSupportedError(existingFile.path);
}
final parsedContent = await existingFile.readAndParse(fileType);
final appliedTranslations = applyMapRecursive(
baseMap: baseTranslations,
newMap: const {},
oldMap: parsedContent,
verbose: true,
);
FileUtils.writeFileOfType(
fileType: fileType,
path: existingFile.path,
content: appliedTranslations,
);
}