Change build system to hereby

This eliminates a significant number of dependencies, eliminating all
npm audit issues, speeding up `npm ci` by 20%, and overall making the
build faster (faster startup, direct code is faster than streams, etc)
and clearer to understand.

I'm finding it much easier to make build changes for the module
transform with this; I can more clearly indicate task dependencies and
prevent running tasks that don't need to be run.

Given we're changing our build process entirely (new deps, new steps),
it seems like this is a good time to change things up.
This commit is contained in:
Jake Bailey 2022-10-09 13:15:45 -07:00
parent f45cc4578e
commit 3cd72e76b2
32 changed files with 1330 additions and 9695 deletions

View File

@ -4,4 +4,4 @@
ARG VARIANT="14-buster"
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
RUN sudo -u node npm install -g gulp-cli
RUN sudo -u node npm install -g hereby

View File

@ -4,7 +4,7 @@ Thank you for submitting a pull request!
Please verify that:
* [ ] There is an associated issue in the `Backlog` milestone (**required**)
* [ ] Code is up-to-date with the `main` branch
* [ ] You've successfully run `gulp runtests` locally
* [ ] You've successfully run `hereby runtests` locally
* [ ] There are new or updated unit tests validating the change
Refer to CONTRIBUTING.MD for more details.

View File

@ -17,8 +17,8 @@ jobs:
git config user.name "TypeScript Bot"
npm install
git rm -r --quiet tests/baselines/reference :^tests/baselines/reference/docker :^tests/baselines/reference/user
gulp runtests-parallel --ci --fix || true
gulp baseline-accept
npx hereby runtests-parallel --ci --fix || true
npx hereby baseline-accept
git add ./src
git add ./tests/baselines/reference
git diff --cached

View File

@ -69,11 +69,8 @@ jobs:
- name: Adding playwright
run: npm install --no-save --no-package-lock playwright
- name: Build local
run: gulp local
- name: Validate the browser can import TypeScript
run: gulp test-browser-integration
run: npx hereby test-browser-integration
typecheck:
runs-on: ubuntu-latest
@ -102,10 +99,10 @@ jobs:
- run: npm ci
- name: Build scripts
run: gulp scripts
run: npx hereby scripts
- name: ESLint tests
run: gulp run-eslint-rules-tests
run: npx hereby run-eslint-rules-tests
self-check:
runs-on: ubuntu-latest
@ -119,10 +116,10 @@ jobs:
- run: npm ci
- name: Build tsc
run: gulp tsc
run: npx hereby tsc
- name: Clean
run: gulp clean-src
run: npx hereby clean-src
- name: Self build
run: gulp build-src --built
run: npx hereby build-src --built

View File

@ -21,7 +21,7 @@ jobs:
sed -i -e 's/const versionMajorMinor = ".*"/const versionMajorMinor = "${{ github.event.client_payload.core_major_minor }}"/g' tests/baselines/reference/api/tsserverlibrary.d.ts
sed -i -e 's/const version\(: string\)\{0,1\} = `${versionMajorMinor}.0-.*`/const version = `${versionMajorMinor}.0-${{ github.event.client_payload.core_tag || 'dev' }}`/g' src/compiler/corePublic.ts
npm ci
gulp LKG
npx hereby LKG
npm test
git diff
git add package.json

View File

@ -23,10 +23,10 @@ jobs:
run: |
npm whoami
npm ci
gulp configure-nightly
gulp LKG
gulp runtests-parallel
gulp clean
npx hereby configure-nightly
npx hereby LKG
npx hereby runtests-parallel
npx hereby clean
npm publish --tag next
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}

View File

@ -19,11 +19,11 @@ jobs:
- name: Adding playwright
run: npm install --no-save --no-package-lock playwright
- name: Validate the browser can import TypeScript
run: gulp test-browser-integration
run: npx hereby test-browser-integration
- name: LKG, clean, and pack
run: |
gulp LKG
gulp clean
npx hereby LKG
npx hereby clean
npm pack ./
mv typescript-*.tgz typescript.tgz
- name: Upload built tarfile

View File

