2014-07-13 01:04:16 +02:00
|
|
|
// This file contains the build logic for the public repo
|
2017-09-15 00:42:06 +02:00
|
|
|
// @ts-check
|
2017-12-19 22:40:32 +01:00
|
|
|
/// <reference types="jake" />
|
2014-07-13 01:04:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
const fs = require("fs");
|
|
|
|
const os = require("os");
|
|
|
|
const path = require("path");
|
|
|
|
const child_process = require("child_process");
|
|
|
|
const removeInternal = require("remove-internal");
|
|
|
|
const fold = require("travis-fold");
|
|
|
|
const ts = require("./lib/typescript");
|
|
|
|
const del = require("del");
|
2018-06-08 02:53:44 +02:00
|
|
|
const getDirSize = require("./scripts/build/getDirSize");
|
2017-02-08 03:14:23 +01:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
const host = process.env.TYPESCRIPT_HOST || process.env.host || "node";
|
|
|
|
|
|
|
|
const locales = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"];
|
|
|
|
|
|
|
|
const defaultTestTimeout = 40000;
|
|
|
|
|
|
|
|
let useDebugMode = true;
|
|
|
|
|
|
|
|
const TaskNames = {
|
|
|
|
local: "local",
|
|
|
|
runtests: "runtests",
|
|
|
|
runtestsParallel: "runtests-parallel",
|
|
|
|
buildRules: "build-rules",
|
|
|
|
clean: "clean",
|
|
|
|
lib: "lib",
|
|
|
|
buildFoldStart: "build-fold-start",
|
|
|
|
buildFoldEnd: "build-fold-end",
|
|
|
|
generateDiagnostics: "generate-diagnostics",
|
|
|
|
coreBuild: "core-build",
|
|
|
|
lkg: "LKG",
|
|
|
|
release: "release",
|
|
|
|
lssl: "lssl",
|
|
|
|
lint: "lint"
|
|
|
|
};
|
|
|
|
|
|
|
|
const Paths = {
|
|
|
|
lkg: "lib",
|
|
|
|
lkgCompiler: "lib/tsc.js",
|
|
|
|
|
|
|
|
built: "built",
|
|
|
|
builtLocal: "built/local",
|
|
|
|
builtLocalCompiler: "built/local/tsc.js",
|
|
|
|
builtLocalRun: "built/local/run.js",
|
|
|
|
locLcg: "built/local/enu/diagnosticMessages.generated.json.lcg",
|
|
|
|
typesMapOutput: "built/local/typesMap.json",
|
2018-06-10 23:56:48 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
servicesFile: "built/local/typescriptServices.js",
|
|
|
|
servicesDefinitionFile: "built/local/typescriptServices.d.ts",
|
|
|
|
|
2018-06-10 23:56:48 +02:00
|
|
|
tsserverGlobalLibraryFile: "built/local/tsserverGlobalLibrary.js",
|
|
|
|
tsserverGlobalLibraryDefinitionFile: "built/local/tsserverGlobalLibrary.d.ts",
|
2018-06-10 22:23:16 +02:00
|
|
|
tsserverLibraryFile: "built/local/tsserverlibrary.js",
|
|
|
|
tsserverLibraryDefinitionFile: "built/local/tsserverlibrary.d.ts",
|
|
|
|
|
|
|
|
baselines: {
|
|
|
|
local: "tests/baselines/local",
|
|
|
|
localTest262: "tests/baselines/test262/local",
|
|
|
|
localRwc: "tests/baselines/rwc/local",
|
|
|
|
reference: "tests/baselines/reference",
|
|
|
|
referenceTest262: "tests/baselines/test262/reference",
|
|
|
|
referenceRwc: "tests/baselines/rwc/reference"
|
|
|
|
},
|
|
|
|
copyright: "CopyrightNotice.txt",
|
|
|
|
thirdParty: "ThirdPartyNoticeText.txt",
|
|
|
|
library: "src/lib",
|
|
|
|
|
|
|
|
processDiagnosticMessagesJs: "scripts/processDiagnosticMessages.js",
|
|
|
|
diagnosticInformationMap: "src/parser/diagnosticInformationMap.generated.ts",
|
|
|
|
diagnosticMessagesJson: "src/parser/diagnosticMessages.json",
|
|
|
|
|
|
|
|
srcServer: "src/server",
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const ConfigFileFor = {
|
|
|
|
tsc: "src/tsc",
|
|
|
|
tsserver: "src/tsserver",
|
|
|
|
runjs: "src/testRunner",
|
|
|
|
lint: "scripts/tslint",
|
|
|
|
all: "src"
|
|
|
|
};
|
|
|
|
|
|
|
|
const ExpectedLKGFiles = [
|
|
|
|
"tsc.js",
|
|
|
|
"tsserver.js",
|
|
|
|
"typescriptServices.js",
|
|
|
|
"typescriptServices.d.ts",
|
|
|
|
"typescript.js",
|
|
|
|
"typescript.d.ts",
|
|
|
|
"tsserverlibrary.js",
|
|
|
|
"tsserverlibrary.d.js",
|
|
|
|
"cancellationToken.js",
|
|
|
|
"typingsInstaller.js",
|
|
|
|
"protocol.d.ts",
|
|
|
|
"watchGuard.js"
|
|
|
|
];
|
2018-06-10 19:59:03 +02:00
|
|
|
|
|
|
|
/** @type {{ libs: string[], paths?: Record<string, string>, sources?: Record<string, string[]> }} */
|
2018-06-10 22:23:16 +02:00
|
|
|
const libraries = readJson("./src/lib/libs.json");
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
directory(Paths.builtLocal);
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
// Local target to build the compiler and services
|
|
|
|
desc("Builds the full compiler and services");
|
|
|
|
task(TaskNames.local, [
|
|
|
|
TaskNames.buildFoldStart,
|
|
|
|
TaskNames.generateDiagnostics,
|
|
|
|
TaskNames.lib,
|
|
|
|
TaskNames.coreBuild,
|
|
|
|
// buildProtocolDts,
|
|
|
|
// builtGeneratedDiagnosticMessagesJSON,
|
|
|
|
TaskNames.lssl,
|
|
|
|
// "localize",
|
|
|
|
TaskNames.buildFoldEnd
|
|
|
|
]);
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true.");
|
|
|
|
task(TaskNames.runtestsParallel, [TaskNames.lib], function () {
|
|
|
|
tsbuild([ConfigFileFor.runjs, ConfigFileFor.lint]);
|
|
|
|
runConsoleTests("min", /*parallel*/ true);
|
|
|
|
}, { async: true });
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true.");
|
|
|
|
task(TaskNames.runtests, [TaskNames.lib], function () {
|
|
|
|
tsbuild([ConfigFileFor.runjs, ConfigFileFor.lint]);
|
|
|
|
runConsoleTests('mocha-fivemat-progress-reporter', /*runInParallel*/ false);;
|
|
|
|
}, { async: true });
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:26:16 +02:00
|
|
|
// Makes the test results the new baseline
|
|
|
|
desc("Makes the most recent test results the new baseline, overwriting the old baseline");
|
|
|
|
task("baseline-accept", function () {
|
|
|
|
acceptBaseline(Paths.baselines.local, Paths.baselines.reference);
|
|
|
|
});
|
|
|
|
|
|
|
|
desc("Makes the most recent rwc test results the new baseline, overwriting the old baseline");
|
|
|
|
task("baseline-accept-rwc", function () {
|
|
|
|
acceptBaseline(Paths.baselines.localRwc, Paths.baselines.referenceRwc);
|
|
|
|
});
|
|
|
|
|
|
|
|
desc("Makes the most recent test262 test results the new baseline, overwriting the old baseline");
|
|
|
|
task("baseline-accept-test262", function () {
|
|
|
|
acceptBaseline(Paths.baselines.localTest262, Paths.baselines.referenceTest262);
|
|
|
|
});
|
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
const libraryTargets = getLibraryTargets();
|
|
|
|
desc("Builds the library targets");
|
|
|
|
task(TaskNames.lib, libraryTargets);
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Builds language service server library");
|
|
|
|
task("lssl", [TaskNames.coreBuild, Paths.tsserverLibraryFile, Paths.tsserverLibraryDefinitionFile, Paths.typesMapOutput]);
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
|
|
|
|
desc("Makes a new LKG out of the built js files");
|
|
|
|
task(TaskNames.lkg, [
|
|
|
|
TaskNames.clean,
|
|
|
|
TaskNames.release,
|
|
|
|
TaskNames.local,
|
|
|
|
...libraryTargets
|
|
|
|
], () => {
|
|
|
|
const sizeBefore = getDirSize(Paths.lkg);
|
|
|
|
const localizationTargets = locales.map(f => path.join(Paths.builtLocal, f)).concat(path.dirname(Paths.locLcg));
|
|
|
|
|
2018-06-10 23:56:48 +02:00
|
|
|
const copyrightContent = readFileSync(Paths.copyright);
|
2018-06-10 22:23:16 +02:00
|
|
|
|
|
|
|
const expectedFiles = [...libraryTargets, ...ExpectedLKGFiles, ...localizationTargets];
|
|
|
|
const missingFiles = expectedFiles.filter(f => !fs.existsSync(f));
|
|
|
|
if (missingFiles.length > 0) {
|
|
|
|
fail(new Error("Cannot replace the LKG unless all built targets are present in directory " + Paths.builtLocal +
|
|
|
|
". The following files are missing:\n" + missingFiles.join("\n")));
|
|
|
|
}
|
|
|
|
// Copy all the targets into the LKG directory
|
|
|
|
jake.mkdirP(Paths.lkg);
|
|
|
|
expectedFiles.forEach(f => {
|
2018-06-10 23:56:48 +02:00
|
|
|
let content = readFileSync(f);
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
// If this is a .d.ts file, run remove-internal on it
|
|
|
|
if (f.endsWith(".d.ts")) {
|
|
|
|
content = removeInternal.elide(content).result;
|
2018-06-10 19:58:16 +02:00
|
|
|
}
|
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
if (f.endsWith(".d.ts") || f.endsWith(".js")) {
|
|
|
|
// Prepend the copyright header to it
|
|
|
|
content = copyrightContent + content;
|
2018-06-10 19:59:03 +02:00
|
|
|
}
|
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
fs.writeFile(path.join(Paths.lkg, path.basename(f)), content, { encoding: 'utf-8' }, (err) => {
|
|
|
|
if (err) throw err;
|
2018-06-10 19:59:03 +02:00
|
|
|
});
|
2018-06-10 19:58:16 +02:00
|
|
|
});
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
const sizeAfter = getDirSize(Paths.lkg);
|
|
|
|
if (sizeAfter > (sizeBefore * 1.10)) {
|
|
|
|
throw new Error("The lib folder increased by 10% or more. This likely indicates a bug.");
|
2018-06-10 19:58:16 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Runs tslint on the compiler sources. Optional arguments are: f[iles]=regex");
|
|
|
|
task(TaskNames.lint, [TaskNames.buildRules], () => {
|
|
|
|
if (fold.isTravis()) console.log(fold.start("lint"));
|
|
|
|
function lint(project, cb) {
|
|
|
|
const fix = process.env.fix || process.env.f;
|
|
|
|
const cmd = `node node_modules/tslint/bin/tslint --project ${project} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish${fix ? " --fix" : ""}`;
|
|
|
|
console.log("Linting: " + cmd);
|
|
|
|
jake.exec([cmd], cb, /** @type {jake.ExecOptions} */({ interactive: true, windowsVerbatimArguments: true }));
|
|
|
|
}
|
|
|
|
lint("scripts/tslint/tsconfig.json", () => lint("src/tsconfig-base.json", () => {
|
|
|
|
if (fold.isTravis()) console.log(fold.end("lint"));
|
|
|
|
complete();
|
|
|
|
}));
|
2018-06-10 19:59:03 +02:00
|
|
|
});
|
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Diffs the compiler baselines using the diff tool specified by the 'DIFF' environment variable");
|
|
|
|
task('diff', function () {
|
|
|
|
var cmd = `"${getDiffTool()} ${Paths.baselines.reference} ${Paths.baselines.local}`;
|
2018-06-10 19:59:03 +02:00
|
|
|
console.log(cmd);
|
|
|
|
exec(cmd);
|
|
|
|
}, { async: true });
|
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Diffs the RWC baselines using the diff tool specified by the 'DIFF' environment variable");
|
|
|
|
task('diff-rwc', function () {
|
|
|
|
var cmd = `"${getDiffTool()} ${Paths.baselines.referenceRwc} ${Paths.baselines.localRwc}`;
|
2018-06-10 19:58:16 +02:00
|
|
|
console.log(cmd);
|
|
|
|
exec(cmd);
|
2018-06-10 22:23:16 +02:00
|
|
|
}, { async: true });
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Sets the release mode flag");
|
|
|
|
task("release", function () {
|
|
|
|
useDebugMode = false;
|
2018-06-10 19:58:16 +02:00
|
|
|
});
|
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Clears the release mode flag");
|
|
|
|
task("setDebugMode", function () {
|
|
|
|
useDebugMode = true;
|
|
|
|
});
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Emit the start of the build fold");
|
|
|
|
task(TaskNames.buildFoldStart, [], function () {
|
|
|
|
if (fold.isTravis()) console.log(fold.start("build"));
|
|
|
|
});
|
2015-09-18 22:13:26 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Emit the end of the build fold");
|
|
|
|
task(TaskNames.buildFoldEnd, [], function () {
|
|
|
|
if (fold.isTravis()) console.log(fold.end("build"));
|
|
|
|
});
|
2015-09-18 02:55:07 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Compiles tslint rules to js");
|
|
|
|
task(TaskNames.buildRules, [], function () {
|
|
|
|
tsbuild(ConfigFileFor.lint, undefined, () => complete());
|
|
|
|
}, { async: true });
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Cleans the compiler output, declare files, and tests");
|
|
|
|
task(TaskNames.clean, function () {
|
|
|
|
jake.rmRf(Paths.built);
|
|
|
|
});
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
desc("Generates a diagnostic file in TypeScript based on an input JSON file");
|
|
|
|
task(TaskNames.generateDiagnostics, [Paths.diagnosticInformationMap]);
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
task(TaskNames.coreBuild, function () {
|
|
|
|
tsbuild(ConfigFileFor.all, undefined, () => complete());
|
|
|
|
}, { async: true });
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
file(Paths.diagnosticMessagesJson);
|
|
|
|
file(Paths.diagnosticInformationMap, [Paths.diagnosticMessagesJson], function (complete) {
|
|
|
|
tsbuild("scripts/processDiagnosticMessages.tsconfig.json", /*lkg*/ true, function () {
|
|
|
|
const cmd = `${host} scripts/processDiagnosticMessages.js ${Paths.diagnosticMessagesJson}`;
|
|
|
|
console.log(cmd);
|
|
|
|
var ex = jake.createExec([cmd]);
|
|
|
|
// Add listeners for output and error
|
|
|
|
ex.addListener("stdout", function (output) {
|
|
|
|
process.stdout.write(output);
|
|
|
|
});
|
|
|
|
ex.addListener("stderr", function (error) {
|
|
|
|
process.stderr.write(error);
|
|
|
|
});
|
|
|
|
ex.addListener("cmdEnd", function () {
|
|
|
|
complete();
|
|
|
|
});
|
|
|
|
ex.run();
|
2018-06-10 19:58:16 +02:00
|
|
|
});
|
2018-06-10 22:23:16 +02:00
|
|
|
}, { async: true });
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
file(Paths.typesMapOutput, /** @type {*} */(function () {
|
2018-06-10 23:56:48 +02:00
|
|
|
var content = readFileSync(path.join(Paths.srcServer, 'typesMap.json'));
|
2018-06-10 22:23:16 +02:00
|
|
|
// Validate that it's valid JSON
|
|
|
|
try {
|
|
|
|
JSON.parse(content.toString());
|
|
|
|
} catch (e) {
|
|
|
|
console.log("Parse error in typesMap.json: " + e);
|
2018-06-10 19:58:16 +02:00
|
|
|
}
|
2018-06-10 22:23:16 +02:00
|
|
|
fs.writeFileSync(Paths.typesMapOutput, content);
|
|
|
|
}));
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
file(Paths.tsserverLibraryFile, [TaskNames.coreBuild, Paths.copyright, ...libraryTargets], function() {
|
2018-06-10 23:56:48 +02:00
|
|
|
const originalContent = readFileSync(Paths.tsserverGlobalLibraryFile);
|
|
|
|
const newContent =
|
|
|
|
readFileSync(Paths.copyright) +
|
|
|
|
originalContent;
|
|
|
|
writeFileSync(Paths.tsserverLibraryFile, newContent);
|
2018-06-10 22:23:16 +02:00
|
|
|
});
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
file(Paths.tsserverLibraryDefinitionFile, [TaskNames.coreBuild, Paths.copyright, ...libraryTargets], function () {
|
2018-06-10 23:56:48 +02:00
|
|
|
const content = readFileSync(Paths.tsserverGlobalLibraryDefinitionFile);
|
2018-06-10 22:23:16 +02:00
|
|
|
const newContent =
|
|
|
|
removeConstModifierFromEnumDeclarations(content) +
|
|
|
|
`\nexport = ts` +
|
|
|
|
`\nexport as namespace ts;`;
|
2014-07-13 01:04:16 +02:00
|
|
|
|
2018-06-10 23:56:48 +02:00
|
|
|
writeFileSync(Paths.tsserverLibraryDefinitionFile, newContent);
|
2018-06-10 22:23:16 +02:00
|
|
|
});
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
function getLibraryTargets() {
|
|
|
|
return libraries.libs.map(function (lib) {
|
|
|
|
var relativeSources = ["header.d.ts"].concat(libraries.sources && libraries.sources[lib] || [lib + ".d.ts"]);
|
|
|
|
var relativeTarget = libraries.paths && libraries.paths[lib] || ("lib." + lib + ".d.ts");
|
|
|
|
var sources = [Paths.copyright].concat(relativeSources.map(s => path.join(Paths.library, s)));
|
|
|
|
var target = path.join(Paths.builtLocal, relativeTarget);
|
|
|
|
file(target, [Paths.builtLocal].concat(sources), function () {
|
|
|
|
concatenateFiles(target, sources);
|
|
|
|
});
|
|
|
|
return target;
|
|
|
|
});
|
2018-06-10 19:58:16 +02:00
|
|
|
}
|
|
|
|
|
2016-05-24 01:00:56 +02:00
|
|
|
function runConsoleTests(defaultReporter, runInParallel) {
|
2016-06-07 19:32:03 +02:00
|
|
|
var dirty = process.env.dirty;
|
2016-04-13 03:40:39 +02:00
|
|
|
if (!dirty) {
|
|
|
|
cleanTestDirs();
|
|
|
|
}
|
|
|
|
|
2017-06-08 21:24:20 +02:00
|
|
|
var debug = process.env.debug || process.env["debug-brk"] || process.env.d;
|
|
|
|
var inspect = process.env.inspect || process.env["inspect-brk"] || process.env.i;
|
2017-06-06 22:33:19 +02:00
|
|
|
var testTimeout = process.env.timeout || defaultTestTimeout;
|
2017-11-06 20:24:17 +01:00
|
|
|
var runners = process.env.runners || process.env.runner || process.env.ru;
|
2017-06-06 22:33:19 +02:00
|
|
|
var tests = process.env.test || process.env.tests || process.env.t;
|
2017-10-20 02:15:54 +02:00
|
|
|
var light = process.env.light === undefined || process.env.light !== "false";
|
2016-06-07 19:32:03 +02:00
|
|
|
var stackTraceLimit = process.env.stackTraceLimit;
|
2014-07-13 01:04:16 +02:00
|
|
|
var testConfigFile = 'test.config';
|
2016-08-19 23:34:14 +02:00
|
|
|
if (fs.existsSync(testConfigFile)) {
|
2014-07-13 01:04:16 +02:00
|
|
|
fs.unlinkSync(testConfigFile);
|
|
|
|
}
|
2016-05-24 01:00:56 +02:00
|
|
|
var workerCount, taskConfigsFolder;
|
|
|
|
if (runInParallel) {
|
|
|
|
// generate name to store task configuration files
|
|
|
|
var prefix = os.tmpdir() + "/ts-tests";
|
|
|
|
var i = 1;
|
|
|
|
do {
|
|
|
|
taskConfigsFolder = prefix + i;
|
|
|
|
i++;
|
|
|
|
} while (fs.existsSync(taskConfigsFolder));
|
|
|
|
fs.mkdirSync(taskConfigsFolder);
|
|
|
|
|
2017-06-06 22:33:19 +02:00
|
|
|
workerCount = process.env.workerCount || process.env.p || os.cpus().length;
|
2016-05-24 01:00:56 +02:00
|
|
|
}
|
2014-09-03 19:37:32 +02:00
|
|
|
|
|
|
|
if (tests && tests.toLocaleLowerCase() === "rwc") {
|
2016-11-22 02:25:38 +01:00
|
|
|
testTimeout = 800000;
|
2014-09-03 19:37:32 +02:00
|
|
|
}
|
|
|
|
|
2018-01-08 21:28:04 +01:00
|
|
|
if (tests || runners || light || testTimeout || taskConfigsFolder) {
|
|
|
|
writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors, testTimeout);
|
|
|
|
}
|
|
|
|
|
2017-07-25 23:35:22 +02:00
|
|
|
var colorsFlag = process.env.color || process.env.colors;
|
|
|
|
var colors = colorsFlag !== "false" && colorsFlag !== "0";
|
2017-02-07 23:36:15 +01:00
|
|
|
var reporter = process.env.reporter || process.env.r || defaultReporter;
|
|
|
|
var bail = process.env.bail || process.env.b;
|
2016-05-16 20:53:44 +02:00
|
|
|
var lintFlag = process.env.lint !== 'false';
|
2015-10-26 18:25:01 +01:00
|
|
|
|
2014-07-26 02:01:01 +02:00
|
|
|
// timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally
|
|
|
|
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
2016-08-19 23:34:14 +02:00
|
|
|
if (!runInParallel) {
|
2018-06-10 22:23:16 +02:00
|
|
|
var startTime = Travis.mark();
|
2017-02-07 23:36:15 +01:00
|
|
|
var args = [];
|
|
|
|
args.push("-R", reporter);
|
|
|
|
if (tests) {
|
|
|
|
args.push("-g", `"${tests}"`);
|
|
|
|
}
|
|
|
|
if (colors) {
|
|
|
|
args.push("--colors");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
args.push("--no-colors");
|
|
|
|
}
|
|
|
|
if (bail) {
|
|
|
|
args.push("--bail");
|
|
|
|
}
|
2017-06-08 21:24:20 +02:00
|
|
|
if (inspect) {
|
|
|
|
args.unshift("--inspect-brk");
|
|
|
|
}
|
|
|
|
else if (debug) {
|
|
|
|
args.unshift("--debug-brk");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
args.push("-t", testTimeout);
|
|
|
|
}
|
2018-06-10 22:23:16 +02:00
|
|
|
args.push(Paths.builtLocalRun);
|
2017-02-07 23:36:15 +01:00
|
|
|
|
|
|
|
var cmd = "mocha " + args.join(" ");
|
2015-10-24 01:27:44 +02:00
|
|
|
console.log(cmd);
|
2016-06-10 07:07:07 +02:00
|
|
|
|
|
|
|
var savedNodeEnv = process.env.NODE_ENV;
|
|
|
|
process.env.NODE_ENV = "development";
|
2016-05-20 22:40:34 +02:00
|
|
|
exec(cmd, function () {
|
2016-06-10 07:07:07 +02:00
|
|
|
process.env.NODE_ENV = savedNodeEnv;
|
2018-06-10 22:23:16 +02:00
|
|
|
Travis.measure(startTime);
|
2016-05-24 23:29:52 +02:00
|
|
|
runLinter();
|
2016-05-20 22:40:34 +02:00
|
|
|
finish();
|
2016-08-19 23:34:14 +02:00
|
|
|
}, function (e, status) {
|
2016-06-10 07:07:07 +02:00
|
|
|
process.env.NODE_ENV = savedNodeEnv;
|
2018-06-10 22:23:16 +02:00
|
|
|
Travis.measure(startTime);
|
2016-05-26 01:23:51 +02:00
|
|
|
finish(status);
|
|
|
|
});
|
2016-05-24 01:00:56 +02:00
|
|
|
}
|
|
|
|
else {
|
2016-06-10 07:07:07 +02:00
|
|
|
var savedNodeEnv = process.env.NODE_ENV;
|
|
|
|
process.env.NODE_ENV = "development";
|
2018-06-10 22:23:16 +02:00
|
|
|
var startTime = Travis.mark();
|
|
|
|
exec(host + " " + Paths.builtLocalRun, function () {
|
2016-06-10 07:07:07 +02:00
|
|
|
process.env.NODE_ENV = savedNodeEnv;
|
2018-06-10 22:23:16 +02:00
|
|
|
Travis.measure(startTime);
|
|
|
|
var lint = jake.Task["lint"];
|
|
|
|
lint.addListener("complete", () => finish());
|
|
|
|
lint.invoke();
|
2017-09-15 00:42:06 +02:00
|
|
|
finish();
|
|
|
|
}, function (e, status) {
|
|
|
|
process.env.NODE_ENV = savedNodeEnv;
|
2018-06-10 22:23:16 +02:00
|
|
|
Travis.measure(startTime);
|
2017-09-15 00:42:06 +02:00
|
|
|
finish(status);
|
2016-05-24 01:00:56 +02:00
|
|
|
});
|
|
|
|
}
|
2016-06-06 20:37:59 +02:00
|
|
|
|
2016-05-26 01:23:51 +02:00
|
|
|
function failWithStatus(status) {
|
|
|
|
fail("Process exited with code " + status);
|
|
|
|
}
|
2016-06-06 20:37:59 +02:00
|
|
|
|
2016-05-26 01:23:51 +02:00
|
|
|
function finish(errorStatus) {
|
2016-05-24 01:00:56 +02:00
|
|
|
deleteTemporaryProjectOutput();
|
2016-05-26 01:23:51 +02:00
|
|
|
if (errorStatus !== undefined) {
|
|
|
|
failWithStatus(errorStatus);
|
2016-05-20 22:40:34 +02:00
|
|
|
}
|
2016-05-26 01:23:51 +02:00
|
|
|
else {
|
|
|
|
complete();
|
|
|
|
}
|
2016-05-24 01:00:56 +02:00
|
|
|
}
|
|
|
|
function runLinter() {
|
2016-06-01 03:43:51 +02:00
|
|
|
if (!lintFlag || dirty) {
|
2016-05-24 01:00:56 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
var lint = jake.Task['lint'];
|
|
|
|
lint.addListener('complete', function () {
|
|
|
|
complete();
|
|
|
|
});
|
|
|
|
lint.invoke();
|
|
|
|
}
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
// used to pass data from jake command line directly to run.js
|
|
|
|
function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, colors, testTimeout) {
|
|
|
|
var testConfigContents = JSON.stringify({
|
|
|
|
runners: runners ? runners.split(",") : undefined,
|
|
|
|
test: tests ? [tests] : undefined,
|
|
|
|
light: light,
|
|
|
|
workerCount: workerCount,
|
|
|
|
taskConfigsFolder: taskConfigsFolder,
|
|
|
|
stackTraceLimit: stackTraceLimit,
|
|
|
|
noColor: !colors,
|
|
|
|
timeout: testTimeout
|
|
|
|
});
|
|
|
|
fs.writeFileSync('test.config', testConfigContents);
|
2014-12-04 20:15:00 +01:00
|
|
|
}
|
2017-02-14 07:13:48 +01:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
function deleteTemporaryProjectOutput() {
|
|
|
|
if (fs.existsSync(path.join(Paths.baselines.local, "projectOutput/"))) {
|
|
|
|
jake.rmRf(path.join(Paths.baselines.local, "projectOutput/"));
|
2014-07-13 01:04:16 +02:00
|
|
|
}
|
2018-06-10 19:59:03 +02:00
|
|
|
}
|
|
|
|
}
|
2014-07-13 01:04:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
function cleanTestDirs() {
|
|
|
|
// Clean the local baselines directory
|
|
|
|
if (fs.existsSync(Paths.baselines.local)) {
|
|
|
|
del.sync(Paths.baselines.local);
|
|
|
|
}
|
2015-03-04 07:12:06 +01:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
// Clean the local Rwc baselines directory
|
|
|
|
if (fs.existsSync(Paths.baselines.localRwc)) {
|
|
|
|
del.sync(Paths.baselines.localRwc);
|
|
|
|
}
|
2014-09-02 21:19:58 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
jake.mkdirP(Paths.baselines.local);
|
|
|
|
jake.mkdirP(Paths.baselines.localRwc);
|
|
|
|
jake.mkdirP(Paths.baselines.localTest262);
|
|
|
|
}
|
2014-09-02 21:19:58 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
function tsbuild(tsconfigPath, useLkg = true, done = undefined) {
|
|
|
|
const startCompileTime = Travis.mark();
|
2018-06-10 01:48:08 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
const compilerPath = useLkg ? Paths.lkgCompiler : Paths.builtLocalCompiler;
|
|
|
|
const cmd = `${host} ${compilerPath} -b -v ${Array.isArray(tsconfigPath) ? tsconfigPath.join(" ") : tsconfigPath}`;
|
2018-06-10 19:59:03 +02:00
|
|
|
|
|
|
|
var ex = jake.createExec([cmd]);
|
2018-06-10 22:23:16 +02:00
|
|
|
// Add listeners for output and error
|
|
|
|
ex.addListener("stdout", function (output) {
|
|
|
|
process.stdout.write(output);
|
|
|
|
});
|
|
|
|
ex.addListener("stderr", function (error) {
|
|
|
|
process.stderr.write(error);
|
|
|
|
});
|
2016-08-19 23:34:14 +02:00
|
|
|
ex.addListener("cmdEnd", function () {
|
2018-06-10 22:23:16 +02:00
|
|
|
Travis.measure(startCompileTime);
|
|
|
|
done && done();
|
|
|
|
});
|
|
|
|
ex.addListener("error", function () {
|
|
|
|
fail(`Compilation of ${tsconfigPath} unsuccessful`);
|
|
|
|
Travis.measure(startCompileTime);
|
2015-03-04 07:12:06 +01:00
|
|
|
});
|
2018-06-10 19:59:03 +02:00
|
|
|
ex.run();
|
2018-06-10 22:23:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const Travis = {
|
|
|
|
mark() {
|
|
|
|
if (!fold.isTravis()) return;
|
|
|
|
var stamp = process.hrtime();
|
|
|
|
var id = Math.floor(Math.random() * 0xFFFFFFFF).toString(16);
|
|
|
|
console.log("travis_time:start:" + id + "\r");
|
|
|
|
return {
|
|
|
|
stamp: stamp,
|
|
|
|
id: id
|
|
|
|
};
|
|
|
|
},
|
|
|
|
measure(marker) {
|
|
|
|
if (!fold.isTravis()) return;
|
|
|
|
var diff = process.hrtime(marker.stamp);
|
|
|
|
var total = [marker.stamp[0] + diff[0], marker.stamp[1] + diff[1]];
|
|
|
|
console.log("travis_time:end:" + marker.id + ":start=" + toNs(marker.stamp) + ",finish=" + toNs(total) + ",duration=" + toNs(diff) + "\r");
|
|
|
|
}
|
|
|
|
};
|
2018-06-10 19:59:03 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
function toNs(diff) {
|
|
|
|
return diff[0] * 1e9 + diff[1];
|
|
|
|
}
|
2016-08-11 18:53:38 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
function exec(cmd, completeHandler, errorHandler) {
|
|
|
|
var ex = jake.createExec([cmd], /** @type {jake.ExecOptions} */({ windowsVerbatimArguments: true, interactive: true }));
|
|
|
|
// Add listeners for output and error
|
|
|
|
ex.addListener("stdout", function (output) {
|
|
|
|
process.stdout.write(output);
|
|
|
|
});
|
|
|
|
ex.addListener("stderr", function (error) {
|
|
|
|
process.stderr.write(error);
|
|
|
|
});
|
2018-06-10 19:59:03 +02:00
|
|
|
ex.addListener("cmdEnd", function () {
|
2018-06-10 22:23:16 +02:00
|
|
|
if (completeHandler) {
|
|
|
|
completeHandler();
|
|
|
|
}
|
2018-06-10 19:59:03 +02:00
|
|
|
complete();
|
|
|
|
});
|
2018-06-10 22:23:16 +02:00
|
|
|
ex.addListener("error", function (e, status) {
|
|
|
|
if (errorHandler) {
|
|
|
|
errorHandler(e, status);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
fail("Process exited with code " + status);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-06-10 01:48:08 +02:00
|
|
|
ex.run();
|
2018-06-10 22:23:16 +02:00
|
|
|
}
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
/** @param jsonPath {string} */
|
|
|
|
function readJson(jsonPath) {
|
|
|
|
const jsonText = fs.readFileSync(jsonPath, "utf8");
|
|
|
|
const result = ts.parseConfigFileTextToJson(jsonPath, jsonText);
|
|
|
|
if (result.error) {
|
|
|
|
reportDiagnostics([result.error]);
|
|
|
|
throw new Error("An error occurred during parse.");
|
|
|
|
}
|
|
|
|
return result.config;
|
|
|
|
}
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
/** @param diagnostics {ts.Diagnostic[]} */
|
|
|
|
function reportDiagnostics(diagnostics) {
|
|
|
|
console.log(diagnosticsToString(diagnostics, process.stdout.isTTY));
|
|
|
|
}
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
/**
|
|
|
|
* @param diagnostics {ts.Diagnostic[]}
|
|
|
|
* @param [pretty] {boolean}
|
|
|
|
*/
|
|
|
|
function diagnosticsToString(diagnostics, pretty) {
|
|
|
|
const host = {
|
|
|
|
getCurrentDirectory() { return process.cwd(); },
|
|
|
|
getCanonicalFileName(fileName) { return fileName; },
|
|
|
|
getNewLine() { return os.EOL; }
|
|
|
|
};
|
|
|
|
return pretty ? ts.formatDiagnosticsWithColorAndContext(diagnostics, host) :
|
|
|
|
ts.formatDiagnostics(diagnostics, host);
|
|
|
|
}
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:26:16 +02:00
|
|
|
function acceptBaseline(sourceFolder, targetFolder) {
|
|
|
|
console.log('Accept baselines from ' + sourceFolder + ' to ' + targetFolder);
|
|
|
|
var deleteEnding = '.delete';
|
|
|
|
|
|
|
|
acceptBaselineFolder(sourceFolder, targetFolder);
|
|
|
|
|
|
|
|
function acceptBaselineFolder(sourceFolder, targetFolder) {
|
|
|
|
var files = fs.readdirSync(sourceFolder);
|
|
|
|
|
|
|
|
for (var i in files) {
|
|
|
|
var filename = files[i];
|
|
|
|
var fullLocalPath = path.join(sourceFolder, filename);
|
|
|
|
var stat = fs.statSync(fullLocalPath);
|
|
|
|
if (stat.isFile()) {
|
|
|
|
if (filename.substr(filename.length - deleteEnding.length) === deleteEnding) {
|
|
|
|
filename = filename.substr(0, filename.length - deleteEnding.length);
|
|
|
|
fs.unlinkSync(path.join(targetFolder, filename));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
var target = path.join(targetFolder, filename);
|
|
|
|
if (fs.existsSync(target)) {
|
|
|
|
fs.unlinkSync(target);
|
|
|
|
}
|
|
|
|
jake.mkdirP(path.dirname(target));
|
|
|
|
fs.renameSync(path.join(sourceFolder, filename), target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (stat.isDirectory()) {
|
|
|
|
acceptBaselineFolder(fullLocalPath, path.join(targetFolder, filename));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
// concatenate a list of sourceFiles to a destinationFile
|
|
|
|
function concatenateFiles(destinationFile, sourceFiles) {
|
|
|
|
var temp = "temptemp";
|
|
|
|
// append all files in sequence
|
|
|
|
var text = "";
|
|
|
|
for (var i = 0; i < sourceFiles.length; i++) {
|
|
|
|
if (!fs.existsSync(sourceFiles[i])) {
|
|
|
|
fail(sourceFiles[i] + " does not exist!");
|
|
|
|
}
|
|
|
|
if (i > 0) { text += "\n\n"; }
|
|
|
|
text += fs.readFileSync(sourceFiles[i]).toString().replace(/\r?\n/g, "\n");
|
|
|
|
}
|
|
|
|
fs.writeFileSync(temp, text);
|
|
|
|
// Move the file to the final destination
|
|
|
|
fs.renameSync(temp, destinationFile);
|
|
|
|
}
|
2018-06-10 19:58:16 +02:00
|
|
|
|
2018-06-10 22:23:16 +02:00
|
|
|
function getDiffTool() {
|
|
|
|
var program = process.env['DIFF'];
|
|
|
|
if (!program) {
|
|
|
|
fail("Add the 'DIFF' environment variable to the path of the program you want to use.");
|
2018-06-10 19:58:16 +02:00
|
|
|
}
|
2018-06-10 22:23:16 +02:00
|
|
|
return program;
|
|
|
|
}
|
|
|
|
|
|
|
|
function removeConstModifierFromEnumDeclarations(text) {
|
|
|
|
return text.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4');
|
|
|
|
}
|
2018-06-10 23:56:48 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {string} path
|
|
|
|
*/
|
|
|
|
function readFileSync(path) {
|
|
|
|
return fs.readFileSync(path, { encoding: "utf-8" });
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {string} path
|
|
|
|
* @param {string} contents
|
|
|
|
*/
|
|
|
|
function writeFileSync(path, contents) {
|
|
|
|
fs.writeFileSync(path, contents, { encoding: "utf-8" });
|
|
|
|
}
|