-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
Copy pathgulp-transifex-test.js
183 lines (149 loc) · 5.59 KB
/
gulp-transifex-test.js
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import fs from 'fs';
import _ from 'lodash';
import gulp from 'gulp';
import { postToSlack, conf } from './taskHelper';
const SLACK_CONFIG = {
channel: conf.get('TRANSIFEX_SLACK_CHANNEL'),
username: 'Transifex',
emoji: 'transifex',
};
const LOCALES = './website/common/locales/';
const ENGLISH_LOCALE = `${LOCALES}en/`;
function getArrayOfLanguages () {
const languages = fs.readdirSync(LOCALES);
languages.shift(); // Remove README.md from array of languages
return languages;
}
const ALL_LANGUAGES = getArrayOfLanguages();
function stripOutNonJsonFiles (collection) {
const onlyJson = _.filter(collection, file => file.match(/[a-zA-Z]*\.json/));
return onlyJson;
}
function eachTranslationFile (languages, cb) {
const jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
_.each(languages, lang => {
_.each(jsonFiles, filename => {
let parsedTranslationFile;
try {
const translationFile = fs.readFileSync(`${LOCALES}${lang}/${filename}`);
parsedTranslationFile = JSON.parse(translationFile);
} catch (err) {
return cb(err);
}
const englishFile = fs.readFileSync(ENGLISH_LOCALE + filename);
const parsedEnglishFile = JSON.parse(englishFile);
return cb(null, lang, filename, parsedEnglishFile, parsedTranslationFile);
});
});
}
function eachTranslationString (languages, cb) {
eachTranslationFile(languages, (error, language, filename, englishJSON, translationJSON) => {
if (error) return;
_.each(englishJSON, (string, key) => {
const translationString = translationJSON[key];
cb(language, filename, key, string, translationString);
});
});
}
function formatMessageForPosting (msg, items) {
let body = `*Warning:* ${msg}`;
body += '\n\n```\n';
body += items.join('\n');
body += '\n```';
return body;
}
function getStringsWith (json, interpolationRegex) {
const strings = {};
_.each(json, fileName => {
const rawFile = fs.readFileSync(ENGLISH_LOCALE + fileName);
const parsedJson = JSON.parse(rawFile);
strings[fileName] = {};
_.each(parsedJson, (value, key) => {
const match = value.match(interpolationRegex);
if (match) strings[fileName][key] = match;
});
});
return strings;
}
const malformedStringExceptions = {
messageDropFood: true,
armoireFood: true,
feedPet: true,
};
gulp.task('transifex:missingFiles', done => {
const missingStrings = [];
eachTranslationFile(ALL_LANGUAGES, error => {
if (error) {
missingStrings.push(error.path);
}
});
if (!_.isEmpty(missingStrings)) {
const message = 'the following files were missing from the translations folder';
const formattedMessage = formatMessageForPosting(message, missingStrings);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
});
gulp.task('transifex:missingStrings', done => {
const missingStrings = [];
eachTranslationString(ALL_LANGUAGES, (lang, filename, key, englishString, translationString) => {
if (!translationString) {
const errorString = `${lang} - ${filename} - ${key} - ${englishString}`;
missingStrings.push(errorString);
}
});
if (!_.isEmpty(missingStrings)) {
const message = 'The following strings are not translated';
const formattedMessage = formatMessageForPosting(message, missingStrings);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
});
gulp.task('transifex:malformedStrings', done => {
const jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
const interpolationRegex = /<%= [a-zA-Z]* %>/g;
const stringsToLookFor = getStringsWith(jsonFiles, interpolationRegex);
const stringsWithMalformedInterpolations = [];
const stringsWithIncorrectNumberOfInterpolations = [];
_.each(ALL_LANGUAGES, lang => {
_.each(stringsToLookFor, (strings, filename) => {
const translationFile = fs.readFileSync(`${LOCALES}${lang}/${filename}`);
const parsedTranslationFile = JSON.parse(translationFile);
_.each(strings, (value, key) => { // eslint-disable-line max-nested-callbacks
const translationString = parsedTranslationFile[key];
if (!translationString) return;
const englishOccurences = stringsToLookFor[filename][key];
const translationOccurences = translationString.match(interpolationRegex);
if (!translationOccurences) {
const malformedString = `${lang} - ${filename} - ${key} - ${translationString}`;
stringsWithMalformedInterpolations.push(malformedString);
} else if (
englishOccurences.length !== translationOccurences.length
&& !malformedStringExceptions[key]
) {
const missingInterpolationString = `${lang} - ${filename} - ${key} - ${translationString}`;
stringsWithIncorrectNumberOfInterpolations.push(missingInterpolationString);
}
});
});
});
if (!_.isEmpty(stringsWithMalformedInterpolations)) {
const message = 'The following strings have malformed or missing interpolations';
const formattedMessage = formatMessageForPosting(message, stringsWithMalformedInterpolations);
postToSlack(formattedMessage, SLACK_CONFIG);
}
if (!_.isEmpty(stringsWithIncorrectNumberOfInterpolations)) {
const message = 'The following strings have a different number of string interpolations';
const formattedMessage = formatMessageForPosting(
message,
stringsWithIncorrectNumberOfInterpolations,
);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
});
gulp.task(
'transifex',
gulp.series('transifex:missingFiles', 'transifex:missingStrings', 'transifex:malformedStrings'),
done => done(),
);