Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/build/lib/electron.ts
5222 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 fs from 'fs';
7
import path from 'path';
8
import vfs from 'vinyl-fs';
9
import filter from 'gulp-filter';
10
import * as util from './util.ts';
11
import { getVersion } from './getVersion.ts';
12
import electron from '@vscode/gulp-electron';
13
import json from 'gulp-json-editor';
14
15
type DarwinDocumentSuffix = 'document' | 'script' | 'file' | 'source code';
16
type DarwinDocumentType = {
17
name: string;
18
role: string;
19
ostypes: string[];
20
extensions: string[];
21
iconFile: string;
22
utis?: string[];
23
};
24
25
function isDocumentSuffix(str?: string): str is DarwinDocumentSuffix {
26
return str === 'document' || str === 'script' || str === 'file' || str === 'source code';
27
}
28
29
const root = path.dirname(path.dirname(import.meta.dirname));
30
const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8'));
31
const commit = getVersion(root);
32
const useVersionedUpdate = process.platform === 'win32' && (product as typeof product & { win32VersionedUpdate?: boolean })?.win32VersionedUpdate;
33
const versionedResourcesFolder = useVersionedUpdate ? commit!.substring(0, 10) : '';
34
35
function createTemplate(input: string): (params: Record<string, string>) => string {
36
return (params: Record<string, string>) => {
37
return input.replace(/<%=\s*([^\s]+)\s*%>/g, (match, key) => {
38
return params[key] || match;
39
});
40
};
41
}
42
43
const darwinCreditsTemplate = product.darwinCredits && createTemplate(fs.readFileSync(path.join(root, product.darwinCredits), 'utf8'));
44
45
/**
46
* Generate a `DarwinDocumentType` given a list of file extensions, an icon name, and an optional suffix or file type name.
47
* @param extensions A list of file extensions, such as `['bat', 'cmd']`
48
* @param icon A sentence-cased file type name that matches the lowercase name of a darwin icon resource.
49
* For example, `'HTML'` instead of `'html'`, or `'Java'` instead of `'java'`.
50
* This parameter is lowercased before it is used to reference an icon file.
51
* @param nameOrSuffix An optional suffix or a string to use as the file type. If a suffix is provided,
52
* it is used with the icon parameter to generate a file type string. If nothing is provided,
53
* `'document'` is used with the icon parameter to generate file type string.
54
*
55
* For example, if you call `darwinBundleDocumentType(..., 'HTML')`, the resulting file type is `"HTML document"`,
56
* and the `'html'` darwin icon is used.
57
*
58
* If you call `darwinBundleDocumentType(..., 'Javascript', 'file')`, the resulting file type is `"Javascript file"`.
59
* and the `'javascript'` darwin icon is used.
60
*
61
* If you call `darwinBundleDocumentType(..., 'bat', 'Windows command script')`, the file type is `"Windows command script"`,
62
* and the `'bat'` darwin icon is used.
63
*/
64
function darwinBundleDocumentType(extensions: string[], icon: string, nameOrSuffix?: string | DarwinDocumentSuffix, utis?: string[]): DarwinDocumentType {
65
// If given a suffix, generate a name from it. If not given anything, default to 'document'
66
if (isDocumentSuffix(nameOrSuffix) || !nameOrSuffix) {
67
nameOrSuffix = icon.charAt(0).toUpperCase() + icon.slice(1) + ' ' + (nameOrSuffix ?? 'document');
68
}
69
70
return {
71
name: nameOrSuffix,
72
role: 'Editor',
73
ostypes: ['TEXT', 'utxt', 'TUTX', '****'],
74
extensions,
75
iconFile: 'resources/darwin/' + icon.toLowerCase() + '.icns',
76
utis
77
};
78
}
79
80
/**
81
* Generate several `DarwinDocumentType`s with unique names and a shared icon.
82
* @param types A map of file type names to their associated file extensions.
83
* @param icon A darwin icon resource to use. For example, `'HTML'` would refer to `resources/darwin/html.icns`
84
*
85
* Examples:
86
* ```
87
* darwinBundleDocumentTypes({ 'C header file': 'h', 'C source code': 'c' },'c')
88
* darwinBundleDocumentTypes({ 'React source code': ['jsx', 'tsx'] }, 'react')
89
* ```
90
*/
91
function darwinBundleDocumentTypes(types: { [name: string]: string | string[] }, icon: string): DarwinDocumentType[] {
92
return Object.keys(types).map((name: string): DarwinDocumentType => {
93
const extensions = types[name];
94
return {
95
name,
96
role: 'Editor',
97
ostypes: ['TEXT', 'utxt', 'TUTX', '****'],
98
extensions: Array.isArray(extensions) ? extensions : [extensions],
99
iconFile: 'resources/darwin/' + icon + '.icns'
100
};
101
});
102
}
103
104
const { electronVersion, msBuildId } = util.getElectronVersion();
105
106
export const config = {
107
version: electronVersion,
108
tag: product.electronRepository ? `v${electronVersion}-${msBuildId}` : undefined,
109
productAppName: product.nameLong,
110
companyName: 'Microsoft Corporation',
111
copyright: 'Copyright (C) 2026 Microsoft. All rights reserved',
112
darwinExecutable: product.nameShort,
113
darwinIcon: 'resources/darwin/code.icns',
114
darwinBundleIdentifier: product.darwinBundleIdentifier,
115
darwinApplicationCategoryType: 'public.app-category.developer-tools',
116
darwinHelpBookFolder: 'VS Code HelpBook',
117
darwinHelpBookName: 'VS Code HelpBook',
118
darwinBundleDocumentTypes: [
119
...darwinBundleDocumentTypes({ 'C header file': 'h', 'C source code': 'c' }, 'c'),
120
...darwinBundleDocumentTypes({ 'Git configuration file': ['gitattributes', 'gitconfig', 'gitignore'] }, 'config'),
121
...darwinBundleDocumentTypes({ 'HTML template document': ['asp', 'aspx', 'cshtml', 'jshtm', 'jsp', 'phtml', 'shtml'] }, 'html'),
122
darwinBundleDocumentType(['bat', 'cmd'], 'bat', 'Windows command script'),
123
darwinBundleDocumentType(['bowerrc'], 'Bower'),
124
darwinBundleDocumentType(['config', 'editorconfig', 'ini', 'cfg'], 'config', 'Configuration file'),
125
darwinBundleDocumentType(['hh', 'hpp', 'hxx', 'h++'], 'cpp', 'C++ header file'),
126
darwinBundleDocumentType(['cc', 'cpp', 'cxx', 'c++'], 'cpp', 'C++ source code'),
127
darwinBundleDocumentType(['m'], 'default', 'Objective-C source code'),
128
darwinBundleDocumentType(['mm'], 'cpp', 'Objective-C++ source code'),
129
darwinBundleDocumentType(['cs', 'csx'], 'csharp', 'C# source code'),
130
darwinBundleDocumentType(['css'], 'css', 'CSS'),
131
darwinBundleDocumentType(['go'], 'go', 'Go source code'),
132
darwinBundleDocumentType(['htm', 'html', 'xhtml'], 'HTML'),
133
darwinBundleDocumentType(['jade'], 'Jade'),
134
darwinBundleDocumentType(['jav', 'java'], 'Java'),
135
darwinBundleDocumentType(['js', 'jscsrc', 'jshintrc', 'mjs', 'cjs'], 'Javascript', 'file'),
136
darwinBundleDocumentType(['json'], 'JSON'),
137
darwinBundleDocumentType(['less'], 'Less'),
138
darwinBundleDocumentType(['markdown', 'md', 'mdoc', 'mdown', 'mdtext', 'mdtxt', 'mdwn', 'mkd', 'mkdn'], 'Markdown'),
139
darwinBundleDocumentType(['php'], 'PHP', 'source code'),
140
darwinBundleDocumentType(['ps1', 'psd1', 'psm1'], 'Powershell', 'script'),
141
darwinBundleDocumentType(['py', 'pyi'], 'Python', 'script'),
142
darwinBundleDocumentType(['gemspec', 'rb', 'erb'], 'Ruby', 'source code'),
143
darwinBundleDocumentType(['scss', 'sass'], 'SASS', 'file'),
144
darwinBundleDocumentType(['sql'], 'SQL', 'script'),
145
darwinBundleDocumentType(['ts'], 'TypeScript', 'file'),
146
darwinBundleDocumentType(['tsx', 'jsx'], 'React', 'source code'),
147
darwinBundleDocumentType(['vue'], 'Vue', 'source code'),
148
darwinBundleDocumentType(['ascx', 'csproj', 'dtd', 'plist', 'wxi', 'wxl', 'wxs', 'xml', 'xaml'], 'XML'),
149
darwinBundleDocumentType(['eyaml', 'eyml', 'yaml', 'yml'], 'YAML'),
150
darwinBundleDocumentType([
151
'bash', 'bash_login', 'bash_logout', 'bash_profile', 'bashrc',
152
'profile', 'rhistory', 'rprofile', 'sh', 'zlogin', 'zlogout',
153
'zprofile', 'zsh', 'zshenv', 'zshrc'
154
], 'Shell', 'script'),
155
// Default icon with specified names
156
...darwinBundleDocumentTypes({
157
'Clojure source code': ['clj', 'cljs', 'cljx', 'clojure'],
158
'VS Code workspace file': 'code-workspace',
159
'CoffeeScript source code': 'coffee',
160
'Comma Separated Values': 'csv',
161
'CMake script': 'cmake',
162
'Dart script': 'dart',
163
'Diff file': 'diff',
164
'Dockerfile': 'dockerfile',
165
'Gradle file': 'gradle',
166
'Groovy script': 'groovy',
167
'Makefile': ['makefile', 'mk'],
168
'Lua script': 'lua',
169
'Pug document': 'pug',
170
'Jupyter': 'ipynb',
171
'Lockfile': 'lock',
172
'Log file': 'log',
173
'Plain Text File': 'txt',
174
'Xcode project file': 'xcodeproj',
175
'Xcode workspace file': 'xcworkspace',
176
'Visual Basic script': 'vb',
177
'R source code': 'r',
178
'Rust source code': 'rs',
179
'Restructured Text document': 'rst',
180
'LaTeX document': ['tex', 'cls'],
181
'F# source code': 'fs',
182
'F# signature file': 'fsi',
183
'F# script': ['fsx', 'fsscript'],
184
'SVG document': ['svg'],
185
'TOML document': 'toml',
186
'Swift source code': 'swift',
187
}, 'default'),
188
// Default icon with default name
189
darwinBundleDocumentType([
190
'containerfile', 'ctp', 'dot', 'edn', 'handlebars', 'hbs', 'ml', 'mli',
191
'pl', 'pl6', 'pm', 'pm6', 'pod', 'pp', 'properties', 'psgi', 'rt', 't'
192
], 'default', product.nameLong + ' document'),
193
// Folder support ()
194
darwinBundleDocumentType([], 'default', 'Folder', ['public.folder'])
195
],
196
darwinBundleURLTypes: [{
197
role: 'Viewer',
198
name: product.nameLong,
199
urlSchemes: [product.urlProtocol]
200
}],
201
darwinForceDarkModeSupport: true,
202
darwinCredits: darwinCreditsTemplate ? Buffer.from(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : undefined,
203
linuxExecutableName: product.applicationName,
204
winIcon: 'resources/win32/code.ico',
205
token: process.env['GITHUB_TOKEN'],
206
repo: product.electronRepository || undefined,
207
validateChecksum: true,
208
checksumFile: path.join(root, 'build', 'checksums', 'electron.txt'),
209
createVersionedResources: useVersionedUpdate,
210
productVersionString: versionedResourcesFolder,
211
};
212
213
function getElectron(arch: string): () => NodeJS.ReadWriteStream {
214
return () => {
215
const electronOpts = {
216
...config,
217
platform: process.platform,
218
arch: arch === 'armhf' ? 'arm' : arch,
219
ffmpegChromium: false,
220
keepDefaultApp: true
221
};
222
223
return vfs.src('package.json')
224
.pipe(json({ name: product.nameShort }))
225
.pipe(electron(electronOpts))
226
.pipe(filter(['**', '!**/app/package.json']))
227
.pipe(vfs.dest('.build/electron'));
228
};
229
}
230
231
async function main(arch: string = process.arch): Promise<void> {
232
const electronPath = path.join(root, '.build', 'electron');
233
await util.rimraf(electronPath)();
234
await util.streamToPromise(getElectron(arch)());
235
}
236
237
if (import.meta.main) {
238
main(process.argv[2]).catch(err => {
239
console.error(err);
240
process.exit(1);
241
});
242
}
243
244