Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/build/gulpfile.vscode.ts
5240 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 useVersionedUpdate = process.platform === 'win32' && (product as typeof product & { win32VersionedUpdate?: boolean })?.win32VersionedUpdate;
43
const versionedResourcesFolder = useVersionedUpdate ? commit!.substring(0, 10) : '';
44
45
// Build
46
const vscodeEntryPoints = [
47
buildfile.workerEditor,
48
buildfile.workerExtensionHost,
49
buildfile.workerNotebook,
50
buildfile.workerLanguageDetection,
51
buildfile.workerLocalFileSearch,
52
buildfile.workerProfileAnalysis,
53
buildfile.workerOutputLinks,
54
buildfile.workerBackgroundTokenization,
55
buildfile.workbenchDesktop,
56
buildfile.code
57
].flat();
58
59
const vscodeResourceIncludes = [
60
61
// NLS
62
'out-build/nls.messages.json',
63
'out-build/nls.keys.json',
64
65
// Workbench
66
'out-build/vs/code/electron-browser/workbench/workbench.html',
67
68
// Electron Preload
69
'out-build/vs/base/parts/sandbox/electron-browser/preload.js',
70
'out-build/vs/base/parts/sandbox/electron-browser/preload-aux.js',
71
'out-build/vs/platform/browserView/electron-browser/preload-browserView.js',
72
73
// Node Scripts
74
'out-build/vs/base/node/{terminateProcess.sh,cpuUsage.sh,ps.sh}',
75
76
// Touchbar
77
'out-build/vs/workbench/browser/parts/editor/media/*.png',
78
'out-build/vs/workbench/contrib/debug/browser/media/*.png',
79
80
// External Terminal
81
'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt',
82
83
// Terminal shell integration
84
'out-build/vs/workbench/contrib/terminal/common/scripts/*.fish',
85
'out-build/vs/workbench/contrib/terminal/common/scripts/*.ps1',
86
'out-build/vs/workbench/contrib/terminal/common/scripts/*.psm1',
87
'out-build/vs/workbench/contrib/terminal/common/scripts/*.sh',
88
'out-build/vs/workbench/contrib/terminal/common/scripts/*.zsh',
89
90
// Accessibility Signals
91
'out-build/vs/platform/accessibilitySignal/browser/media/*.mp3',
92
93
// Welcome
94
'out-build/vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.{svg,png}',
95
96
// Extensions
97
'out-build/vs/workbench/contrib/extensions/browser/media/{theme-icon.png,language-icon.svg}',
98
'out-build/vs/workbench/services/extensionManagement/common/media/*.{svg,png}',
99
100
// Webview
101
'out-build/vs/workbench/contrib/webview/browser/pre/*.{js,html}',
102
103
// Extension Host Worker
104
'out-build/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html',
105
106
// Tree Sitter highlights
107
'out-build/vs/editor/common/languages/highlights/*.scm',
108
109
// Tree Sitter injection queries
110
'out-build/vs/editor/common/languages/injections/*.scm'
111
];
112
113
const vscodeResources = [
114
115
// Includes
116
...vscodeResourceIncludes,
117
118
// Excludes
119
'!out-build/vs/code/browser/**',
120
'!out-build/vs/editor/standalone/**',
121
'!out-build/vs/code/**/*-dev.html',
122
'!out-build/vs/workbench/contrib/issue/**/*-dev.html',
123
'!**/test/**'
124
];
125
126
const bootstrapEntryPoints = [
127
'out-build/main.js',
128
'out-build/cli.js',
129
'out-build/bootstrap-fork.js'
130
];
131
132
const bundleVSCodeTask = task.define('bundle-vscode', task.series(
133
util.rimraf('out-vscode'),
134
// Optimize: bundles source files automatically based on
135
// import statements based on the passed in entry points.
136
// In addition, concat window related bootstrap files into
137
// a single file.
138
optimize.bundleTask(
139
{
140
out: 'out-vscode',
141
esm: {
142
src: 'out-build',
143
entryPoints: [
144
...vscodeEntryPoints,
145
...bootstrapEntryPoints
146
],
147
resources: vscodeResources,
148
skipTSBoilerplateRemoval: entryPoint => entryPoint === 'vs/code/electron-browser/workbench/workbench'
149
}
150
}
151
)
152
));
153
gulp.task(bundleVSCodeTask);
154
155
const sourceMappingURLBase = `https://main.vscode-cdn.net/sourcemaps/${commit}`;
156
const minifyVSCodeTask = task.define('minify-vscode', task.series(
157
bundleVSCodeTask,
158
util.rimraf('out-vscode-min'),
159
optimize.minifyTask('out-vscode', `${sourceMappingURLBase}/core`)
160
));
161
gulp.task(minifyVSCodeTask);
162
163
const coreCI = task.define('core-ci', task.series(
164
gulp.task('compile-build-with-mangling') as task.Task,
165
task.parallel(
166
gulp.task('minify-vscode') as task.Task,
167
gulp.task('minify-vscode-reh') as task.Task,
168
gulp.task('minify-vscode-reh-web') as task.Task,
169
)
170
));
171
gulp.task(coreCI);
172
173
const coreCIPR = task.define('core-ci-pr', task.series(
174
gulp.task('compile-build-without-mangling') as task.Task,
175
task.parallel(
176
gulp.task('minify-vscode') as task.Task,
177
gulp.task('minify-vscode-reh') as task.Task,
178
gulp.task('minify-vscode-reh-web') as task.Task,
179
)
180
));
181
gulp.task(coreCIPR);
182
183
/**
184
* Compute checksums for some files.
185
*
186
* @param out The out folder to read the file from.
187
* @param filenames The paths to compute a checksum for.
188
* @return A map of paths to checksums.
189
*/
190
function computeChecksums(out: string, filenames: string[]): Record<string, string> {
191
const result: Record<string, string> = {};
192
filenames.forEach(function (filename) {
193
const fullPath = path.join(process.cwd(), out, filename);
194
result[filename] = computeChecksum(fullPath);
195
});
196
return result;
197
}
198
199
/**
200
* Compute checksums for a file.
201
*
202
* @param filename The absolute path to a filename.
203
* @return The checksum for `filename`.
204
*/
205
function computeChecksum(filename: string): string {
206
const contents = fs.readFileSync(filename);
207
208
const hash = crypto
209
.createHash('sha256')
210
.update(contents)
211
.digest('base64')
212
.replace(/=+$/, '');
213
214
return hash;
215
}
216
217
function packageTask(platform: string, arch: string, sourceFolderName: string, destinationFolderName: string, _opts?: { stats?: boolean }) {
218
const destination = path.join(path.dirname(root), destinationFolderName);
219
platform = platform || process.platform;
220
221
const task = () => {
222
const out = sourceFolderName;
223
224
const checksums = computeChecksums(out, [
225
'vs/base/parts/sandbox/electron-browser/preload.js',
226
'vs/workbench/workbench.desktop.main.js',
227
'vs/workbench/workbench.desktop.main.css',
228
'vs/workbench/api/node/extensionHostProcess.js',
229
'vs/code/electron-browser/workbench/workbench.html',
230
'vs/code/electron-browser/workbench/workbench.js'
231
]);
232
233
const src = gulp.src(out + '/**', { base: '.' })
234
.pipe(rename(function (path) { path.dirname = path.dirname!.replace(new RegExp('^' + out), 'out'); }))
235
.pipe(util.setExecutableBit(['**/*.sh']));
236
237
const platformSpecificBuiltInExtensionsExclusions = product.builtInExtensions.filter(ext => {
238
if (!(ext as { platforms?: string[] }).platforms) {
239
return false;
240
}
241
242
const set = new Set((ext as { platforms?: string[] }).platforms);
243
return !set.has(platform);
244
}).map(ext => `!.build/extensions/${ext.name}/**`);
245
246
const extensions = gulp.src(['.build/extensions/**', ...platformSpecificBuiltInExtensionsExclusions], { base: '.build', dot: true });
247
248
const sources = es.merge(src, extensions)
249
.pipe(filter(['**', '!**/*.{js,css}.map'], { dot: true }));
250
251
let version = packageJson.version;
252
const quality = (product as { quality?: string }).quality;
253
254
if (quality && quality !== 'stable') {
255
version += '-' + quality;
256
}
257
258
const name = product.nameShort;
259
const packageJsonUpdates: Record<string, unknown> = { name, version };
260
261
if (platform === 'linux') {
262
packageJsonUpdates.desktopName = `${product.applicationName}.desktop`;
263
}
264
265
let packageJsonContents: string;
266
const packageJsonStream = gulp.src(['package.json'], { base: '.' })
267
.pipe(jsonEditor(packageJsonUpdates))
268
.pipe(es.through(function (file) {
269
packageJsonContents = file.contents.toString();
270
this.emit('data', file);
271
}));
272
273
let productJsonContents: string;
274
const productJsonStream = gulp.src(['product.json'], { base: '.' })
275
.pipe(jsonEditor({ commit, date: readISODate('out-build'), checksums, version }))
276
.pipe(es.through(function (file) {
277
productJsonContents = file.contents.toString();
278
this.emit('data', file);
279
}));
280
281
const license = gulp.src([product.licenseFileName, 'ThirdPartyNotices.txt', 'licenses/**'], { base: '.', allowEmpty: true });
282
283
// TODO the API should be copied to `out` during compile, not here
284
const api = gulp.src('src/vscode-dts/vscode.d.ts').pipe(rename('out/vscode-dts/vscode.d.ts'));
285
286
const telemetry = gulp.src('.build/telemetry/**', { base: '.build/telemetry', dot: true });
287
288
const workbenchModes = gulp.src('resources/workbenchModes/**', { base: '.', dot: true });
289
290
const jsFilter = util.filter(data => !data.isDirectory() && /\.js$/.test(data.path));
291
const root = path.resolve(path.join(import.meta.dirname, '..'));
292
const productionDependencies = getProductionDependencies(root);
293
const dependenciesSrc = productionDependencies.map(d => path.relative(root, d)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`]).flat().concat('!**/*.mk');
294
295
const deps = gulp.src(dependenciesSrc, { base: '.', dot: true })
296
.pipe(filter(['**', `!**/${config.version}/**`, '!**/bin/darwin-arm64-87/**', '!**/package-lock.json', '!**/yarn.lock', '!**/*.{js,css}.map']))
297
.pipe(util.cleanNodeModules(path.join(import.meta.dirname, '.moduleignore')))
298
.pipe(util.cleanNodeModules(path.join(import.meta.dirname, `.moduleignore.${process.platform}`)))
299
.pipe(jsFilter)
300
.pipe(util.rewriteSourceMappingURL(sourceMappingURLBase))
301
.pipe(jsFilter.restore)
302
.pipe(createAsar(path.join(process.cwd(), 'node_modules'), [
303
'**/*.node',
304
'**/@vscode/ripgrep/bin/*',
305
'**/node-pty/build/Release/*',
306
'**/node-pty/build/Release/conpty/*',
307
'**/node-pty/lib/worker/conoutSocketWorker.js',
308
'**/node-pty/lib/shared/conout.js',
309
'**/*.wasm',
310
'**/@vscode/vsce-sign/bin/*',
311
], [
312
'**/*.mk',
313
'!node_modules/vsda/**' // stay compatible with extensions that depend on us shipping `vsda` into ASAR
314
], [
315
'node_modules/vsda/**' // retain copy of `vsda` in node_modules for internal use
316
], 'node_modules.asar'));
317
318
let all = es.merge(
319
packageJsonStream,
320
productJsonStream,
321
license,
322
api,
323
telemetry,
324
workbenchModes,
325
sources,
326
deps
327
);
328
329
if (platform === 'win32') {
330
all = es.merge(all, gulp.src([
331
'resources/win32/bower.ico',
332
'resources/win32/c.ico',
333
'resources/win32/code.ico',
334
'resources/win32/config.ico',
335
'resources/win32/cpp.ico',
336
'resources/win32/csharp.ico',
337
'resources/win32/css.ico',
338
'resources/win32/default.ico',
339
'resources/win32/go.ico',
340
'resources/win32/html.ico',
341
'resources/win32/jade.ico',
342
'resources/win32/java.ico',
343
'resources/win32/javascript.ico',
344
'resources/win32/json.ico',
345
'resources/win32/less.ico',
346
'resources/win32/markdown.ico',
347
'resources/win32/php.ico',
348
'resources/win32/powershell.ico',
349
'resources/win32/python.ico',
350
'resources/win32/react.ico',
351
'resources/win32/ruby.ico',
352
'resources/win32/sass.ico',
353
'resources/win32/shell.ico',
354
'resources/win32/sql.ico',
355
'resources/win32/typescript.ico',
356
'resources/win32/vue.ico',
357
'resources/win32/xml.ico',
358
'resources/win32/yaml.ico',
359
'resources/win32/code_70x70.png',
360
'resources/win32/code_150x150.png'
361
], { base: '.' }));
362
} else if (platform === 'linux') {
363
const policyDest = gulp.src('.build/policies/linux/**', { base: '.build/policies/linux' })
364
.pipe(rename(f => f.dirname = `policies/${f.dirname}`));
365
all = es.merge(all, gulp.src('resources/linux/code.png', { base: '.' }), policyDest);
366
} else if (platform === 'darwin') {
367
const shortcut = gulp.src('resources/darwin/bin/code.sh')
368
.pipe(replace('@@APPNAME@@', product.applicationName))
369
.pipe(replace('@@NAME@@', product.nameShort))
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 }))
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 (useVersionedUpdate) {
397
result = es.merge(result, gulp.src('resources/win32/versioned/bin/code.cmd', { base: 'resources/win32/versioned' })
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/versioned/bin/code.sh', { base: 'resources/win32/versioned' })
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