Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/definitions-parser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"@definitelytyped/typescript-versions": "^0.0.112-next.9",
"@definitelytyped/utils": "^0.0.112-next.9",
"@types/node": "^14.14.35",
"fs-extra": "^9.1.0"
"fs-extra": "^9.1.0",
"semver": "^7.3.7"
},
"devDependencies": {
"@types/fs-extra": "^9.0.8"
Expand Down
29 changes: 14 additions & 15 deletions packages/definitions-parser/src/check-parse-results.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ import { ParseDefinitionsOptions } from "./get-definitely-typed";
import { TypingsData, AllPackages, formatTypingVersion } from "./packages";
import {
assertDefined,
best,
mapDefined,
nAtATime,
FS,
logger,
writeLog,
Logger,
Semver,
UncachedNpmInfoClient,
NpmInfoRawVersions,
NpmInfoVersion,
max,
min,
} from "@definitelytyped/utils";
import * as semver from "semver";

export async function checkParseResults(
includeNpmChecks: false,
Expand Down Expand Up @@ -132,21 +133,19 @@ async function checkNpm(
}

const versions = getRegularVersions(info.versions);
const firstTypedVersion = best(
const firstTypedVersion = min(
mapDefined(versions, ({ hasTypes, version }) => (hasTypes ? version : undefined)),
(a, b) => b.greaterThan(a)
semver.compare
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use semver.compare().

);
// A package might have added types but removed them later, so check the latest version too
if (firstTypedVersion === undefined || !best(versions, (a, b) => a.version.greaterThan(b.version))!.hasTypes) {
if (firstTypedVersion === undefined || !max(versions, (a, b) => semver.compare(a.version, b.version))!.hasTypes) {
return;
}

const ourVersion = `${major}.${minor}`;

log("");
log(
`Typings already defined for ${name} (${libraryName}) as of ${firstTypedVersion.versionString} (our version: ${ourVersion})`
);
log(`Typings already defined for ${name} (${libraryName}) as of ${firstTypedVersion} (our version: ${ourVersion})`);
const contributorUrls = contributors
.map((c) => {
const gh = "https://github.com/";
Expand All @@ -155,14 +154,14 @@ async function checkNpm(
.join(", ");
log(" To fix this:");
log(` git checkout -b not-needed-${name}`);
const yarnargs = [name, firstTypedVersion.versionString, projectName];
const yarnargs = [name, firstTypedVersion, projectName];
if (libraryName !== name) {
yarnargs.push(JSON.stringify(libraryName));
}
log(" yarn not-needed " + yarnargs.join(" "));
log(` git add --all && git commit -m "${name}: Provides its own types" && git push -u origin not-needed-${name}`);
log(` And comment PR: This will deprecate \`@types/${name}\` in favor of just \`${name}\`. CC ${contributorUrls}`);
if (new Semver(major, minor, 0).greaterThan(firstTypedVersion)) {
if (semver.gt(`${major}.${minor}.0`, firstTypedVersion)) {
log(" WARNING: our version is greater!");
}
if (dependedOn.has(name)) {
Expand All @@ -177,11 +176,11 @@ export async function packageHasTypes(packageName: string, client: UncachedNpmIn

function getRegularVersions(
versions: NpmInfoRawVersions
): readonly { readonly version: Semver; readonly hasTypes: boolean }[] {
return mapDefined(Object.entries(versions), ([versionString, info]) => {
const version = Semver.tryParse(versionString);
return version === undefined ? undefined : { version, hasTypes: versionHasTypes(info) };
});
): readonly { readonly version: semver.SemVer; readonly hasTypes: boolean }[] {
return Object.entries(versions).map(([versionString, info]) => ({
version: new semver.SemVer(versionString),
hasTypes: versionHasTypes(info),
}));
}

function versionHasTypes(info: NpmInfoVersion): boolean {
Expand Down
20 changes: 9 additions & 11 deletions packages/definitions-parser/src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import {
FS,
consoleLogger,
assertDefined,
Semver,
UncachedNpmInfoClient,
NpmInfo,
} from "@definitelytyped/utils";
import * as semver from "semver";
import { getAffectedPackages } from "./get-affected-packages";

export interface GitDiff {
Expand Down Expand Up @@ -145,20 +145,18 @@ export function checkNotNeededPackage(
Unneeded packages have to be replaced with a package on npm.`
);
typings = assertDefined(typings, `Unexpected error: @types package not found for ${unneeded.fullNpmName}`);
const latestTypings = Semver.parse(
assertDefined(
typings.distTags.get("latest"),
`Unexpected error: ${unneeded.fullNpmName} is missing the "latest" tag.`
)
const latestTypings = assertDefined(
typings.distTags.get("latest"),
`Unexpected error: ${unneeded.fullNpmName} is missing the "latest" tag.`
);
assert(
unneeded.version.greaterThan(latestTypings),
`The specified version ${unneeded.version.versionString} of ${unneeded.libraryName} must be newer than the version
it is supposed to replace, ${latestTypings.versionString} of ${unneeded.fullNpmName}.`
semver.gt(unneeded.version, latestTypings),
`The specified version ${unneeded.version} of ${unneeded.libraryName} must be newer than the version
it is supposed to replace, ${latestTypings} of ${unneeded.fullNpmName}.`
);
assert(
source.versions.has(unneeded.version.versionString),
`The specified version ${unneeded.version.versionString} of ${unneeded.libraryName} is not on npm.`
source.versions.has(String(unneeded.version)),
`The specified version ${unneeded.version} of ${unneeded.libraryName} is not on npm.`
);
}

Expand Down
5 changes: 3 additions & 2 deletions packages/definitions-parser/src/mocks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { parseHeaderOrFail } from "@definitelytyped/header-parser";
import { Dir, FS, InMemoryFS, mangleScopedPackage, Semver } from "@definitelytyped/utils";
import { Dir, FS, InMemoryFS, mangleScopedPackage } from "@definitelytyped/utils";
import * as semver from "semver";

class DTMock {
public readonly fs: FS;
Expand Down Expand Up @@ -43,7 +44,7 @@ class DTMock {
const index = latestDir.get("index.d.ts") as string;
const latestHeader = parseHeaderOrFail(index);
const latestVersion = `${latestHeader.libraryMajorVersion}.${latestHeader.libraryMinorVersion}`;
const olderVersionParsed = Semver.parse(olderVersion, true)!;
const olderVersionParsed = semver.coerce(olderVersion)!;

const oldDir = latestDir.subdir(`v${olderVersion}`);
const tsconfig = JSON.parse(latestDir.get("tsconfig.json") as string);
Expand Down
25 changes: 8 additions & 17 deletions packages/definitions-parser/src/packages.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import assert = require("assert");
import { Author } from "@definitelytyped/header-parser";
import {
FS,
mapValues,
assertSorted,
unmangleScopedPackage,
Semver,
assertDefined,
unique,
} from "@definitelytyped/utils";
import { FS, mapValues, assertSorted, unmangleScopedPackage, assertDefined, unique } from "@definitelytyped/utils";
import { AllTypeScriptVersion, TypeScriptVersion } from "@definitelytyped/typescript-versions";
import * as semver from "semver";
import { readDataFile } from "./data-file";
import { scopeName, typesDirectoryName } from "./lib/settings";
import { parseVersionFromDirectoryName } from "./lib/definition-parser";
Expand Down Expand Up @@ -261,7 +254,7 @@ interface NotNeededPackageRaw extends BaseRaw {
}

export class NotNeededPackage extends PackageBase {
readonly version: Semver;
readonly version: semver.SemVer;

get license(): License.MIT {
return License.MIT;
Expand All @@ -286,7 +279,7 @@ export class NotNeededPackage extends PackageBase {
constructor(readonly name: string, readonly libraryName: string, asOfVersion: string) {
super({ libraryName });
assert(libraryName && name && asOfVersion);
this.version = Semver.parse(asOfVersion);
this.version = new semver.SemVer(asOfVersion);
}

get major(): number {
Expand Down Expand Up @@ -496,22 +489,20 @@ export function getLicenseFromPackageJson(packageJsonLicense: unknown): License
}

export class TypingsVersions {
private readonly map: ReadonlyMap<Semver, TypingsData>;
private readonly map: ReadonlyMap<semver.SemVer, TypingsData>;

/**
* Sorted from latest to oldest.
*/
private readonly versions: Semver[];
private readonly versions: semver.SemVer[];

constructor(data: TypingsVersionsRaw) {
/**
* Sorted from latest to oldest so that we publish the current version first.
* This is important because older versions repeatedly reset the "latest" tag to the current version.
*/
this.versions = Object.keys(data)
.map((key) => Semver.parse(key, true))
.sort(Semver.compare)
.reverse();
this.versions = Object.keys(data).map((key) => new semver.SemVer(`${key}.0`));
this.versions.sort(semver.rcompare);

this.map = new Map(
this.versions.map((version, i) => [version, new TypingsData(data[`${version.major}.${version.minor}`], !i)])
Expand Down
2 changes: 1 addition & 1 deletion packages/definitions-parser/test/packages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ describe(NotNeededPackage, () => {
expect(data.license).toBe(License.MIT);
expect(data.name).toBe("types-package");
expect(data.libraryName).toBe("real-package");
expect(data.version).toEqual({
expect(data.version).toMatchObject({
major: 1,
minor: 0,
patch: 0,
Expand Down
2 changes: 1 addition & 1 deletion packages/dts-critic/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ The most common way to resolve this error is to use 'export =' syntax instead of
To learn more about 'export =' syntax, see https://www.typescriptlang.org/docs/handbook/modules.html#export--and-import--require.`,
position: {
start: 0,
length: 32,
length: 33,
},
},
])
Expand Down
1 change: 1 addition & 0 deletions packages/perf/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@octokit/rest": "^16.33.0",
"@types/node": "^12.12.29",
"markdown-table": "^1.1.3",
"semver": "^7.3.7",
"typescript": "^4.1.0",
"yargs": "^15.4.1"
},
Expand Down
12 changes: 6 additions & 6 deletions packages/perf/src/measure/measurePerf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import {
MeasureBatchCompilationChildProcessResult,
} from "./measureBatchCompilationWorker";
import { AllPackages, HeaderParsedTypingVersion } from "@definitelytyped/definitions-parser";
import { runWithListeningChildProcesses, runWithChildProcesses, Semver } from "@definitelytyped/utils";
import { TypeScriptVersion } from "@definitelytyped/typescript-versions";
import { runWithListeningChildProcesses, runWithChildProcesses } from "@definitelytyped/utils";
import * as semver from "semver";

export interface MeasurePerfOptions {
packageName: string;
Expand Down Expand Up @@ -253,14 +255,12 @@ export async function measurePerf({
}

function getLatestTypesVersionForTypeScriptVersion(
typesVersions: readonly string[],
typesVersions: readonly TypeScriptVersion[],
typeScriptVersion: string
): string | undefined {
const tsVersion = Semver.parse(typeScriptVersion.replace(/-dev.*$/, ""));
const tsVersion = new semver.SemVer(typeScriptVersion);
for (let i = typesVersions.length - 1; i > 0; i--) {
const [major, minor] = typesVersions[i].split(".").map(Number); // e.g. '3.5'
const typesVersion = new Semver(major, minor, 0);
if (tsVersion.greaterThan(typesVersion)) {
if (semver.gte(tsVersion, `${typesVersions[i]}.0-`)) {
return typesVersions[i];
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/publisher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"hh-mm-ss": "^1.2.0",
"longjohn": "^0.2.11",
"oboe": "^2.1.3",
"semver": "^7.3.7",
"source-map-support": "^0.4.0",
"typescript": "^4.1.0",
"yargs": "15.3.1"
Expand Down
2 changes: 1 addition & 1 deletion packages/publisher/src/generate-packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ function dependencySemver(dependency: DependencyVersion): string {
export function createNotNeededPackageJSON({ libraryName, license, fullNpmName, version }: NotNeededPackage): string {
const out = {
name: fullNpmName,
version: version.versionString,
version: String(version),
typings: null, // tslint:disable-line no-null-keyword
description: `Stub TypeScript definitions entry for ${libraryName}, which provides its own types definitions`,
main: "",
Expand Down
27 changes: 10 additions & 17 deletions packages/publisher/src/lib/npm.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { NotNeededPackage } from "@definitelytyped/definitions-parser";
import { Logger, assertDefined, Semver, best, CachedNpmInfoClient } from "@definitelytyped/utils";
import { Logger, assertDefined, CachedNpmInfoClient, max } from "@definitelytyped/utils";
import * as semver from "semver";

/**
* When we fail to publish a deprecated package, it leaves behind an entry in the time property.
Expand All @@ -10,27 +11,19 @@ export function skipBadPublishes(pkg: NotNeededPackage, client: CachedNpmInfoCli
// because this is called right after isAlreadyDeprecated, we can rely on the cache being up-to-date
const info = assertDefined(client.getNpmInfoFromCache(pkg.fullEscapedNpmName));
const notNeeded = pkg.version;
const latest = Semver.parse(findActualLatest(info.time));
if (
latest.equals(notNeeded) ||
latest.greaterThan(notNeeded) ||
(info.versions.has(notNeeded.versionString) &&
!assertDefined(info.versions.get(notNeeded.versionString)).deprecated)
Comment on lines -17 to -18
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!isAlreadyDeprecated() ensures notNeeded is either < latest or not deprecated.

) {
const plusOne = new Semver(latest.major, latest.minor, latest.patch + 1);
log(`Deprecation of ${notNeeded.versionString} failed, instead using ${plusOne.versionString}.`);
return new NotNeededPackage(pkg.name, pkg.libraryName, plusOne.versionString);
const latest = new semver.SemVer(findActualLatest(info.time));
if (semver.lte(notNeeded, latest)) {
const plusOne = semver.inc(latest, "patch")!;
log(`Deprecation of ${notNeeded} failed, instead using ${plusOne}.`);
return new NotNeededPackage(pkg.name, pkg.libraryName, plusOne);
}
return pkg;
}

function findActualLatest(times: Map<string, string>) {
const actual = best(times, ([k, v], [bestK, bestV]) =>
bestK === "modified" || bestK === "created"
? true
: k === "modified" || k === "created"
? false
: new Date(v).getTime() > new Date(bestV).getTime()
const actual = max(
[...times].filter(([version]) => version !== "modified" && version !== "created"),
([, a], [, b]) => (new Date(a) as never) - (new Date(b) as never)
);
if (!actual) {
throw new Error("failed to find actual latest");
Expand Down
6 changes: 3 additions & 3 deletions packages/publisher/src/lib/package-publisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ export async function deprecateNotNeededPackage(
): Promise<void> {
const name = pkg.fullNpmName;
if (dry) {
log("(dry) Skip deprecate not needed package " + name + " at " + pkg.version.versionString);
log("(dry) Skip deprecate not needed package " + name + " at " + pkg.version);
} else {
log(`Deprecating ${name} at ${pkg.version.versionString} with message: ${pkg.deprecatedMessage()}.`);
await client.deprecate(name, pkg.version.versionString, pkg.deprecatedMessage());
log(`Deprecating ${name} at ${pkg.version} with message: ${pkg.deprecatedMessage()}.`);
await client.deprecate(name, String(pkg.version), pkg.deprecatedMessage());
}
}
Loading