mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-03-15 14:05:47 -05:00
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:
@@ -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")));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user