Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/build/gulpfile.extensions.js
3520 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
// Increase max listeners for event emitters
7
require('events').EventEmitter.defaultMaxListeners = 100;
8
9
const gulp = require('gulp');
10
const path = require('path');
11
const nodeUtil = require('util');
12
const es = require('event-stream');
13
const filter = require('gulp-filter');
14
const util = require('./lib/util');
15
const { getVersion } = require('./lib/getVersion');
16
const task = require('./lib/task');
17
const watcher = require('./lib/watch');
18
const createReporter = require('./lib/reporter').createReporter;
19
const glob = require('glob');
20
const root = path.dirname(__dirname);
21
const commit = getVersion(root);
22
const plumber = require('gulp-plumber');
23
const ext = require('./lib/extensions');
24
25
// To save 250ms for each gulp startup, we are caching the result here
26
// const compilations = glob.sync('**/tsconfig.json', {
27
// cwd: extensionsPath,
28
// ignore: ['**/out/**', '**/node_modules/**']
29
// });
30
const compilations = [
31
'extensions/configuration-editing/tsconfig.json',
32
'extensions/css-language-features/client/tsconfig.json',
33
'extensions/css-language-features/server/tsconfig.json',
34
'extensions/debug-auto-launch/tsconfig.json',
35
'extensions/debug-server-ready/tsconfig.json',
36
'extensions/emmet/tsconfig.json',
37
'extensions/extension-editing/tsconfig.json',
38
'extensions/git/tsconfig.json',
39
'extensions/git-base/tsconfig.json',
40
'extensions/github/tsconfig.json',
41
'extensions/github-authentication/tsconfig.json',
42
'extensions/grunt/tsconfig.json',
43
'extensions/gulp/tsconfig.json',
44
'extensions/html-language-features/client/tsconfig.json',
45
'extensions/html-language-features/server/tsconfig.json',
46
'extensions/ipynb/tsconfig.json',
47
'extensions/jake/tsconfig.json',
48
'extensions/json-language-features/client/tsconfig.json',
49
'extensions/json-language-features/server/tsconfig.json',
50
'extensions/markdown-language-features/tsconfig.json',
51
'extensions/markdown-math/tsconfig.json',
52
'extensions/media-preview/tsconfig.json',
53
'extensions/merge-conflict/tsconfig.json',
54
'extensions/mermaid-chat-features/tsconfig.json',
55
'extensions/terminal-suggest/tsconfig.json',
56
'extensions/microsoft-authentication/tsconfig.json',
57
'extensions/notebook-renderers/tsconfig.json',
58
'extensions/npm/tsconfig.json',
59
'extensions/php-language-features/tsconfig.json',
60
'extensions/references-view/tsconfig.json',
61
'extensions/search-result/tsconfig.json',
62
'extensions/simple-browser/tsconfig.json',
63
'extensions/tunnel-forwarding/tsconfig.json',
64
'extensions/typescript-language-features/web/tsconfig.json',
65
'extensions/typescript-language-features/tsconfig.json',
66
'extensions/vscode-api-tests/tsconfig.json',
67
'extensions/vscode-colorize-tests/tsconfig.json',
68
'extensions/vscode-colorize-perf-tests/tsconfig.json',
69
'extensions/vscode-test-resolver/tsconfig.json',
70
71
'.vscode/extensions/vscode-selfhost-test-provider/tsconfig.json',
72
'.vscode/extensions/vscode-selfhost-import-aid/tsconfig.json',
73
];
74
75
const getBaseUrl = out => `https://main.vscode-cdn.net/sourcemaps/${commit}/${out}`;
76
77
const tasks = compilations.map(function (tsconfigFile) {
78
const absolutePath = path.join(root, tsconfigFile);
79
const relativeDirname = path.dirname(tsconfigFile.replace(/^(.*\/)?extensions\//i, ''));
80
81
const overrideOptions = {};
82
overrideOptions.sourceMap = true;
83
84
const name = relativeDirname.replace(/\//g, '-');
85
86
const srcRoot = path.dirname(tsconfigFile);
87
const srcBase = path.join(srcRoot, 'src');
88
const src = path.join(srcBase, '**');
89
const srcOpts = { cwd: root, base: srcBase, dot: true };
90
91
const out = path.join(srcRoot, 'out');
92
const baseUrl = getBaseUrl(out);
93
94
function createPipeline(build, emitError, transpileOnly) {
95
const tsb = require('./lib/tsb');
96
const sourcemaps = require('gulp-sourcemaps');
97
98
const reporter = createReporter('extensions');
99
100
overrideOptions.inlineSources = Boolean(build);
101
overrideOptions.base = path.dirname(absolutePath);
102
103
const compilation = tsb.create(absolutePath, overrideOptions, { verbose: false, transpileOnly, transpileOnlyIncludesDts: transpileOnly, transpileWithEsbuild: true }, err => reporter(err.toString()));
104
105
const pipeline = function () {
106
const input = es.through();
107
const tsFilter = filter(['**/*.ts', '!**/lib/lib*.d.ts', '!**/node_modules/**'], { restore: true, dot: true });
108
const output = input
109
.pipe(plumber({
110
errorHandler: function (err) {
111
if (err && !err.__reporter__) {
112
reporter(err);
113
}
114
}
115
}))
116
.pipe(tsFilter)
117
.pipe(util.loadSourcemaps())
118
.pipe(compilation())
119
.pipe(build ? util.stripSourceMappingURL() : es.through())
120
.pipe(sourcemaps.write('.', {
121
sourceMappingURL: !build ? null : f => `${baseUrl}/${f.relative}.map`,
122
addComment: !!build,
123
includeContent: !!build,
124
// note: trailing slash is important, else the source URLs in V8's file coverage are incorrect
125
sourceRoot: '../src/',
126
}))
127
.pipe(tsFilter.restore)
128
.pipe(reporter.end(emitError));
129
130
return es.duplex(input, output);
131
};
132
133
// add src-stream for project files
134
pipeline.tsProjectSrc = () => {
135
return compilation.src(srcOpts);
136
};
137
return pipeline;
138
}
139
140
const cleanTask = task.define(`clean-extension-${name}`, util.rimraf(out));
141
142
const transpileTask = task.define(`transpile-extension:${name}`, task.series(cleanTask, () => {
143
const pipeline = createPipeline(false, true, true);
144
const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts']));
145
const input = es.merge(nonts, pipeline.tsProjectSrc());
146
147
return input
148
.pipe(pipeline())
149
.pipe(gulp.dest(out));
150
}));
151
152
const compileTask = task.define(`compile-extension:${name}`, task.series(cleanTask, () => {
153
const pipeline = createPipeline(false, true);
154
const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts']));
155
const input = es.merge(nonts, pipeline.tsProjectSrc());
156
157
return input
158
.pipe(pipeline())
159
.pipe(gulp.dest(out));
160
}));
161
162
const watchTask = task.define(`watch-extension:${name}`, task.series(cleanTask, () => {
163
const pipeline = createPipeline(false);
164
const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts']));
165
const input = es.merge(nonts, pipeline.tsProjectSrc());
166
const watchInput = watcher(src, { ...srcOpts, ...{ readDelay: 200 } });
167
168
return watchInput
169
.pipe(util.incremental(pipeline, input))
170
.pipe(gulp.dest(out));
171
}));
172
173
const compileBuildTask = task.define(`compile-build-extension-${name}`, task.series(cleanTask, () => {
174
const pipeline = createPipeline(true, true);
175
const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts']));
176
const input = es.merge(nonts, pipeline.tsProjectSrc());
177
178
return input
179
.pipe(pipeline())
180
.pipe(gulp.dest(out));
181
}));
182
183
// Tasks
184
gulp.task(transpileTask);
185
gulp.task(compileTask);
186
gulp.task(watchTask);
187
188
return { transpileTask, compileTask, watchTask, compileBuildTask };
189
});
190
191
const transpileExtensionsTask = task.define('transpile-extensions', task.parallel(...tasks.map(t => t.transpileTask)));
192
gulp.task(transpileExtensionsTask);
193
194
const compileExtensionsTask = task.define('compile-extensions', task.parallel(...tasks.map(t => t.compileTask)));
195
gulp.task(compileExtensionsTask);
196
exports.compileExtensionsTask = compileExtensionsTask;
197
198
const watchExtensionsTask = task.define('watch-extensions', task.parallel(...tasks.map(t => t.watchTask)));
199
gulp.task(watchExtensionsTask);
200
exports.watchExtensionsTask = watchExtensionsTask;
201
202
const compileExtensionsBuildLegacyTask = task.define('compile-extensions-build-legacy', task.parallel(...tasks.map(t => t.compileBuildTask)));
203
gulp.task(compileExtensionsBuildLegacyTask);
204
205
//#region Extension media
206
207
const compileExtensionMediaTask = task.define('compile-extension-media', () => ext.buildExtensionMedia(false));
208
gulp.task(compileExtensionMediaTask);
209
exports.compileExtensionMediaTask = compileExtensionMediaTask;
210
211
const watchExtensionMedia = task.define('watch-extension-media', () => ext.buildExtensionMedia(true));
212
gulp.task(watchExtensionMedia);
213
exports.watchExtensionMedia = watchExtensionMedia;
214
215
const compileExtensionMediaBuildTask = task.define('compile-extension-media-build', () => ext.buildExtensionMedia(false, '.build/extensions'));
216
gulp.task(compileExtensionMediaBuildTask);
217
exports.compileExtensionMediaBuildTask = compileExtensionMediaBuildTask;
218
219
//#endregion
220
221
//#region Azure Pipelines
222
223
/**
224
* Cleans the build directory for extensions
225
*/
226
const cleanExtensionsBuildTask = task.define('clean-extensions-build', util.rimraf('.build/extensions'));
227
exports.cleanExtensionsBuildTask = cleanExtensionsBuildTask;
228
229
/**
230
* brings in the marketplace extensions for the build
231
*/
232
const bundleMarketplaceExtensionsBuildTask = task.define('bundle-marketplace-extensions-build', () => ext.packageMarketplaceExtensionsStream(false).pipe(gulp.dest('.build')));
233
234
/**
235
* Compiles the non-native extensions for the build
236
* @note this does not clean the directory ahead of it. See {@link cleanExtensionsBuildTask} for that.
237
*/
238
const compileNonNativeExtensionsBuildTask = task.define('compile-non-native-extensions-build', task.series(
239
bundleMarketplaceExtensionsBuildTask,
240
task.define('bundle-non-native-extensions-build', () => ext.packageNonNativeLocalExtensionsStream(false, false).pipe(gulp.dest('.build')))
241
));
242
gulp.task(compileNonNativeExtensionsBuildTask);
243
exports.compileNonNativeExtensionsBuildTask = compileNonNativeExtensionsBuildTask;
244
245
/**
246
* Compiles the native extensions for the build
247
* @note this does not clean the directory ahead of it. See {@link cleanExtensionsBuildTask} for that.
248
*/
249
const compileNativeExtensionsBuildTask = task.define('compile-native-extensions-build', () => ext.packageNativeLocalExtensionsStream(false, false).pipe(gulp.dest('.build')));
250
gulp.task(compileNativeExtensionsBuildTask);
251
exports.compileNativeExtensionsBuildTask = compileNativeExtensionsBuildTask;
252
253
/**
254
* Compiles the extensions for the build.
255
* This is essentially a helper task that combines {@link cleanExtensionsBuildTask}, {@link compileNonNativeExtensionsBuildTask} and {@link compileNativeExtensionsBuildTask}
256
*/
257
const compileAllExtensionsBuildTask = task.define('compile-extensions-build', task.series(
258
cleanExtensionsBuildTask,
259
bundleMarketplaceExtensionsBuildTask,
260
task.define('bundle-extensions-build', () => ext.packageAllLocalExtensionsStream(false, false).pipe(gulp.dest('.build'))),
261
));
262
gulp.task(compileAllExtensionsBuildTask);
263
exports.compileAllExtensionsBuildTask = compileAllExtensionsBuildTask;
264
265
// This task is run in the compilation stage of the CI pipeline. We only compile the non-native extensions since those can be fully built regardless of platform.
266
// This defers the native extensions to the platform specific stage of the CI pipeline.
267
gulp.task(task.define('extensions-ci', task.series(compileNonNativeExtensionsBuildTask, compileExtensionMediaBuildTask)));
268
269
const compileExtensionsBuildPullRequestTask = task.define('compile-extensions-build-pr', task.series(
270
cleanExtensionsBuildTask,
271
bundleMarketplaceExtensionsBuildTask,
272
task.define('bundle-extensions-build-pr', () => ext.packageAllLocalExtensionsStream(false, true).pipe(gulp.dest('.build'))),
273
));
274
gulp.task(compileExtensionsBuildPullRequestTask);
275
276
// This task is run in the compilation stage of the PR pipeline. We compile all extensions in it to verify compilation.
277
gulp.task(task.define('extensions-ci-pr', task.series(compileExtensionsBuildPullRequestTask, compileExtensionMediaBuildTask)));
278
279
//#endregion
280
281
const compileWebExtensionsTask = task.define('compile-web', () => buildWebExtensions(false));
282
gulp.task(compileWebExtensionsTask);
283
exports.compileWebExtensionsTask = compileWebExtensionsTask;
284
285
const watchWebExtensionsTask = task.define('watch-web', () => buildWebExtensions(true));
286
gulp.task(watchWebExtensionsTask);
287
exports.watchWebExtensionsTask = watchWebExtensionsTask;
288
289
/**
290
* @param {boolean} isWatch
291
*/
292
async function buildWebExtensions(isWatch) {
293
const extensionsPath = path.join(root, 'extensions');
294
const webpackConfigLocations = await nodeUtil.promisify(glob)(
295
path.join(extensionsPath, '**', 'extension-browser.webpack.config.js'),
296
{ ignore: ['**/node_modules'] }
297
);
298
return ext.webpackExtensions('packaging web extension', isWatch, webpackConfigLocations.map(configPath => ({ configPath })));
299
}
300
301