From da36d0e878196378ef0976bcf00813eb5eff1732 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Sat, 14 Sep 2019 09:51:42 -0400 Subject: [PATCH] Allow using peer dependencies in a package json to indicate that a dependency doesn't have to be included for the package to pass - this is because styled-components infers react-native, but it doesn't need it to pass --- src/generate-packages.ts | 19 +++++++++++++++---- src/lib/definition-parser-worker.ts | 1 - src/lib/definition-parser.ts | 17 ++++++++++++----- src/lib/packages.ts | 11 ++++++++++- src/tester/get-affected-packages.ts | 6 +++--- src/util/test.ts | 1 + 6 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/generate-packages.ts b/src/generate-packages.ts index ccc71cee..f1c31e16 100644 --- a/src/generate-packages.ts +++ b/src/generate-packages.ts @@ -1,4 +1,4 @@ -import { emptyDir } from "fs-extra"; +import { emptyDir, mkdir, mkdirp, readFileSync } from "fs-extra"; import * as yargs from "yargs"; import { FS, getDefinitelyTyped } from "./get-definitely-typed"; @@ -6,14 +6,13 @@ import { Options } from "./lib/common"; import { AllPackages, AnyPackage, DependencyVersion, getFullNpmName, License, NotNeededPackage, PackageJsonDependency, TypingsData, } from "./lib/packages"; -import { sourceBranch, outputDirPath } from "./lib/settings"; +import { outputDirPath, sourceBranch } from "./lib/settings"; import { ChangedPackages, readChangedPackages, skipBadPublishes } from "./lib/versions"; import { writeFile } from "./util/io"; import { logger, loggerWithErrors, writeLog, Logger } from "./util/logging"; import { writeTgz } from "./util/tgz"; import { assertNever, joinPaths, logUncaughtErrors, sortObjectKeys } from "./util/util"; import { makeTypesVersionsForPackageJson } from "definitelytyped-header-parser"; -import { mkdir, mkdirp, readFileSync } from "fs-extra"; import * as path from "path"; import { withNpmCache, CachedNpmInfoClient, UncachedNpmInfoClient } from "./lib/npm-client"; @@ -112,6 +111,7 @@ function createPackageJSON(typing: TypingsData, version: string, packages: AllPa }, scripts: {}, dependencies: getDependencies(typing.packageJsonDependencies, typing, packages), + peerDependencies: getPeerDependencies(typing.peerDependencies), typesPublisherContentHash: typing.contentHash, typeScriptVersion: typing.minTypeScriptVersion, }; @@ -121,7 +121,7 @@ function createPackageJSON(typing: TypingsData, version: string, packages: AllPa const definitelyTypedURL = "https://github.com/DefinitelyTyped/DefinitelyTyped"; -/** Adds inferred dependencies to `dependencies`, if they are not already specified in either `dependencies` or `peerDependencies`. */ +/** Adds inferred dependencies to `dependencies`, if they are not already specified in either `dependencies`. */ function getDependencies(packageJsonDependencies: ReadonlyArray, typing: TypingsData, allPackages: AllPackages): Dependencies { const dependencies: Dependencies = {}; for (const { name, version } of packageJsonDependencies) { @@ -138,6 +138,15 @@ function getDependencies(packageJsonDependencies: ReadonlyArray): Dependencies { + const dependencies: Dependencies = {}; + for (const { name, version } of packageJsonDependencies) { + dependencies[name] = version; + } + + return sortObjectKeys(dependencies); +} + function dependencySemver(dependency: DependencyVersion): string { return dependency === "*" ? dependency : `^${dependency}`; } @@ -185,6 +194,8 @@ function createReadme(typing: TypingsData): string { lines.push(` * Last updated: ${(new Date()).toUTCString()}`); const dependencies = Array.from(typing.dependencies).map(d => getFullNpmName(d.name)); lines.push(` * Dependencies: ${dependencies.length ? dependencies.join(", ") : "none"}`); + const peerDependencies = Array.from(typing.peerDependencies).map(d => getFullNpmName(d.name)); + lines.push(` * Peer Dependencies: ${peerDependencies.length ? peerDependencies.join(", ") : "none"}`); lines.push(` * Global values: ${typing.globals.length ? typing.globals.join(", ") : "none"}`); lines.push(""); diff --git a/src/lib/definition-parser-worker.ts b/src/lib/definition-parser-worker.ts index 9c37fd83..8b7dc1a7 100644 --- a/src/lib/definition-parser-worker.ts +++ b/src/lib/definition-parser-worker.ts @@ -22,4 +22,3 @@ if (!module.parent) { }); } - diff --git a/src/lib/definition-parser.ts b/src/lib/definition-parser.ts index e191f287..a5b1dc63 100644 --- a/src/lib/definition-parser.ts +++ b/src/lib/definition-parser.ts @@ -93,15 +93,21 @@ async function combineDataForAllTypesVersions( }); const allTypesVersions = [dataForRoot, ...dataForOtherTypesVersions]; + interface OptionalPackageJSON { readonly license?: unknown; readonly dependencies?: unknown; peerDependencies?: unknown; } + // tslint:disable-next-line await-promise (tslint bug) - const packageJson = hasPackageJson ? await fs.readJson(packageJsonName) as { readonly license?: unknown, readonly dependencies?: unknown } : {}; + const packageJson = hasPackageJson ? await fs.readJson(packageJsonName) as OptionalPackageJSON : {}; const license = getLicenseFromPackageJson(packageJson.license); - const packageJsonDependencies = checkPackageJsonDependencies(packageJson.dependencies, packageJsonName); + const packageJsonDependencies = checkPackageJsonDependencies(packageJson.dependencies, packageJsonName, /* checkWhitelist */ true); + const packageJsonPeerDependencies = checkPackageJsonDependencies(packageJson.peerDependencies, packageJsonName, /* checkWhitelist */ false); const files = Array.from(flatMap(allTypesVersions, ({ typescriptVersion, declFiles }) => declFiles.map(file => typescriptVersion === undefined ? file : `ts${typescriptVersion}/${file}`))); + // Get all package dependencies and remove any peer dependencies from them + const dependencies = getAllUniqueValues<"dependencies", PackageId>(allTypesVersions, "dependencies") + .filter(dep => !packageJsonPeerDependencies.find(peerDep => peerDep.name === dep.name)); return { libraryName, typingsPackageName, @@ -113,11 +119,12 @@ async function combineDataForAllTypesVersions( typesVersions, files, license, + dependencies, // TODO: Explicit type arguments shouldn't be necessary. https://github.com/Microsoft/TypeScript/issues/27507 - dependencies: getAllUniqueValues<"dependencies", PackageId>(allTypesVersions, "dependencies"), testDependencies: getAllUniqueValues<"testDependencies", string>(allTypesVersions, "testDependencies"), pathMappings: getAllUniqueValues<"pathMappings", PathMapping>(allTypesVersions, "pathMappings"), packageJsonDependencies, + packageJsonPeerDependencies, contentHash: await hash(hasPackageJson ? [...files, packageJsonName] : files, mapDefined(allTypesVersions, a => a.tsconfigPathsForHash), fs), globals: getAllUniqueValues<"globals", string>(allTypesVersions, "globals"), declaredModules: getAllUniqueValues<"declaredModules", string>(allTypesVersions, "declaredModules"), @@ -179,7 +186,7 @@ async function getTypingDataForSingleTypesVersion( return { typescriptVersion, dependencies, testDependencies, pathMappings, globals, declaredModules, declFiles, tsconfigPathsForHash }; } -function checkPackageJsonDependencies(dependencies: unknown, path: string): ReadonlyArray { +function checkPackageJsonDependencies(dependencies: unknown, path: string, checkWhitelist: boolean): ReadonlyArray { if (dependencies === undefined) { // tslint:disable-line strict-type-predicates (false positive) return []; } @@ -190,7 +197,7 @@ function checkPackageJsonDependencies(dependencies: unknown, path: string): Read const deps: PackageJsonDependency[] = []; for (const dependencyName in dependencies) { - if (!dependenciesWhitelist.has(dependencyName)) { + if (checkWhitelist && !dependenciesWhitelist.has(dependencyName)) { const msg = dependencyName.startsWith("@types/") ? `Don't use a 'package.json' for @types dependencies unless this package relies on an old version of types that have since been moved to the source repo. diff --git a/src/lib/packages.ts b/src/lib/packages.ts index 13d147d8..f3eeef94 100644 --- a/src/lib/packages.ts +++ b/src/lib/packages.ts @@ -112,7 +112,7 @@ export class AllPackages { return this.notNeeded; } - /** Returns all of the dependences *that have typings*, ignoring others, and including test dependencies. */ + /** Returns all of the dependencies *that have typings*, ignoring others, and including test dependencies. */ *allDependencyTypings(pkg: TypingsData): Iterable { for (const { name, majorVersion } of pkg.dependencies) { const versions = this.data.get(getMangledNameForScopedPackage(name)); @@ -308,8 +308,13 @@ export interface TypingsDataRaw extends BaseRaw { // Whether a "package.json" exists readonly license: License; + + // List of dependencies which indicate they should come from npm, not def typed readonly packageJsonDependencies: ReadonlyArray; + // These should be removed from the packageJsonDependencies above + readonly packageJsonPeerDependencies: ReadonlyArray; + // A hash computed from all files from this definition readonly contentHash: string; @@ -419,6 +424,10 @@ export class TypingsData extends PackageBase { return this.data.dependencies; } + get peerDependencies(): ReadonlyArray { + return this.data.packageJsonPeerDependencies; + } + /** Path to this package, *relative* to the DefinitelyTyped directory. */ get subDirectoryPath(): string { return this.isLatest ? this.name : `${this.name}/v${this.data.libraryMajorVersion}`; diff --git a/src/tester/get-affected-packages.ts b/src/tester/get-affected-packages.ts index 9c164d50..7cdf365f 100644 --- a/src/tester/get-affected-packages.ts +++ b/src/tester/get-affected-packages.ts @@ -62,10 +62,10 @@ function transitiveClosure(initialItems: Iterable, getRelatedItems: (item: /** Generate a map from a package to packages that depend on it. */ function getReverseDependencies(allPackages: AllPackages, changedPackages: PackageId[]): Map> { - const map = new Map]>(); - for (const changed of changedPackages) { + const map = new Map]>(); + for (const changed of changedPackages) { map.set(packageIdToKey(changed), [changed, new Set()]); - } + } for (const typing of allPackages.allTypings()) { if (!map.has(packageIdToKey(typing.id))) { map.set(packageIdToKey(typing.id), [typing.id, new Set()]); diff --git a/src/util/test.ts b/src/util/test.ts index 8ceb0534..e5201851 100644 --- a/src/util/test.ts +++ b/src/util/test.ts @@ -23,6 +23,7 @@ export function createTypingsVersionRaw( typesVersions: [], license: License.MIT, packageJsonDependencies: [], + packageJsonPeerDependencies: [], contentHash: "11111111111111", projectName: "zombo.com", globals: [],