mirror of
https://github.com/chenasraf/DefinitelyTyped-tools.git
synced 2026-05-18 01:49:03 +00:00
Remove database-related functionality from perf tool (#378)
* [perf] Remove all database-related functionality * Throw error on comparison attempt for new package * Update tests
This commit is contained in:
@@ -15,7 +15,6 @@
|
||||
"url": "git://github.com/andrewbranch/definitely-not-slow.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/cosmos": "^3.6.3",
|
||||
"@definitelytyped/definitions-parser": "^0.0.101-next.7",
|
||||
"@definitelytyped/header-parser": "^0.0.100",
|
||||
"@definitelytyped/utils": "^0.0.100",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { mean } from "../measure/utils";
|
||||
import { PackageBenchmarkSummary, Document, config, getPercentDiff, supportsMemoryUsage, not } from "../common";
|
||||
import { PackageBenchmarkSummary, config, getPercentDiff } from "../common";
|
||||
import { assertNever } from "@definitelytyped/utils";
|
||||
|
||||
export interface FormatOptions {
|
||||
@@ -19,8 +19,8 @@ export type GetSignificance = (
|
||||
percentDiff: number,
|
||||
beforeValue: number,
|
||||
afterValue: number,
|
||||
beforeDoc: Document<PackageBenchmarkSummary>,
|
||||
afterDoc: Document<PackageBenchmarkSummary>
|
||||
beforeDoc: PackageBenchmarkSummary,
|
||||
afterDoc: PackageBenchmarkSummary
|
||||
) => SignificanceLevel | undefined;
|
||||
|
||||
export type CreateGetSignificance = (getSignificance: GetSignificance) => GetSignificance;
|
||||
@@ -29,7 +29,7 @@ export interface Metric {
|
||||
columnName: string;
|
||||
sentenceName: string;
|
||||
formatOptions?: FormatOptions;
|
||||
getValue: (x: Document<PackageBenchmarkSummary>) => number | undefined;
|
||||
getValue: (x: PackageBenchmarkSummary) => number | undefined;
|
||||
getSignificance: GetSignificance;
|
||||
}
|
||||
|
||||
@@ -139,21 +139,6 @@ function withThreshold(fineIf: FineIf, threshold: number) {
|
||||
};
|
||||
}
|
||||
|
||||
function ignoreIfEitherBenchmark(predicate: (document: Document<PackageBenchmarkSummary>) => boolean) {
|
||||
return (getSignificance: GetSignificance): GetSignificance => (
|
||||
percentDiff,
|
||||
beforeValue,
|
||||
afterValue,
|
||||
beforeDoc,
|
||||
afterDoc
|
||||
) => {
|
||||
if (predicate(beforeDoc) || predicate(afterDoc)) {
|
||||
return undefined;
|
||||
}
|
||||
return getSignificance(percentDiff, beforeValue, afterValue, beforeDoc, afterDoc);
|
||||
};
|
||||
}
|
||||
|
||||
function compose(x: CreateGetSignificance, ...xs: CreateGetSignificance[]): CreateGetSignificance {
|
||||
return getSignificance => {
|
||||
let current = x(getSignificance);
|
||||
@@ -169,7 +154,7 @@ export const metrics: { [K in MetricName]: Metric } = {
|
||||
columnName: "Type count",
|
||||
sentenceName: "type count",
|
||||
formatOptions: { precision: 0 },
|
||||
getValue: x => x.body.typeCount,
|
||||
getValue: x => x.typeCount,
|
||||
getSignificance: compose(
|
||||
proportionalTo("identifierCount"),
|
||||
withThreshold(FineIf.LessThan, 5000)
|
||||
@@ -178,18 +163,17 @@ export const metrics: { [K in MetricName]: Metric } = {
|
||||
memoryUsage: {
|
||||
columnName: "Memory usage (MiB)",
|
||||
sentenceName: "memory usage",
|
||||
getValue: x => x.body.memoryUsage / 2 ** 20,
|
||||
getValue: x => x.memoryUsage / 2 ** 20,
|
||||
getSignificance: compose(
|
||||
proportionalTo("identifierCount"),
|
||||
withThreshold(FineIf.LessThan, 65),
|
||||
ignoreIfEitherBenchmark(not(supportsMemoryUsage))
|
||||
)(getOrderOfMagnitudeSignificance)
|
||||
},
|
||||
assignabilityCacheSize: {
|
||||
columnName: "Assignability cache size",
|
||||
sentenceName: "assignability cache size",
|
||||
formatOptions: { precision: 0 },
|
||||
getValue: x => x.body.relationCacheSizes && x.body.relationCacheSizes.assignable,
|
||||
getValue: x => x.relationCacheSizes && x.relationCacheSizes.assignable,
|
||||
getSignificance: compose(
|
||||
proportionalTo("identifierCount"),
|
||||
withThreshold(FineIf.LessThan, 1000)
|
||||
@@ -199,64 +183,64 @@ export const metrics: { [K in MetricName]: Metric } = {
|
||||
columnName: "Samples taken",
|
||||
sentenceName: "number of samples taken",
|
||||
formatOptions: { precision: 0 },
|
||||
getValue: x => Math.max(x.body.completions.trials, x.body.quickInfo.trials),
|
||||
getValue: x => Math.max(x.completions.trials, x.quickInfo.trials),
|
||||
getSignificance: getInsignificant
|
||||
},
|
||||
identifierCount: {
|
||||
columnName: "Identifiers in tests",
|
||||
sentenceName: "number of identifiers present in test files",
|
||||
formatOptions: { precision: 0 },
|
||||
getValue: x => x.body.testIdentifierCount,
|
||||
getValue: x => x.testIdentifierCount,
|
||||
getSignificance: getInsignificant
|
||||
},
|
||||
completionsMean: {
|
||||
columnName: "Mean duration (ms)",
|
||||
sentenceName: "mean duration for getting completions at a position",
|
||||
getValue: x => x.body.completions.mean,
|
||||
getValue: x => x.completions.mean,
|
||||
getSignificance: withThreshold(FineIf.LessThan, 150)(getDefaultSignificance)
|
||||
},
|
||||
completionsStdDev: {
|
||||
columnName: "Std. deviation (ms)",
|
||||
sentenceName: "standard deviation of the durations for getting completions at a position",
|
||||
getValue: x => x.body.completions.standardDeviation,
|
||||
getValue: x => x.completions.standardDeviation,
|
||||
getSignificance: getInsignificant
|
||||
},
|
||||
completionsAvgCV: {
|
||||
columnName: "Mean [CV](https://en.wikipedia.org/wiki/Coefficient_of_variation)",
|
||||
sentenceName: "mean coefficient of variation of samples measured for completions time",
|
||||
getValue: x => x.body.completions.meanCoefficientOfVariation,
|
||||
getValue: x => x.completions.meanCoefficientOfVariation,
|
||||
getSignificance: getInsignificant,
|
||||
formatOptions: { percentage: true, noDiff: true }
|
||||
},
|
||||
completionsWorstMean: {
|
||||
columnName: "Worst duration (ms)",
|
||||
sentenceName: "worst-case duration for getting completions at a position",
|
||||
getValue: x => mean(x.body.completions.worst.completionsDurations),
|
||||
getValue: x => mean(x.completions.worst.completionsDurations),
|
||||
getSignificance: withThreshold(FineIf.LessThan, 200)(getDefaultSignificance)
|
||||
},
|
||||
quickInfoMean: {
|
||||
columnName: "Mean duration (ms)",
|
||||
sentenceName: "mean duration for getting quick info at a position",
|
||||
getValue: x => x.body.quickInfo.mean,
|
||||
getValue: x => x.quickInfo.mean,
|
||||
getSignificance: withThreshold(FineIf.LessThan, 150)(getDefaultSignificance)
|
||||
},
|
||||
quickInfoStdDev: {
|
||||
columnName: "Std. deviation (ms)",
|
||||
sentenceName: "standard deviation of the durations for getting quick info at a position",
|
||||
getValue: x => x.body.quickInfo.standardDeviation,
|
||||
getValue: x => x.quickInfo.standardDeviation,
|
||||
getSignificance: getInsignificant
|
||||
},
|
||||
quickInfoAvgCV: {
|
||||
columnName: "Mean [CV](https://en.wikipedia.org/wiki/Coefficient_of_variation)",
|
||||
sentenceName: "mean coefficient of variation of samples measured for quick info time",
|
||||
getValue: x => x.body.quickInfo.meanCoefficientOfVariation,
|
||||
getValue: x => x.quickInfo.meanCoefficientOfVariation,
|
||||
getSignificance: getInsignificant,
|
||||
formatOptions: { percentage: true, noDiff: true }
|
||||
},
|
||||
quickInfoWorstMean: {
|
||||
columnName: "Worst duration (ms)",
|
||||
sentenceName: "worst-case duration for getting quick info at a position",
|
||||
getValue: x => mean(x.body.quickInfo.worst.quickInfoDurations),
|
||||
getValue: x => mean(x.quickInfo.worst.quickInfoDurations),
|
||||
getSignificance: withThreshold(FineIf.LessThan, 200)(getDefaultSignificance)
|
||||
}
|
||||
};
|
||||
@@ -268,8 +252,8 @@ export interface ComparedMetric {
|
||||
}
|
||||
|
||||
export function getInterestingMetrics(
|
||||
before: Document<PackageBenchmarkSummary>,
|
||||
after: Document<PackageBenchmarkSummary>
|
||||
before: PackageBenchmarkSummary,
|
||||
after: PackageBenchmarkSummary
|
||||
): ComparedMetric[] {
|
||||
return Object.values(metrics).reduce(
|
||||
(acc: { metric: Metric; percentDiff: number; significance: SignificanceLevel }[], metric) => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { PackageBenchmarkSummary, Document } from "../common";
|
||||
import { PackageBenchmarkSummary } from "../common";
|
||||
import { getInterestingMetrics, SignificanceLevel } from "./metrics";
|
||||
import { assertNever } from "@definitelytyped/utils";
|
||||
|
||||
type BeforeAndAfter = [Document<PackageBenchmarkSummary> | undefined, Document<PackageBenchmarkSummary>];
|
||||
type BeforeAndAfter = [PackageBenchmarkSummary, PackageBenchmarkSummary];
|
||||
|
||||
export enum OverallChange {
|
||||
Same = 0,
|
||||
@@ -12,8 +12,8 @@ export enum OverallChange {
|
||||
}
|
||||
|
||||
export function getOverallChangeForSingleComparison(
|
||||
before: Document<PackageBenchmarkSummary>,
|
||||
after: Document<PackageBenchmarkSummary>
|
||||
before: PackageBenchmarkSummary,
|
||||
after: PackageBenchmarkSummary
|
||||
) {
|
||||
let change = OverallChange.Same;
|
||||
for (const { significance } of getInterestingMetrics(before, after)) {
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
import {
|
||||
getDatabase,
|
||||
DatabaseAccessLevel,
|
||||
config,
|
||||
getParsedPackages,
|
||||
assertString,
|
||||
assertNumber,
|
||||
getSystemInfo
|
||||
} from "../common";
|
||||
import { getTypeScript } from "../measure/getTypeScript";
|
||||
import { insertDocument } from "../write";
|
||||
import { printSummary, measurePerf } from "../measure";
|
||||
import { summarize } from "../analysis";
|
||||
import { PackageId, formatDependencyVersion, tryParsePackageVersion } from "@definitelytyped/definitions-parser";
|
||||
@@ -21,7 +17,6 @@ export interface BenchmarkPackageOptions {
|
||||
groups?: PackageId[][];
|
||||
agentIndex?: number;
|
||||
package?: string;
|
||||
upload: boolean;
|
||||
tsVersion: string;
|
||||
progress: boolean;
|
||||
iterations: number;
|
||||
@@ -87,7 +82,6 @@ export async function benchmarkPackage(
|
||||
options: BenchmarkPackageOptions
|
||||
) {
|
||||
const {
|
||||
upload,
|
||||
progress,
|
||||
iterations,
|
||||
nProcesses,
|
||||
@@ -129,16 +123,5 @@ export async function benchmarkPackage(
|
||||
printSummary([summary]);
|
||||
}
|
||||
|
||||
if (upload) {
|
||||
const { packageBenchmarks } = await getDatabase(DatabaseAccessLevel.Write);
|
||||
const item = await insertDocument(
|
||||
summary,
|
||||
config.database.packageBenchmarksDocumentSchemaVersion,
|
||||
packageBenchmarks
|
||||
);
|
||||
|
||||
return { benchmark, summary, id: item.id };
|
||||
}
|
||||
|
||||
return { benchmark, summary, id: undefined };
|
||||
}
|
||||
|
||||
@@ -1,20 +1,12 @@
|
||||
import * as os from "os";
|
||||
import {
|
||||
getDatabase,
|
||||
DatabaseAccessLevel,
|
||||
config,
|
||||
getChangedPackages,
|
||||
packageIdsAreEqual,
|
||||
PackageBenchmarkSummary,
|
||||
getParsedPackages,
|
||||
Document,
|
||||
createDocument,
|
||||
shuffle,
|
||||
systemsAreCloseEnough,
|
||||
getSystemInfo,
|
||||
forEachWithTimeLimit
|
||||
} from "../common";
|
||||
import { getLatestBenchmark } from "../query";
|
||||
import { benchmarkPackage } from "./benchmark";
|
||||
import { printSummary } from "../measure";
|
||||
import { getTypeScript } from "../measure/getTypeScript";
|
||||
@@ -23,12 +15,9 @@ import { postDependentsComparisonResult } from "../github/postDependentsComparis
|
||||
import {
|
||||
AllPackages,
|
||||
DependencyVersion,
|
||||
formatDependencyVersion,
|
||||
getAffectedPackages,
|
||||
PackageId
|
||||
} from "@definitelytyped/definitions-parser";
|
||||
import { execAndThrowErrors } from "@definitelytyped/utils";
|
||||
const currentSystem = getSystemInfo();
|
||||
|
||||
export interface CompareOptions {
|
||||
allPackages: AllPackages;
|
||||
@@ -67,7 +56,7 @@ export async function compare({
|
||||
|
||||
await getTypeScript(tsVersion);
|
||||
const affectedPackages = getAffectedPackages(allPackages, changedPackages);
|
||||
const comparisons: [Document<PackageBenchmarkSummary> | undefined, Document<PackageBenchmarkSummary>][] = [];
|
||||
const comparisons: [PackageBenchmarkSummary, PackageBenchmarkSummary][] = [];
|
||||
const maxRunMs = (maxRunSeconds ?? Infinity) * 1000;
|
||||
const { overtime } = await forEachWithTimeLimit(
|
||||
maxRunMs,
|
||||
@@ -104,7 +93,7 @@ export async function compare({
|
||||
}
|
||||
}
|
||||
|
||||
const dependentComparisons: [Document<PackageBenchmarkSummary> | undefined, Document<PackageBenchmarkSummary>][] = [];
|
||||
const dependentComparisons: [PackageBenchmarkSummary, PackageBenchmarkSummary][] = [];
|
||||
await forEachWithTimeLimit(
|
||||
maxRunMs,
|
||||
dependentsToTest,
|
||||
@@ -136,79 +125,35 @@ export async function compare({
|
||||
}
|
||||
|
||||
export async function compareBenchmarks({
|
||||
allPackages,
|
||||
definitelyTypedPath,
|
||||
typeScriptVersionMajorMinor,
|
||||
packageName,
|
||||
packageVersion,
|
||||
maxRunSeconds,
|
||||
upload = true
|
||||
}: CompareOptions): Promise<[Document<PackageBenchmarkSummary> | undefined, Document<PackageBenchmarkSummary>]> {
|
||||
const typings = allPackages.getTypingsData({ name: packageName, version: packageVersion });
|
||||
const { packageBenchmarks: container } = await getDatabase(DatabaseAccessLevel.Read);
|
||||
const latestBenchmarkDocument = await getLatestBenchmark({
|
||||
container,
|
||||
typeScriptVersionMajorMinor,
|
||||
packageName,
|
||||
packageVersion: typings.id.version,
|
||||
matchMinor: allPackages.hasSeparateMinorVersions(packageName)
|
||||
});
|
||||
}: CompareOptions): Promise<[PackageBenchmarkSummary, PackageBenchmarkSummary]> {
|
||||
await execAndThrowErrors("git checkout -f origin/master && git clean -xdf types", definitelyTypedPath);
|
||||
const baseBenchmark = (await benchmarkPackage(packageName, packageVersion.toString(), new Date(), {
|
||||
definitelyTypedPath,
|
||||
printSummary: false,
|
||||
iterations: config.benchmarks.languageServiceIterations,
|
||||
progress: false,
|
||||
tsVersion: typeScriptVersionMajorMinor,
|
||||
nProcesses: os.cpus().length,
|
||||
failOnErrors: true,
|
||||
installTypeScript: false,
|
||||
maxRunSeconds
|
||||
}))?.summary;
|
||||
|
||||
let latestBenchmark: PackageBenchmarkSummary | undefined = latestBenchmarkDocument && latestBenchmarkDocument.body;
|
||||
const packageId: PackageId = {
|
||||
name: packageName,
|
||||
version: packageVersion
|
||||
};
|
||||
|
||||
const changedPackagesBetweenLastRunAndMaster =
|
||||
latestBenchmark &&
|
||||
(await getChangedPackages({
|
||||
diffFrom: "origin/master",
|
||||
diffTo: latestBenchmark.sourceVersion,
|
||||
definitelyTypedPath
|
||||
}));
|
||||
|
||||
if (latestBenchmarkDocument && !systemsAreCloseEnough(currentSystem, latestBenchmarkDocument.system)) {
|
||||
latestBenchmark = undefined;
|
||||
if (!baseBenchmark) {
|
||||
throw new Error(`Package ${packageName} does not exist in master so cannot be compared.`);
|
||||
}
|
||||
|
||||
if (changedPackagesBetweenLastRunAndMaster || !latestBenchmark) {
|
||||
let needsRerun = !latestBenchmark;
|
||||
if (changedPackagesBetweenLastRunAndMaster) {
|
||||
const affectedPackages = getAffectedPackages(allPackages, changedPackagesBetweenLastRunAndMaster);
|
||||
const affected = [...affectedPackages.changedPackages, ...affectedPackages.dependentPackages];
|
||||
needsRerun = affected.some(affectedPackage => packageIdsAreEqual(packageId, affectedPackage.id));
|
||||
}
|
||||
if (needsRerun) {
|
||||
console.log(
|
||||
`No comparable benchmark for ${packageName}/v${formatDependencyVersion(
|
||||
packageVersion
|
||||
)}. Checking out master and running one...`
|
||||
);
|
||||
await execAndThrowErrors("git checkout -f origin/master && git clean -xdf types", definitelyTypedPath);
|
||||
const latest = await benchmarkPackage(packageName, packageVersion.toString(), new Date(), {
|
||||
definitelyTypedPath,
|
||||
printSummary: false,
|
||||
iterations: config.benchmarks.languageServiceIterations,
|
||||
progress: false,
|
||||
upload,
|
||||
tsVersion: typeScriptVersionMajorMinor,
|
||||
nProcesses: os.cpus().length,
|
||||
failOnErrors: true,
|
||||
installTypeScript: false,
|
||||
maxRunSeconds
|
||||
});
|
||||
await execAndThrowErrors(`git checkout -f . && git checkout - && git clean -xdf types`, definitelyTypedPath);
|
||||
latestBenchmark = latest && latest.summary;
|
||||
}
|
||||
}
|
||||
|
||||
const currentBenchmark = (await benchmarkPackage(packageName, packageVersion.toString(), new Date(), {
|
||||
|
||||
await execAndThrowErrors(`git checkout -f . && git checkout - && git clean -xdf types`, definitelyTypedPath);
|
||||
const headBenchmark = (await benchmarkPackage(packageName, packageVersion.toString(), new Date(), {
|
||||
definitelyTypedPath,
|
||||
printSummary: true,
|
||||
iterations: config.benchmarks.languageServiceIterations,
|
||||
progress: false,
|
||||
upload: false,
|
||||
tsVersion: typeScriptVersionMajorMinor,
|
||||
nProcesses: os.cpus().length,
|
||||
failOnErrors: true,
|
||||
@@ -216,18 +161,17 @@ export async function compareBenchmarks({
|
||||
maxRunSeconds
|
||||
}))!.summary;
|
||||
|
||||
if (latestBenchmark) {
|
||||
if (baseBenchmark) {
|
||||
console.log("\nmaster");
|
||||
console.log("======");
|
||||
console.log(printSummary([latestBenchmark]));
|
||||
console.log(printSummary([baseBenchmark]));
|
||||
}
|
||||
|
||||
console.log("\nHEAD");
|
||||
console.log("====");
|
||||
console.log(printSummary([currentBenchmark]));
|
||||
console.log(printSummary([headBenchmark]));
|
||||
return [
|
||||
latestBenchmarkDocument ||
|
||||
(latestBenchmark && createDocument(latestBenchmark, config.database.packageBenchmarksDocumentSchemaVersion)),
|
||||
createDocument(currentBenchmark, config.database.packageBenchmarksDocumentSchemaVersion)
|
||||
baseBenchmark,
|
||||
headBenchmark,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,272 +0,0 @@
|
||||
import * as os from "os";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { promisify } from "util";
|
||||
import {
|
||||
getDatabase,
|
||||
DatabaseAccessLevel,
|
||||
Document,
|
||||
PackageBenchmarkSummary,
|
||||
getChangedPackages,
|
||||
packageIdsAreEqual,
|
||||
getParsedPackages,
|
||||
config,
|
||||
toPackageKey,
|
||||
parsePackageKey,
|
||||
createDocument,
|
||||
assertString,
|
||||
getSystemInfo,
|
||||
systemsAreCloseEnough,
|
||||
JSONDocument,
|
||||
deserializeSummary,
|
||||
QueryResult,
|
||||
TypeScriptComparisonRun,
|
||||
getSourceVersion
|
||||
} from "../common";
|
||||
import { Container, FeedResponse } from "@azure/cosmos";
|
||||
import { benchmarkPackage } from "./benchmark";
|
||||
import { getTypeScript } from "../measure/getTypeScript";
|
||||
import { postTypeScriptComparisonResults } from "../github/postTypeScriptComparisonResult";
|
||||
import { insertDocument } from "../write";
|
||||
import { PackageId, AllPackages, formatDependencyVersion } from "@definitelytyped/definitions-parser";
|
||||
import { assertDefined } from "@definitelytyped/utils";
|
||||
const writeFile = promisify(fs.writeFile);
|
||||
const currentSystem = getSystemInfo();
|
||||
|
||||
export interface CompareTypeScriptOptions {
|
||||
compareAgainstVersion: string;
|
||||
definitelyTypedPath: string;
|
||||
packages?: PackageId[];
|
||||
maxRunSeconds?: number;
|
||||
localTypeScriptPath: string;
|
||||
outFile?: string;
|
||||
groups?: { [key: string]: QueryResult<JSONDocument<PackageBenchmarkSummary>> }[];
|
||||
agentCount?: number;
|
||||
agentIndex?: number;
|
||||
upload?: boolean;
|
||||
}
|
||||
|
||||
export interface CompareTypeScriptCLIArgs {
|
||||
file?: string;
|
||||
compareAgainstVersion: string;
|
||||
definitelyTypedPath: string;
|
||||
localTypeScriptPath: string;
|
||||
maxRunSeconds?: number;
|
||||
outFile?: string;
|
||||
upload?: boolean;
|
||||
packages?: PackageId[];
|
||||
}
|
||||
|
||||
function convertArgs({ file, ...args }: CompareTypeScriptCLIArgs): CompareTypeScriptOptions {
|
||||
if (file) {
|
||||
// tslint:disable-next-line:non-literal-require -- filename comes from Azure artifact
|
||||
const jsonContent = require(path.resolve(assertString(file, "file")));
|
||||
return {
|
||||
...args,
|
||||
...jsonContent.options,
|
||||
groups: jsonContent.groups
|
||||
};
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
export function compareTypeScriptCLI(args: CompareTypeScriptCLIArgs) {
|
||||
return compareTypeScript(convertArgs(args));
|
||||
}
|
||||
|
||||
export async function compareTypeScript({
|
||||
compareAgainstVersion,
|
||||
definitelyTypedPath,
|
||||
packages,
|
||||
maxRunSeconds,
|
||||
localTypeScriptPath: typeScriptPath,
|
||||
upload,
|
||||
outFile,
|
||||
groups,
|
||||
...opts
|
||||
}: CompareTypeScriptOptions) {
|
||||
const { packageBenchmarks, typeScriptComparisons } = await getDatabase(
|
||||
upload && !outFile ? DatabaseAccessLevel.Write : DatabaseAccessLevel.Read
|
||||
);
|
||||
const agentIndex = groups && assertDefined(opts.agentIndex, "agentIndex");
|
||||
const priorResults = groups
|
||||
? new Map<string, QueryResult<Document<PackageBenchmarkSummary>>>(
|
||||
Object.keys(groups[agentIndex!]).map(key => [key, deserializeSummary(groups[agentIndex!][key])] as const)
|
||||
)
|
||||
: await getPackagesToTestAndPriorResults(
|
||||
packageBenchmarks,
|
||||
compareAgainstVersion,
|
||||
definitelyTypedPath,
|
||||
(await getParsedPackages(definitelyTypedPath)).allPackages,
|
||||
packages
|
||||
);
|
||||
|
||||
if (outFile) {
|
||||
const agentCount = assertDefined(opts.agentCount, "agentCount");
|
||||
const fileContent = JSON.stringify(
|
||||
{
|
||||
options: {
|
||||
compareAgainstVersion,
|
||||
definitelyTypedPath,
|
||||
maxRunSeconds,
|
||||
typeScriptPath,
|
||||
upload
|
||||
},
|
||||
groups: Array.from(priorResults.keys()).reduce((groups, key, index) => {
|
||||
const agentIndex = index % agentCount;
|
||||
if (groups[agentIndex]) {
|
||||
groups[agentIndex][key] = priorResults.get(key)!;
|
||||
} else {
|
||||
groups[agentIndex] = { [key]: priorResults.get(key)! };
|
||||
}
|
||||
return groups;
|
||||
}, [] as { [key: string]: Document<PackageBenchmarkSummary> }[])
|
||||
},
|
||||
undefined,
|
||||
2
|
||||
);
|
||||
|
||||
return writeFile(outFile, fileContent, "utf8");
|
||||
}
|
||||
|
||||
await getTypeScript(compareAgainstVersion);
|
||||
const packagesToTest = packages
|
||||
? packages.map(p => `${p.name}/v${formatDependencyVersion(p.version)}`)
|
||||
: Array.from(priorResults.keys());
|
||||
const now = new Date();
|
||||
const comparisons: [Document<PackageBenchmarkSummary>, Document<PackageBenchmarkSummary>][] = [];
|
||||
for (const packageKey of packagesToTest) {
|
||||
const { name, version } = parsePackageKey(packageKey);
|
||||
let priorResult:
|
||||
| Document<PackageBenchmarkSummary>
|
||||
| QueryResult<Document<PackageBenchmarkSummary>>
|
||||
| undefined = priorResults.get(packageKey);
|
||||
const priorResultId = priorResult && "id" in priorResult && priorResult.id;
|
||||
if (priorResult) {
|
||||
if (!systemsAreCloseEnough(currentSystem, priorResult.system)) {
|
||||
console.log(`Skipping ${packageKey} because the system is too different`);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
const benchmark = await benchmarkPackage(name, formatDependencyVersion(version), now, {
|
||||
definitelyTypedPath,
|
||||
iterations: config.benchmarks.languageServiceIterations,
|
||||
tsVersion: compareAgainstVersion,
|
||||
nProcesses: os.cpus().length,
|
||||
printSummary: true,
|
||||
progress: false,
|
||||
upload: !!upload,
|
||||
installTypeScript: false,
|
||||
failOnErrors: false,
|
||||
maxRunSeconds
|
||||
});
|
||||
|
||||
if (!benchmark) {
|
||||
console.log(`Skipping ${packageKey} because it was deleted`);
|
||||
continue;
|
||||
}
|
||||
|
||||
priorResult = {
|
||||
id: benchmark.id,
|
||||
...createDocument(benchmark.summary, config.database.packageBenchmarksDocumentSchemaVersion)
|
||||
};
|
||||
}
|
||||
|
||||
const currentResult = createDocument(
|
||||
(await benchmarkPackage(name, formatDependencyVersion(version), now, {
|
||||
definitelyTypedPath,
|
||||
iterations: config.benchmarks.languageServiceIterations,
|
||||
tsVersion: "local",
|
||||
localTypeScriptPath: typeScriptPath,
|
||||
nProcesses: os.cpus().length,
|
||||
printSummary: true,
|
||||
progress: false,
|
||||
upload: false,
|
||||
installTypeScript: false,
|
||||
failOnErrors: false,
|
||||
maxRunSeconds
|
||||
}))!.summary,
|
||||
config.database.packageBenchmarksDocumentSchemaVersion
|
||||
);
|
||||
|
||||
comparisons.push([priorResult!, currentResult]);
|
||||
if (upload && priorResultId) {
|
||||
const comparison: TypeScriptComparisonRun = {
|
||||
sourceVersion: getSourceVersion(typeScriptPath),
|
||||
compareAgainstPackageBenchmarkId: priorResultId,
|
||||
headBenchmark: currentResult.body
|
||||
};
|
||||
await insertDocument(
|
||||
comparison,
|
||||
config.database.typeScriptComparisonsDocumentSchemaVersion,
|
||||
typeScriptComparisons
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const comment = await postTypeScriptComparisonResults({ comparisons, dryRun: true });
|
||||
console.log(comment);
|
||||
}
|
||||
|
||||
async function getPackagesToTestAndPriorResults(
|
||||
container: Container,
|
||||
typeScriptVersion: string,
|
||||
definitelyTypedPath: string,
|
||||
allPackages: AllPackages,
|
||||
packageList?: PackageId[]
|
||||
) {
|
||||
const iterator: AsyncIterable<FeedResponse<QueryResult<Document<PackageBenchmarkSummary>>>> = await container.items
|
||||
.query({
|
||||
query:
|
||||
`SELECT * FROM ${config.database.packageBenchmarksContainerId} b` +
|
||||
` WHERE b.body.typeScriptVersionMajorMinor = @typeScriptVersion` +
|
||||
(packageList
|
||||
? ` AND b.body.packageName IN (${packageList!.map(({ name }) => `"${name}"`).join(", ")})` // Couldn’t figure out how to do this with parameters
|
||||
: ""),
|
||||
parameters: [{ name: "@typeScriptVersion", value: typeScriptVersion }]
|
||||
})
|
||||
.getAsyncIterator();
|
||||
|
||||
const packageKeys = packageList && packageList.map(id => toPackageKey(allPackages.resolve(id)));
|
||||
const packages = new Map<string, QueryResult<Document<PackageBenchmarkSummary>>>();
|
||||
|
||||
for await (const x of iterator) {
|
||||
for (const result of x.resources) {
|
||||
if (!result) continue;
|
||||
const packageKey = toPackageKey(result.body);
|
||||
if (packageKeys && !packageKeys.includes(packageKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const candidate = packages.get(packageKey);
|
||||
if (candidate && candidate.createdAt > result.createdAt) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const packageId: PackageId = {
|
||||
name: result.body.packageName,
|
||||
version: { major: result.body.packageVersionMajor, minor: result.body.packageVersionMinor }
|
||||
};
|
||||
const changedPackages = await getChangedPackages({ diffTo: result.body.sourceVersion, definitelyTypedPath });
|
||||
if (changedPackages && changedPackages.some(packageIdsAreEqual(packageId))) {
|
||||
console.log(`Skipping ${packageKey} because it changed`);
|
||||
continue;
|
||||
} else if (changedPackages) {
|
||||
const dependencies = allPackages.getTypingsData(packageId).dependencies;
|
||||
if (
|
||||
Object.entries(dependencies).some(([name, version]) =>
|
||||
changedPackages.some(packageIdsAreEqual({ name, version }))
|
||||
)
|
||||
) {
|
||||
console.log(`Skipping ${packageKey} because one or more of its dependencies changed`);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
packages.set(packageKey, result);
|
||||
}
|
||||
}
|
||||
|
||||
return packages;
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
import * as fs from "fs";
|
||||
import { promisify } from "util";
|
||||
import {
|
||||
getDatabase,
|
||||
getParsedPackages,
|
||||
DatabaseAccessLevel,
|
||||
compact,
|
||||
getSystemInfo,
|
||||
getChangedPackages,
|
||||
packageIdsAreEqual,
|
||||
systemsAreCloseEnough
|
||||
} from "../common";
|
||||
import { BenchmarkPackageOptions } from "./benchmark";
|
||||
import { getLatestBenchmark } from "../query";
|
||||
import { nAtATime } from "@definitelytyped/utils";
|
||||
import { getAffectedPackages, PackageId, formatDependencyVersion } from "@definitelytyped/definitions-parser";
|
||||
const writeFile = promisify(fs.writeFile);
|
||||
const currentSystem = getSystemInfo();
|
||||
|
||||
export interface GetPackagesToBenchmarkOptions {
|
||||
definitelyTypedPath: string;
|
||||
tsVersion: string;
|
||||
agentCount: number;
|
||||
outFile: string;
|
||||
}
|
||||
|
||||
export async function getPackagesToBenchmark({
|
||||
definitelyTypedPath,
|
||||
agentCount,
|
||||
tsVersion,
|
||||
outFile
|
||||
}: GetPackagesToBenchmarkOptions) {
|
||||
if (tsVersion.split(".").length !== 2) {
|
||||
throw new Error(`Argument 'typeScriptVersion' must be in format 'major.minor' (e.g. '3.1')`);
|
||||
}
|
||||
|
||||
const { allPackages } = await getParsedPackages(definitelyTypedPath);
|
||||
const { packageBenchmarks: container } = await getDatabase(DatabaseAccessLevel.Read);
|
||||
const changedPackages = await nAtATime(10, allPackages.allTypings(), async typingsData => {
|
||||
const result = await getLatestBenchmark({
|
||||
container,
|
||||
typeScriptVersionMajorMinor: tsVersion,
|
||||
packageName: typingsData.id.name,
|
||||
packageVersion: typingsData.id.version,
|
||||
matchMinor: allPackages.hasSeparateMinorVersions(typingsData.name)
|
||||
});
|
||||
|
||||
// No previous run exists; run one
|
||||
if (!result) {
|
||||
return typingsData.id;
|
||||
}
|
||||
|
||||
// System specs are different; run it
|
||||
if (!systemsAreCloseEnough(result.system, currentSystem)) {
|
||||
console.log(
|
||||
`Queueing ${typingsData.id.name}/v${formatDependencyVersion(typingsData.id.version)} due to system change`
|
||||
);
|
||||
return typingsData.id;
|
||||
}
|
||||
|
||||
const changedPackages = await getChangedPackages({ diffTo: result.body.sourceVersion, definitelyTypedPath });
|
||||
if (!changedPackages) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (changedPackages.some(packageIdsAreEqual(typingsData.id))) {
|
||||
// Package has changed; run it
|
||||
return typingsData.id;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
|
||||
const affectedPackages = getAffectedPackages(allPackages, compact(changedPackages));
|
||||
const packagesToBenchmark = [...affectedPackages.changedPackages, ...affectedPackages.dependentPackages];
|
||||
const groups = packagesToBenchmark.reduce((groups: PackageId[][], typingsData, index) => {
|
||||
const agentIndex = index % agentCount;
|
||||
if (groups[agentIndex]) {
|
||||
groups[agentIndex].push(typingsData.id);
|
||||
} else {
|
||||
groups[agentIndex] = [typingsData.id];
|
||||
}
|
||||
return groups;
|
||||
}, []);
|
||||
|
||||
const benchmarkOptions: Partial<BenchmarkPackageOptions> = {
|
||||
definitelyTypedPath,
|
||||
tsVersion,
|
||||
upload: true
|
||||
};
|
||||
|
||||
await writeFile(
|
||||
outFile,
|
||||
JSON.stringify(
|
||||
{
|
||||
changedPackageCount: affectedPackages.changedPackages.length,
|
||||
dependentPackageCount: affectedPackages.dependentPackages.length,
|
||||
totalPackageCount: packagesToBenchmark.length,
|
||||
system: currentSystem,
|
||||
options: benchmarkOptions,
|
||||
groups
|
||||
},
|
||||
undefined,
|
||||
2
|
||||
),
|
||||
"utf8"
|
||||
);
|
||||
}
|
||||
@@ -3,10 +3,7 @@ import path from "path";
|
||||
import process from "process";
|
||||
import yargs from "yargs";
|
||||
import { benchmark } from "./benchmark";
|
||||
import { getPackagesToBenchmark } from "./getPackagesToBenchmark";
|
||||
import { compare } from "./compare";
|
||||
import { compareTypeScriptCLI } from "./compareTypeScript";
|
||||
import { parsePackageKey } from "../common";
|
||||
|
||||
const maxRunSeconds = {
|
||||
type: "number",
|
||||
@@ -91,33 +88,6 @@ void yargs
|
||||
},
|
||||
benchmark
|
||||
)
|
||||
.command(
|
||||
"getPackagesToBenchmark",
|
||||
"generates a benchmark manifest file to be run by multiple agents",
|
||||
{
|
||||
definitelyTypedPath: {
|
||||
...definitelyTypedPath,
|
||||
coerce: (dtPath: string) => (path.isAbsolute(dtPath) ? dtPath : path.resolve(process.cwd(), dtPath))
|
||||
},
|
||||
agentCount: {
|
||||
type: "number",
|
||||
requiresArg: true,
|
||||
description: "the number of agents that will run the benchmarks",
|
||||
demandOption: true
|
||||
},
|
||||
tsVersion: {
|
||||
...tsVersion,
|
||||
demandOption: true
|
||||
},
|
||||
outFile: {
|
||||
type: "string",
|
||||
requiresArg: true,
|
||||
description: "the path to the manifest file to be written",
|
||||
demandOption: true
|
||||
}
|
||||
},
|
||||
getPackagesToBenchmark
|
||||
)
|
||||
.command(
|
||||
"compare",
|
||||
"compare packages modified in a PR to those packages in the main branch",
|
||||
@@ -147,29 +117,6 @@ void yargs
|
||||
},
|
||||
compare
|
||||
)
|
||||
.command(
|
||||
"compareTypeScript",
|
||||
"compare packages’ performance between different TypeScript versions",
|
||||
{
|
||||
file,
|
||||
compareAgainstVersion: {
|
||||
type: "string",
|
||||
requiresArg: true,
|
||||
description: "the TypeScript major/minor version to compare against",
|
||||
demandOption: true
|
||||
},
|
||||
packages: {
|
||||
type: ("array" as unknown) as undefined, // yargs seems to have a problem with "array" + `coerce`
|
||||
description: "list of packages to benchmark",
|
||||
requiresArg: true,
|
||||
coerce: (packages: string[]) => packages.map(parsePackageKey)
|
||||
},
|
||||
maxRunSeconds,
|
||||
definitelyTypedPath,
|
||||
localTypeScriptPath
|
||||
},
|
||||
compareTypeScriptCLI
|
||||
)
|
||||
.help().argv;
|
||||
|
||||
process.on("unhandledRejection", err => {
|
||||
|
||||
@@ -4,26 +4,6 @@ export const config = {
|
||||
benchmarks: {
|
||||
languageServiceIterations: 5
|
||||
},
|
||||
database: {
|
||||
benchmarksDatabaseId: "benchmarks",
|
||||
packageBenchmarksContainerId: "packageBenchmarks",
|
||||
packageBenchmarksDocumentSchemaVersion: 5,
|
||||
typeScriptComparisonsContainerId: "typeScriptComparisons",
|
||||
typeScriptComparisonsDocumentSchemaVersion: 1,
|
||||
endpoint: "https://dt-perf.documents.azure.com:443/",
|
||||
get writeKey() {
|
||||
return assertDefined(
|
||||
process.env.DATABASE_WRITE_KEY,
|
||||
`Required environment variable 'DATABASE_WRITE_KEY' was not set`
|
||||
);
|
||||
},
|
||||
get readKey() {
|
||||
return assertDefined(
|
||||
process.env.DATABASE_READ_KEY,
|
||||
`Required environment variable 'DATABASE_READ_KEY' was not set`
|
||||
);
|
||||
}
|
||||
},
|
||||
github: {
|
||||
userAgent: "definitely-not-slow",
|
||||
typeScriptBotUsername: "typescript-bot",
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
import { CosmosClient, Database, Container } from "@azure/cosmos";
|
||||
import { config } from "./config";
|
||||
import { assertNever } from "@definitelytyped/utils";
|
||||
|
||||
export const enum DatabaseAccessLevel {
|
||||
Read = "read",
|
||||
Write = "write"
|
||||
}
|
||||
|
||||
function getKey(accessLevel: DatabaseAccessLevel) {
|
||||
switch (accessLevel) {
|
||||
case DatabaseAccessLevel.Read:
|
||||
return config.database.readKey;
|
||||
case DatabaseAccessLevel.Write:
|
||||
return config.database.writeKey;
|
||||
default:
|
||||
assertNever(accessLevel);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getDatabase(
|
||||
accessLevel: DatabaseAccessLevel
|
||||
): Promise<{
|
||||
database: Database;
|
||||
packageBenchmarks: Container;
|
||||
typeScriptComparisons: Container;
|
||||
}> {
|
||||
const client = new CosmosClient({
|
||||
endpoint: config.database.endpoint,
|
||||
key: getKey(accessLevel)
|
||||
});
|
||||
|
||||
const { database } = await client.databases.createIfNotExists({
|
||||
id: config.database.benchmarksDatabaseId
|
||||
});
|
||||
|
||||
const { container: packageBenchmarks } = await database.containers.createIfNotExists({
|
||||
id: config.database.packageBenchmarksContainerId,
|
||||
partitionKey: {
|
||||
paths: ["/body/packageName"]
|
||||
}
|
||||
});
|
||||
|
||||
const { container: typeScriptComparisons } = await database.containers.createIfNotExists({
|
||||
id: config.database.typeScriptComparisonsContainerId
|
||||
});
|
||||
|
||||
return { database, packageBenchmarks, typeScriptComparisons };
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
export * from "./config";
|
||||
export * from "./db";
|
||||
export * from "./getParsedPackages";
|
||||
export * from "./types";
|
||||
export * from "./utils";
|
||||
export * from "./support";
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import { Document, PackageBenchmarkSummary } from "./types";
|
||||
|
||||
export function supportsMemoryUsage(doc: Document<PackageBenchmarkSummary>) {
|
||||
return doc.version >= 4;
|
||||
}
|
||||
@@ -87,35 +87,3 @@ export interface SystemInfo {
|
||||
hash: string;
|
||||
nodeVersion: string;
|
||||
}
|
||||
|
||||
export interface Document<T> {
|
||||
version: number;
|
||||
createdAt: Date;
|
||||
system: SystemInfo;
|
||||
body: T;
|
||||
}
|
||||
|
||||
type Serialized<T extends {}> = {
|
||||
[K in keyof T]: T[K] extends string
|
||||
? string
|
||||
: T[K] extends number
|
||||
? number
|
||||
: T[K] extends boolean
|
||||
? boolean
|
||||
: T[K] extends Date
|
||||
? string
|
||||
: T[K] extends readonly (infer U)[]
|
||||
? Serialized<U>[]
|
||||
: T[K] extends {}
|
||||
? Serialized<T[K]>
|
||||
: never;
|
||||
};
|
||||
|
||||
export interface JSONDocument<T extends {}> {
|
||||
version: number;
|
||||
createdAt: string;
|
||||
system: SystemInfo;
|
||||
body: Serialized<T>;
|
||||
}
|
||||
|
||||
export type QueryResult<T extends {}> = T & { id: string };
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as fs from "fs";
|
||||
import { randomBytes, createHash } from "crypto";
|
||||
import { promisify } from "util";
|
||||
import { execSync } from "child_process";
|
||||
import { SystemInfo, Document, JSONDocument, PackageBenchmarkSummary, QueryResult, PackageBenchmark } from "./types";
|
||||
import { SystemInfo, PackageBenchmarkSummary, PackageBenchmark } from "./types";
|
||||
import { assertDefined, execAndThrowErrors } from "@definitelytyped/utils";
|
||||
import {
|
||||
PackageId,
|
||||
@@ -104,31 +104,6 @@ export function isWithin(actual: number, expected: number, tolerance: number): b
|
||||
return Math.abs(getPercentDiff(actual, expected)) <= tolerance;
|
||||
}
|
||||
|
||||
export function systemsAreCloseEnough(a: SystemInfo, b: SystemInfo, cpuSpeedTolerance = 0.1): boolean {
|
||||
if (a.hash === b.hash) {
|
||||
return true;
|
||||
}
|
||||
return (
|
||||
a.arch === b.arch &&
|
||||
a.platform === b.platform &&
|
||||
a.nodeVersion === b.nodeVersion &&
|
||||
a.cpus.length === b.cpus.length &&
|
||||
a.cpus.every((cpu, index) => {
|
||||
const otherCPU = b.cpus[index];
|
||||
return cpu.model === otherCPU.model && isWithin(cpu.speed, otherCPU.speed, cpuSpeedTolerance);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export function createDocument<T>(body: T, version: number): Document<T> {
|
||||
return {
|
||||
version,
|
||||
createdAt: new Date(),
|
||||
system: getSystemInfo(),
|
||||
body
|
||||
};
|
||||
}
|
||||
|
||||
export function isVersionedBenchmark(
|
||||
obj: any
|
||||
): obj is Pick<PackageBenchmark, "packageVersionMajor" | "packageVersionMinor"> {
|
||||
@@ -176,20 +151,6 @@ export function toPackageKey(
|
||||
return `${packageId.name}/${formatDependencyVersion(packageId.version)}`;
|
||||
}
|
||||
|
||||
export function deserializeSummary(
|
||||
doc: QueryResult<JSONDocument<PackageBenchmarkSummary>>
|
||||
): QueryResult<Document<PackageBenchmarkSummary>>;
|
||||
export function deserializeSummary(doc: JSONDocument<PackageBenchmarkSummary>): Document<PackageBenchmarkSummary> {
|
||||
return {
|
||||
...doc,
|
||||
createdAt: new Date(doc.createdAt),
|
||||
body: {
|
||||
...doc.body,
|
||||
batchRunStart: new Date(doc.body.batchRunStart)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getSourceVersion(cwd: string) {
|
||||
return execSync("git rev-parse HEAD", { cwd, encoding: "utf8" }).trim();
|
||||
}
|
||||
|
||||
@@ -14,9 +14,6 @@ function assertCommentSafe(str: string) {
|
||||
|
||||
export interface CommentData {
|
||||
overallChange?: OverallChange;
|
||||
benchmarks: {
|
||||
createdAt: Date;
|
||||
}[];
|
||||
}
|
||||
|
||||
export function createPerfCommentBody(data: CommentData, body: string): string {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import table from "markdown-table";
|
||||
import { PackageBenchmarkSummary, Document, config, getPercentDiff, compact, supportsMemoryUsage } from "../common";
|
||||
import { PackageBenchmarkSummary, config, getPercentDiff, compact } from "../common";
|
||||
import { metrics, Metric, FormatOptions, SignificanceLevel } from "../analysis";
|
||||
import { assertNever } from "@definitelytyped/utils";
|
||||
|
||||
export function createComparisonTable(
|
||||
before: Document<PackageBenchmarkSummary>,
|
||||
after: Document<PackageBenchmarkSummary>,
|
||||
before: PackageBenchmarkSummary,
|
||||
after: PackageBenchmarkSummary,
|
||||
beforeTitle: string,
|
||||
afterTitle: string
|
||||
) {
|
||||
@@ -13,9 +13,7 @@ export function createComparisonTable(
|
||||
compact([
|
||||
["", beforeTitle, afterTitle, "diff"],
|
||||
["**Batch compilation**"],
|
||||
supportsMemoryUsage(before) && supportsMemoryUsage(after)
|
||||
? createComparisonRowFromMetric(metrics.memoryUsage, before, after)
|
||||
: undefined,
|
||||
createComparisonRowFromMetric(metrics.memoryUsage, before, after),
|
||||
createComparisonRowFromMetric(metrics.typeCount, before, after),
|
||||
createComparisonRowFromMetric(metrics.assignabilityCacheSize, before, after),
|
||||
[],
|
||||
@@ -32,10 +30,10 @@ export function createComparisonTable(
|
||||
after,
|
||||
x =>
|
||||
sourceLink(
|
||||
x.body.completions.worst.identifierText,
|
||||
x.body.sourceVersion,
|
||||
x.body.completions.worst.fileName,
|
||||
x.body.completions.worst.line
|
||||
x.completions.worst.identifierText,
|
||||
x.sourceVersion,
|
||||
x.completions.worst.fileName,
|
||||
x.completions.worst.line
|
||||
),
|
||||
undefined,
|
||||
{ indent: 1 }
|
||||
@@ -50,35 +48,19 @@ export function createComparisonTable(
|
||||
after,
|
||||
x =>
|
||||
sourceLink(
|
||||
x.body.quickInfo.worst.identifierText,
|
||||
x.body.sourceVersion,
|
||||
x.body.quickInfo.worst.fileName,
|
||||
x.body.quickInfo.worst.line
|
||||
x.quickInfo.worst.identifierText,
|
||||
x.sourceVersion,
|
||||
x.quickInfo.worst.fileName,
|
||||
x.quickInfo.worst.line
|
||||
),
|
||||
undefined,
|
||||
{ indent: 1 }
|
||||
),
|
||||
|
||||
// Only show system info if they’re not identical
|
||||
...(before.system.hash === after.system.hash
|
||||
? []
|
||||
: [
|
||||
[],
|
||||
["**System information**"],
|
||||
createComparisonRow("Node version", before, after, x => x.system.nodeVersion),
|
||||
createComparisonRow("CPU count", before, after, x => x.system.cpus.length, undefined, { precision: 0 }),
|
||||
createComparisonRow("CPU speed", before, after, x => `${x.system.cpus[0].speed / 1000} GHz`),
|
||||
createComparisonRow("CPU model", before, after, x => x.system.cpus[0].model),
|
||||
createComparisonRow("CPU Architecture", before, after, x => x.system.arch),
|
||||
createComparisonRow("Memory", before, after, x => `${format(x.system.totalmem / 2 ** 30)} GiB`),
|
||||
createComparisonRow("Platform", before, after, x => x.system.platform),
|
||||
createComparisonRow("Release", before, after, x => x.system.release)
|
||||
])
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
export function createSingleRunTable(benchmark: Document<PackageBenchmarkSummary>) {
|
||||
export function createSingleRunTable(benchmark: PackageBenchmarkSummary) {
|
||||
return table([
|
||||
["**Batch compilation**"],
|
||||
// createSingleRunRowFromMetric(metrics.memoryUsage, benchmark),
|
||||
@@ -97,10 +79,10 @@ export function createSingleRunTable(benchmark: Document<PackageBenchmarkSummary
|
||||
benchmark,
|
||||
x =>
|
||||
sourceLink(
|
||||
x.body.completions.worst.identifierText,
|
||||
x.body.sourceVersion,
|
||||
x.body.completions.worst.fileName,
|
||||
x.body.completions.worst.line
|
||||
x.completions.worst.identifierText,
|
||||
x.sourceVersion,
|
||||
x.completions.worst.fileName,
|
||||
x.completions.worst.line
|
||||
),
|
||||
{ indent: 1 }
|
||||
),
|
||||
@@ -113,23 +95,13 @@ export function createSingleRunTable(benchmark: Document<PackageBenchmarkSummary
|
||||
benchmark,
|
||||
x =>
|
||||
sourceLink(
|
||||
x.body.quickInfo.worst.identifierText,
|
||||
x.body.sourceVersion,
|
||||
x.body.quickInfo.worst.fileName,
|
||||
x.body.quickInfo.worst.line
|
||||
x.quickInfo.worst.identifierText,
|
||||
x.sourceVersion,
|
||||
x.quickInfo.worst.fileName,
|
||||
x.quickInfo.worst.line
|
||||
),
|
||||
{ indent: 1 }
|
||||
),
|
||||
[],
|
||||
["**System information**"],
|
||||
createSingleRunRow("Node version", benchmark, x => x.system.nodeVersion),
|
||||
createSingleRunRow("CPU count", benchmark, x => x.system.cpus.length, { precision: 0 }),
|
||||
createSingleRunRow("CPU speed", benchmark, x => `${x.system.cpus[0].speed / 1000} GHz`),
|
||||
createSingleRunRow("CPU model", benchmark, x => x.system.cpus[0].model),
|
||||
createSingleRunRow("CPU Architecture", benchmark, x => x.system.arch),
|
||||
createSingleRunRow("Memory", benchmark, x => `${format(x.system.totalmem / 2 ** 30)} GiB`),
|
||||
createSingleRunRow("Platform", benchmark, x => x.system.platform),
|
||||
createSingleRunRow("Release", benchmark, x => x.system.release)
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -141,8 +113,8 @@ function sourceLink(text: string, sourceVersion: string, fileName: string, line:
|
||||
|
||||
function createComparisonRowFromMetric(
|
||||
metric: Metric,
|
||||
before: Document<PackageBenchmarkSummary>,
|
||||
after: Document<PackageBenchmarkSummary>,
|
||||
before: PackageBenchmarkSummary,
|
||||
after: PackageBenchmarkSummary,
|
||||
formatOptions: FormatOptions = {}
|
||||
) {
|
||||
const beforeValue = metric.getValue(before);
|
||||
@@ -169,7 +141,7 @@ function createComparisonRowFromMetric(
|
||||
|
||||
function createSingleRunRowFromMetric(
|
||||
metric: Metric,
|
||||
benchmark: Document<PackageBenchmarkSummary>,
|
||||
benchmark: PackageBenchmarkSummary,
|
||||
formatOptions?: FormatOptions
|
||||
) {
|
||||
return createSingleRunRow(metric.columnName, benchmark, metric.getValue, {
|
||||
@@ -180,9 +152,9 @@ function createSingleRunRowFromMetric(
|
||||
|
||||
function createComparisonRow(
|
||||
title: string,
|
||||
a: Document<PackageBenchmarkSummary>,
|
||||
b: Document<PackageBenchmarkSummary>,
|
||||
getValue: (x: Document<PackageBenchmarkSummary>) => number | string | undefined,
|
||||
a: PackageBenchmarkSummary,
|
||||
b: PackageBenchmarkSummary,
|
||||
getValue: (x: PackageBenchmarkSummary) => number | string | undefined,
|
||||
diff?: string,
|
||||
formatOptions: FormatOptions = {}
|
||||
): string[] {
|
||||
@@ -199,8 +171,8 @@ function createComparisonRow(
|
||||
|
||||
function createSingleRunRow(
|
||||
title: string,
|
||||
benchmark: Document<PackageBenchmarkSummary>,
|
||||
getValue: (x: Document<PackageBenchmarkSummary>) => number | string | undefined,
|
||||
benchmark: PackageBenchmarkSummary,
|
||||
getValue: (x: PackageBenchmarkSummary) => number | string | undefined,
|
||||
formatOptions: FormatOptions = {}
|
||||
): string[] {
|
||||
const value = getValue(benchmark);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { createComparisonTable, createSingleRunTable } from "./createTable";
|
||||
import {
|
||||
PackageBenchmarkSummary,
|
||||
systemsAreCloseEnough,
|
||||
Document,
|
||||
compact,
|
||||
toPackageKey,
|
||||
packageVersionsAreEqual
|
||||
@@ -10,7 +8,7 @@ import {
|
||||
import { getInterestingMetrics, SignificanceLevel, ComparedMetric } from "../analysis";
|
||||
|
||||
export function createTablesWithAnalysesMessage(
|
||||
pairs: [Document<PackageBenchmarkSummary> | undefined, Document<PackageBenchmarkSummary>][],
|
||||
pairs: [PackageBenchmarkSummary, PackageBenchmarkSummary][],
|
||||
prNumber: number,
|
||||
alwaysWriteHeading = false,
|
||||
alwaysCollapseDetails = false
|
||||
@@ -24,12 +22,11 @@ export function createTablesWithAnalysesMessage(
|
||||
? createComparisonTable(before, after, getBeforeTitle(before, after), getAfterTitle(before, after, prNumber))
|
||||
: createSingleRunTable(after),
|
||||
``,
|
||||
before && getSystemMismatchMessage(before, after)
|
||||
].join("\n");
|
||||
|
||||
return compact([
|
||||
pairs.length > 1 || alwaysWriteHeading
|
||||
? `### ${after.body.packageName}/v${after.body.packageVersionMajor}.${after.body.packageVersionMinor}`
|
||||
? `### ${after.packageName}/v${after.packageVersionMajor}.${after.packageVersionMinor}`
|
||||
: undefined,
|
||||
getIntroMessage(before, after),
|
||||
``,
|
||||
@@ -43,47 +40,47 @@ export function createTablesWithAnalysesMessage(
|
||||
.join("\n\n");
|
||||
}
|
||||
|
||||
function getDetailsSummaryTitle(comparisonsCount: number, benchmark: Document<PackageBenchmarkSummary>) {
|
||||
function getDetailsSummaryTitle(comparisonsCount: number, benchmark: PackageBenchmarkSummary) {
|
||||
let titleStart = "<strong>Comparison details";
|
||||
if (comparisonsCount > 1) {
|
||||
titleStart += ` for ${toPackageKey(benchmark.body)}`;
|
||||
titleStart += ` for ${toPackageKey(benchmark)}`;
|
||||
}
|
||||
return titleStart + "</strong> 📊";
|
||||
}
|
||||
|
||||
function getBeforeTitle(before: Document<PackageBenchmarkSummary>, after: Document<PackageBenchmarkSummary>) {
|
||||
if (packageVersionsAreEqual(before.body, after.body)) {
|
||||
function getBeforeTitle(before: PackageBenchmarkSummary, after: PackageBenchmarkSummary) {
|
||||
if (packageVersionsAreEqual(before, after)) {
|
||||
return "master";
|
||||
}
|
||||
return `${before.body.packageVersionMajor}.${before.body.packageVersionMinor}@master`;
|
||||
return `${before.packageVersionMajor}.${before.packageVersionMinor}@master`;
|
||||
}
|
||||
|
||||
function getAfterTitle(
|
||||
before: Document<PackageBenchmarkSummary>,
|
||||
after: Document<PackageBenchmarkSummary>,
|
||||
before: PackageBenchmarkSummary,
|
||||
after: PackageBenchmarkSummary,
|
||||
prNumber: number
|
||||
) {
|
||||
if (packageVersionsAreEqual(before.body, after.body)) {
|
||||
if (packageVersionsAreEqual(before, after)) {
|
||||
return `#${prNumber}`;
|
||||
}
|
||||
return `${after.body.packageVersionMajor}.${after.body.packageVersionMinor} in #${prNumber}`;
|
||||
return `${after.packageVersionMajor}.${after.packageVersionMinor} in #${prNumber}`;
|
||||
}
|
||||
|
||||
function getIntroMessage(
|
||||
before: Document<PackageBenchmarkSummary> | undefined,
|
||||
after: Document<PackageBenchmarkSummary>
|
||||
before: PackageBenchmarkSummary | undefined,
|
||||
after: PackageBenchmarkSummary
|
||||
) {
|
||||
if (before && packageVersionsAreEqual(before.body, after.body)) {
|
||||
if (before && packageVersionsAreEqual(before, after)) {
|
||||
return;
|
||||
}
|
||||
if (before) {
|
||||
return `These typings are for a version of ${before.body.packageName} that doesn’t yet exist on master, so I’ve compared them with v${before.body.packageVersionMajor}.${before.body.packageVersionMinor}.`;
|
||||
return `These typings are for a version of ${before.packageName} that doesn’t yet exist on master, so I’ve compared them with v${before.packageVersionMajor}.${before.packageVersionMinor}.`;
|
||||
}
|
||||
return `These typings are for a package that doesn’t yet exist on master, so I don’t have anything to compare against yet! In the future, I’ll be able to compare PRs to ${after.body.packageName} with its source on master.`;
|
||||
return `These typings are for a package that doesn’t yet exist on master, so I don’t have anything to compare against yet! In the future, I’ll be able to compare PRs to ${after.packageName} with its source on master.`;
|
||||
}
|
||||
|
||||
function getLanguageServiceCrashMessage(benchmark: Document<PackageBenchmarkSummary>) {
|
||||
if (benchmark.body.languageServiceCrashed) {
|
||||
function getLanguageServiceCrashMessage(benchmark: PackageBenchmarkSummary) {
|
||||
if (benchmark.languageServiceCrashed) {
|
||||
return (
|
||||
`Before we get into it, I need to mention that **the language service crashed** while taking these measurements. ` +
|
||||
`This isn’t your fault—on the contrary, you helped us find a probably TypeScript bug! But, be aware that these results ` +
|
||||
@@ -94,12 +91,6 @@ function getLanguageServiceCrashMessage(benchmark: Document<PackageBenchmarkSumm
|
||||
return;
|
||||
}
|
||||
|
||||
function getSystemMismatchMessage(a: Document<PackageBenchmarkSummary>, b: Document<PackageBenchmarkSummary>) {
|
||||
return !systemsAreCloseEnough(a.system, b.system)
|
||||
? `First off, note that the system varied slightly between these two runs, so you’ll have to take these measurements with a grain of salt.`
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function getInterestingMetricsMessage(interestingMetrics: readonly ComparedMetric[]) {
|
||||
if (!interestingMetrics.length) {
|
||||
return `It looks like nothing changed too much. I won’t post performance data again unless it gets worse.`;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { PackageBenchmarkSummary, Document, config, compact } from "../common";
|
||||
import { PackageBenchmarkSummary, config, compact } from "../common";
|
||||
import { getOctokit } from "./getOctokit";
|
||||
import { createTablesWithAnalysesMessage } from "./createTablesWithAnalysesMessage";
|
||||
import { createPerfCommentBody } from "./comment";
|
||||
import { getOverallChangeForComparisons } from "../analysis";
|
||||
import { assertDefined } from "@definitelytyped/utils";
|
||||
|
||||
type BeforeAndAfter = [Document<PackageBenchmarkSummary> | undefined, Document<PackageBenchmarkSummary>];
|
||||
type BeforeAndAfter = [PackageBenchmarkSummary, PackageBenchmarkSummary];
|
||||
|
||||
export interface PostDependentsComparisonResultOptions {
|
||||
comparisons: BeforeAndAfter[];
|
||||
@@ -37,7 +37,6 @@ export async function postDependentsComparisonResult({ comparisons, dryRun }: Po
|
||||
body: createPerfCommentBody(
|
||||
{
|
||||
overallChange: getOverallChangeForComparisons(comparisons),
|
||||
benchmarks: comparisons.map(([, b]) => ({ createdAt: b.createdAt }))
|
||||
},
|
||||
message
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PackageBenchmarkSummary, Document, config, compact, findLast } from "../common";
|
||||
import { PackageBenchmarkSummary, config, compact, findLast } from "../common";
|
||||
import { getOctokit } from "./getOctokit";
|
||||
import { createTablesWithAnalysesMessage } from "./createTablesWithAnalysesMessage";
|
||||
import { isPerfComment, createPerfCommentBody, getCommentData, CommentData } from "./comment";
|
||||
@@ -6,7 +6,7 @@ import { OverallChange, getOverallChangeForComparisons } from "../analysis";
|
||||
import { setLabels } from "./setLabels";
|
||||
import { assertDefined } from "@definitelytyped/utils";
|
||||
|
||||
type BeforeAndAfter = [Document<PackageBenchmarkSummary> | undefined, Document<PackageBenchmarkSummary>];
|
||||
type BeforeAndAfter = [PackageBenchmarkSummary, PackageBenchmarkSummary];
|
||||
|
||||
export interface PostInitialComparisonResultsOptions {
|
||||
comparisons: BeforeAndAfter[];
|
||||
@@ -45,7 +45,6 @@ export async function postInitialComparisonResults({
|
||||
const mostRecentComment = findLast(comments.data, isPerfComment);
|
||||
const commentData: CommentData = {
|
||||
overallChange: currentOverallChange,
|
||||
benchmarks: comparisons.map(([, b]) => ({ createdAt: b.createdAt }))
|
||||
};
|
||||
if (mostRecentComment) {
|
||||
const lastOverallChange = getCommentData(mostRecentComment)?.overallChange;
|
||||
@@ -64,7 +63,7 @@ export async function postInitialComparisonResults({
|
||||
/*alwaysWriteHeader*/ false,
|
||||
/*alwaysCollapseDetails*/ true
|
||||
),
|
||||
comparisons[0][1].body.sourceVersion
|
||||
comparisons[0][1].sourceVersion
|
||||
);
|
||||
|
||||
await octokit.issues.createComment({
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import { PackageBenchmarkSummary, Document, toPackageKey } from "../common";
|
||||
import { createComparisonTable } from "./createTable";
|
||||
|
||||
type BeforeAndAfter = [Document<PackageBenchmarkSummary>, Document<PackageBenchmarkSummary>];
|
||||
|
||||
export interface PostTypeScriptComparisonResultsOptions {
|
||||
comparisons: BeforeAndAfter[];
|
||||
dryRun: boolean;
|
||||
}
|
||||
|
||||
export async function postTypeScriptComparisonResults({ comparisons }: PostTypeScriptComparisonResultsOptions) {
|
||||
return comparisons
|
||||
.map(([baseline, head]) =>
|
||||
[
|
||||
`### ${toPackageKey(baseline.body)}`,
|
||||
createComparisonTable(baseline, head, baseline.body.typeScriptVersion, "HEAD")
|
||||
].join("\n")
|
||||
)
|
||||
.join("\n\n");
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import { Container } from "@azure/cosmos";
|
||||
import { DirectoryParsedTypingVersion } from "@definitelytyped/definitions-parser";
|
||||
import { config, PackageBenchmarkSummary, Document, QueryResult } from "../common";
|
||||
|
||||
export interface GetLatestBenchmarkOptions {
|
||||
container: Container;
|
||||
packageName: string;
|
||||
packageVersion: DirectoryParsedTypingVersion;
|
||||
matchMinor: boolean;
|
||||
typeScriptVersionMajorMinor: string;
|
||||
}
|
||||
|
||||
export async function getLatestBenchmark({
|
||||
container,
|
||||
packageName,
|
||||
packageVersion,
|
||||
matchMinor,
|
||||
typeScriptVersionMajorMinor
|
||||
}: GetLatestBenchmarkOptions): Promise<QueryResult<Document<PackageBenchmarkSummary>> | undefined> {
|
||||
const response = await container.items
|
||||
.query<QueryResult<Document<PackageBenchmarkSummary>>>({
|
||||
query:
|
||||
`SELECT TOP 1 * FROM ${config.database.packageBenchmarksContainerId} b` +
|
||||
` WHERE b.body.packageName = @packageName` +
|
||||
` AND b.body.packageVersionMajor = @packageVersionMajor` +
|
||||
(matchMinor ? ` AND b.body.packageVersionMinor = @packageVersionMinor` : "") +
|
||||
` AND b.body.typeScriptVersionMajorMinor = @tsVersion` +
|
||||
` ORDER BY b.createdAt DESC`,
|
||||
parameters: [
|
||||
{ name: "@packageName", value: packageName },
|
||||
{ name: "@packageVersionMajor", value: packageVersion.major },
|
||||
{ name: "@packageVersionMinor", value: packageVersion.minor ?? "" },
|
||||
{ name: "@tsVersion", value: typeScriptVersionMajorMinor }
|
||||
]
|
||||
})
|
||||
.fetchNext();
|
||||
return response.resources[0];
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { Container, Item } from "@azure/cosmos";
|
||||
import { PackageBenchmarkSummary, createDocument, TypeScriptComparisonRun } from "../common";
|
||||
|
||||
export async function insertDocument(
|
||||
benchmark: PackageBenchmarkSummary | TypeScriptComparisonRun,
|
||||
version: number,
|
||||
container: Container
|
||||
): Promise<Item> {
|
||||
const response = await container.items.create(createDocument(benchmark, version));
|
||||
return response.item;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { metrics, SignificanceLevel } from "../../src/analysis";
|
||||
import { Document, PackageBenchmarkSummary, config } from "../../src/common";
|
||||
import { PackageBenchmarkSummary, config } from "../../src/common";
|
||||
|
||||
describe("analysis", () => {
|
||||
describe("metrics", () => {
|
||||
@@ -8,8 +8,8 @@ describe("analysis", () => {
|
||||
6,
|
||||
1000,
|
||||
6000,
|
||||
{ body: { testIdentifierCount: 1000, typeCount: 1000 } } as Document<PackageBenchmarkSummary>,
|
||||
{ body: { testIdentifierCount: 6000, typeCount: 6000 } } as Document<PackageBenchmarkSummary>
|
||||
{ testIdentifierCount: 1000, typeCount: 1000 } as PackageBenchmarkSummary,
|
||||
{ testIdentifierCount: 6000, typeCount: 6000 } as PackageBenchmarkSummary
|
||||
);
|
||||
|
||||
expect(significance1).toBe(undefined);
|
||||
@@ -18,8 +18,8 @@ describe("analysis", () => {
|
||||
6,
|
||||
1000,
|
||||
6000,
|
||||
{ body: { testIdentifierCount: 1000, typeCount: 1000 } } as Document<PackageBenchmarkSummary>,
|
||||
{ body: { testIdentifierCount: 1000, typeCount: 6000 } } as Document<PackageBenchmarkSummary>
|
||||
{ testIdentifierCount: 1000, typeCount: 1000 } as PackageBenchmarkSummary,
|
||||
{ testIdentifierCount: 1000, typeCount: 6000 } as PackageBenchmarkSummary
|
||||
);
|
||||
|
||||
expect(significance2).toBe(SignificanceLevel.Warning);
|
||||
@@ -28,8 +28,8 @@ describe("analysis", () => {
|
||||
config.comparison.percentDiffWarningThreshold + 0.01,
|
||||
1000,
|
||||
200,
|
||||
{ body: { testIdentifierCount: 1000, typeCount: 1000 } } as Document<PackageBenchmarkSummary>,
|
||||
{ body: { testIdentifierCount: 5000, typeCount: 2000 } } as Document<PackageBenchmarkSummary>
|
||||
{ testIdentifierCount: 1000, typeCount: 1000 } as PackageBenchmarkSummary,
|
||||
{ testIdentifierCount: 5000, typeCount: 2000 } as PackageBenchmarkSummary
|
||||
);
|
||||
|
||||
expect(significance3).toBe(undefined);
|
||||
@@ -40,8 +40,8 @@ describe("analysis", () => {
|
||||
6,
|
||||
100,
|
||||
600,
|
||||
{ body: { testIdentifierCount: 100, typeCount: 100 } } as Document<PackageBenchmarkSummary>,
|
||||
{ body: { testIdentifierCount: 600, typeCount: 600 } } as Document<PackageBenchmarkSummary>
|
||||
{ testIdentifierCount: 100, typeCount: 100 } as PackageBenchmarkSummary,
|
||||
{ testIdentifierCount: 600, typeCount: 600 } as PackageBenchmarkSummary
|
||||
);
|
||||
|
||||
expect(significance1).toBe(undefined);
|
||||
|
||||
36
yarn.lock
36
yarn.lock
@@ -104,22 +104,6 @@
|
||||
"@opentelemetry/api" "^1.0.1"
|
||||
tslib "^2.2.0"
|
||||
|
||||
"@azure/cosmos@^3.6.3":
|
||||
version "3.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@azure/cosmos/-/cosmos-3.6.3.tgz#bb53bde35fbf338160691d2b6a62f47b4a9a1cbb"
|
||||
integrity sha512-JoCDxl0TnL6EHL4xD3KC9r2bMivK13q1jl7h69wd/YFLlt3aBTTCehtAX+y4alNSENpL53XdRdw/cna0mI2XDw==
|
||||
dependencies:
|
||||
"@types/debug" "^4.1.4"
|
||||
debug "^4.1.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
node-abort-controller "^1.0.4"
|
||||
node-fetch "^2.6.0"
|
||||
os-name "^3.1.0"
|
||||
priorityqueuejs "^1.0.0"
|
||||
semaphore "^1.0.5"
|
||||
tslib "^1.10.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
"@azure/functions@^1.2.3":
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@azure/functions/-/functions-1.2.3.tgz#65765837e7319eedffbf8a971cb2f78d4e043d54"
|
||||
@@ -1773,11 +1757,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/command-exists/-/command-exists-1.2.0.tgz#d97e0ed10097090e4ab0367ed425b0312fad86f3"
|
||||
integrity sha512-ugsxEJfsCuqMLSuCD4PIJkp5Uk2z6TCMRCgYVuhRo5cYQY3+1xXTQkSlPtkpGHuvWMjS2KTeVQXxkXRACMbM6A==
|
||||
|
||||
"@types/debug@^4.1.4":
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
|
||||
integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==
|
||||
|
||||
"@types/fs-extra@^5.0.2":
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.1.0.tgz#2a325ef97901504a3828718c390d34b8426a10a1"
|
||||
@@ -6367,11 +6346,6 @@ node-abi@^2.21.0:
|
||||
dependencies:
|
||||
semver "^5.4.1"
|
||||
|
||||
node-abort-controller@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-1.0.4.tgz#4095e41d58b2fae169d2f9892904d603e11c7a39"
|
||||
integrity sha512-7cNtLKTAg0LrW3ViS2C7UfIzbL3rZd8L0++5MidbKqQVJ8yrH6+1VRSHl33P0ZjBTbOJd37d9EYekvHyKkB0QQ==
|
||||
|
||||
node-addon-api@^3.0.0:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161"
|
||||
@@ -7120,11 +7094,6 @@ pretty-format@^25.2.1, pretty-format@^25.5.0:
|
||||
ansi-styles "^4.0.0"
|
||||
react-is "^16.12.0"
|
||||
|
||||
priorityqueuejs@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz#2ee4f23c2560913e08c07ce5ccdd6de3df2c5af8"
|
||||
integrity sha1-LuTyPCVgkT4IwHzlzN1t498sWvg=
|
||||
|
||||
process-nextick-args@~2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
@@ -7622,11 +7591,6 @@ saxes@^3.1.9:
|
||||
dependencies:
|
||||
xmlchars "^2.1.1"
|
||||
|
||||
semaphore@^1.0.5:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa"
|
||||
integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==
|
||||
|
||||
"semver@2 >=2.2.1 || 3.x || 4 || 5 || 7", semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5:
|
||||
version "7.3.5"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
|
||||
|
||||
Reference in New Issue
Block a user