@ -27,7 +27,7 @@ jobs:
sed -i -e 's/const versionMajorMinor = ".*"/const versionMajorMinor = "${{ github.event.client_payload.core_major_minor }}"/g' tests/baselines/reference/api/tsserverlibrary.d.ts
sed -i -e 's/const version\(: string\)\{0,1\} = .*;/const version = "${{ github.event.client_payload.package_version }}" as string;/g' src/compiler/corePublic.ts
npm ci
gulp LKG
npx hereby LKG
npm test
git diff
git add package.json

View File

@ -16,7 +16,7 @@ jobs:
git config user.email "typescriptbot@microsoft.com"
git config user.name "TypeScript Bot"
npm ci
gulp LKG
npx hereby LKG
npm test
git diff
git add ./lib

19
.gulp.js Normal file
View File

@ -0,0 +1,19 @@
const cp = require("child_process");
const path = require("path");
const chalk = require("chalk");
const argv = process.argv.slice(2);
// --tasks-simple is used by VS Code to infer a task list; try and keep that working.
if (!argv.includes("--tasks-simple")) {
console.error(chalk.yellowBright("Warning: using gulp shim; please consider running hereby directly."));
}
const args = [
...process.execArgv,
path.join(__dirname, "node_modules", "hereby", "bin", "hereby.js"),
...argv,
];
const { status } = cp.spawnSync(process.execPath, args, { stdio: "inherit" });
process.exit(status ?? 1);

View File

@ -20,7 +20,6 @@
"configurations": [
{
"type": "node",
"protocol": "inspector",
"request": "launch",
"name": "Mocha Tests (currently opened test)",
"runtimeArgs": ["--nolazy"],
@ -43,12 +42,12 @@
},
"sourceMaps": true,
"smartStep": true,
"preLaunchTask": "gulp: tests",
"preLaunchTask": "npm: build:tests",
"console": "integratedTerminal",
"outFiles": [
"${workspaceRoot}/built/local/run.js"
],
"customDescriptionGenerator": "'__tsDebuggerDisplay' in this ? this.__tsDebuggerDisplay(defaultValue) : defaultValue",
"customDescriptionGenerator": "'__tsDebuggerDisplay' in this ? this.__tsDebuggerDisplay(defaultValue) : defaultValue"
},
{
// See: https://github.com/microsoft/TypeScript/wiki/Debugging-Language-Service-in-VS-Code
@ -56,7 +55,7 @@
"request": "attach",
"name": "Attach to VS Code TS Server via Port",
"processId": "${command:PickProcess}",
"customDescriptionGenerator": "'__tsDebuggerDisplay' in this ? this.__tsDebuggerDisplay(defaultValue) : defaultValue",
"customDescriptionGenerator": "'__tsDebuggerDisplay' in this ? this.__tsDebuggerDisplay(defaultValue) : defaultValue"
}
]
}

View File

@ -12,4 +12,12 @@
// "--ignore-revs-file",
// ".git-blame-ignore-revs"
// ]
// These options search the repo recursively and slow down
// the build task menu. We define our own in tasks.json.
"typescript.tsc.autoDetect": "off",
"npm.autoDetect": "off",
"grunt.autoDetect": "off",
"jake.autoDetect": "off",
"gulp.autoDetect": "off"
}

67
.vscode/tasks.json vendored
View File

@ -4,42 +4,51 @@
"version": "2.0.0",
"tasks": [
{
"type": "gulp",
"label": "gulp: local",
"task": "local",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$tsc"
]
},
{
"type": "gulp",
"label": "gulp: tsc",
"task": "tsc",
"group": "build",
"problemMatcher": [
"$tsc"
]
},
{
"type": "gulp",
// Kept for backwards compat for old launch.json files so it's
// less annoying if moving up to the new build or going back to
// the old build.
//
// This is first because the acutal "npm: build:tests" task
// below has the same script value, and VS Code ignores labels
// and deduplicates them.
// https://github.com/microsoft/vscode/issues/93001
"label": "gulp: tests",
"task": "tests",
"type": "npm",
"script": "build:tests",
"group": "build",
"hide": true,
"problemMatcher": [
"$tsc"
]
},
{
"label": "tsc: watch ./src",
"type": "shell",
"command": "node",
"args": ["${workspaceFolder}/lib/tsc.js", "--build", "${workspaceFolder}/src", "--watch"],
"group": "build",
"isBackground": true,
"problemMatcher": [
"$tsc-watch"
]
},
{
"label": "npm: build:compiler",
"type": "npm",
"script": "build:compiler",
"group": "build",
"problemMatcher": [
"$tsc"
]
},
{
"type": "gulp",
"task": "services",
"label": "gulp: services",
"label": "npm: build:tests",
"type": "npm",
"script": "build:tests",
"group": "build",
"problemMatcher": [
"$tsc"
],
}
]
},
]
}
}

