Convert gulp files to ts

For #277526

Had to add a few ugly casts in difficult cases but mostly trying to add proper types
This commit is contained in:
Matt Bierner
2025-11-21 15:38:55 -08:00
parent 538db6134e
commit fcfb37c8f8
17 changed files with 217 additions and 274 deletions

View File

@@ -12,12 +12,11 @@ import * as cp from 'child_process';
import { tmpdir } from 'os';
import { existsSync, mkdirSync, rmSync } from 'fs';
import * as task from './lib/task.ts';
import * as watcher from './lib/watch/index.ts';
import watcher from './lib/watch/index.ts';
import * as utilModule from './lib/util.ts';
import * as reporterModule from './lib/reporter.ts';
import untar from 'gulp-untar';
import gunzip from 'gulp-gunzip';
import { fileURLToPath } from 'url';
const { debounce } = utilModule;
const { createReporter } = reporterModule;
@@ -43,8 +42,7 @@ const platformOpensslDirName =
const platformOpensslDir = path.join(rootAbs, 'openssl', 'package', 'out', platformOpensslDirName);
const hasLocalRust = (() => {
/** @type boolean | undefined */
let result = undefined;
let result: boolean | undefined = undefined;
return () => {
if (result !== undefined) {
return result;
@@ -61,15 +59,14 @@ const hasLocalRust = (() => {
};
})();
const compileFromSources = (callback) => {
const compileFromSources = (callback: (err?: string) => void) => {
const proc = cp.spawn('cargo', ['--color', 'always', 'build'], {
cwd: root,
stdio: ['ignore', 'pipe', 'pipe'],
env: existsSync(platformOpensslDir) ? { OPENSSL_DIR: platformOpensslDir, ...process.env } : process.env
});
/** @type Buffer[] */
const stdoutErr = [];
const stdoutErr: Buffer[] = [];
proc.stdout.on('data', d => stdoutErr.push(d));
proc.stderr.on('data', d => stdoutErr.push(d));
proc.on('error', callback);
@@ -82,7 +79,7 @@ const compileFromSources = (callback) => {
});
};
const acquireBuiltOpenSSL = (callback) => {
const acquireBuiltOpenSSL = (callback: (err?: unknown) => void) => {
const dir = path.join(tmpdir(), 'vscode-openssl-download');
mkdirSync(dir, { recursive: true });
@@ -103,29 +100,28 @@ const acquireBuiltOpenSSL = (callback) => {
});
};
const compileWithOpenSSLCheck = (/** @type import('./lib/reporter').IReporter */ reporter) => es.map((_, callback) => {
const compileWithOpenSSLCheck = (reporter: import('./lib/reporter.ts').IReporter) => es.map((_, callback) => {
compileFromSources(err => {
if (!err) {
// no-op
callback();
} else if (err.toString().includes('Could not find directory of OpenSSL installation') && !existsSync(platformOpensslDir)) {
fancyLog(ansiColors.yellow(`[cli]`), 'OpenSSL libraries not found, acquiring prebuilt bits...');
acquireBuiltOpenSSL(err => {
if (err) {
callback(err);
callback(err as Error);
} else {
compileFromSources(err => {
if (err) {
reporter(err.toString());
}
callback(null, '');
callback();
});
}
});
} else {
reporter(err.toString());
callback();
}
callback(null, '');
});
});
@@ -147,8 +143,14 @@ const compileCliTask = task.define('compile-cli', () => {
const watchCliTask = task.define('watch-cli', () => {
warnIfRustNotInstalled();
const compile = () => {
const reporter = createReporter('cli');
return gulp.src(`${root}/Cargo.toml`)
.pipe(compileWithOpenSSLCheck(reporter))
.pipe(reporter.end(true));
};
return watcher(`${src}/**`, { read: false })
.pipe(debounce(compileCliTask));
.pipe(debounce(compile));
});
gulp.task(compileCliTask);

View File

@@ -2,17 +2,14 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
import gulp from 'gulp';
import * as util from './lib/util.ts';
import * as date from './lib/date.ts';
import * as task from './lib/task.ts';
import * as compilation from './lib/compilation.ts';
/**
* @param {boolean} disableMangle
*/
function makeCompileBuildTask(disableMangle) {
function makeCompileBuildTask(disableMangle: boolean) {
return task.series(
util.rimraf('out-build'),
date.writeISODate('out-build'),

View File

@@ -2,7 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
import gulp from 'gulp';
import path from 'path';
import * as util from './lib/util.ts';
@@ -84,10 +84,7 @@ const compileEditorESMTask = task.define('compile-editor-esm', () => {
);
});
/**
* @param {string} contents
*/
function toExternalDTS(contents) {
function toExternalDTS(contents: string) {
const lines = contents.split(/\r\n|\r|\n/);
let killNextCloseCurlyBrace = false;
for (let i = 0; i < lines.length; i++) {
@@ -230,10 +227,7 @@ gulp.task('monacodts', task.define('monacodts', () => {
//#region monaco type checking
/**
* @param {boolean} watch
*/
function createTscCompileTask(watch) {
function createTscCompileTask(watch: boolean) {
return () => {
return new Promise((resolve, reject) => {
const args = ['./node_modules/.bin/tsc', '-p', './src/tsconfig.monaco.json', '--noEmit'];
@@ -244,11 +238,10 @@ function createTscCompileTask(watch) {
cwd: path.join(import.meta.dirname, '..'),
// stdio: [null, 'pipe', 'inherit']
});
const errors = [];
const errors: string[] = [];
const reporter = createReporter('monaco');
/** @type {NodeJS.ReadWriteStream | undefined} */
let report;
let report: NodeJS.ReadWriteStream | undefined;
const magic = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; // https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings
child.stdout.on('data', data => {
@@ -287,13 +280,7 @@ export const monacoTypecheckTask = task.define('monaco-typecheck', createTscComp
//#endregion
/**
* Sets a field on an object only if it's not already set, otherwise throws an error
* @param {any} obj - The object to modify
* @param {string} field - The field name to set
* @param {any} value - The value to set
*/
function setUnsetField(obj, field, value) {
function setUnsetField(obj: Record<string, unknown>, field: string, value: unknown) {
if (obj[field] !== undefined) {
throw new Error(`Field "${field}" is already set (but was expected to not be).`);
}

View File

@@ -22,7 +22,6 @@ import plumber from 'gulp-plumber';
import * as ext from './lib/extensions.ts';
import * as tsb from './lib/tsb/index.ts';
import sourcemaps from 'gulp-sourcemaps';
import { fileURLToPath } from 'url';
const { getVersion } = getVersionModule;
const { createReporter } = reporterModule;
@@ -79,13 +78,13 @@ const compilations = [
'.vscode/extensions/vscode-selfhost-import-aid/tsconfig.json',
];
const getBaseUrl = out => `https://main.vscode-cdn.net/sourcemaps/${commit}/${out}`;
const getBaseUrl = (out: string) => `https://main.vscode-cdn.net/sourcemaps/${commit}/${out}`;
const tasks = compilations.map(function (tsconfigFile) {
const absolutePath = path.join(root, tsconfigFile);
const relativeDirname = path.dirname(tsconfigFile.replace(/^(.*\/)?extensions\//i, ''));
const overrideOptions = {};
const overrideOptions: { sourceMap?: boolean; inlineSources?: boolean; base?: string } = {};
overrideOptions.sourceMap = true;
const name = relativeDirname.replace(/\//g, '-');
@@ -98,7 +97,7 @@ const tasks = compilations.map(function (tsconfigFile) {
const out = path.join(srcRoot, 'out');
const baseUrl = getBaseUrl(out);
function createPipeline(build, emitError, transpileOnly) {
function createPipeline(build: boolean, emitError?: boolean, transpileOnly?: boolean) {
const reporter = createReporter('extensions');
overrideOptions.inlineSources = Boolean(build);
@@ -122,14 +121,14 @@ const tasks = compilations.map(function (tsconfigFile) {
.pipe(compilation())
.pipe(build ? util.stripSourceMappingURL() : es.through())
.pipe(sourcemaps.write('.', {
sourceMappingURL: !build ? null : f => `${baseUrl}/${f.relative}.map`,
sourceMappingURL: !build ? undefined : f => `${baseUrl}/${f.relative}.map`,
addComment: !!build,
includeContent: !!build,
// note: trailing slash is important, else the source URLs in V8's file coverage are incorrect
sourceRoot: '../src/',
}))
.pipe(tsFilter.restore)
.pipe(reporter.end(emitError));
.pipe(reporter.end(!!emitError));
return es.duplex(input, output);
};
@@ -266,10 +265,7 @@ gulp.task(compileWebExtensionsTask);
export const watchWebExtensionsTask = task.define('watch-web', () => buildWebExtensions(true));
gulp.task(watchWebExtensionsTask);
/**
* @param {boolean} isWatch
*/
async function buildWebExtensions(isWatch) {
async function buildWebExtensions(isWatch: boolean) {
const extensionsPath = path.join(root, 'extensions');
const webpackConfigLocations = await nodeUtil.promisify(glob)(
path.join(extensionsPath, '**', 'extension-browser.webpack.config.js'),

View File

@@ -11,13 +11,10 @@ import { hygiene } from './hygiene.ts';
const dirName = path.dirname(new URL(import.meta.url).pathname);
/**
* @param {string} actualPath
*/
function checkPackageJSON(actualPath) {
function checkPackageJSON(this: NodeJS.ReadWriteStream, actualPath: string) {
const actual = JSON.parse(fs.readFileSync(path.join(dirName, '..', actualPath), 'utf8'));
const rootPackageJSON = JSON.parse(fs.readFileSync(path.join(dirName, '..', 'package.json'), 'utf8'));
const checkIncluded = (set1, set2) => {
const checkIncluded = (set1: Record<string, string>, set2: Record<string, string>) => {
for (const depName in set1) {
const depVersion = set1[depName];
const rootDepVersion = set2[depName];

View File

@@ -7,16 +7,16 @@ import gulp from 'gulp';
import * as path from 'path';
import es from 'event-stream';
import * as util from './lib/util.ts';
import * as getVersionModule from './lib/getVersion.ts';
import { getVersion } from './lib/getVersion.ts';
import * as task from './lib/task.ts';
import * as optimize from './lib/optimize.ts';
import * as inlineMetaModule from './lib/inlineMeta.ts';
import { inlineMeta } from './lib/inlineMeta.ts';
import product from '../product.json' with { type: 'json' };
import rename from 'gulp-rename';
import replace from 'gulp-replace';
import filter from 'gulp-filter';
import * as dependenciesModule from './lib/dependencies.ts';
import * as dateModule from './lib/date.ts';
import { getProductionDependencies } from './lib/dependencies.ts';
import { readISODate } from './lib/date.ts';
import vfs from 'vinyl-fs';
import packageJson from '../package.json' with { type: 'json' };
import flatmap from 'gulp-flatmap';
@@ -25,21 +25,15 @@ import untar from 'gulp-untar';
import File from 'vinyl';
import * as fs from 'fs';
import glob from 'glob';
import { compileBuildWithManglingTask } from './gulpfile.compile.mjs';
import { cleanExtensionsBuildTask, compileNonNativeExtensionsBuildTask, compileNativeExtensionsBuildTask, compileExtensionMediaBuildTask } from './gulpfile.extensions.mjs';
import { vscodeWebResourceIncludes, createVSCodeWebFileContentMapper } from './gulpfile.vscode.web.mjs';
import { compileBuildWithManglingTask } from './gulpfile.compile.ts';
import { cleanExtensionsBuildTask, compileNonNativeExtensionsBuildTask, compileNativeExtensionsBuildTask, compileExtensionMediaBuildTask } from './gulpfile.extensions.ts';
import { vscodeWebResourceIncludes, createVSCodeWebFileContentMapper } from './gulpfile.vscode.web.ts';
import * as cp from 'child_process';
import log from 'fancy-log';
import buildfile from './buildfile.ts';
import { fileURLToPath } from 'url';
import * as fetchModule from './lib/fetch.ts';
import { fetchUrls, fetchGithub } from './lib/fetch.ts';
import jsonEditor from 'gulp-json-editor';
const { inlineMeta } = inlineMetaModule;
const { getVersion } = getVersionModule;
const { getProductionDependencies } = dependenciesModule;
const { readISODate } = dateModule;
const { fetchUrls, fetchGithub } = fetchModule;
const REPO_ROOT = path.dirname(import.meta.dirname);
const commit = getVersion(REPO_ROOT);
@@ -146,12 +140,12 @@ const bootstrapEntryPoints = [
function getNodeVersion() {
const npmrc = fs.readFileSync(path.join(REPO_ROOT, 'remote', '.npmrc'), 'utf8');
const nodeVersion = /^target="(.*)"$/m.exec(npmrc)[1];
const internalNodeVersion = /^ms_build_id="(.*)"$/m.exec(npmrc)[1];
const nodeVersion = /^target="(.*)"$/m.exec(npmrc)![1];
const internalNodeVersion = /^ms_build_id="(.*)"$/m.exec(npmrc)![1];
return { nodeVersion, internalNodeVersion };
}
function getNodeChecksum(expectedName) {
function getNodeChecksum(expectedName: string): string | undefined {
const nodeJsChecksums = fs.readFileSync(path.join(REPO_ROOT, 'build', 'checksums', 'nodejs.txt'), 'utf8');
for (const line of nodeJsChecksums.split('\n')) {
const [checksum, name] = line.split(/\s+/);
@@ -162,11 +156,12 @@ function getNodeChecksum(expectedName) {
return undefined;
}
function extractAlpinefromDocker(nodeVersion, platform, arch) {
function extractAlpinefromDocker(nodeVersion: string, platform: string, arch: string) {
const imageName = arch === 'arm64' ? 'arm64v8/node' : 'node';
log(`Downloading node.js ${nodeVersion} ${platform} ${arch} from docker image ${imageName}`);
const contents = cp.execSync(`docker run --rm ${imageName}:${nodeVersion}-alpine /bin/sh -c 'cat \`which node\`'`, { maxBuffer: 100 * 1024 * 1024, encoding: 'buffer' });
return es.readArray([new File({ path: 'node', contents, stat: { mode: parseInt('755', 8) } })]);
// eslint-disable-next-line local/code-no-dangerous-type-assertions
return es.readArray([new File({ path: 'node', contents, stat: { mode: parseInt('755', 8) } as fs.Stats })]);
}
const { nodeVersion, internalNodeVersion } = getNodeVersion();
@@ -178,7 +173,7 @@ BUILD_TARGETS.forEach(({ platform, arch }) => {
if (!fs.existsSync(nodePath)) {
util.rimraf(nodePath);
return nodejs(platform, arch)
return nodejs(platform, arch)!
.pipe(vfs.dest(nodePath));
}
@@ -189,10 +184,10 @@ BUILD_TARGETS.forEach(({ platform, arch }) => {
const defaultNodeTask = gulp.task(`node-${process.platform}-${process.arch}`);
if (defaultNodeTask) {
gulp.task(task.define('node', defaultNodeTask));
gulp.task(task.define('node', () => defaultNodeTask));
}
function nodejs(platform, arch) {
function nodejs(platform: string, arch: string): NodeJS.ReadWriteStream | undefined {
if (arch === 'armhf') {
arch = 'armv7l';
@@ -204,7 +199,7 @@ function nodejs(platform, arch) {
log(`Downloading node.js ${nodeVersion} ${platform} ${arch} from ${product.nodejsRepository}...`);
const glibcPrefix = process.env['VSCODE_NODE_GLIBC'] ?? '';
let expectedName;
let expectedName: string | undefined;
switch (platform) {
case 'win32':
expectedName = product.nodejsRepository !== 'https://nodejs.org' ?
@@ -221,7 +216,7 @@ function nodejs(platform, arch) {
expectedName = `node-v${nodeVersion}-linux-${arch}-musl.tar.gz`;
break;
}
const checksumSha256 = getNodeChecksum(expectedName);
const checksumSha256 = expectedName ? getNodeChecksum(expectedName) : undefined;
if (checksumSha256) {
log(`Using SHA256 checksum for checking integrity: ${checksumSha256}`);
@@ -232,13 +227,13 @@ function nodejs(platform, arch) {
switch (platform) {
case 'win32':
return (product.nodejsRepository !== 'https://nodejs.org' ?
fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName, checksumSha256 }) :
fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName!, checksumSha256 }) :
fetchUrls(`/dist/v${nodeVersion}/win-${arch}/node.exe`, { base: 'https://nodejs.org', checksumSha256 }))
.pipe(rename('node.exe'));
case 'darwin':
case 'linux':
return (product.nodejsRepository !== 'https://nodejs.org' ?
fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName, checksumSha256 }) :
fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName!, checksumSha256 }) :
fetchUrls(`/dist/v${nodeVersion}/node-v${nodeVersion}-${platform}-${arch}.tar.gz`, { base: 'https://nodejs.org', checksumSha256 })
).pipe(flatmap(stream => stream.pipe(gunzip()).pipe(untar())))
.pipe(filter('**/node'))
@@ -246,7 +241,7 @@ function nodejs(platform, arch) {
.pipe(rename('node'));
case 'alpine':
return product.nodejsRepository !== 'https://nodejs.org' ?
fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName, checksumSha256 })
fetchGithub(product.nodejsRepository, { version: `${nodeVersion}-${internalNodeVersion}`, name: expectedName!, checksumSha256 })
.pipe(flatmap(stream => stream.pipe(gunzip()).pipe(untar())))
.pipe(filter('**/node'))
.pipe(util.setExecutableBit('**'))
@@ -255,17 +250,17 @@ function nodejs(platform, arch) {
}
}
function packageTask(type, platform, arch, sourceFolderName, destinationFolderName) {
function packageTask(type: string, platform: string, arch: string, sourceFolderName: string, destinationFolderName: string) {
const destination = path.join(BUILD_ROOT, destinationFolderName);
return () => {
const src = gulp.src(sourceFolderName + '/**', { base: '.' })
.pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); }))
.pipe(rename(function (path) { path.dirname = path.dirname!.replace(new RegExp('^' + sourceFolderName), 'out'); }))
.pipe(util.setExecutableBit(['**/*.sh']))
.pipe(filter(['**', '!**/*.{js,css}.map']));
const workspaceExtensionPoints = ['debuggers', 'jsonValidation'];
const isUIExtension = (manifest) => {
const isUIExtension = (manifest: { extensionKind?: string; main?: string; contributes?: Record<string, unknown> }) => {
switch (manifest.extensionKind) {
case 'ui': return true;
case 'workspace': return false;
@@ -294,9 +289,9 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa
}).map((extensionPath) => path.basename(path.dirname(extensionPath)))
.filter(name => name !== 'vscode-api-tests' && name !== 'vscode-test-resolver'); // Do not ship the test extensions
const marketplaceExtensions = JSON.parse(fs.readFileSync(path.join(REPO_ROOT, 'product.json'), 'utf8')).builtInExtensions
.filter(entry => !entry.platforms || new Set(entry.platforms).has(platform))
.filter(entry => !entry.clientOnly)
.map(entry => entry.name);
.filter((entry: { platforms?: string[]; clientOnly?: boolean }) => !entry.platforms || new Set(entry.platforms).has(platform))
.filter((entry: { clientOnly?: boolean }) => !entry.clientOnly)
.map((entry: { name: string }) => entry.name);
const extensionPaths = [...localWorkspaceExtensions, ...marketplaceExtensions]
.map(name => `.build/extensions/${name}/**`);
@@ -306,7 +301,7 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa
.pipe(filter(['**', '!**/*.{js,css}.map'], { dot: true }));
let version = packageJson.version;
const quality = product.quality;
const quality = (product as typeof product & { quality?: string }).quality;
if (quality && quality !== 'stable') {
version += '-' + quality;
@@ -314,7 +309,7 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa
const name = product.nameShort;
let packageJsonContents;
let packageJsonContents: string = '';
const packageJsonStream = gulp.src(['remote/package.json'], { base: 'remote' })
.pipe(jsonEditor({ name, version, dependencies: undefined, optionalDependencies: undefined, type: 'module' }))
.pipe(es.through(function (file) {
@@ -322,7 +317,7 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa
this.emit('data', file);
}));
let productJsonContents;
let productJsonContents: string = '';
const productJsonStream = gulp.src(['product.json'], { base: '.' })
.pipe(jsonEditor({ commit, date: readISODate('out-build'), version }))
.pipe(es.through(function (file) {
@@ -348,7 +343,7 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa
const nodePath = `.build/node/v${nodeVersion}/${platform}-${arch}`;
const node = gulp.src(`${nodePath}/**`, { base: nodePath, dot: true });
let web = [];
let web: NodeJS.ReadWriteStream[] = [];
if (type === 'reh-web') {
web = [
'resources/server/favicon.ico',
@@ -376,12 +371,12 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa
result = es.merge(result,
gulp.src('resources/server/bin/remote-cli/code.cmd', { base: '.' })
.pipe(replace('@@VERSION@@', version))
.pipe(replace('@@COMMIT@@', commit))
.pipe(replace('@@COMMIT@@', commit || ''))
.pipe(replace('@@APPNAME@@', product.applicationName))
.pipe(rename(`bin/remote-cli/${product.applicationName}.cmd`)),
gulp.src('resources/server/bin/helpers/browser.cmd', { base: '.' })
.pipe(replace('@@VERSION@@', version))
.pipe(replace('@@COMMIT@@', commit))
.pipe(replace('@@COMMIT@@', commit || ''))
.pipe(replace('@@APPNAME@@', product.applicationName))
.pipe(rename(`bin/helpers/browser.cmd`)),
gulp.src('resources/server/bin/code-server.cmd', { base: '.' })
@@ -391,13 +386,13 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa
result = es.merge(result,
gulp.src(`resources/server/bin/remote-cli/${platform === 'darwin' ? 'code-darwin.sh' : 'code-linux.sh'}`, { base: '.' })
.pipe(replace('@@VERSION@@', version))
.pipe(replace('@@COMMIT@@', commit))
.pipe(replace('@@COMMIT@@', commit || ''))
.pipe(replace('@@APPNAME@@', product.applicationName))
.pipe(rename(`bin/remote-cli/${product.applicationName}`))
.pipe(util.setExecutableBit()),
gulp.src(`resources/server/bin/helpers/${platform === 'darwin' ? 'browser-darwin.sh' : 'browser-linux.sh'}`, { base: '.' })
.pipe(replace('@@VERSION@@', version))
.pipe(replace('@@COMMIT@@', commit))
.pipe(replace('@@COMMIT@@', commit || ''))
.pipe(replace('@@APPNAME@@', product.applicationName))
.pipe(rename(`bin/helpers/browser.sh`))
.pipe(util.setExecutableBit()),
@@ -425,11 +420,8 @@ function packageTask(type, platform, arch, sourceFolderName, destinationFolderNa
};
}
/**
* @param {object} product The parsed product.json file contents
*/
function tweakProductForServerWeb(product) {
const result = { ...product };
function tweakProductForServerWeb(product: typeof import('../product.json')) {
const result: typeof product & { webEndpointUrlTemplate?: string } = { ...product };
delete result.webEndpointUrlTemplate;
return result;
}
@@ -461,7 +453,7 @@ function tweakProductForServerWeb(product) {
gulp.task(minifyTask);
BUILD_TARGETS.forEach(buildTarget => {
const dashed = (str) => (str ? `-${str}` : ``);
const dashed = (str: string) => (str ? `-${str}` : ``);
const platform = buildTarget.platform;
const arch = buildTarget.arch;
@@ -471,7 +463,13 @@ function tweakProductForServerWeb(product) {
const serverTaskCI = task.define(`vscode-${type}${dashed(platform)}${dashed(arch)}${dashed(minified)}-ci`, task.series(
compileNativeExtensionsBuildTask,
gulp.task(`node-${platform}-${arch}`),
() => {
const nodeTask = gulp.task(`node-${platform}-${arch}`) as task.CallbackTask;
if (nodeTask) {
return nodeTask();
}
return Promise.resolve();
},
util.rimraf(path.join(BUILD_ROOT, destinationFolderName)),
packageTask(type, platform, arch, sourceFolderName, destinationFolderName)
));

View File

@@ -12,9 +12,9 @@ import * as electronConfigModule from './lib/electron.ts';
import filter from 'gulp-filter';
import * as deps from './lib/dependencies.ts';
import { existsSync, readdirSync } from 'fs';
import { fileURLToPath } from 'url';
const { config } = electronConfigModule;
const electronDest = (electron as unknown as { dest: (destination: string, options: unknown) => NodeJS.ReadWriteStream }).dest;
const root = path.dirname(import.meta.dirname);
@@ -35,32 +35,32 @@ const excludedCheckList = [
];
BUILD_TARGETS.forEach(buildTarget => {
const dashed = (/** @type {string | null} */ str) => (str ? `-${str}` : ``);
const dashed = (str: string | null) => (str ? `-${str}` : ``);
const platform = buildTarget.platform;
const arch = buildTarget.arch;
const destinationExe = path.join(path.dirname(root), 'scanbin', `VSCode${dashed(platform)}${dashed(arch)}`, 'bin');
const destinationPdb = path.join(path.dirname(root), 'scanbin', `VSCode${dashed(platform)}${dashed(arch)}`, 'pdb');
const tasks = [];
const tasks: task.Task[] = [];
// removal tasks
tasks.push(util.rimraf(destinationExe), util.rimraf(destinationPdb));
// electron
tasks.push(() => electron.dest(destinationExe, { ...config, platform, arch: arch === 'armhf' ? 'arm' : arch }));
tasks.push(() => electronDest(destinationExe, { ...config, platform, arch: arch === 'armhf' ? 'arm' : arch }));
// pdbs for windows
if (platform === 'win32') {
tasks.push(
() => electron.dest(destinationPdb, { ...config, platform, arch: arch === 'armhf' ? 'arm' : arch, pdbs: true }),
() => electronDest(destinationPdb, { ...config, platform, arch: arch === 'armhf' ? 'arm' : arch, pdbs: true }),
() => confirmPdbsExist(destinationExe, destinationPdb)
);
}
if (platform === 'linux') {
tasks.push(
() => electron.dest(destinationPdb, { ...config, platform, arch: arch === 'armhf' ? 'arm' : arch, symbols: true })
() => electronDest(destinationPdb, { ...config, platform, arch: arch === 'armhf' ? 'arm' : arch, symbols: true })
);
}
@@ -81,7 +81,7 @@ function getProductionDependencySources() {
return productionDependencies.map(d => path.relative(root, d)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`]).flat();
}
function nodeModules(destinationExe, destinationPdb, platform) {
function nodeModules(destinationExe: string, destinationPdb: string, platform: string): task.CallbackTask {
const exe = () => {
return gulp.src(getProductionDependencySources(), { base: '.', dot: true })
@@ -101,7 +101,7 @@ function nodeModules(destinationExe, destinationPdb, platform) {
.pipe(gulp.dest(destinationPdb));
};
return gulp.parallel(exe, pdb);
return gulp.parallel(exe, pdb) as task.CallbackTask;
}
if (platform === 'linux') {
@@ -111,13 +111,13 @@ function nodeModules(destinationExe, destinationPdb, platform) {
.pipe(gulp.dest(destinationPdb));
};
return gulp.parallel(exe, pdb);
return gulp.parallel(exe, pdb) as task.CallbackTask;
}
return exe;
}
function confirmPdbsExist(destinationExe, destinationPdb) {
function confirmPdbsExist(destinationExe: string, destinationPdb: string) {
readdirSync(destinationExe).forEach(file => {
if (excludedCheckList.includes(file)) {
return;

View File

@@ -6,8 +6,8 @@ import { EventEmitter } from 'events';
import glob from 'glob';
import gulp from 'gulp';
import { createRequire } from 'node:module';
import { monacoTypecheckTask /* , monacoTypecheckWatchTask */ } from './gulpfile.editor.mjs';
import { compileExtensionMediaTask, compileExtensionsTask, watchExtensionsTask } from './gulpfile.extensions.mjs';
import { monacoTypecheckTask /* , monacoTypecheckWatchTask */ } from './gulpfile.editor.ts';
import { compileExtensionMediaTask, compileExtensionsTask, watchExtensionsTask } from './gulpfile.extensions.ts';
import * as compilation from './lib/compilation.ts';
import * as task from './lib/task.ts';
import * as util from './lib/util.ts';
@@ -52,7 +52,7 @@ process.on('unhandledRejection', (reason, p) => {
});
// Load all the gulpfiles only if running tasks other than the editor tasks
glob.sync('gulpfile.*.{mjs,js}', { cwd: import.meta.dirname })
glob.sync('gulpfile.*.ts', { cwd: import.meta.dirname })
.forEach(f => {
return require(`./${f}`);
});

View File

@@ -8,35 +8,33 @@ import replace from 'gulp-replace';
import rename from 'gulp-rename';
import es from 'event-stream';
import vfs from 'vinyl-fs';
import * as utilModule from './lib/util.ts';
import * as getVersionModule from './lib/getVersion.ts';
import { rimraf } from './lib/util.ts';
import { getVersion } from './lib/getVersion.ts';
import * as task from './lib/task.ts';
import packageJson from '../package.json' with { type: 'json' };
import product from '../product.json' with { type: 'json' };
import { getDependencies } from './linux/dependencies-generator.ts';
import * as depLists from './linux/debian/dep-lists.ts';
import { recommendedDeps as debianRecommendedDependencies } from './linux/debian/dep-lists.ts';
import * as path from 'path';
import * as cp from 'child_process';
import { promisify } from 'util';
import { fileURLToPath } from 'url';
const { rimraf } = utilModule;
const { getVersion } = getVersionModule;
const { recommendedDeps: debianRecommendedDependencies } = depLists;
const exec = promisify(cp.exec);
const root = path.dirname(import.meta.dirname);
const commit = getVersion(root);
const linuxPackageRevision = Math.floor(new Date().getTime() / 1000);
/**
* @param {string} arch
*/
function getDebPackageArch(arch) {
return { x64: 'amd64', armhf: 'armhf', arm64: 'arm64' }[arch];
function getDebPackageArch(arch: string): string {
switch (arch) {
case 'x64': return 'amd64';
case 'armhf': return 'armhf';
case 'arm64': return 'arm64';
default: throw new Error(`Unknown arch: ${arch}`);
}
}
function prepareDebPackage(arch) {
function prepareDebPackage(arch: string) {
const binaryDir = '../VSCode-linux-' + arch;
const debArch = getDebPackageArch(arch);
const destination = '.build/linux/deb/' + debArch + '/' + product.applicationName + '-' + debArch;
@@ -94,7 +92,7 @@ function prepareDebPackage(arch) {
.pipe(replace('@@ARCHITECTURE@@', debArch))
.pipe(replace('@@DEPENDS@@', dependencies.join(', ')))
.pipe(replace('@@RECOMMENDS@@', debianRecommendedDependencies.join(', ')))
.pipe(replace('@@INSTALLEDSIZE@@', Math.ceil(size / 1024)))
.pipe(replace('@@INSTALLEDSIZE@@', Math.ceil(size / 1024).toString()))
.pipe(rename('DEBIAN/control'))
.pipe(es.through(function (f) { that.emit('data', f); }, function () { that.emit('end'); }));
}));
@@ -122,10 +120,7 @@ function prepareDebPackage(arch) {
};
}
/**
* @param {string} arch
*/
function buildDebPackage(arch) {
function buildDebPackage(arch: string) {
const debArch = getDebPackageArch(arch);
const cwd = `.build/linux/deb/${debArch}`;
@@ -136,24 +131,20 @@ function buildDebPackage(arch) {
};
}
/**
* @param {string} rpmArch
*/
function getRpmBuildPath(rpmArch) {
function getRpmBuildPath(rpmArch: string): string {
return '.build/linux/rpm/' + rpmArch + '/rpmbuild';
}
/**
* @param {string} arch
*/
function getRpmPackageArch(arch) {
return { x64: 'x86_64', armhf: 'armv7hl', arm64: 'aarch64' }[arch];
function getRpmPackageArch(arch: string): string {
switch (arch) {
case 'x64': return 'x86_64';
case 'armhf': return 'armv7hl';
case 'arm64': return 'aarch64';
default: throw new Error(`Unknown arch: ${arch}`);
}
}
/**
* @param {string} arch
*/
function prepareRpmPackage(arch) {
function prepareRpmPackage(arch: string) {
const binaryDir = '../VSCode-linux-' + arch;
const rpmArch = getRpmPackageArch(arch);
const stripBinary = process.env['STRIP'] ?? '/usr/bin/strip';
@@ -205,11 +196,11 @@ function prepareRpmPackage(arch) {
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@ICON@@', product.linuxIconName))
.pipe(replace('@@VERSION@@', packageJson.version))
.pipe(replace('@@RELEASE@@', linuxPackageRevision))
.pipe(replace('@@RELEASE@@', linuxPackageRevision.toString()))
.pipe(replace('@@ARCHITECTURE@@', rpmArch))
.pipe(replace('@@LICENSE@@', product.licenseName))
.pipe(replace('@@QUALITY@@', product.quality || '@@QUALITY@@'))
.pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@'))
.pipe(replace('@@QUALITY@@', (product as typeof product & { quality?: string }).quality || '@@QUALITY@@'))
.pipe(replace('@@UPDATEURL@@', (product as typeof product & { updateUrl?: string }).updateUrl || '@@UPDATEURL@@'))
.pipe(replace('@@DEPENDENCIES@@', dependencies.join(', ')))
.pipe(replace('@@STRIP@@', stripBinary))
.pipe(rename('SPECS/' + product.applicationName + '.spec'));
@@ -223,10 +214,7 @@ function prepareRpmPackage(arch) {
};
}
/**
* @param {string} arch
*/
function buildRpmPackage(arch) {
function buildRpmPackage(arch: string) {
const rpmArch = getRpmPackageArch(arch);
const rpmBuildPath = getRpmBuildPath(rpmArch);
const rpmOut = `${rpmBuildPath}/RPMS/${rpmArch}`;
@@ -239,17 +227,11 @@ function buildRpmPackage(arch) {
};
}
/**
* @param {string} arch
*/
function getSnapBuildPath(arch) {
function getSnapBuildPath(arch: string): string {
return `.build/linux/snap/${arch}/${product.applicationName}-${arch}`;
}
/**
* @param {string} arch
*/
function prepareSnapPackage(arch) {
function prepareSnapPackage(arch: string) {
const binaryDir = '../VSCode-linux-' + arch;
const destination = getSnapBuildPath(arch);
@@ -279,7 +261,7 @@ function prepareSnapPackage(arch) {
const snapcraft = gulp.src('resources/linux/snap/snapcraft.yaml', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@VERSION@@', commit.substr(0, 8)))
.pipe(replace('@@VERSION@@', commit!.substr(0, 8)))
// Possible run-on values https://snapcraft.io/docs/architectures
.pipe(replace('@@ARCHITECTURE@@', arch === 'x64' ? 'amd64' : arch))
.pipe(rename('snap/snapcraft.yaml'));
@@ -293,10 +275,7 @@ function prepareSnapPackage(arch) {
};
}
/**
* @param {string} arch
*/
function buildSnapPackage(arch) {
function buildSnapPackage(arch: string) {
const cwd = getSnapBuildPath(arch);
return () => exec('snapcraft', { cwd });
}

View File

@@ -14,33 +14,27 @@ import filter from 'gulp-filter';
import electron from '@vscode/gulp-electron';
import jsonEditor from 'gulp-json-editor';
import * as util from './lib/util.ts';
import * as getVersionModule from './lib/getVersion.ts';
import * as dateModule from './lib/date.ts';
import { getVersion } from './lib/getVersion.ts';
import { readISODate } from './lib/date.ts';
import * as task from './lib/task.ts';
import buildfile from './buildfile.ts';
import * as optimize from './lib/optimize.ts';
import * as inlineMetaModule from './lib/inlineMeta.ts';
import { inlineMeta } from './lib/inlineMeta.ts';
import packageJson from '../package.json' with { type: 'json' };
import product from '../product.json' with { type: 'json' };
import * as crypto from 'crypto';
import * as i18n from './lib/i18n.ts';
import * as dependenciesModule from './lib/dependencies.ts';
import * as electronModule from './lib/electron.ts';
import * as asarModule from './lib/asar.ts';
import { getProductionDependencies } from './lib/dependencies.ts';
import { config } from './lib/electron.ts';
import { createAsar } from './lib/asar.ts';
import minimist from 'minimist';
import { compileBuildWithoutManglingTask, compileBuildWithManglingTask } from './gulpfile.compile.mjs';
import { compileNonNativeExtensionsBuildTask, compileNativeExtensionsBuildTask, compileAllExtensionsBuildTask, compileExtensionMediaBuildTask, cleanExtensionsBuildTask } from './gulpfile.extensions.mjs';
import { compileBuildWithoutManglingTask, compileBuildWithManglingTask } from './gulpfile.compile.ts';
import { compileNonNativeExtensionsBuildTask, compileNativeExtensionsBuildTask, compileAllExtensionsBuildTask, compileExtensionMediaBuildTask, cleanExtensionsBuildTask } from './gulpfile.extensions.ts';
import { promisify } from 'util';
import globCallback from 'glob';
import rceditCallback from 'rcedit';
import { fileURLToPath } from 'url';
const { getVersion } = getVersionModule;
const { readISODate } = dateModule;
const { inlineMeta } = inlineMetaModule;
const { getProductionDependencies } = dependenciesModule;
const { config } = electronModule;
const { createAsar } = asarModule;
const glob = promisify(globCallback);
const rcedit = promisify(rceditCallback);
const root = path.dirname(import.meta.dirname);
@@ -164,34 +158,30 @@ const minifyVSCodeTask = task.define('minify-vscode', task.series(
gulp.task(minifyVSCodeTask);
const coreCI = task.define('core-ci', task.series(
gulp.task('compile-build-with-mangling'),
gulp.task('compile-build-with-mangling') as task.Task,
task.parallel(
gulp.task('minify-vscode'),
gulp.task('minify-vscode-reh'),
gulp.task('minify-vscode-reh-web'),
gulp.task('minify-vscode') as task.Task,
gulp.task('minify-vscode-reh') as task.Task,
gulp.task('minify-vscode-reh-web') as task.Task,
)
));
gulp.task(coreCI);
const coreCIPR = task.define('core-ci-pr', task.series(
gulp.task('compile-build-without-mangling'),
gulp.task('compile-build-without-mangling') as task.Task,
task.parallel(
gulp.task('minify-vscode'),
gulp.task('minify-vscode-reh'),
gulp.task('minify-vscode-reh-web'),
gulp.task('minify-vscode') as task.Task,
gulp.task('minify-vscode-reh') as task.Task,
gulp.task('minify-vscode-reh-web') as task.Task,
)
));
gulp.task(coreCIPR);
/**
* Compute checksums for some files.
*
* @param {string} out The out folder to read the file from.
* @param {string[]} filenames The paths to compute a checksum for.
* @return {Object} A map of paths to checksums.
*/
function computeChecksums(out, filenames) {
const result = {};
function computeChecksums(out: string, filenames: string[]): Record<string, string> {
const result: Record<string, string> = {};
filenames.forEach(function (filename) {
const fullPath = path.join(process.cwd(), out, filename);
result[filename] = computeChecksum(fullPath);
@@ -200,12 +190,9 @@ function computeChecksums(out, filenames) {
}
/**
* Compute checksum for a file.
*
* @param {string} filename The absolute path to a filename.
* @return {string} The checksum for `filename`.
* Compute checksums for a file.
*/
function computeChecksum(filename) {
function computeChecksum(filename: string): string {
const contents = fs.readFileSync(filename);
const hash = crypto
@@ -217,9 +204,7 @@ function computeChecksum(filename) {
return hash;
}
function packageTask(platform, arch, sourceFolderName, destinationFolderName, opts) {
opts = opts || {};
function packageTask(platform: string, arch: string, sourceFolderName: string, destinationFolderName: string, _opts?: { stats?: boolean }) {
const destination = path.join(path.dirname(root), destinationFolderName);
platform = platform || process.platform;
@@ -236,15 +221,15 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
]);
const src = gulp.src(out + '/**', { base: '.' })
.pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + out), 'out'); }))
.pipe(rename(function (path) { path.dirname = path.dirname!.replace(new RegExp('^' + out), 'out'); }))
.pipe(util.setExecutableBit(['**/*.sh']));
const platformSpecificBuiltInExtensionsExclusions = product.builtInExtensions.filter(ext => {
if (!ext.platforms) {
if (!(ext as { platforms?: string[] }).platforms) {
return false;
}
const set = new Set(ext.platforms);
const set = new Set((ext as { platforms?: string[] }).platforms);
return !set.has(platform);
}).map(ext => `!.build/extensions/${ext.name}/**`);
@@ -254,20 +239,20 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
.pipe(filter(['**', '!**/*.{js,css}.map'], { dot: true }));
let version = packageJson.version;
const quality = product.quality;
const quality = (product as { quality?: string }).quality;
if (quality && quality !== 'stable') {
version += '-' + quality;
}
const name = product.nameShort;
const packageJsonUpdates = { name, version };
const packageJsonUpdates: Record<string, unknown> = { name, version };
if (platform === 'linux') {
packageJsonUpdates.desktopName = `${product.applicationName}.desktop`;
}
let packageJsonContents;
let packageJsonContents: string;
const packageJsonStream = gulp.src(['package.json'], { base: '.' })
.pipe(jsonEditor(packageJsonUpdates))
.pipe(es.through(function (file) {
@@ -275,7 +260,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
this.emit('data', file);
}));
let productJsonContents;
let productJsonContents: string;
const productJsonStream = gulp.src(['product.json'], { base: '.' })
.pipe(jsonEditor({ commit, date: readISODate('out-build'), checksums, version }))
.pipe(es.through(function (file) {
@@ -373,7 +358,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
all = es.merge(all, shortcut, policyDest);
}
let result = all
let result: NodeJS.ReadWriteStream = all
.pipe(util.skipDirectories())
.pipe(util.fixWin32DirectoryPermissions())
.pipe(filter(['**', '!**/.github/**'], { dot: true })) // https://github.com/microsoft/vscode/issues/116523
@@ -401,10 +386,10 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
.pipe(replace('@@NAME@@', product.nameShort))
.pipe(replace('@@PRODNAME@@', product.nameLong))
.pipe(replace('@@VERSION@@', version))
.pipe(replace('@@COMMIT@@', commit))
.pipe(replace('@@COMMIT@@', commit ?? ''))
.pipe(replace('@@APPNAME@@', product.applicationName))
.pipe(replace('@@SERVERDATAFOLDER@@', product.serverDataFolderName || '.vscode-remote'))
.pipe(replace('@@QUALITY@@', quality))
.pipe(replace('@@QUALITY@@', quality ?? ''))
.pipe(rename(function (f) { f.basename = product.applicationName; f.extname = ''; })));
result = es.merge(result, gulp.src('resources/win32/VisualElementsManifest.xml', { base: 'resources/win32' })
@@ -425,7 +410,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
.pipe(replace('@@ApplicationIdShort@@', product.win32RegValueName))
.pipe(replace('@@ApplicationExe@@', product.nameShort + '.exe'))
.pipe(replace('@@FileExplorerContextMenuID@@', quality === 'stable' ? 'OpenWithCode' : 'OpenWithCodeInsiders'))
.pipe(replace('@@FileExplorerContextMenuCLSID@@', product.win32ContextMenu[arch].clsid))
.pipe(replace('@@FileExplorerContextMenuCLSID@@', (product as { win32ContextMenu?: Record<string, { clsid: string }> }).win32ContextMenu![arch].clsid))
.pipe(replace('@@FileExplorerContextMenuDLL@@', `${quality === 'stable' ? 'code' : 'code_insider'}_explorer_command_${arch}.dll`))
.pipe(rename(f => f.dirname = `appx/manifest`)));
}
@@ -448,7 +433,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
return task;
}
function patchWin32DependenciesTask(destinationFolderName) {
function patchWin32DependenciesTask(destinationFolderName: string) {
const cwd = path.join(path.dirname(root), destinationFolderName);
return async () => {
@@ -489,7 +474,7 @@ const BUILD_TARGETS = [
{ platform: 'linux', arch: 'arm64' },
];
BUILD_TARGETS.forEach(buildTarget => {
const dashed = (str) => (str ? `-${str}` : ``);
const dashed = (str: string) => (str ? `-${str}` : ``);
const platform = buildTarget.platform;
const arch = buildTarget.arch;
const opts = buildTarget.opts;
@@ -532,7 +517,7 @@ BUILD_TARGETS.forEach(buildTarget => {
// #region nls
const innoSetupConfig = {
const innoSetupConfig: Record<string, { codePage: string; defaultInfo?: { name: string; id: string } }> = {
'zh-cn': { codePage: 'CP936', defaultInfo: { name: 'Simplified Chinese', id: '$0804', } },
'zh-tw': { codePage: 'CP950', defaultInfo: { name: 'Traditional Chinese', id: '$0404' } },
'ko': { codePage: 'CP949', defaultInfo: { name: 'Korean', id: '$0412' } },

View File

@@ -7,33 +7,28 @@ import gulp from 'gulp';
import * as path from 'path';
import es from 'event-stream';
import * as util from './lib/util.ts';
import * as getVersionModule from './lib/getVersion.ts';
import { getVersion } from './lib/getVersion.ts';
import * as task from './lib/task.ts';
import * as optimize from './lib/optimize.ts';
import * as dateModule from './lib/date.ts';
import { readISODate } from './lib/date.ts';
import product from '../product.json' with { type: 'json' };
import rename from 'gulp-rename';
import filter from 'gulp-filter';
import * as dependenciesModule from './lib/dependencies.ts';
import { getProductionDependencies } from './lib/dependencies.ts';
import vfs from 'vinyl-fs';
import packageJson from '../package.json' with { type: 'json' };
import { compileBuildWithManglingTask } from './gulpfile.compile.mjs';
import { compileBuildWithManglingTask } from './gulpfile.compile.ts';
import * as extensions from './lib/extensions.ts';
import VinylFile from 'vinyl';
import jsonEditor from 'gulp-json-editor';
import buildfile from './buildfile.ts';
import { fileURLToPath } from 'url';
const { getVersion } = getVersionModule;
const { readISODate } = dateModule;
const { getProductionDependencies } = dependenciesModule;
const REPO_ROOT = path.dirname(import.meta.dirname);
const BUILD_ROOT = path.dirname(REPO_ROOT);
const WEB_FOLDER = path.join(REPO_ROOT, 'remote', 'web');
const commit = getVersion(REPO_ROOT);
const quality = product.quality;
const quality = (product as { quality?: string }).quality;
const version = (quality && quality !== 'stable') ? `${packageJson.version}-${quality}` : packageJson.version;
export const vscodeWebResourceIncludes = [
@@ -90,16 +85,8 @@ const vscodeWebEntryPoints = [
buildfile.entrypoint('vs/workbench/workbench.web.main.internal') // TODO@esm remove line when we stop supporting web-amd-esm-bridge
].flat();
/**
* @param extensionsRoot {string} The location where extension will be read from
* @param {object} product The parsed product.json file contents
*/
export const createVSCodeWebFileContentMapper = (extensionsRoot, product) => {
/**
* @param {string} path
* @returns {((content: string) => string) | undefined}
*/
return path => {
export const createVSCodeWebFileContentMapper = (extensionsRoot: string, product: typeof import('../product.json')) => {
return (path: string): ((content: string) => string) | undefined => {
if (path.endsWith('vs/platform/product/common/product.js')) {
return content => {
const productConfiguration = JSON.stringify({
@@ -143,16 +130,12 @@ const minifyVSCodeWebTask = task.define('minify-vscode-web', task.series(
));
gulp.task(minifyVSCodeWebTask);
/**
* @param {string} sourceFolderName
* @param {string} destinationFolderName
*/
function packageTask(sourceFolderName, destinationFolderName) {
function packageTask(sourceFolderName: string, destinationFolderName: string) {
const destination = path.join(BUILD_ROOT, destinationFolderName);
return () => {
const src = gulp.src(sourceFolderName + '/**', { base: '.' })
.pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); }));
.pipe(rename(function (path) { path.dirname = path.dirname!.replace(new RegExp('^' + sourceFolderName), 'out'); }));
const extensions = gulp.src('.build/web/extensions/**', { base: '.build/web', dot: true });
@@ -218,7 +201,7 @@ const compileWebExtensionsBuildTask = task.define('compile-web-extensions-build'
));
gulp.task(compileWebExtensionsBuildTask);
const dashed = (/** @type {string} */ str) => (str ? `-${str}` : ``);
const dashed = (str: string) => (str ? `-${str}` : ``);
['', 'min'].forEach(minified => {
const sourceFolderName = `out-vscode-web${dashed(minified)}`;

View File

@@ -17,15 +17,13 @@ import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const repoPath = path.dirname(import.meta.dirname);
const buildPath = (/** @type {string} */ arch) => path.join(path.dirname(repoPath), `VSCode-win32-${arch}`);
const setupDir = (/** @type {string} */ arch, /** @type {string} */ target) => path.join(repoPath, '.build', `win32-${arch}`, `${target}-setup`);
const buildPath = (arch: string) => path.join(path.dirname(repoPath), `VSCode-win32-${arch}`);
const setupDir = (arch: string, target: string) => path.join(repoPath, '.build', `win32-${arch}`, `${target}-setup`);
const issPath = path.join(import.meta.dirname, 'win32', 'code.iss');
const innoSetupPath = path.join(path.dirname(path.dirname(require.resolve('innosetup'))), 'bin', 'ISCC.exe');
const signWin32Path = path.join(repoPath, 'build', 'azure-pipelines', 'common', 'sign-win32.ts');
function packageInnoSetup(iss, options, cb) {
options = options || {};
function packageInnoSetup(iss: string, options: { definitions?: Record<string, string> }, cb: (err?: Error | null) => void) {
const definitions = options.definitions || {};
if (process.argv.some(arg => arg === '--debug-inno')) {
@@ -58,16 +56,12 @@ function packageInnoSetup(iss, options, cb) {
});
}
/**
* @param {string} arch
* @param {string} target
*/
function buildWin32Setup(arch, target) {
function buildWin32Setup(arch: string, target: string) {
if (target !== 'system' && target !== 'user') {
throw new Error('Invalid setup target');
}
return cb => {
return (cb?: (err?: any) => void) => {
const x64AppId = target === 'system' ? product.win32x64AppId : product.win32x64UserAppId;
const arm64AppId = target === 'system' ? product.win32arm64AppId : product.win32arm64UserAppId;
@@ -81,8 +75,8 @@ function buildWin32Setup(arch, target) {
productJson['target'] = target;
fs.writeFileSync(productJsonPath, JSON.stringify(productJson, undefined, '\t'));
const quality = product.quality || 'dev';
const definitions = {
const quality = (product as { quality?: string }).quality || 'dev';
const definitions: Record<string, any> = {
NameLong: product.nameLong,
NameShort: product.nameShort,
DirName: product.win32DirName,
@@ -117,15 +111,11 @@ function buildWin32Setup(arch, target) {
definitions['AppxPackageName'] = `${product.win32AppUserModelId}`;
}
packageInnoSetup(issPath, { definitions }, cb);
packageInnoSetup(issPath, { definitions }, cb as (err?: Error | null) => void);
};
}
/**
* @param {string} arch
* @param {string} target
*/
function defineWin32SetupTasks(arch, target) {
function defineWin32SetupTasks(arch: string, target: string) {
const cleanTask = util.rimraf(setupDir(arch, target));
gulp.task(task.define(`vscode-win32-${arch}-${target}-setup`, task.series(cleanTask, buildWin32Setup(arch, target))));
}
@@ -135,20 +125,14 @@ defineWin32SetupTasks('arm64', 'system');
defineWin32SetupTasks('x64', 'user');
defineWin32SetupTasks('arm64', 'user');
/**
* @param {string} arch
*/
function copyInnoUpdater(arch) {
function copyInnoUpdater(arch: string) {
return () => {
return gulp.src('build/win32/{inno_updater.exe,vcruntime140.dll}', { base: 'build/win32' })
.pipe(vfs.dest(path.join(buildPath(arch), 'tools')));
};
}
/**
* @param {string} executablePath
*/
function updateIcon(executablePath) {
function updateIcon(executablePath: string): task.CallbackTask {
return cb => {
const icon = path.join(repoPath, 'resources', 'win32', 'code.ico');
rcedit(executablePath, { icon }, cb);

View File

@@ -30,7 +30,7 @@ interface VinylFileWithLines extends VinylFile {
/**
* Main hygiene function that runs checks on files
*/
export function hygiene(some: NodeJS.ReadWriteStream | string[], runEslint = true): NodeJS.ReadWriteStream {
export function hygiene(some: NodeJS.ReadWriteStream | string[] | undefined, runEslint = true): NodeJS.ReadWriteStream {
console.log('Starting hygiene...');
let errorCount = 0;

View File

@@ -209,7 +209,7 @@ function bundleESMTask(opts: IBundleESMTaskOpts): NodeJS.ReadWriteStream {
}));
}
export interface IBundleESMTaskOpts {
export interface IBundleTaskOpts {
/**
* Destination folder for the bundled files.
*/
@@ -220,7 +220,7 @@ export interface IBundleESMTaskOpts {
esm: IBundleESMTaskOpts;
}
export function bundleTask(opts: IBundleESMTaskOpts): () => NodeJS.ReadWriteStream {
export function bundleTask(opts: IBundleTaskOpts): () => NodeJS.ReadWriteStream {
return function () {
return bundleESMTask(opts.esm).pipe(gulp.dest(opts.out));
};

15
build/lib/typings/gulp-gunzip.d.ts vendored Normal file
View File

@@ -0,0 +1,15 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'gulp-gunzip' {
import type { Transform } from 'stream';
/**
* Gunzip plugin for gulp
*/
function gunzip(): Transform;
export = gunzip;
}

15
build/lib/typings/gulp-untar.d.ts vendored Normal file
View File

@@ -0,0 +1,15 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'gulp-untar' {
import type { Transform } from 'stream';
/**
* Extract TAR files
*/
function untar(): Transform;
export = untar;
}

5
build/lib/typings/rcedit.d.ts vendored Normal file
View File

@@ -0,0 +1,5 @@
declare module 'rcedit' {
export default function rcedit(exePath, options, cb): Promise<void>;
}