Skip to content

Commit 6558e04

Browse files
committed
Merge branch 'main' into fix(29118)
2 parents f85c772 + 0c60da9 commit 6558e04

File tree

647 files changed

+25905
-6945
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

647 files changed

+25905
-6945
lines changed

Diff for: .eslintrc.json

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
"@typescript-eslint", "no-null", "import", "eslint-plugin-local"
1414
],
1515
"rules": {
16+
"sort-imports": ["error", {
17+
"ignoreCase": true,
18+
"ignoreDeclarationSort": true,
19+
"allowSeparatedGroups": true
20+
}],
21+
1622
"@typescript-eslint/adjacent-overload-signatures": "error",
1723
"@typescript-eslint/array-type": "error",
1824
"@typescript-eslint/no-array-constructor": "error",

Diff for: .github/workflows/ci.yml

+64
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,70 @@ jobs:
8686
- name: Build src
8787
run: npx hereby build-src
8888

89+
smoke:
90+
runs-on: ubuntu-latest
91+
92+
steps:
93+
- uses: actions/checkout@v3
94+
- uses: actions/setup-node@v3
95+
with:
96+
node-version: "*"
97+
check-latest: true
98+
- run: npm ci
99+
100+
- run: npx hereby lkg
101+
- run: |
102+
npm pack
103+
mv typescript*.tgz typescript.tgz
104+
echo "PACKAGE=$PWD/typescript.tgz" >> $GITHUB_ENV
105+
106+
- name: Smoke test
107+
run: |
108+
cd "$(mktemp -d)"
109+
npm init --yes
110+
npm install $PACKAGE tslib
111+
112+
echo "Testing tsc..."
113+
npx tsc --version
114+
115+
echo "Testing tsserver..."
116+
echo '{"seq": 1, "command": "status"}' | npx tsserver
117+
118+
cat > smoke.js << 'EOF'
119+
console.log(`Testing ${process.argv[2]}...`);
120+
const { __importDefault, __importStar } = require("tslib");
121+
const ts = require(process.argv[2]);
122+
123+
// See: https://github.com/microsoft/TypeScript/pull/51474#issuecomment-1310871623
124+
const fns = [
125+
[() => ts.version, true],
126+
[() => ts.default.version, false],
127+
[() => __importDefault(ts).version, false],
128+
[() => __importDefault(ts).default.version, true],
129+
[() => __importStar(ts).version, true],
130+
[() => __importStar(ts).default.version, true],
131+
];
132+
133+
for (const [fn, shouldSucceed] of fns) {
134+
let success = false;
135+
try {
136+
success = !!fn();
137+
}
138+
catch {}
139+
const status = success ? "succeeded" : "failed";
140+
if (success === shouldSucceed) {
141+
console.log(`${fn.toString()} ${status} as expected.`);
142+
}
143+
else {
144+
console.log(`${fn.toString()} unexpectedly ${status}.`);
145+
process.exitCode = 1;
146+
}
147+
}
148+
console.log("ok");
149+
EOF
150+
151+
node ./smoke.js typescript
152+
node ./smoke.js typescript/lib/tsserverlibrary
89153
90154
misc:
91155
runs-on: ubuntu-latest

Diff for: .vscode/tasks.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// https://github.com/microsoft/vscode/issues/93001
1515
"label": "gulp: tests",
1616
"type": "npm",
17-
"script": "build:tests",
17+
"script": "build:tests -- --no-typecheck",
1818
"group": "build",
1919
"hide": true,
2020
"problemMatcher": [
@@ -44,7 +44,7 @@
4444
{
4545
"label": "npm: build:tests",
4646
"type": "npm",
47-
"script": "build:tests",
47+
"script": "build:tests -- --no-typecheck",
4848
"group": "build",
4949
"problemMatcher": [
5050
"$tsc"

Diff for: Herebyfile.mjs

+143-22
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ import { task } from "hereby";
66
import _glob from "glob";
77
import util from "util";
88
import chalk from "chalk";
9-
import { exec, readJson, getDiffTool, getDirSize, memoize, needsUpdate } from "./scripts/build/utils.mjs";
10-
import { runConsoleTests, refBaseline, localBaseline, refRwcBaseline, localRwcBaseline } from "./scripts/build/tests.mjs";
11-
import { buildProject as realBuildProject, cleanProject, watchProject } from "./scripts/build/projects.mjs";
9+
import { Debouncer, Deferred, exec, getDiffTool, getDirSize, memoize, needsUpdate, readJson } from "./scripts/build/utils.mjs";
10+
import { cleanTestDirs, localBaseline, localRwcBaseline, refBaseline, refRwcBaseline, runConsoleTests } from "./scripts/build/tests.mjs";
11+
import { cleanProject, buildProject as realBuildProject, watchProject } from "./scripts/build/projects.mjs";
1212
import { localizationDirectories } from "./scripts/build/localization.mjs";
1313
import cmdLineOptions from "./scripts/build/options.mjs";
1414
import esbuild from "esbuild";
15+
import chokidar from "chokidar";
16+
import { EventEmitter } from "events";
17+
import { CancelToken } from "@esfx/canceltoken";
1518

1619
const glob = util.promisify(_glob);
1720

@@ -191,6 +194,7 @@ async function runDtsBundler(entrypoint, output) {
191194
* @property {string[]} [external]
192195
* @property {boolean} [exportIsTsObject]
193196
* @property {boolean} [treeShaking]
197+
* @property {esbuild.WatchMode} [watchMode]
194198
*/
195199
function createBundler(entrypoint, outfile, taskOptions = {}) {
196200
const getOptions = memoize(async () => {
@@ -269,7 +273,7 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
269273

270274
return {
271275
build: async () => esbuild.build(await getOptions()),
272-
watch: async () => esbuild.build({ ...await getOptions(), watch: true, logLevel: "info" }),
276+
watch: async () => esbuild.build({ ...await getOptions(), watch: taskOptions.watchMode ?? true, logLevel: "info" }),
273277
};
274278
}
275279

@@ -324,10 +328,21 @@ function entrypointBuildTask(options) {
324328
},
325329
});
326330

331+
const mainDeps = options.mainDeps?.slice(0) ?? [];
332+
if (cmdLineOptions.bundle) {
333+
mainDeps.push(bundle);
334+
if (cmdLineOptions.typecheck) {
335+
mainDeps.push(build);
336+
}
337+
}
338+
else {
339+
mainDeps.push(build, shim);
340+
}
341+
327342
const main = task({
328343
name: options.name,
329344
description: options.description,
330-
dependencies: (options.mainDeps ?? []).concat(cmdLineOptions.bundle ? [bundle] : [build, shim]),
345+
dependencies: mainDeps,
331346
});
332347

333348
const watch = task({
@@ -354,7 +369,7 @@ function entrypointBuildTask(options) {
354369
}
355370

356371

357-
const { main: tsc, build: buildTsc, watch: watchTsc } = entrypointBuildTask({
372+
const { main: tsc, watch: watchTsc } = entrypointBuildTask({
358373
name: "tsc",
359374
description: "Builds the command-line compiler",
360375
buildDeps: [generateDiagnostics],
@@ -392,7 +407,7 @@ export const dtsServices = task({
392407
});
393408

394409

395-
const { main: tsserver, build: buildTsserver, watch: watchTsserver } = entrypointBuildTask({
410+
const { main: tsserver, watch: watchTsserver } = entrypointBuildTask({
396411
name: "tsserver",
397412
description: "Builds the language server",
398413
buildDeps: [generateDiagnostics],
@@ -410,15 +425,10 @@ const { main: tsserver, build: buildTsserver, watch: watchTsserver } = entrypoin
410425
export { tsserver, watchTsserver };
411426

412427

413-
const buildMin = task({
414-
name: "build-min",
415-
dependencies: [buildTsc, buildTsserver],
416-
});
417-
418428
export const min = task({
419429
name: "min",
420430
description: "Builds only tsc and tsserver",
421-
dependencies: [tsc, tsserver].concat(cmdLineOptions.typecheck ? [buildMin] : []),
431+
dependencies: [tsc, tsserver],
422432
});
423433

424434
export const watchMin = task({
@@ -461,7 +471,7 @@ export const dts = task({
461471

462472

463473
const testRunner = "./built/local/run.js";
464-
474+
const watchTestsEmitter = new EventEmitter();
465475
const { main: tests, watch: watchTests } = entrypointBuildTask({
466476
name: "tests",
467477
description: "Builds the test infrastructure",
@@ -482,6 +492,11 @@ const { main: tests, watch: watchTests } = entrypointBuildTask({
482492
"mocha",
483493
"ms",
484494
],
495+
watchMode: {
496+
onRebuild() {
497+
watchTestsEmitter.emit("rebuild");
498+
}
499+
}
485500
},
486501
});
487502
export { tests, watchTests };
@@ -582,15 +597,10 @@ export const watchOtherOutputs = task({
582597
dependencies: [watchCancellationToken, watchTypingsInstaller, watchWatchGuard, generateTypesMap, copyBuiltLocalDiagnosticMessages],
583598
});
584599

585-
const buildLocal = task({
586-
name: "build-local",
587-
dependencies: [buildTsc, buildTsserver, buildServices, buildLssl]
588-
});
589-
590600
export const local = task({
591601
name: "local",
592602
description: "Builds the full compiler and services",
593-
dependencies: [localize, tsc, tsserver, services, lssl, otherOutputs, dts].concat(cmdLineOptions.typecheck ? [buildLocal] : []),
603+
dependencies: [localize, tsc, tsserver, services, lssl, otherOutputs, dts],
594604
});
595605
export default local;
596606

@@ -601,7 +611,7 @@ export const watchLocal = task({
601611
dependencies: [localize, watchTsc, watchTsserver, watchServices, watchLssl, watchOtherOutputs, dts, watchSrc],
602612
});
603613

604-
const runtestsDeps = [tests, generateLibs].concat(cmdLineOptions.typecheck ? [dts, buildSrc] : []);
614+
const runtestsDeps = [tests, generateLibs].concat(cmdLineOptions.typecheck ? [dts] : []);
605615

606616
export const runTests = task({
607617
name: "runtests",
@@ -625,6 +635,117 @@ export const runTests = task({
625635
// " --shardId": "1-based ID of this shard (default: 1)",
626636
// };
627637

638+
export const runTestsAndWatch = task({
639+
name: "runtests-watch",
640+
dependencies: [watchTests],
641+
run: async () => {
642+
if (!cmdLineOptions.tests && !cmdLineOptions.failed) {
643+
console.log(chalk.redBright(`You must specifiy either --tests/-t or --failed to use 'runtests-watch'.`));
644+
return;
645+
}
646+
647+
let watching = true;
648+
let running = true;
649+
let lastTestChangeTimeMs = Date.now();
650+
let testsChangedDeferred = /** @type {Deferred<void>} */(new Deferred());
651+
let testsChangedCancelSource = CancelToken.source();
652+
653+
const testsChangedDebouncer = new Debouncer(1_000, endRunTests);
654+
const testCaseWatcher = chokidar.watch([
655+
"tests/cases/**/*.*",
656+
"tests/lib/**/*.*",
657+
"tests/projects/**/*.*",
658+
], {
659+
ignorePermissionErrors: true,
660+
alwaysStat: true
661+
});
662+
663+
process.on("SIGINT", endWatchMode);
664+
process.on("SIGKILL", endWatchMode);
665+
process.on("beforeExit", endWatchMode);
666+
watchTestsEmitter.on("rebuild", onRebuild);
667+
testCaseWatcher.on("all", onChange);
668+
669+
while (watching) {
670+
const promise = testsChangedDeferred.promise;
671+
const token = testsChangedCancelSource.token;
672+
if (!token.signaled) {
673+
running = true;
674+
try {
675+
await runConsoleTests(testRunner, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, { token, watching: true });
676+
}
677+
catch {
678+
// ignore
679+
}
680+
running = false;
681+
}
682+
if (watching) {
683+
console.log(chalk.yellowBright(`[watch] test run complete, waiting for changes...`));
684+
await promise;
685+
}
686+
}
687+
688+
function onRebuild() {
689+
beginRunTests(testRunner);
690+
}
691+
692+
/**
693+
* @param {'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir'} eventName
694+
* @param {string} path
695+
* @param {fs.Stats | undefined} stats
696+
*/
697+
function onChange(eventName, path, stats) {
698+
switch (eventName) {
699+
case "change":
700+
case "unlink":
701+
case "unlinkDir":
702+
break;
703+
case "add":
704+
case "addDir":
705+
// skip files that are detected as 'add' but haven't actually changed since the last time tests were
706+
// run.
707+
if (stats && stats.mtimeMs <= lastTestChangeTimeMs) {
708+
return;
709+
}
710+
break;
711+
}
712+
beginRunTests(path);
713+
}
714+
715+
/**
716+
* @param {string} path
717+
*/
718+
function beginRunTests(path) {
719+
if (testsChangedDebouncer.empty) {
720+
console.log(chalk.yellowBright(`[watch] tests changed due to '${path}', restarting...`));
721+
if (running) {
722+
console.log(chalk.yellowBright("[watch] aborting in-progress test run..."));
723+
}
724+
testsChangedCancelSource.cancel();
725+
testsChangedCancelSource = CancelToken.source();
726+
}
727+
728+
testsChangedDebouncer.enqueue();
729+
}
730+
731+
function endRunTests() {
732+
lastTestChangeTimeMs = Date.now();
733+
testsChangedDeferred.resolve();
734+
testsChangedDeferred = /** @type {Deferred<void>} */(new Deferred());
735+
}
736+
737+
function endWatchMode() {
738+
if (watching) {
739+
watching = false;
740+
console.log(chalk.yellowBright("[watch] exiting watch mode..."));
741+
testsChangedCancelSource.cancel();
742+
testCaseWatcher.close();
743+
watchTestsEmitter.off("rebuild", onRebuild);
744+
}
745+
}
746+
},
747+
});
748+
628749
export const runTestsParallel = task({
629750
name: "runtests-parallel",
630751
description: "Runs all the tests in parallel using the built run.js file.",
@@ -726,7 +847,7 @@ export const importDefinitelyTypedTests = task({
726847
export const produceLKG = task({
727848
name: "LKG",
728849
description: "Makes a new LKG out of the built js files",
729-
dependencies: [localize, tsc, tsserver, services, lssl, otherOutputs, dts],
850+
dependencies: [local],
730851
run: async () => {
731852
if (!cmdLineOptions.bundle) {
732853
throw new Error("LKG cannot be created when --bundle=false");

0 commit comments

Comments
 (0)