View File

@ -54,42 +54,42 @@ In general, things we find useful when reviewing suggestions are:
2. A copy of the TypeScript code. See the next steps for instructions.
3. [Node](https://nodejs.org), which runs JavaScript locally. Current or LTS will both work.
4. An editor. [VS Code](https://code.visualstudio.com) is the best place to start for TypeScript.
5. The gulp command line tool, for building and testing changes. See the next steps for how to install it.
5. The hereby command line tool, for building and testing changes. See the next steps for how to install it.
## Get Started
1. Install node using the version you downloaded from [nodejs.org](https://nodejs.org).
2. Open a terminal.
3. Make a fork—your own copy—of TypeScript on your GitHub account, then make a clone—a local copy—on your computer. ([Here are some step-by-step instructions](https://github.com/anitab-org/mentorship-android/wiki/Fork%2C-Clone-%26-Remote)). Add `--depth=1` to the end of the `git clone` command to save time.
4. Install the gulp command line tool: `npm install -g gulp-cli`
4. Install the hereby command line tool: `npm install -g hereby`
5. Change to the TypeScript folder you made: `cd TypeScript`
6. Install dependencies: `npm ci`
7. Make sure everything builds and tests pass: `gulp runtests-parallel`
7. Make sure everything builds and tests pass: `hereby runtests-parallel`
8. Open the TypeScript folder in your editor.
9. Follow the directions below to add and debug a test.
## Helpful tasks
Running `gulp --tasks --depth 1` provides the full listing, but here are a few common tasks you might use.
Running `hereby --tasks` provides the full listing, but here are a few common tasks you might use.
```
gulp local # Build the compiler into built/local.
gulp clean # Delete the built compiler.
gulp LKG # Replace the last known good with the built one.
# Bootstrapping step to be executed when the built compiler reaches a stable state.
gulp tests # Build the test infrastructure using the built compiler.
gulp runtests # Run tests using the built compiler and test infrastructure.
# You can override the specific suite runner used or specify a test for this command.
# Use --tests=<testPath> for a specific test and/or --runner=<runnerName> for a specific suite.
# Valid runners include conformance, compiler, fourslash, project, user, and docker
# The user and docker runners are extended test suite runners - the user runner
# works on disk in the tests/cases/user directory, while the docker runner works in containers.
# You'll need to have the docker executable in your system path for the docker runner to work.
gulp runtests-parallel # Like runtests, but split across multiple threads. Uses a number of threads equal to the system
# core count by default. Use --workers=<number> to adjust this.
gulp baseline-accept # This replaces the baseline test results with the results obtained from gulp runtests.
gulp lint # Runs eslint on the TypeScript source.
gulp help # List the above commands.
hereby local # Build the compiler into built/local.
hereby clean # Delete the built compiler.
hereby LKG # Replace the last known good with the built one.
# Bootstrapping step to be executed when the built compiler reaches a stable state.
hereby tests # Build the test infrastructure using the built compiler.
hereby runtests # Run tests using the built compiler and test infrastructure.
# You can override the specific suite runner used or specify a test for this command.
# Use --tests=<testPath> for a specific test and/or --runner=<runnerName> for a specific suite.
# Valid runners include conformance, compiler, fourslash, project, user, and docker
# The user and docker runners are extended test suite runners - the user runner
# works on disk in the tests/cases/user directory, while the docker runner works in containers.
# You'll need to have the docker executable in your system path for the docker runner to work.
hereby runtests-parallel # Like runtests, but split across multiple threads. Uses a number of threads equal to the system
# core count by default. Use --workers=<number> to adjust this.
hereby baseline-accept # This replaces the baseline test results with the results obtained from hereby runtests.
hereby lint # Runs eslint on the TypeScript source.
hereby help # List the above commands.
```
## Tips
@ -111,7 +111,7 @@ You might need to run `git config --global core.longpaths true` before cloning T
### Using local builds
Run `gulp` to build a version of the compiler/language service that reflects changes you've made. You can then run `node <repo-root>/built/local/tsc.js` in place of `tsc` in your project. For example, to run `tsc --watch` from within the root of the repository on a file called `test.ts`, you can run `node ./built/local/tsc.js --watch test.ts`.
Run `hereby` to build a version of the compiler/language service that reflects changes you've made. You can then run `node <repo-root>/built/local/tsc.js` in place of `tsc` in your project. For example, to run `tsc --watch` from within the root of the repository on a file called `test.ts`, you can run `node ./built/local/tsc.js --watch test.ts`.
## Contributing bug fixes
@ -163,7 +163,7 @@ Any changes should be made to [src/lib](https://github.com/Microsoft/TypeScript/
Library files in `built/local/` are updated automatically by running the standard build task:
```sh
gulp
hereby
```
The files in `lib/` are used to bootstrap compilation and usually **should not** be updated unless publishing a new version or updating the LKG.
@ -178,36 +178,36 @@ If you need a head start understanding how the compiler works, or how the code i
## Running the Tests
To run all tests, invoke the `runtests-parallel` target using gulp:
To run all tests, invoke the `runtests-parallel` target using hereby:
```Shell
gulp runtests-parallel
hereby runtests-parallel
```
This will run all tests; to run only a specific subset of tests, use:
```Shell
gulp runtests --tests=<regex>
hereby runtests --tests=<regex>
```
e.g. to run all compiler baseline tests:
```Shell
gulp runtests --tests=compiler
hereby runtests --tests=compiler
```
or to run a specific test: `tests\cases\compiler\2dArrays.ts`
```Shell
gulp runtests --tests=2dArrays
hereby runtests --tests=2dArrays
```
## Debugging the tests
You can debug with VS Code or Node instead with `gulp runtests -i`:
You can debug with VS Code or Node instead with `hereby runtests -i`:
```Shell
gulp runtests --tests=2dArrays -i
hereby runtests --tests=2dArrays -i
```
You can also use the [provided VS Code launch configuration](./.vscode/launch.template.json) to launch a debug session for an open test file. Rename the file 'launch.json', open the test file of interest, and launch the debugger from the debug panel (or press F5).
@ -257,12 +257,12 @@ When a change in the baselines is detected, the test will fail. To inspect chang
git diff --diff-filter=AM --no-index ./tests/baselines/reference ./tests/baselines/local
```
Alternatively, you can set the `DIFF` environment variable and run `gulp diff`, or manually run your favorite folder diffing tool between `tests/baselines/reference` and `tests/baselines/local`. Our team largely uses Beyond Compare and WinMerge.
Alternatively, you can set the `DIFF` environment variable and run `hereby diff`, or manually run your favorite folder diffing tool between `tests/baselines/reference` and `tests/baselines/local`. Our team largely uses Beyond Compare and WinMerge.
After verifying that the changes in the baselines are correct, run
```Shell
gulp baseline-accept
hereby baseline-accept
```
This will change the files in `tests\baselines\reference`, which should be included as part of your commit.
@ -271,6 +271,6 @@ Be sure to validate the changes carefully -- apparently unrelated changes to bas
## Localization
All strings the user may see are stored in [`diagnosticMessages.json`](./src/compiler/diagnosticMessages.json).
If you make changes to it, run `gulp generate-diagnostics` to push them to the `Diagnostic` interface in `diagnosticInformationMap.generated.ts`.
If you make changes to it, run `hereby generate-diagnostics` to push them to the `Diagnostic` interface in `diagnosticInformationMap.generated.ts`.
See [coding guidelines on diagnostic messages](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#diagnostic-messages).

View File

@ -3,5 +3,4 @@ FROM node:current
COPY . /typescript
WORKDIR /typescript
RUN npm ci
RUN npm i -g gulp-cli
RUN gulp configure-insiders && gulp LKG && gulp clean && npm pack .
RUN npx hereby configure-insiders && npx hereby LKG && npx hereby clean && npm pack .

File diff suppressed because it is too large Load Diff

View File

@ -2,4 +2,4 @@
**These files are not meant to be edited by hand.**
If you need to make modifications, the respective files should be changed within the repository's top-level `src` directory.
Running `gulp LKG` will then appropriately update the files in this directory.
Running `hereby LKG` will then appropriately update the files in this directory.

9292
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -41,15 +41,8 @@
"devDependencies": {
"@octokit/rest": "latest",
"@types/chai": "latest",
"@types/fancy-log": "^2.0.0",
"@types/fs-extra": "^9.0.13",
"@types/glob": "latest",
"@types/gulp": "^4.0.9",
"@types/gulp-concat": "latest",
"@types/gulp-newer": "latest",
"@types/gulp-rename": "latest",
"@types/gulp-sourcemaps": "latest",
"@types/merge2": "latest",
"@types/microsoft__typescript-etw": "latest",
"@types/minimist": "latest",
"@types/mkdirp": "latest",
@ -74,16 +67,9 @@
"eslint-plugin-jsdoc": "^39.3.6",
"eslint-plugin-local": "^1.0.0",
"eslint-plugin-no-null": "^1.0.2",
"fancy-log": "latest",
"fs-extra": "^9.1.0",
"glob": "latest",
"gulp": "^4.0.2",
"gulp-concat": "latest",
"gulp-insert": "latest",
"gulp-newer": "latest",
"gulp-rename": "latest",
"gulp-sourcemaps": "latest",
"merge2": "latest",
"hereby": "^1.6.4",
"minimist": "latest",
"mkdirp": "latest",
"mocha": "latest",
@ -92,23 +78,19 @@
"node-fetch": "^3.2.10",
"source-map-support": "latest",
"typescript": "^4.8.4",
"vinyl": "latest",
"which": "^2.0.2",
"xml2js": "^0.4.23"
},
"overrides": {
"es5-ext": "0.10.53"
},
"scripts": {
"test": "gulp runtests-parallel --light=false",
"test:eslint-rules": "gulp run-eslint-rules-tests",
"test": "hereby runtests-parallel --light=false",
"test:eslint-rules": "hereby run-eslint-rules-tests",
"build": "npm run build:compiler && npm run build:tests",
"build:compiler": "gulp local",
"build:tests": "gulp tests",
"build:compiler": "hereby local",
"build:tests": "hereby tests",
"start": "node lib/tsc",
"clean": "gulp clean",
"gulp": "gulp",
"lint": "gulp lint",
"clean": "hereby clean",
"gulp": "hereby",
"lint": "hereby lint",
"setup-hooks": "node scripts/link-hooks.mjs"
},
"browser": {

View File

@ -26,4 +26,4 @@ export function findUpFile(name) {
/** @type {string | undefined} */
let findUpRootCache;
export const findUpRoot = () => findUpRootCache || (findUpRootCache = dirname(findUpFile("Gulpfile.mjs")));
export const findUpRoot = () => findUpRootCache || (findUpRootCache = dirname(findUpFile("Herebyfile.mjs")));

View File

@ -49,7 +49,7 @@ const projectCleaner = new ProjectQueue((projects) => execTsc("--clean", ...proj
*/
export const cleanProject = (project) => projectCleaner.enqueue(project);
const projectWatcher = new ProjectQueue((projects) => execTsc("--watch", ...projects));
const projectWatcher = new ProjectQueue((projects) => execTsc("--watch", "--preserveWatchOutput", ...projects));
/**
* @param {string} project

View File

@ -1,48 +0,0 @@
/**
* @param {string} message
* @returns {never}
*/
function fail(message) {
throw new Error(message);
}
/**
* @param {number} value
*/
function base64FormatEncode(value) {
return value < 0 ? fail("Invalid value") :
value < 26 ? 0x41 /*A*/ + value :
value < 52 ? 0x61 /*a*/ + value - 26 :
value < 62 ? 0x30 /*0*/ + value - 52 :
value === 62 ? 0x2B /*+*/ :
value === 63 ? 0x2F /*/*/ :
fail("Invalid value");
}
/**
* @param {number} value
*/
export function base64VLQFormatEncode(value) {
if (value < 0) {
value = ((-value) << 1) + 1;
}
else {
value = value << 1;
}
// Encode 5 bits at a time starting from least significant bits
let result = "";
do {
let currentDigit = value & 31; // 11111
value = value >> 5;
if (value > 0) {
// There are still more digits to decode, set the msb (6th bit)
currentDigit = currentDigit | 32;
}
result += String.fromCharCode(base64FormatEncode(currentDigit));
} while (value > 0);
return result;
}
/** @typedef {object} RawSourceMap */

View File

@ -3,7 +3,6 @@ import fs from "fs";
import os from "os";
import path from "path";
import mkdirP from "mkdirp";
import log from "fancy-log";
import cmdLineOptions from "./options.mjs";
import { exec } from "./utils.mjs";
import { findUpFile, findUpRoot } from "./findUpDir.mjs";
@ -19,9 +18,8 @@ export const localTest262Baseline = "internal/baselines/test262/local";
* @param {string} runJs
* @param {string} defaultReporter
* @param {boolean} runInParallel
* @param {boolean} _watchMode
*/
export async function runConsoleTests(runJs, defaultReporter, runInParallel, _watchMode) {
export async function runConsoleTests(runJs, defaultReporter, runInParallel) {
let testTimeout = cmdLineOptions.timeout;
const tests = cmdLineOptions.tests;
const inspect = cmdLineOptions.break || cmdLineOptions.inspect;
@ -147,7 +145,7 @@ export async function cleanTestDirs() {
}
/**
* used to pass data from gulp command line directly to run.js
* used to pass data from command line directly to run.js
* @param {string} tests
* @param {string} runners
* @param {boolean} light
@ -173,7 +171,7 @@ export function writeTestConfigFile(tests, runners, light, taskConfigsFolder, wo
shards,
shardId
});
log.info("Running tests with config: " + testConfigContents);
console.info("Running tests with config: " + testConfigContents);
fs.writeFileSync("test.config", testConfigContents);
}

View File

@ -1,17 +1,11 @@
/* eslint-disable no-restricted-globals */
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
/// <reference path="../types/ambient.d.ts" />
import fs from "fs";
import path from "path";
import log from "fancy-log";
import del from "del";
import File from "vinyl";
import ts from "../../lib/typescript.js";
import chalk from "chalk";
import which from "which";
import { spawn } from "child_process";
import { Duplex } from "stream";
import assert from "assert";
/**
@ -29,7 +23,7 @@ export async function exec(cmd, args, options = {}) {
return /**@type {Promise<{exitCode?: number}>}*/(new Promise((resolve, reject) => {
const { ignoreExitCode, waitForExit = true } = options;
if (!options.hidePrompt) log(`> ${chalk.green(cmd)} ${args.join(" ")}`);
if (!options.hidePrompt) console.log(`> ${chalk.green(cmd)} ${args.join(" ")}`);
const proc = spawn(which.sync(cmd), args, { stdio: waitForExit ? "inherit" : "ignore" });
if (waitForExit) {
proc.on("exit", exitCode => {
@ -67,7 +61,7 @@ function formatDiagnostics(diagnostics, options) {
* @param {{ cwd?: string }} [options]
*/
function reportDiagnostics(diagnostics, options) {
log(formatDiagnostics(diagnostics, { cwd: options && options.cwd, pretty: process.stdout.isTTY }));
console.log(formatDiagnostics(diagnostics, { cwd: options && options.cwd, pretty: process.stdout.isTTY }));
}
/**
@ -167,7 +161,7 @@ export function needsUpdate(source, dest) {
export function getDiffTool() {
const program = process.env.DIFF;
if (!program) {
log.warn("Add the 'DIFF' environment variable to the path of the program you want to use.");
console.warn("Add the 'DIFF' environment variable to the path of the program you want to use.");
process.exit(1);
}
return program;
@ -191,82 +185,6 @@ export function getDirSize(root) {
.reduce((acc, num) => acc + num, 0);
}
/**
* @param {string | ((file: File) => string) | { cwd?: string }} [dest]
* @param {{ cwd?: string }} [opts]
*/
export function rm(dest, opts) {
if (dest && typeof dest === "object") {
opts = dest;
dest = undefined;
}
let failed = false;
const cwd = path.resolve(opts && opts.cwd || process.cwd());
/** @type {{ file: File, deleted: boolean, promise: Promise<any>, cb: Function }[]} */
const pending = [];
const processDeleted = () => {
if (failed) return;
while (pending.length && pending[0].deleted) {
const fileAndCallback = pending.shift();
assert(fileAndCallback);
const { file, cb } = fileAndCallback;
duplex.push(file);
cb();
}
};
const duplex = new Duplex({
objectMode: true,
/**
* @param {string|Buffer|File} file
*/
write(file, _, cb) {
if (failed) return;
if (typeof file === "string" || Buffer.isBuffer(file)) return cb(new Error("Only Vinyl files are supported."));
const basePath = typeof dest === "string" ? path.resolve(cwd, dest) :
typeof dest === "function" ? path.resolve(cwd, dest(file)) :
file.base;
const filePath = path.resolve(basePath, file.relative);
file.cwd = cwd;
file.base = basePath;
file.path = filePath;
const entry = {
file,
deleted: false,
cb,
promise: del(file.path).then(() => {
entry.deleted = true;
processDeleted();
}, err => {
failed = true;
pending.length = 0;
cb(err);
})
};
pending.push(entry);
},
final(cb) {
// eslint-disable-next-line no-null/no-null
const endThenCb = () => (duplex.push(null), cb()); // signal end of read queue
processDeleted();
if (pending.length) {
Promise
.all(pending.map(entry => entry.promise))
.then(() => processDeleted())
.then(() => endThenCb(), endThenCb);
return;
}
endThenCb();
},
read() {
}
});
return duplex;
}
class Deferred {
constructor() {
this.promise = new Promise((resolve, reject) => {
@ -317,3 +235,20 @@ export class Debouncer {
}
}
}
const unset = Symbol();
/**
* @template T
* @param {() => T} fn
* @returns {() => T}
*/
export function memoize(fn) {
/** @type {T | unset} */
let value = unset;
return () => {
if (value === unset) {
value = fn();
}
return value;
};
}

View File

@ -1,2 +1,2 @@
#!/bin/sh
npm run gulp -- generate-diagnostics
npm run npx hereby -- generate-diagnostics

View File

@ -71,7 +71,7 @@ ${logText.trim()}`;
]);
if (produceLKG) {
runSequence([
["gulp", ["LKG"]],
["node", ["./node_modules/hereby/dist/cli.js", "LKG"]],
["git", ["add", "lib"]],
["git", ["commit", "-m", `"Update LKG"`]]
]);

View File

@ -15,7 +15,7 @@ runSequence([
["git", ["checkout", "."]], // reset any changes
["git", ["fetch", baseRef === "main" ? "origin" : "fork", baseRef]], // fetch target ref in case it's not present locally
["git", ["checkout", baseRef]], // move head to target
["node", ["./node_modules/gulp/bin/gulp.js", "baseline-accept"]], // accept baselines
["node", ["./node_modules/hereby/dist/cli.js", "baseline-accept"]], // accept baselines
["git", ["checkout", "-b", branchName]], // create a branch
["git", ["add", "."]], // Add all changes
["git", ["commit", "-m", `"Update user baselines${+(process.env.SOURCE_ISSUE ?? 0) === 33716 ? " +cc @sandersn" : ""}"`]], // Commit all changes (ping nathan if we would post to CI thread)

View File

@ -1,90 +0,0 @@
import { TaskFunction } from "gulp";
declare module "gulp-insert" {
export function append(text: string | Buffer): NodeJS.ReadWriteStream;
export function prepend(text: string | Buffer): NodeJS.ReadWriteStream;
export function wrap(text: string | Buffer, tail: string | Buffer): NodeJS.ReadWriteStream;
export function transform(cb: (contents: string, file: {path: string, relative: string}) => string): NodeJS.ReadWriteStream; // file is a vinyl file
}
declare module "sorcery";
declare module "vinyl" {
// NOTE: This makes it possible to correctly type vinyl Files under @ts-check.
export = File;
declare class File<T extends File.Contents = File.Contents> {
constructor(options?: File.VinylOptions<T>);
cwd: string;
base: string;
path: string;
readonly history: readonly string[];
contents: T;
relative: string;
dirname: string;
basename: string;
stem: string;
extname: string;
symlink: string | null;
stat: import("fs").Stats | null;
sourceMap?: import("./sourcemaps").RawSourceMap | string;
[custom: string]: any;
isBuffer(): this is T extends Buffer ? File<Buffer> : never;
isStream(): this is T extends NodeJS.ReadableStream ? File<NodeJS.ReadableStream> : never;
isNull(): this is T extends null ? File<null> : never;
isDirectory(): this is T extends null ? File.Directory : never;
isSymbolic(): this is T extends null ? File.Symbolic : never;
clone(opts?: { contents?: boolean, deep?: boolean }): this;
}
namespace File {
export interface VinylOptions<T extends Contents = Contents> {
cwd?: string;
base?: string;
path?: string;
history?: readonly string[];
stat?: import("fs").Stats;
contents?: T;
sourceMap?: import("./sourcemaps").RawSourceMap | string;
[custom: string]: any;
}
export type Contents = Buffer | NodeJS.ReadableStream | null;
export type File = import("./vinyl");
export type NullFile = File<null>;
export type BufferFile = File<Buffer>;
export type StreamFile = File<NodeJS.ReadableStream>;
export interface Directory extends NullFile {
isNull(): true;
isDirectory(): true;
isSymbolic(): this is never;
}
export interface Symbolic extends NullFile {
isNull(): true;
isDirectory(): this is never;
isSymbolic(): true;
}
}
}
declare module "undertaker" {
interface TaskFunctionParams {
flags?: Record<string, string>;
}
interface TaskFunctionWrapped {
description: string
flags: { [name: string]: string }
}
}
declare module "gulp-sourcemaps" {
interface WriteOptions {
destPath?: string;
}
}

View File

@ -1567,10 +1567,7 @@ export let sys: System = (() => {
debugMode: !!process.env.NODE_INSPECTOR_IPC || !!process.env.VSCODE_INSPECTOR_OPTIONS || some(process.execArgv as string[], arg => /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg)),
tryEnableSourceMapsForHost() {
try {
// Trick esbuild into not eagerly resolving a path to a JS file.
// See: https://github.com/evanw/esbuild/issues/1958
const moduleName = "source-map-support" as const;
(require(moduleName) as typeof import("source-map-support")).install();
(require("source-map-support") as typeof import("source-map-support")).install();
}
catch {
// Could not enable source maps.

View File

@ -16,4 +16,4 @@ export function findUpFile(name: string): string {
}
export const findUpRoot: { (): string; cached?: string; } = () =>
findUpRoot.cached ||= dirname(findUpFile("Gulpfile.mjs"));
findUpRoot.cached ||= dirname(findUpFile("Herebyfile.mjs"));

View File

@ -1406,7 +1406,7 @@ export namespace Baseline {
}
function getBaselineFileChangedErrorMessage(relativeFileName: string): string {
return `The baseline file ${relativeFileName} has changed. (Run "gulp baseline-accept" if the new baseline is correct.)`;
return `The baseline file ${relativeFileName} has changed. (Run "hereby baseline-accept" if the new baseline is correct.)`;
}
export function runBaseline(relativeFileName: string, actual: string | null, opts?: BaselineOptions): void {

View File

@ -125,12 +125,15 @@ export class MainProcessLogger extends BaseLogger {
}
}
/** @internal */
// eslint-disable-next-line prefer-const
export let dynamicImport = async (_id: string): Promise<any> => {
let dynamicImport = async (_id: string): Promise<any> => {
throw new Error("Dynamic import not implemented");
};
/** @internal */
export function setDynamicImport(fn: (id: string) => Promise<any>) {
dynamicImport = fn;
}
/** @internal */
export function createWebSystem(host: WebHost, args: string[], getExecutingFilePath: () => string): ServerHost {
const returnEmptyString = () => "";