Skip to content

Commit 3c0abb8

Browse files
committed
Add support to regenerate nsl cache if corrupted.
1 parent e79e446 commit 3c0abb8

6 files changed

Lines changed: 134 additions & 55 deletions

File tree

src/bootstrap-amd.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ function readFile(file) {
2929
});
3030
}
3131

32+
const writeFile = (file, content) => new Promise((c, e) => fs.writeFile(file, content, 'utf8', err => err ? e(err) : c()));
33+
3234
var rawNlsConfig = process.env['VSCODE_NLS_CONFIG'];
3335
var nlsConfig = rawNlsConfig ? JSON.parse(rawNlsConfig) : { availableLanguages: {} };
3436

@@ -46,8 +48,15 @@ if (nlsConfig._resolvedLanguagePackCoreLocation) {
4648
let json = JSON.parse(content);
4749
bundles[bundle] = json;
4850
cb(undefined, json);
49-
})
50-
.catch(cb);
51+
}).catch((error) => {
52+
try {
53+
if (nlsConfig._corruptedFile) {
54+
writeFile(nlsConfig._corruptedFile, 'corrupted').catch(function (error) { console.error(error); });
55+
}
56+
} finally {
57+
cb(error, undefined);
58+
}
59+
});
5160
};
5261
}
5362

src/main.js

Lines changed: 79 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ const exists = file => new Promise(c => fs.exists(file, c));
123123
const readFile = file => new Promise((c, e) => fs.readFile(file, 'utf8', (err, data) => err ? e(err) : c(data)));
124124
const writeFile = (file, content) => new Promise((c, e) => fs.writeFile(file, content, 'utf8', err => err ? e(err) : c()));
125125
const touch = file => new Promise((c, e) => { const d = new Date(); fs.utimes(file, d, d, err => err ? e(err) : c()); });
126+
const lstat = file => new Promise((c, e) => fs.lstat(file, (err, stats) => err ? e(err) : c(stats)));
127+
const readdir = dir => new Promise((c, e) => fs.readdir(dir, (err, files) => err ? e(err) : c(files)));
128+
const rmdir = dir => new Promise((c, e) => fs.rmdir(dir, err => err ? e(err) : c(undefined)));
129+
const unlink = file => new Promise((c, e) => fs.unlink(file, err => err ? e(err) : c(undefined)));
126130

