Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/build/gulpfile.vscode.ts
4770 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import gulp from 'gulp';
7
import * as fs from 'fs';
8
import * as path from 'path';
9
import es from 'event-stream';
10
import vfs from 'vinyl-fs';
11
import rename from 'gulp-rename';
12
import replace from 'gulp-replace';
13
import filter from 'gulp-filter';
14
import electron from '@vscode/gulp-electron';
15
import jsonEditor from 'gulp-json-editor';
16
import * as util from './lib/util.ts';
17
import { getVersion } from './lib/getVersion.ts';
18
import { readISODate } from './lib/date.ts';
19
import * as task from './lib/task.ts';
20
import buildfile from './buildfile.ts';
21
import * as optimize from './lib/optimize.ts';
22
import { inlineMeta } from './lib/inlineMeta.ts';
23
import packageJson from '../package.json' with { type: 'json' };
24
import product from '../product.json' with { type: 'json' };
25
import * as crypto from 'crypto';
26
import * as i18n from './lib/i18n.ts';
27
import { getProductionDependencies } from './lib/dependencies.ts';
28
import { config } from './lib/electron.ts';
29
import { createAsar } from './lib/asar.ts';
30
import minimist from 'minimist';
31
import { compileBuildWithoutManglingTask, compileBuildWithManglingTask } from './gulpfile.compile.ts';
32
import { compileNonNativeExtensionsBuildTask, compileNativeExtensionsBuildTask, compileAllExtensionsBuildTask, compileExtensionMediaBuildTask, cleanExtensionsBuildTask } from './gulpfile.extensions.ts';
33
import { promisify } from 'util';
34
import globCallback from 'glob';
35
import rceditCallback from 'rcedit';
36
37
38
const glob = promisify(globCallback);
39
const rcedit = promisify(rceditCallback);
40
const root = path.dirname(import.meta.dirname);
41
const commit = getVersion(root);
42
const versionedResourcesFolder = (product as typeof product & { quality?: string })?.quality === 'insider' ? commit!.substring(0, 10) : '';
43
44
// Build
45
const vscodeEntryPoints = [
46
buildfile.workerEditor,
47
buildfile.workerExtensionHost,
48
buildfile.workerNotebook,
49
buildfile.workerLanguageDetection,
50
buildfile.workerLocalFileSearch,
51
buildfile.workerProfileAnalysis,
52
buildfile.workerOutputLinks,
53
buildfile.workerBackgroundTokenization,
54
buildfile.workbenchDesktop,
55
buildfile.code
56
].flat();
57
58
const vscodeResourceIncludes = [
59
60
// NLS
61
'out-build/nls.messages.json',
62
'out-build/nls.keys.json',
63
64
// Workbench
65
'out-build/vs/code/electron-browser/workbench/workbench.html',
66
67
// Electron Preload
68
'out-build/vs/base/parts/sandbox/electron-browser/preload.js',
69
'out-build/vs/base/parts/sandbox/electron-browser/preload-aux.js',
70
71
// Node Scripts
72
'out-build/vs/base/node/{terminateProcess.sh,cpuUsage.sh,ps.sh}',
73
74
// Touchbar
75
'out-build/vs/workbench/browser/parts/editor/media/*.png',
76
'out-build/vs/workbench/contrib/debug/browser/media/*.png',
77
78
// External Terminal
79
'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt',
80
81
// Terminal shell integration
82
'out-build/vs/workbench/contrib/terminal/common/scripts/*.fish',
83
'out-build/vs/workbench/contrib/terminal/common/scripts/*.ps1',
84
'out-build/vs/workbench/contrib/terminal/common/scripts/*.psm1',
85
'out-build/vs/workbench/contrib/terminal/common/scripts/*.sh',
86
'out-build/vs/workbench/contrib/terminal/common/scripts/*.zsh',
87
88
// Accessibility Signals
89
'out-build/vs/platform/accessibilitySignal/browser/media/*.mp3',
90
91
// Welcome
92
'out-build/vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.{svg,png}',
93
94
// Extensions
95
'out-build/vs/workbench/contrib/extensions/browser/media/{theme-icon.png,language-icon.svg}',
96
'out-build/vs/workbench/services/extensionManagement/common/media/*.{svg,png}',
97
98
// Webview
99
'out-build/vs/workbench/contrib/webview/browser/pre/*.{js,html}',
100
101
// Extension Host Worker
102
'out-build/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html',
103
104
// Tree Sitter highlights
105
'out-build/vs/editor/common/languages/highlights/*.scm',
106
107
// Tree Sitter injection queries
108
'out-build/vs/editor/common/languages/injections/*.scm'
109
];
110
111
const vscodeResources = [
112
113
// Includes
114
...vscodeResourceIncludes,
115
116
// Excludes
117
'!out-build/vs/code/browser/**',
118
'!out-build/vs/editor/standalone/**',
119
'!out-build/vs/code/**/*-dev.html',
120
'!out-build/vs/workbench/contrib/issue/**/*-dev.html',
121
'!**/test/**'
122
];
123
124
const bootstrapEntryPoints = [
125
'out-build/main.js',
126
'out-build/cli.js',
127
'out-build/bootstrap-fork.js'
128
];
129
130
const bundleVSCodeTask = task.define('bundle-vscode', task.series(
131
util.rimraf('out-vscode'),
132
// Optimize: bundles source files automatically based on
133
// import statements based on the passed in entry points.
134
// In addition, concat window related bootstrap files into
135
// a single file.
136
optimize.bundleTask(
137
{
138
out: 'out-vscode',
139
esm: {
140
src: 'out-build',
141
entryPoints: [
142
...vscodeEntryPoints,
143
...bootstrapEntryPoints
144
],
145
resources: vscodeResources,
146
skipTSBoilerplateRemoval: entryPoint => entryPoint === 'vs/code/electron-browser/workbench/workbench'
147
}
148
}
149
)
150
));
151
gulp.task(bundleVSCodeTask);
152
153
const sourceMappingURLBase = `https://main.vscode-cdn.net/sourcemaps/${commit}`;
154
const minifyVSCodeTask = task.define('minify-vscode', task.series(
155
bundleVSCodeTask,
156
util.rimraf('out-vscode-min'),
157
optimize.minifyTask('out-vscode', `${sourceMappingURLBase}/core`)
158
));
159
gulp.task(minifyVSCodeTask);
160
161
const coreCI = task.define('core-ci', task.series(
162
gulp.task('compile-build-with-mangling') as task.Task,
163
task.parallel(
164
gulp.task('minify-vscode') as task.Task,
165
gulp.task('minify-vscode-reh') as task.Task,
166
gulp.task('minify-vscode-reh-web') as task.Task,
167
)
168
));
169
gulp.task(coreCI);
170
171
const coreCIPR = task.define('core-ci-pr', task.series(
172
gulp.task('compile-build-without-mangling') as task.Task,
173
task.parallel(
174
gulp.task('minify-vscode') as task.Task,
175
gulp.task('minify-vscode-reh') as task.Task,
176
gulp.task('minify-vscode-reh-web') as task.Task,
177
)
178
));
179
gulp.task(coreCIPR);
180
181
/**
182
* Compute checksums for some files.
183
*
184
* @param out The out folder to read the file from.
185
* @param filenames The paths to compute a checksum for.
186
* @return A map of paths to checksums.
187
*/
188
function computeChecksums(out: string, filenames: string[]): Record<string, string> {
189
const result: Record<string, string> = {};
190
filenames.forEach(function (filename) {
191
const fullPath = path.join(process.cwd(), out, filename);
192
result[filename] = computeChecksum(fullPath);
193
});
194
return result;
195
}
196
197
/**
198
* Compute checksums for a file.
199
*
200
* @param filename The absolute path to a filename.
201
* @return The checksum for `filename`.
202
*/
203
function computeChecksum(filename: string): string {
204
const contents = fs.readFileSync(filename);
205
206
const hash = crypto
207
.createHash('sha256')
208
.update(contents)
209
.digest('base64')
210
.replace(/=+$/, '');
211
212
return hash;
213
}
214
215
function packageTask(platform: string, arch: string, sourceFolderName: string, destinationFolderName: string, _opts?: { stats?: boolean }) {
216
const destination = path.join(path.dirname(root), destinationFolderName);
217
platform = platform || process.platform;
218
219
const task = () => {
220
const out = sourceFolderName;
221
222
const checksums = computeChecksums(out, [
223
'vs/base/parts/sandbox/electron-browser/preload.js',
224
'vs/workbench/workbench.desktop.main.js',
225
'vs/workbench/workbench.desktop.main.css',
226
'vs/workbench/api/node/extensionHostProcess.js',
227
'vs/code/electron-browser/workbench/workbench.html',
228
'vs/code/electron-browser/workbench/workbench.js'
229
]);
230
231
const src = gulp.src(out + '/**', { base: '.' })
232
.pipe(rename(function (path) { path.dirname = path.dirname!.replace(new RegExp('^' + out), 'out'); }))
233
.pipe(util.setExecutableBit(['**/*.sh']));
234
235
const platformSpecificBuiltInExtensionsExclusions = product.builtInExtensions.filter(ext => {
236
if (!(ext as { platforms?: string[] }).platforms) {
237
return false;
238
}
239
240
const set = new Set((ext as { platforms?: string[] }).platforms);
241
return !set.has(platform);
242
}).map(ext => `!.build/extensions/${ext.name}/**`);
243
244
const extensions = gulp.src(['.build/extensions/**', ...platformSpecificBuiltInExtensionsExclusions], { base: '.build', dot: true });
245
246
const sources = es.merge(src, extensions)
247
.pipe(filter(['**', '!**/*.{js,css}.map'], { dot: true }));
248
249
let version = packageJson.version;
250
const quality = (product as { quality?: string }).quality;
251
252
if (quality && quality !== 'stable') {
253
version += '-' + quality;
254
}
255
256
const name = product.nameShort;
257
const packageJsonUpdates: Record<string, unknown> = { name, version };
258
259
if (platform === 'linux') {
260
packageJsonUpdates.desktopName = `${product.applicationName}.desktop`;
261
}
262
263
let packageJsonContents: string;
264
const packageJsonStream = gulp.src(['package.json'], { base: '.' })
265
.pipe(jsonEditor(packageJsonUpdates))
266
.pipe(es.through(function (file) {
267
packageJsonContents = file.contents.toString();
268
this.emit('data', file);
269
}));
270
271
let productJsonContents: string;
272
const productJsonStream = gulp.src(['product.json'], { base: '.' })
273
.pipe(jsonEditor({ commit, date: readISODate('out-build'), checksums, version }))
274
.pipe(es.through(function (file) {
275
productJsonContents = file.contents.toString();
276
this.emit('data', file);
277
}));
278
279
const license = gulp.src([product.licenseFileName, 'ThirdPartyNotices.txt', 'licenses/**'], { base: '.', allowEmpty: true });
280
281
// TODO the API should be copied to `out` during compile, not here
282
const api = gulp.src('src/vscode-dts/vscode.d.ts').pipe(rename('out/vscode-dts/vscode.d.ts'));
283
284
const telemetry = gulp.src('.build/telemetry/**', { base: '.build/telemetry', dot: true });
285
286
const jsFilter = util.filter(data => !data.isDirectory() && /\.js$/.test(data.path));
287
const root = path.resolve(path.join(import.meta.dirname, '..'));
288
const productionDependencies = getProductionDependencies(root);
289
const dependenciesSrc = productionDependencies.map(d => path.relative(root, d)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`]).flat().concat('!**/*.mk');
290
291
const deps = gulp.src(dependenciesSrc, { base: '.', dot: true })
292
.pipe(filter(['**', `!**/${config.version}/**`, '!**/bin/darwin-arm64-87/**', '!**/package-lock.json', '!**/yarn.lock', '!**/*.{js,css}.map']))
293
.pipe(util.cleanNodeModules(path.join(import.meta.dirname, '.moduleignore')))
294
.pipe(util.cleanNodeModules(path.join(import.meta.dirname, `.moduleignore.${process.platform}`)))
295
.pipe(jsFilter)
296
.pipe(util.rewriteSourceMappingURL(sourceMappingURLBase))
297
.pipe(jsFilter.restore)
298
.pipe(createAsar(path.join(process.cwd(), 'node_modules'), [
299
'**/*.node',
300
'**/@vscode/ripgrep/bin/*',
301
'**/node-pty/build/Release/*',
302
'**/node-pty/build/Release/conpty/*',
303
'**/node-pty/lib/worker/conoutSocketWorker.js',
304
'**/node-pty/lib/shared/conout.js',
305
'**/*.wasm',
306
'**/@vscode/vsce-sign/bin/*',
307
], [
308
'**/*.mk',
309
'!node_modules/vsda/**' // stay compatible with extensions that depend on us shipping `vsda` into ASAR
310
], [
311
'node_modules/vsda/**' // retain copy of `vsda` in node_modules for internal use
312
], 'node_modules.asar'));
313
314
let all = es.merge(
315
packageJsonStream,
316
productJsonStream,
317
license,
318
api,
319
telemetry,
320
sources,
321
deps
322
);
323
324
let customElectronConfig = {};
325
if (platform === 'win32') {
326
all = es.merge(all, gulp.src([
327
'resources/win32/bower.ico',
328
'resources/win32/c.ico',
329
'resources/win32/config.ico',
330
'resources/win32/cpp.ico',
331
'resources/win32/csharp.ico',
332
'resources/win32/css.ico',
333
'resources/win32/default.ico',
334
'resources/win32/go.ico',
335
'resources/win32/html.ico',
336
'resources/win32/jade.ico',
337
'resources/win32/java.ico',
338
'resources/win32/javascript.ico',
339
'resources/win32/json.ico',
340
'resources/win32/less.ico',
341
'resources/win32/markdown.ico',
342
'resources/win32/php.ico',
343
'resources/win32/powershell.ico',
344
'resources/win32/python.ico',
345
'resources/win32/react.ico',
346
'resources/win32/ruby.ico',
347
'resources/win32/sass.ico',
348
'resources/win32/shell.ico',
349
'resources/win32/sql.ico',
350
'resources/win32/typescript.ico',
351
'resources/win32/vue.ico',
352
'resources/win32/xml.ico',
353
'resources/win32/yaml.ico',
354
'resources/win32/code_70x70.png',
355
'resources/win32/code_150x150.png'
356
], { base: '.' }));
357
if (quality && quality === 'insider') {
358
customElectronConfig = {
359
createVersionedResources: true,
360
productVersionString: `${versionedResourcesFolder}`,
361
};
362
}
363
} else if (platform === 'linux') {
364
const policyDest = gulp.src('.build/policies/linux/**', { base: '.build/policies/linux' })
365
.pipe(rename(f => f.dirname = `policies/${f.dirname}`));
366
all = es.merge(all, gulp.src('resources/linux/code.png', { base: '.' }), policyDest);
367
} else if (platform === 'darwin') {
368
const shortcut = gulp.src('resources/darwin/bin/code.sh')
369
.pipe(replace('@@APPNAME@@', product.applicationName))
370
.pipe(rename('bin/code'));
371
const policyDest = gulp.src('.build/policies/darwin/**', { base: '.build/policies/darwin' })
372
.pipe(rename(f => f.dirname = `policies/${f.dirname}`));
373
all = es.merge(all, shortcut, policyDest);
374
}
375
376
let result: NodeJS.ReadWriteStream = all
377
.pipe(util.skipDirectories())
378
.pipe(util.fixWin32DirectoryPermissions())
379
.pipe(filter(['**', '!**/.github/**'], { dot: true })) // https://github.com/microsoft/vscode/issues/116523
380
.pipe(electron({ ...config, platform, arch: arch === 'armhf' ? 'arm' : arch, ffmpegChromium: false, ...customElectronConfig }))
381
.pipe(filter(['**', '!LICENSE', '!version'], { dot: true }));
382
383
if (platform === 'linux') {
384
result = es.merge(result, gulp.src('resources/completions/bash/code', { base: '.' })
385
.pipe(replace('@@APPNAME@@', product.applicationName))
386
.pipe(rename(function (f) { f.basename = product.applicationName; })));
387
388
result = es.merge(result, gulp.src('resources/completions/zsh/_code', { base: '.' })
389
.pipe(replace('@@APPNAME@@', product.applicationName))
390
.pipe(rename(function (f) { f.basename = '_' + product.applicationName; })));
391
}
392
393
if (platform === 'win32') {
394
result = es.merge(result, gulp.src('resources/win32/bin/code.js', { base: 'resources/win32', allowEmpty: true }));
395
396
if (quality && quality === 'insider') {
397
result = es.merge(result, gulp.src('resources/win32/insider/bin/code.cmd', { base: 'resources/win32/insider' })
398
.pipe(replace('@@NAME@@', product.nameShort))
399
.pipe(replace('@@VERSIONFOLDER@@', versionedResourcesFolder))
400
.pipe(rename(function (f) { f.basename = product.applicationName; })));
401
402
result = es.merge(result, gulp.src('resources/win32/insider/bin/code.sh', { base: 'resources/win32/insider' })
403
.pipe(replace('@@NAME@@', product.nameShort))
404
.pipe(replace('@@PRODNAME@@', product.nameLong))
405
.pipe(replace('@@VERSION@@', version))
406
.pipe(replace('@@COMMIT@@', String(commit)))
407
.pipe(replace('@@APPNAME@@', product.applicationName))
408
.pipe(replace('@@VERSIONFOLDER@@', versionedResourcesFolder))
409
.pipe(replace('@@SERVERDATAFOLDER@@', product.serverDataFolderName || '.vscode-remote'))
410
.pipe(replace('@@QUALITY@@', quality))
411
.pipe(rename(function (f) { f.basename = product.applicationName; f.extname = ''; })));
412
} else {
413
result = es.merge(result, gulp.src('resources/win32/bin/code.cmd', { base: 'resources/win32' })
414
.pipe(replace('@@NAME@@', product.nameShort))
415
.pipe(rename(function (f) { f.basename = product.applicationName; })));
416
417
result = es.merge(result, gulp.src('resources/win32/bin/code.sh', { base: 'resources/win32' })
418
.pipe(replace('@@NAME@@', product.nameShort))
419
.pipe(replace('@@PRODNAME@@', product.nameLong))
420
.pipe(replace('@@VERSION@@', version))
421
.pipe(replace('@@COMMIT@@', String(commit)))
422
.pipe(replace('@@APPNAME@@', product.applicationName))
423
.pipe(replace('@@SERVERDATAFOLDER@@', product.serverDataFolderName || '.vscode-remote'))
424
.pipe(replace('@@QUALITY@@', String(quality)))
425
.pipe(rename(function (f) { f.basename = product.applicationName; f.extname = ''; })));
426
}
427
428
result = es.merge(result, gulp.src('resources/win32/VisualElementsManifest.xml', { base: 'resources/win32' })
429
.pipe(rename(product.nameShort + '.VisualElementsManifest.xml')));
430
431
result = es.merge(result, gulp.src('.build/policies/win32/**', { base: '.build/policies/win32' })
432
.pipe(rename(f => f.dirname = `policies/${f.dirname}`)));
433
434
if (quality === 'stable' || quality === 'insider') {
435
result = es.merge(result, gulp.src('.build/win32/appx/**', { base: '.build/win32' }));
436
const rawVersion = version.replace(/-\w+$/, '').split('.');
437
const appxVersion = `${rawVersion[0]}.0.${rawVersion[1]}.${rawVersion[2]}`;
438
result = es.merge(result, gulp.src('resources/win32/appx/AppxManifest.xml', { base: '.' })
439
.pipe(replace('@@AppxPackageName@@', product.win32AppUserModelId))
440
.pipe(replace('@@AppxPackageVersion@@', appxVersion))
441
.pipe(replace('@@AppxPackageDisplayName@@', product.nameLong))
442
.pipe(replace('@@AppxPackageDescription@@', product.win32NameVersion))
443
.pipe(replace('@@ApplicationIdShort@@', product.win32RegValueName))
444
.pipe(replace('@@ApplicationExe@@', product.nameShort + '.exe'))
445
.pipe(replace('@@FileExplorerContextMenuID@@', quality === 'stable' ? 'OpenWithCode' : 'OpenWithCodeInsiders'))
446
.pipe(replace('@@FileExplorerContextMenuCLSID@@', (product as { win32ContextMenu?: Record<string, { clsid: string }> }).win32ContextMenu![arch].clsid))
447
.pipe(replace('@@FileExplorerContextMenuDLL@@', `${quality === 'stable' ? 'code' : 'code_insider'}_explorer_command_${arch}.dll`))
448
.pipe(rename(f => f.dirname = `appx/manifest`)));
449
}
450
} else if (platform === 'linux') {
451
result = es.merge(result, gulp.src('resources/linux/bin/code.sh', { base: '.' })
452
.pipe(replace('@@PRODNAME@@', product.nameLong))
453
.pipe(replace('@@APPNAME@@', product.applicationName))
454
.pipe(rename('bin/' + product.applicationName)));
455
}
456
457
result = inlineMeta(result, {
458
targetPaths: bootstrapEntryPoints,
459
packageJsonFn: () => packageJsonContents,
460
productJsonFn: () => productJsonContents
461
});
462
463
return result.pipe(vfs.dest(destination));
464
};
465
task.taskName = `package-${platform}-${arch}`;
466
return task;
467
}
468
469
function patchWin32DependenciesTask(destinationFolderName: string) {
470
const cwd = path.join(path.dirname(root), destinationFolderName);
471
472
return async () => {
473
const deps = await glob('**/*.node', { cwd, ignore: 'extensions/node_modules/@parcel/watcher/**' });
474
const packageJson = JSON.parse(await fs.promises.readFile(path.join(cwd, versionedResourcesFolder, 'resources', 'app', 'package.json'), 'utf8'));
475
const product = JSON.parse(await fs.promises.readFile(path.join(cwd, versionedResourcesFolder, 'resources', 'app', 'product.json'), 'utf8'));
476
const baseVersion = packageJson.version.replace(/-.*$/, '');
477
478
await Promise.all(deps.map(async dep => {
479
const basename = path.basename(dep);
480
481
await rcedit(path.join(cwd, dep), {
482
'file-version': baseVersion,
483
'version-string': {
484
'CompanyName': 'Microsoft Corporation',
485
'FileDescription': product.nameLong,
486
'FileVersion': packageJson.version,
487
'InternalName': basename,
488
'LegalCopyright': 'Copyright (C) 2022 Microsoft. All rights reserved',
489
'OriginalFilename': basename,
490
'ProductName': product.nameLong,
491
'ProductVersion': packageJson.version,
492
}
493
});
494
}));
495
};
496
}
497
498
const buildRoot = path.dirname(root);
499
500
const BUILD_TARGETS = [
501
{ platform: 'win32', arch: 'x64' },
502
{ platform: 'win32', arch: 'arm64' },
503
{ platform: 'darwin', arch: 'x64', opts: { stats: true } },
504
{ platform: 'darwin', arch: 'arm64', opts: { stats: true } },
505
{ platform: 'linux', arch: 'x64' },
506
{ platform: 'linux', arch: 'armhf' },
507
{ platform: 'linux', arch: 'arm64' },
508
];
509
BUILD_TARGETS.forEach(buildTarget => {
510
const dashed = (str: string) => (str ? `-${str}` : ``);
511
const platform = buildTarget.platform;
512
const arch = buildTarget.arch;
513
const opts = buildTarget.opts;
514
515
const [vscode, vscodeMin] = ['', 'min'].map(minified => {
516
const sourceFolderName = `out-vscode${dashed(minified)}`;
517
const destinationFolderName = `VSCode${dashed(platform)}${dashed(arch)}`;
518
519
const tasks = [
520
compileNativeExtensionsBuildTask,
521
util.rimraf(path.join(buildRoot, destinationFolderName)),
522
packageTask(platform, arch, sourceFolderName, destinationFolderName, opts)
523
];
524
525
if (platform === 'win32') {
526
tasks.push(patchWin32DependenciesTask(destinationFolderName));
527
}
528
529
const vscodeTaskCI = task.define(`vscode${dashed(platform)}${dashed(arch)}${dashed(minified)}-ci`, task.series(...tasks));
530
gulp.task(vscodeTaskCI);
531
532
const vscodeTask = task.define(`vscode${dashed(platform)}${dashed(arch)}${dashed(minified)}`, task.series(
533
minified ? compileBuildWithManglingTask : compileBuildWithoutManglingTask,
534
cleanExtensionsBuildTask,
535
compileNonNativeExtensionsBuildTask,
536
compileExtensionMediaBuildTask,
537
minified ? minifyVSCodeTask : bundleVSCodeTask,
538
vscodeTaskCI
539
));
540
gulp.task(vscodeTask);
541
542
return vscodeTask;
543
});
544
545
if (process.platform === platform && process.arch === arch) {
546
gulp.task(task.define('vscode', task.series(vscode)));
547
gulp.task(task.define('vscode-min', task.series(vscodeMin)));
548
}
549
});
550
551
// #region nls
552
553
const innoSetupConfig: Record<string, { codePage: string; defaultInfo?: { name: string; id: string } }> = {
554
'zh-cn': { codePage: 'CP936', defaultInfo: { name: 'Simplified Chinese', id: '$0804', } },
555
'zh-tw': { codePage: 'CP950', defaultInfo: { name: 'Traditional Chinese', id: '$0404' } },
556
'ko': { codePage: 'CP949', defaultInfo: { name: 'Korean', id: '$0412' } },
557
'ja': { codePage: 'CP932' },
558
'de': { codePage: 'CP1252' },
559
'fr': { codePage: 'CP1252' },
560
'es': { codePage: 'CP1252' },
561
'ru': { codePage: 'CP1251' },
562
'it': { codePage: 'CP1252' },
563
'pt-br': { codePage: 'CP1252' },
564
'hu': { codePage: 'CP1250' },
565
'tr': { codePage: 'CP1254' }
566
};
567
568
gulp.task(task.define(
569
'vscode-translations-export',
570
task.series(
571
coreCI,
572
compileAllExtensionsBuildTask,
573
function () {
574
const pathToMetadata = './out-build/nls.metadata.json';
575
const pathToExtensions = '.build/extensions/*';
576
const pathToSetup = 'build/win32/i18n/messages.en.isl';
577
578
return es.merge(
579
gulp.src(pathToMetadata).pipe(i18n.createXlfFilesForCoreBundle()),
580
gulp.src(pathToSetup).pipe(i18n.createXlfFilesForIsl()),
581
gulp.src(pathToExtensions).pipe(i18n.createXlfFilesForExtensions())
582
).pipe(vfs.dest('../vscode-translations-export'));
583
}
584
)
585
));
586
587
gulp.task('vscode-translations-import', function () {
588
const options = minimist(process.argv.slice(2), {
589
string: 'location',
590
default: {
591
location: '../vscode-translations-import'
592
}
593
});
594
return es.merge([...i18n.defaultLanguages, ...i18n.extraLanguages].map(language => {
595
const id = language.id;
596
return gulp.src(`${options.location}/${id}/vscode-setup/messages.xlf`)
597
.pipe(i18n.prepareIslFiles(language, innoSetupConfig[language.id]))
598
.pipe(vfs.dest(`./build/win32/i18n`));
599
}));
600
});
601
602
// #endregion
603
604