make api proposal names task play better with gulp

cc @jrieken
This commit is contained in:
Joao Moreno 2021-12-10 15:05:42 +01:00
parent a5924046c2
commit acdd512060
No known key found for this signature in database
GPG key ID: 896B853774D1A575
5 changed files with 172 additions and 125 deletions

View file

@ -11,27 +11,29 @@ require('events').EventEmitter.defaultMaxListeners = 100;
const gulp = require('gulp');
const util = require('./lib/util');
const task = require('./lib/task');
const compilation = require('./lib/compilation');
const { compileTask, watchTask, compileApiProposalNamesTask, watchApiProposalNamesTask } = require('./lib/compilation');
const { monacoTypecheckTask/* , monacoTypecheckWatchTask */ } = require('./gulpfile.editor');
const { compileExtensionsTask, watchExtensionsTask, compileExtensionMediaTask } = require('./gulpfile.extensions');
// API proposal names
gulp.task(compileApiProposalNamesTask);
gulp.task(watchApiProposalNamesTask);
// Fast compile for development time
const compileApiProposalNames = task.define('compile-api-proposal-names', compilation.compileApiProposalNames());
const compileClientTask = task.define('compile-client', task.series(util.rimraf('out'), util.buildWebNodePaths('out'), compileApiProposalNames, compilation.compileTask('src', 'out', false)));
const compileClientTask = task.define('compile-client', task.series(util.rimraf('out'), util.buildWebNodePaths('out'), compileApiProposalNamesTask, compileTask('src', 'out', false)));
gulp.task(compileClientTask);
const watchApiProposalNames = task.define('watch-api-proposal-names', compilation.watchApiProposalNames());
const watchClientTask = task.define('watch-client', task.series(util.rimraf('out'), util.buildWebNodePaths('out'), task.parallel(compilation.watchTask('out', false), watchApiProposalNames)));
const watchClientTask = task.define('watch-client', task.series(util.rimraf('out'), util.buildWebNodePaths('out'), task.parallel(watchTask('out', false), watchApiProposalNamesTask)));
gulp.task(watchClientTask);
// All
const compileTask = task.define('compile', task.parallel(monacoTypecheckTask, compileClientTask, compileExtensionsTask, compileExtensionMediaTask));
gulp.task(compileTask);
const _compileTask = task.define('compile', task.parallel(monacoTypecheckTask, compileClientTask, compileExtensionsTask, compileExtensionMediaTask));
gulp.task(_compileTask);
gulp.task(task.define('watch', task.parallel(/* monacoTypecheckWatchTask, */ watchClientTask, watchExtensionsTask)));
// Default
gulp.task('default', compileTask);
gulp.task('default', _compileTask);
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.watchApiProposalNames = exports.compileApiProposalNames = exports.watchTask = exports.compileTask = void 0;
exports.watchApiProposalNamesTask = exports.compileApiProposalNamesTask = exports.watchTask = exports.compileTask = void 0;
const es = require("event-stream");
const fs = require("fs");
const gulp = require("gulp");
@ -16,6 +16,8 @@ const util = require("./util");
const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
const os = require("os");
const File = require("vinyl");
const task = require("./task");
const watch = require('./watch');
const reporter = (0, reporter_1.createReporter)();
function getTypeScriptCompilerOptions(src) {
@ -175,65 +177,54 @@ class MonacoGenerator {
}
}
}
function apiProposalNamesGenerator() {
const stream = es.through();
const pattern = /vscode\.proposed\.([a-zA-Z]+)\.d\.ts/;
const dtsFolder = path.join(REPO_SRC_FOLDER, 'vscode-dts');
const generateFile = () => {
try {
const t1 = Date.now();
const proposalNames = [];
for (let file of fs.readdirSync(dtsFolder).sort()) {
const match = pattern.exec(file);
if (match) {
proposalNames.push([match[1], `https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/${file}`]);
}
}
const source = [
'/*---------------------------------------------------------------------------------------------',
' * Copyright (c) Microsoft Corporation. All rights reserved.',
' * Licensed under the MIT License. See License.txt in the project root for license information.',
' *--------------------------------------------------------------------------------------------*/',
'',
'// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.',
'',
'export const allApiProposals = Object.freeze({',
`${proposalNames.map(t => `\t${t[0]}: '${t[1]}'`).join(`,${os.EOL}`)}`,
'});',
'export type ApiProposalName = keyof typeof allApiProposals;',
'',
].join(os.EOL);
const outFile = path.join(dtsFolder, '../vs/workbench/services/extensions/common/extensionsApiProposals.ts');
if (fs.readFileSync(outFile).toString() !== source) {
fs.writeFileSync(outFile, source);
console.log(`Generated 'extensionsApiProposals.ts' in ${Date.now() - t1}ms`);
}
function generateApiProposalNames() {
const pattern = /vscode\.proposed\.([a-zA-Z]+)\.d\.ts$/;
const proposalNames = new Set();
const input = es.through();
const output = input
.pipe(util.filter((f) => pattern.test(f.path)))
.pipe(es.through((f) => {
const name = path.basename(f.path);
const match = pattern.exec(name);
if (match) {
proposalNames.add(match[1]);
}
catch (err) {
stream.emit('error', err);
}
};
let handle;
stream.on('data', () => {
clearTimeout(handle);
handle = setTimeout(generateFile, 250);
});
return stream;
}, function () {
const names = [...proposalNames.values()].sort();
const contents = [
'/*---------------------------------------------------------------------------------------------',
' * Copyright (c) Microsoft Corporation. All rights reserved.',
' * Licensed under the MIT License. See License.txt in the project root for license information.',
' *--------------------------------------------------------------------------------------------*/',
'',
'// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.',
'',
'export const allApiProposals = Object.freeze({',
`${names.map(name => `\t${name}: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.${name}.d.ts'`).join(`,${os.EOL}`)}`,
'});',
'export type ApiProposalName = keyof typeof allApiProposals;',
'',
].join(os.EOL);
this.emit('data', new File({
path: 'vs/workbench/services/extensions/common/extensionsApiProposals.ts',
contents: Buffer.from(contents)
}));
this.emit('end');
}));
return es.duplex(input, output);
}
function compileApiProposalNames() {
return function () {
const srcPipe = gulp.src('src/vscode-dts/**', { base: 'src' });
const proposals = apiProposalNamesGenerator();
return srcPipe.pipe(proposals);
};
}
exports.compileApiProposalNames = compileApiProposalNames;
function watchApiProposalNames() {
return function () {
const watchSrc = watch('src/vscode-dts/**', { base: 'src', readDelay: 200 });
const proposals = apiProposalNamesGenerator();
proposals.write(undefined); // send something to trigger initial generate
return watchSrc.pipe(proposals);
};
}
exports.watchApiProposalNames = watchApiProposalNames;
const apiProposalNamesReporter = (0, reporter_1.createReporter)('api-proposal-names');
exports.compileApiProposalNamesTask = task.define('compile-api-proposal-names', () => {
return gulp.src('src/vscode-dts/**')
.pipe(generateApiProposalNames())
.pipe(gulp.dest('src'))
.pipe(apiProposalNamesReporter.end(true));
});
exports.watchApiProposalNamesTask = task.define('watch-api-proposal-names', () => {
const task = () => gulp.src('src/vscode-dts/**')
.pipe(generateApiProposalNames())
.pipe(apiProposalNamesReporter.end(true));
return watch('src/vscode-dts/**', { readDelay: 200 })
.pipe(util.debounce(task))
.pipe(gulp.dest('src'));
});

View file

@ -17,6 +17,8 @@ import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
import * as os from 'os';
import ts = require('typescript');
import * as File from 'vinyl';
import * as task from './task';
const watch = require('./watch');
@ -212,26 +214,23 @@ class MonacoGenerator {
}
}
function apiProposalNamesGenerator() {
const stream = es.through();
function generateApiProposalNames() {
const pattern = /vscode\.proposed\.([a-zA-Z]+)\.d\.ts$/;
const proposalNames = new Set<string>();
const pattern = /vscode\.proposed\.([a-zA-Z]+)\.d\.ts/;
const dtsFolder = path.join(REPO_SRC_FOLDER, 'vscode-dts');
const input = es.through();
const output = input
.pipe(util.filter((f: File) => pattern.test(f.path)))
.pipe(es.through((f: File) => {
const name = path.basename(f.path);
const match = pattern.exec(name);
const generateFile = () => {
try {
const t1 = Date.now();
const proposalNames: [name: string, url: string][] = [];
for (let file of fs.readdirSync(dtsFolder).sort()) {
const match = pattern.exec(file);
if (match) {
proposalNames.push([match[1], `https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/${file}`]);
}
if (match) {
proposalNames.add(match[1]);
}
const source = [
}, function () {
const names = [...proposalNames.values()].sort();
const contents = [
'/*---------------------------------------------------------------------------------------------',
' * Copyright (c) Microsoft Corporation. All rights reserved.',
' * Licensed under the MIT License. See License.txt in the project root for license information.',
@ -240,46 +239,37 @@ function apiProposalNamesGenerator() {
'// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.',
'',
'export const allApiProposals = Object.freeze({',
`${proposalNames.map(t => `\t${t[0]}: '${t[1]}'`).join(`,${os.EOL}`)}`,
`${names.map(name => `\t${name}: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.${name}.d.ts'`).join(`,${os.EOL}`)}`,
'});',
'export type ApiProposalName = keyof typeof allApiProposals;',
'',
].join(os.EOL);
const outFile = path.join(dtsFolder, '../vs/workbench/services/extensions/common/extensionsApiProposals.ts');
this.emit('data', new File({
path: 'vs/workbench/services/extensions/common/extensionsApiProposals.ts',
contents: Buffer.from(contents)
}));
this.emit('end');
}));
if (fs.readFileSync(outFile).toString() !== source) {
fs.writeFileSync(outFile, source);
console.log(`Generated 'extensionsApiProposals.ts' in ${Date.now() - t1}ms`);
}
} catch (err) {
stream.emit('error', err);
}
};
let handle: NodeJS.Timeout;
stream.on('data', () => {
clearTimeout(handle);
handle = setTimeout(generateFile, 250);
});
return stream;
return es.duplex(input, output);
}
export function compileApiProposalNames(): () => NodeJS.ReadWriteStream {
return function () {
const srcPipe = gulp.src('src/vscode-dts/**', { base: 'src' });
const proposals = apiProposalNamesGenerator();
return srcPipe.pipe(proposals);
};
}
const apiProposalNamesReporter = createReporter('api-proposal-names');
export function watchApiProposalNames(): () => NodeJS.ReadWriteStream {
return function () {
const watchSrc = watch('src/vscode-dts/**', { base: 'src', readDelay: 200 });
const proposals = apiProposalNamesGenerator();
proposals.write(undefined); // send something to trigger initial generate
return watchSrc.pipe(proposals);
};
}
export const compileApiProposalNamesTask = task.define('compile-api-proposal-names', () => {
return gulp.src('src/vscode-dts/**')
.pipe(generateApiProposalNames())
.pipe(gulp.dest('src'))
.pipe(apiProposalNamesReporter.end(true));
});
export const watchApiProposalNamesTask = task.define('watch-api-proposal-names', () => {
const task = () => gulp.src('src/vscode-dts/**')
.pipe(generateApiProposalNames())
.pipe(apiProposalNamesReporter.end(true));
return watch('src/vscode-dts/**', { readDelay: 200 })
.pipe(util.debounce(task))
.pipe(gulp.dest('src'));
});

View file

@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildWebNodePaths = exports.createExternalLoaderConfig = exports.acquireWebNodePaths = exports.getElectronVersion = exports.streamToPromise = exports.versionStringToNumber = exports.filter = exports.rebase = exports.getVersion = exports.ensureDir = exports.rreddir = exports.rimraf = exports.rewriteSourceMappingURL = exports.stripSourceMappingURL = exports.loadSourcemaps = exports.cleanNodeModules = exports.skipDirectories = exports.toFileUri = exports.setExecutableBit = exports.fixWin32DirectoryPermissions = exports.incremental = void 0;
exports.buildWebNodePaths = exports.createExternalLoaderConfig = exports.acquireWebNodePaths = exports.getElectronVersion = exports.streamToPromise = exports.versionStringToNumber = exports.filter = exports.rebase = exports.getVersion = exports.ensureDir = exports.rreddir = exports.rimraf = exports.rewriteSourceMappingURL = exports.stripSourceMappingURL = exports.loadSourcemaps = exports.cleanNodeModules = exports.skipDirectories = exports.toFileUri = exports.setExecutableBit = exports.fixWin32DirectoryPermissions = exports.debounce = exports.incremental = void 0;
const es = require("event-stream");
const debounce = require("debounce");
const _debounce = require("debounce");
const _filter = require("gulp-filter");
const rename = require("gulp-rename");
const path = require("path");
@ -36,7 +36,7 @@ function incremental(streamProvider, initial, supportsCancellation) {
if (initial) {
run(initial, false);
}
const eventuallyRun = debounce(() => {
const eventuallyRun = _debounce(() => {
const paths = Object.keys(buffer);
if (paths.length === 0) {
return;
@ -54,6 +54,35 @@ function incremental(streamProvider, initial, supportsCancellation) {
return es.duplex(input, output);
}
exports.incremental = incremental;
function debounce(task) {
const input = es.through();
const output = es.through();
let state = 'idle';
const run = () => {
state = 'running';
task()
.pipe(es.through(undefined, () => {
const shouldRunAgain = state === 'stale';
state = 'idle';
if (shouldRunAgain) {
eventuallyRun();
}
}))
.pipe(output);
};
run();
const eventuallyRun = _debounce(() => run(), 500);
input.on('data', () => {
if (state === 'idle') {
eventuallyRun();
}
else {
state = 'stale';
}
});
return es.duplex(input, output);
}
exports.debounce = debounce;
function fixWin32DirectoryPermissions() {
if (!/win32/.test(process.platform)) {
return es.through();

View file

@ -6,7 +6,7 @@
'use strict';
import * as es from 'event-stream';
import debounce = require('debounce');
import _debounce = require('debounce');
import * as _filter from 'gulp-filter';
import * as rename from 'gulp-rename';
import * as _ from 'underscore';
@ -56,7 +56,7 @@ export function incremental(streamProvider: IStreamProvider, initial: NodeJS.Rea
run(initial, false);
}
const eventuallyRun = debounce(() => {
const eventuallyRun = _debounce(() => {
const paths = Object.keys(buffer);
if (paths.length === 0) {
@ -79,6 +79,41 @@ export function incremental(streamProvider: IStreamProvider, initial: NodeJS.Rea
return es.duplex(input, output);
}
export function debounce(task: () => NodeJS.ReadWriteStream): NodeJS.ReadWriteStream {
const input = es.through();
const output = es.through();
let state = 'idle';
const run = () => {
state = 'running';
task()
.pipe(es.through(undefined, () => {
const shouldRunAgain = state === 'stale';
state = 'idle';
if (shouldRunAgain) {
eventuallyRun();
}
}))
.pipe(output);
};
run();
const eventuallyRun = _debounce(() => run(), 500);
input.on('data', () => {
if (state === 'idle') {
eventuallyRun();
} else {
state = 'stale';
}
});
return es.duplex(input, output);
}
export function fixWin32DirectoryPermissions(): NodeJS.ReadWriteStream {
if (!/win32/.test(process.platform)) {
return es.through();