127131
function mkdirp(dir) {
128132
return mkdir(dir).then(null, err => {
@@ -138,6 +142,23 @@ function mkdirp(dir) {
138142
});
139143
}
140144

145+
function rimraf(location) {
146+
return lstat(location).then(stat => {
147+
if (stat.isDirectory() && !stat.isSymbolicLink()) {
148+
return readdir(location)
149+
.then(children => Promise.all(children.map(child => rimraf(path.join(location, child)))))
150+
.then(() => rmdir(location));
151+
} else {
152+
return unlink(location);
153+
}
154+
}, (err) => {
155+
if (err.code === 'ENOENT') {
156+
return void 0;
157+
}
158+
throw err;
159+
});
160+
}
161+
141162
function resolveJSFlags(...jsFlags) {
142163

143164
if (args['js-flags']) {
@@ -267,62 +288,75 @@ function getNLSConfiguration(locale) {
267288
let cacheRoot = path.join(userData, 'clp', packId);
268289
let coreLocation = path.join(cacheRoot, commit);
269290
let translationsConfigFile = path.join(cacheRoot, 'tcf.json');
291+
let corruptedFile = path.join(cacheRoot, 'corrupted.info');
270292
let result = {
271293
locale: initialLocale,
272294
availableLanguages: { '*': locale },
273295
_languagePackId: packId,
274296
_translationsConfigFile: translationsConfigFile,
275297
_cacheRoot: cacheRoot,
276-
_resolvedLanguagePackCoreLocation: coreLocation
298+
_resolvedLanguagePackCoreLocation: coreLocation,
299+
_corruptedFile: corruptedFile
277300
};
278-
return exists(coreLocation).then((fileExists) => {
279-
if (fileExists) {
280-
// We don't wait for this. No big harm if we can't touch
281-
touch(coreLocation).catch(() => { });
282-
perf.mark('nlsGeneration:end');
283-
return result;
301+
return exists(corruptedFile).then((corrupted) => {
302+
// The nls cache directory is corrupted.
303+
let toDelete;
304+
if (corrupted) {
305+
toDelete = rimraf(cacheRoot);
306+
} else {
307+
toDelete = Promise.resolve(undefined);
284308
}
285-
return mkdirp(coreLocation).then(() => {
286-
return Promise.all([readFile(path.join(__dirname, 'nls.metadata.json')), readFile(mainPack)]);
287-
}).then((values) => {
288-
let metadata = JSON.parse(values[0]);
289-
let packData = JSON.parse(values[1]).contents;
290-
let bundles = Object.keys(metadata.bundles);
291-
let writes = [];
292-
for (let bundle of bundles) {
293-
let modules = metadata.bundles[bundle];
294-
let target = Object.create(null);
295-
for (let module of modules) {
296-
let keys = metadata.keys[module];
297-
let defaultMessages = metadata.messages[module];
298-
let translations = packData[module];
299-
let targetStrings;
300-
if (translations) {
301-
targetStrings = [];
302-
for (let i = 0; i < keys.length; i++) {
303-
let elem = keys[i];
304-
let key = typeof elem === 'string' ? elem : elem.key;
305-
let translatedMessage = translations[key];
306-
if (translatedMessage === undefined) {
307-
translatedMessage = defaultMessages[i];
309+
return toDelete.then(() => {
310+
return exists(coreLocation).then((fileExists) => {
311+
if (fileExists) {
312+
// We don't wait for this. No big harm if we can't touch
313+
touch(coreLocation).catch(() => { });
314+
perf.mark('nlsGeneration:end');
315+
return result;
316+
}
317+
return mkdirp(coreLocation).then(() => {
318+
return Promise.all([readFile(path.join(__dirname, 'nls.metadata.json')), readFile(mainPack)]);
319+
}).then((values) => {
320+
let metadata = JSON.parse(values[0]);
321+
let packData = JSON.parse(values[1]).contents;
322+
let bundles = Object.keys(metadata.bundles);
323+
let writes = [];
324+
for (let bundle of bundles) {
325+
let modules = metadata.bundles[bundle];
326+
let target = Object.create(null);
327+
for (let module of modules) {
328+
let keys = metadata.keys[module];
329+
let defaultMessages = metadata.messages[module];
330+
let translations = packData[module];
331+
let targetStrings;
332+
if (translations) {
333+
targetStrings = [];
334+
for (let i = 0; i < keys.length; i++) {
335+
let elem = keys[i];
336+
let key = typeof elem === 'string' ? elem : elem.key;
337+
let translatedMessage = translations[key];
338+
if (translatedMessage === undefined) {
339+
translatedMessage = defaultMessages[i];
340+
}
341+
targetStrings.push(translatedMessage);
342+
}
343+
} else {
344+
targetStrings = defaultMessages;
308345
}
309-
targetStrings.push(translatedMessage);
346+
target[module] = targetStrings;
310347
}
311-
} else {
312-
targetStrings = defaultMessages;
348+
writes.push(writeFile(path.join(coreLocation, bundle.replace(/\//g, '!') + '.nls.json'), JSON.stringify(target)));
313349
}
314-
target[module] = targetStrings;
315-
}
316-
writes.push(writeFile(path.join(coreLocation, bundle.replace(/\//g, '!') + '.nls.json'), JSON.stringify(target)));
317-
}
318-
writes.push(writeFile(translationsConfigFile, JSON.stringify(packConfig.translations)));
319-
return Promise.all(writes);
320-
}).then(() => {
321-
perf.mark('nlsGeneration:end');
322-
return result;
323-
}).catch((err) => {
324-
console.error('Generating translation files failed.', err);
325-
return defaultResult(locale);
350+
writes.push(writeFile(translationsConfigFile, JSON.stringify(packConfig.translations)));
351+
return Promise.all(writes);
352+
}).then(() => {
353+
perf.mark('nlsGeneration:end');
354+
return result;
355+
}).catch((err) => {
356+
console.error('Generating translation files failed.', err);
357+
return defaultResult(locale);
358+
});
359+
});
326360
});
327361
});
328362
});

src/vs/code/electron-browser/issue/issueReporter.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ function readFile(file) {
4545
});
4646
}
4747

48+
const writeFile = (file, content) => new Promise((c, e) => fs.writeFile(file, content, 'utf8', err => err ? e(err) : c()));
49+
4850
function main() {
4951
const args = parseURLQueryArgs();
5052
const configuration = JSON.parse(args['config'] || '{}') || {};
@@ -127,8 +129,15 @@ function main() {
127129
let json = JSON.parse(content);
128130
bundles[bundle] = json;
129131
cb(undefined, json);
130-
})
131-
.catch(cb);
132+
}).catch((error) => {
133+
try {
134+
if (nlsConfig._corruptedFile) {
135+
writeFile(nlsConfig._corruptedFile, 'corrupted').catch(function (error) { console.error(error); });
136+
}
137+
} finally {
138+
cb(error, undefined);
139+
}
140+
});
132141
};
133142
}
134143

src/vs/code/electron-browser/processExplorer/processExplorer.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ function readFile(file) {
4545
});
4646
}
4747

48+
const writeFile = (file, content) => new Promise((c, e) => fs.writeFile(file, content, 'utf8', err => err ? e(err) : c()));
49+
4850
function main() {
4951
const args = parseURLQueryArgs();
5052
const configuration = JSON.parse(args['config'] || '{}') || {};
@@ -102,8 +104,15 @@ function main() {
102104
let json = JSON.parse(content);
103105
bundles[bundle] = json;
104106
cb(undefined, json);
105-
})
106-
.catch(cb);
107+
}).catch((error) => {
108+
try {
109+
if (nlsConfig._corruptedFile) {
110+
writeFile(nlsConfig._corruptedFile, 'corrupted').catch(function (error) { console.error(error); });
111+
}
112+
} finally {
113+
cb(error, undefined);
114+
}
115+
});
107116
};
108117
}
109118

src/vs/code/electron-browser/sharedProcess/sharedProcess.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ function readFile(file) {
5353
});
5454
}
5555

56+
const writeFile = (file, content) => new Promise((c, e) => fs.writeFile(file, content, 'utf8', err => err ? e(err) : c()));
57+
5658
function main() {
5759
const args = parseURLQueryArgs();
5860
const configuration = JSON.parse(args['config'] || '{}') || {};
@@ -111,8 +113,15 @@ function main() {
111113
let json = JSON.parse(content);
112114
bundles[bundle] = json;
113115
cb(undefined, json);
114-
})
115-
.catch(cb);
116+
}).catch((error) => {
117+
try {
118+
if (nlsConfig._corruptedFile) {
119+
writeFile(nlsConfig._corruptedFile, 'corrupted').catch(function (error) { console.error(error); });
120+
}
121+
} finally {
122+
cb(error, undefined);
123+
}
124+
});
116125
};
117126
}
118127

src/vs/workbench/electron-browser/bootstrap/index.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ function readFile(file) {
8181
});
8282
}
8383

84+
const writeFile = (file, content) => new Promise((c, e) => fs.writeFile(file, content, 'utf8', err => err ? e(err) : c()));
85+
8486
function registerListeners(enableDeveloperTools) {
8587

8688
// Devtools & reload support
@@ -180,8 +182,15 @@ function main() {
180182
let json = JSON.parse(content);
181183
bundles[bundle] = json;
182184
cb(undefined, json);
183-
})
184-
.catch(cb);
185+
}).catch((error) => {
186+
try {
187+
if (nlsConfig._corruptedFile) {
188+
writeFile(nlsConfig._corruptedFile, 'corrupted').catch(function (error) { console.error(error); });
189+
}
190+
} finally {
191+
cb(error, undefined);
192+
}
193+
});
185194
};
186195
}
187196

0 commit comments

Comments
 (0)